github.com/minio/console@v1.3.0/api/admin_site_replication.go (about) 1 // This file is part of MinIO Console Server 2 // Copyright (c) 2022 MinIO, Inc. 3 // 4 // This program is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Affero General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Affero General Public License for more details. 13 // 14 // You should have received a copy of the GNU Affero General Public License 15 // along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 package api 18 19 import ( 20 "context" 21 22 "github.com/go-openapi/runtime" 23 "github.com/go-openapi/runtime/middleware" 24 "github.com/minio/console/api/operations" 25 siteRepApi "github.com/minio/console/api/operations/site_replication" 26 "github.com/minio/console/models" 27 "github.com/minio/madmin-go/v3" 28 ) 29 30 func registerSiteReplicationHandler(api *operations.ConsoleAPI) { 31 api.SiteReplicationGetSiteReplicationInfoHandler = siteRepApi.GetSiteReplicationInfoHandlerFunc(func(params siteRepApi.GetSiteReplicationInfoParams, session *models.Principal) middleware.Responder { 32 rInfo, err := getSRInfoResponse(session, params) 33 if err != nil { 34 return siteRepApi.NewGetSiteReplicationInfoDefault(err.Code).WithPayload(err.APIError) 35 } 36 return siteRepApi.NewGetSiteReplicationInfoOK().WithPayload(rInfo) 37 }) 38 39 api.SiteReplicationSiteReplicationInfoAddHandler = siteRepApi.SiteReplicationInfoAddHandlerFunc(func(params siteRepApi.SiteReplicationInfoAddParams, session *models.Principal) middleware.Responder { 40 eInfo, err := getSRAddResponse(session, params) 41 if err != nil { 42 return siteRepApi.NewSiteReplicationInfoAddDefault(err.Code).WithPayload(err.APIError) 43 } 44 return siteRepApi.NewSiteReplicationInfoAddOK().WithPayload(eInfo) 45 }) 46 47 api.SiteReplicationSiteReplicationRemoveHandler = siteRepApi.SiteReplicationRemoveHandlerFunc(func(params siteRepApi.SiteReplicationRemoveParams, session *models.Principal) middleware.Responder { 48 remRes, err := getSRRemoveResponse(session, params) 49 if err != nil { 50 return siteRepApi.NewSiteReplicationRemoveDefault(err.Code).WithPayload(err.APIError) 51 } 52 return siteRepApi.NewSiteReplicationRemoveNoContent().WithPayload(remRes) 53 }) 54 55 api.SiteReplicationSiteReplicationEditHandler = siteRepApi.SiteReplicationEditHandlerFunc(func(params siteRepApi.SiteReplicationEditParams, session *models.Principal) middleware.Responder { 56 eInfo, err := getSREditResponse(session, params) 57 if err != nil { 58 return siteRepApi.NewSiteReplicationRemoveDefault(err.Code).WithPayload(err.APIError) 59 } 60 return siteRepApi.NewSiteReplicationEditOK().WithPayload(eInfo) 61 }) 62 } 63 64 func getSRInfoResponse(session *models.Principal, params siteRepApi.GetSiteReplicationInfoParams) (*models.SiteReplicationInfoResponse, *CodedAPIError) { 65 ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) 66 defer cancel() 67 mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) 68 if err != nil { 69 return nil, ErrorWithContext(ctx, err) 70 } 71 adminClient := AdminClient{Client: mAdmin} 72 73 res, err := getSRConfig(ctx, adminClient) 74 if err != nil { 75 return nil, ErrorWithContext(ctx, err) 76 } 77 return res, nil 78 } 79 80 func getSRAddResponse(session *models.Principal, params siteRepApi.SiteReplicationInfoAddParams) (*models.SiteReplicationAddResponse, *CodedAPIError) { 81 ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) 82 defer cancel() 83 mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) 84 if err != nil { 85 return nil, ErrorWithContext(ctx, err) 86 } 87 adminClient := AdminClient{Client: mAdmin} 88 89 res, err := addSiteReplication(ctx, adminClient, ¶ms) 90 if err != nil { 91 return nil, ErrorWithContext(ctx, err) 92 } 93 return res, nil 94 } 95 96 func getSREditResponse(session *models.Principal, params siteRepApi.SiteReplicationEditParams) (*models.PeerSiteEditResponse, *CodedAPIError) { 97 ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) 98 defer cancel() 99 mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) 100 if err != nil { 101 return nil, ErrorWithContext(ctx, err) 102 } 103 adminClient := AdminClient{Client: mAdmin} 104 eRes, err := editSiteReplication(ctx, adminClient, ¶ms) 105 if err != nil { 106 return nil, ErrorWithContext(ctx, err) 107 } 108 return eRes, nil 109 } 110 111 func getSRRemoveResponse(session *models.Principal, params siteRepApi.SiteReplicationRemoveParams) (*models.PeerSiteRemoveResponse, *CodedAPIError) { 112 ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) 113 defer cancel() 114 mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) 115 if err != nil { 116 return nil, ErrorWithContext(ctx, err) 117 } 118 adminClient := AdminClient{Client: mAdmin} 119 rRes, err := removeSiteReplication(ctx, adminClient, ¶ms) 120 if err != nil { 121 return nil, ErrorWithContext(ctx, err) 122 } 123 return rRes, nil 124 } 125 126 func getSRConfig(ctx context.Context, client MinioAdmin) (info *models.SiteReplicationInfoResponse, err error) { 127 srInfo, err := client.getSiteReplicationInfo(ctx) 128 if err != nil { 129 return nil, err 130 } 131 var sites []*models.PeerInfo 132 133 if len(srInfo.Sites) > 0 { 134 for _, s := range srInfo.Sites { 135 pInfo := &models.PeerInfo{ 136 DeploymentID: s.DeploymentID, 137 Endpoint: s.Endpoint, 138 Name: s.Name, 139 } 140 sites = append(sites, pInfo) 141 } 142 } 143 res := &models.SiteReplicationInfoResponse{ 144 Enabled: srInfo.Enabled, 145 Name: srInfo.Name, 146 ServiceAccountAccessKey: srInfo.ServiceAccountAccessKey, 147 Sites: sites, 148 } 149 return res, nil 150 } 151 152 func addSiteReplication(ctx context.Context, client MinioAdmin, params *siteRepApi.SiteReplicationInfoAddParams) (info *models.SiteReplicationAddResponse, err error) { 153 var rSites []madmin.PeerSite 154 155 if len(params.Body) > 0 { 156 for _, aSite := range params.Body { 157 pInfo := &madmin.PeerSite{ 158 AccessKey: aSite.AccessKey, 159 Name: aSite.Name, 160 SecretKey: aSite.SecretKey, 161 Endpoint: aSite.Endpoint, 162 } 163 rSites = append(rSites, *pInfo) 164 } 165 } 166 qs := runtime.Values(params.HTTPRequest.URL.Query()) 167 _, qhkReplicateILMExpiry, _ := qs.GetOK("replicate-ilm-expiry") 168 var opts madmin.SRAddOptions 169 if qhkReplicateILMExpiry { 170 opts.ReplicateILMExpiry = true 171 } 172 cc, err := client.addSiteReplicationInfo(ctx, rSites, opts) 173 if err != nil { 174 return nil, err 175 } 176 177 res := &models.SiteReplicationAddResponse{ 178 ErrorDetail: cc.ErrDetail, 179 InitialSyncErrorMessage: cc.InitialSyncErrorMessage, 180 Status: cc.Status, 181 Success: cc.Success, 182 } 183 184 return res, nil 185 } 186 187 func editSiteReplication(ctx context.Context, client MinioAdmin, params *siteRepApi.SiteReplicationEditParams) (info *models.PeerSiteEditResponse, err error) { 188 peerSiteInfo := &madmin.PeerInfo{ 189 Endpoint: params.Body.Endpoint, // only endpoint can be edited. 190 Name: params.Body.Name, // does not get updated. 191 DeploymentID: params.Body.DeploymentID, // readonly 192 } 193 qs := runtime.Values(params.HTTPRequest.URL.Query()) 194 _, qhkDisableILMExpiryReplication, _ := qs.GetOK("disable-ilm-expiry-replication") 195 _, qhkEnableILMExpiryReplication, _ := qs.GetOK("enable-ilm-expiry-replication") 196 var opts madmin.SREditOptions 197 if qhkDisableILMExpiryReplication { 198 opts.DisableILMExpiryReplication = true 199 } 200 if qhkEnableILMExpiryReplication { 201 opts.EnableILMExpiryReplication = true 202 } 203 eRes, err := client.editSiteReplicationInfo(ctx, *peerSiteInfo, opts) 204 if err != nil { 205 return nil, err 206 } 207 208 editRes := &models.PeerSiteEditResponse{ 209 ErrorDetail: eRes.ErrDetail, 210 Status: eRes.Status, 211 Success: eRes.Success, 212 } 213 return editRes, nil 214 } 215 216 func removeSiteReplication(ctx context.Context, client MinioAdmin, params *siteRepApi.SiteReplicationRemoveParams) (info *models.PeerSiteRemoveResponse, err error) { 217 delAll := params.Body.All 218 siteNames := params.Body.Sites 219 220 var req *madmin.SRRemoveReq 221 if delAll { 222 req = &madmin.SRRemoveReq{ 223 RemoveAll: delAll, 224 } 225 } else { 226 req = &madmin.SRRemoveReq{ 227 SiteNames: siteNames, 228 RemoveAll: delAll, 229 } 230 } 231 232 rRes, err := client.deleteSiteReplicationInfo(ctx, *req) 233 if err != nil { 234 return nil, err 235 } 236 237 removeRes := &models.PeerSiteRemoveResponse{ 238 ErrorDetail: rRes.ErrDetail, 239 Status: rRes.Status, 240 } 241 return removeRes, nil 242 }