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, &params)
    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, &params)
   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, &params)
   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  }