github.com/minio/console@v1.3.0/api/admin_remote_buckets_test.go (about)

     1  // This file is part of MinIO Console Server
     2  // Copyright (c) 2023 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  	"errors"
    22  	"net/http"
    23  	"net/http/httptest"
    24  	"os"
    25  	"testing"
    26  
    27  	"github.com/minio/console/pkg/utils"
    28  
    29  	"github.com/go-openapi/swag"
    30  	"github.com/minio/console/api/operations"
    31  	bucketApi "github.com/minio/console/api/operations/bucket"
    32  	"github.com/minio/console/models"
    33  	"github.com/minio/madmin-go/v3"
    34  	"github.com/stretchr/testify/assert"
    35  	"github.com/stretchr/testify/suite"
    36  )
    37  
    38  type RemoteBucketsTestSuite struct {
    39  	suite.Suite
    40  	assert           *assert.Assertions
    41  	currentServer    string
    42  	isServerSet      bool
    43  	server           *httptest.Server
    44  	adminClient      AdminClientMock
    45  	minioClient      minioClientMock
    46  	mockRemoteBucket *models.RemoteBucket
    47  	mockBucketTarget *madmin.BucketTarget
    48  	mockListBuckets  *models.ListBucketsResponse
    49  }
    50  
    51  func (suite *RemoteBucketsTestSuite) SetupSuite() {
    52  	suite.assert = assert.New(suite.T())
    53  	suite.adminClient = AdminClientMock{}
    54  	suite.minioClient = minioClientMock{}
    55  	suite.mockObjects()
    56  }
    57  
    58  func (suite *RemoteBucketsTestSuite) mockObjects() {
    59  	suite.mockListBuckets = &models.ListBucketsResponse{
    60  		Buckets: []*models.Bucket{},
    61  		Total:   0,
    62  	}
    63  	suite.mockRemoteBucket = &models.RemoteBucket{
    64  		AccessKey:    swag.String("accessKey"),
    65  		SecretKey:    "secretKey",
    66  		RemoteARN:    swag.String("remoteARN"),
    67  		Service:      "replication",
    68  		SourceBucket: swag.String("sourceBucket"),
    69  		TargetBucket: "targetBucket",
    70  		TargetURL:    "targetURL",
    71  		Status:       "",
    72  	}
    73  	suite.mockBucketTarget = &madmin.BucketTarget{
    74  		Credentials: &madmin.Credentials{
    75  			AccessKey: *suite.mockRemoteBucket.AccessKey,
    76  			SecretKey: suite.mockRemoteBucket.SecretKey,
    77  		},
    78  		Arn:          *suite.mockRemoteBucket.RemoteARN,
    79  		SourceBucket: *suite.mockRemoteBucket.SourceBucket,
    80  		TargetBucket: suite.mockRemoteBucket.TargetBucket,
    81  		Endpoint:     suite.mockRemoteBucket.TargetURL,
    82  	}
    83  }
    84  
    85  func (suite *RemoteBucketsTestSuite) SetupTest() {
    86  	suite.server = httptest.NewServer(http.HandlerFunc(suite.serverHandler))
    87  	suite.currentServer, suite.isServerSet = os.LookupEnv(ConsoleMinIOServer)
    88  	os.Setenv(ConsoleMinIOServer, suite.server.URL)
    89  }
    90  
    91  func (suite *RemoteBucketsTestSuite) serverHandler(w http.ResponseWriter, _ *http.Request) {
    92  	w.WriteHeader(400)
    93  }
    94  
    95  func (suite *RemoteBucketsTestSuite) TearDownSuite() {
    96  }
    97  
    98  func (suite *RemoteBucketsTestSuite) TearDownTest() {
    99  	if suite.isServerSet {
   100  		os.Setenv(ConsoleMinIOServer, suite.currentServer)
   101  	} else {
   102  		os.Unsetenv(ConsoleMinIOServer)
   103  	}
   104  }
   105  
   106  func (suite *RemoteBucketsTestSuite) TestRegisterRemoteBucketsHandlers() {
   107  	api := &operations.ConsoleAPI{}
   108  	suite.assertHandlersAreNil(api)
   109  	registerAdminBucketRemoteHandlers(api)
   110  	suite.assertHandlersAreNotNil(api)
   111  }
   112  
   113  func (suite *RemoteBucketsTestSuite) assertHandlersAreNil(api *operations.ConsoleAPI) {
   114  	suite.assert.Nil(api.BucketListRemoteBucketsHandler)
   115  	suite.assert.Nil(api.BucketRemoteBucketDetailsHandler)
   116  	suite.assert.Nil(api.BucketDeleteRemoteBucketHandler)
   117  	suite.assert.Nil(api.BucketAddRemoteBucketHandler)
   118  	suite.assert.Nil(api.BucketSetMultiBucketReplicationHandler)
   119  	suite.assert.Nil(api.BucketListExternalBucketsHandler)
   120  	suite.assert.Nil(api.BucketDeleteBucketReplicationRuleHandler)
   121  	suite.assert.Nil(api.BucketDeleteAllReplicationRulesHandler)
   122  	suite.assert.Nil(api.BucketDeleteSelectedReplicationRulesHandler)
   123  	suite.assert.Nil(api.BucketUpdateMultiBucketReplicationHandler)
   124  }
   125  
   126  func (suite *RemoteBucketsTestSuite) assertHandlersAreNotNil(api *operations.ConsoleAPI) {
   127  	suite.assert.NotNil(api.BucketListRemoteBucketsHandler)
   128  	suite.assert.NotNil(api.BucketRemoteBucketDetailsHandler)
   129  	suite.assert.NotNil(api.BucketDeleteRemoteBucketHandler)
   130  	suite.assert.NotNil(api.BucketAddRemoteBucketHandler)
   131  	suite.assert.NotNil(api.BucketSetMultiBucketReplicationHandler)
   132  	suite.assert.NotNil(api.BucketListExternalBucketsHandler)
   133  	suite.assert.NotNil(api.BucketDeleteBucketReplicationRuleHandler)
   134  	suite.assert.NotNil(api.BucketDeleteAllReplicationRulesHandler)
   135  	suite.assert.NotNil(api.BucketDeleteSelectedReplicationRulesHandler)
   136  	suite.assert.NotNil(api.BucketUpdateMultiBucketReplicationHandler)
   137  }
   138  
   139  func (suite *RemoteBucketsTestSuite) TestListRemoteBucketsHandlerWithError() {
   140  	params, api := suite.initListRemoteBucketsRequest()
   141  	response := api.BucketListRemoteBucketsHandler.Handle(params, &models.Principal{})
   142  	_, ok := response.(*bucketApi.ListRemoteBucketsDefault)
   143  	suite.assert.True(ok)
   144  }
   145  
   146  func (suite *RemoteBucketsTestSuite) initListRemoteBucketsRequest() (params bucketApi.ListRemoteBucketsParams, api operations.ConsoleAPI) {
   147  	registerAdminBucketRemoteHandlers(&api)
   148  	params.HTTPRequest = &http.Request{}
   149  	return params, api
   150  }
   151  
   152  func (suite *RemoteBucketsTestSuite) TestListRemoteBucketsWithoutError() {
   153  	ctx := context.Background()
   154  	minioListRemoteBucketsMock = func(_ context.Context, _, _ string) (targets []madmin.BucketTarget, err error) {
   155  		return []madmin.BucketTarget{{
   156  			Credentials: &madmin.Credentials{
   157  				AccessKey: "accessKey",
   158  				SecretKey: "secretKey",
   159  			},
   160  		}}, nil
   161  	}
   162  	res, err := listRemoteBuckets(ctx, &suite.adminClient)
   163  	suite.assert.NotNil(res)
   164  	suite.assert.Nil(err)
   165  }
   166  
   167  func (suite *RemoteBucketsTestSuite) TestRemoteBucketDetailsHandlerWithError() {
   168  	params, api := suite.initRemoteBucketDetailsRequest()
   169  	response := api.BucketRemoteBucketDetailsHandler.Handle(params, &models.Principal{})
   170  	_, ok := response.(*bucketApi.RemoteBucketDetailsDefault)
   171  	suite.assert.True(ok)
   172  }
   173  
   174  func (suite *RemoteBucketsTestSuite) initRemoteBucketDetailsRequest() (params bucketApi.RemoteBucketDetailsParams, api operations.ConsoleAPI) {
   175  	registerAdminBucketRemoteHandlers(&api)
   176  	params.HTTPRequest = &http.Request{}
   177  	return params, api
   178  }
   179  
   180  func (suite *RemoteBucketsTestSuite) TestGetRemoteBucketWithoutError() {
   181  	ctx := context.Background()
   182  	minioGetRemoteBucketMock = func(_ context.Context, _, _ string) (targets *madmin.BucketTarget, err error) {
   183  		return suite.mockBucketTarget, nil
   184  	}
   185  	res, err := getRemoteBucket(ctx, &suite.adminClient, "bucketName")
   186  	suite.assert.Nil(err)
   187  	suite.assert.NotNil(res)
   188  	suite.assert.Equal(suite.mockRemoteBucket, res)
   189  }
   190  
   191  func (suite *RemoteBucketsTestSuite) TestDeleteRemoteBucketHandlerWithError() {
   192  	params, api := suite.initDeleteRemoteBucketRequest()
   193  	response := api.BucketDeleteRemoteBucketHandler.Handle(params, &models.Principal{})
   194  	_, ok := response.(*bucketApi.DeleteRemoteBucketDefault)
   195  	suite.assert.True(ok)
   196  }
   197  
   198  func (suite *RemoteBucketsTestSuite) initDeleteRemoteBucketRequest() (params bucketApi.DeleteRemoteBucketParams, api operations.ConsoleAPI) {
   199  	registerAdminBucketRemoteHandlers(&api)
   200  	params.HTTPRequest = &http.Request{}
   201  	return params, api
   202  }
   203  
   204  func (suite *RemoteBucketsTestSuite) TestAddRemoteBucketHandlerWithError() {
   205  	params, api := suite.initAddRemoteBucketRequest()
   206  	response := api.BucketAddRemoteBucketHandler.Handle(params, &models.Principal{})
   207  	_, ok := response.(*bucketApi.AddRemoteBucketDefault)
   208  	suite.assert.True(ok)
   209  }
   210  
   211  func (suite *RemoteBucketsTestSuite) initAddRemoteBucketRequest() (params bucketApi.AddRemoteBucketParams, api operations.ConsoleAPI) {
   212  	registerAdminBucketRemoteHandlers(&api)
   213  	url := "^&*&^%^"
   214  	accessKey := "accessKey"
   215  	secretKey := "secretKey"
   216  	params.HTTPRequest = &http.Request{}
   217  	params.Body = &models.CreateRemoteBucket{
   218  		TargetURL: &url,
   219  		AccessKey: &accessKey,
   220  		SecretKey: &secretKey,
   221  	}
   222  	return params, api
   223  }
   224  
   225  func (suite *RemoteBucketsTestSuite) TestAddRemoteBucketWithoutError() {
   226  	ctx := context.Background()
   227  	minioAddRemoteBucketMock = func(_ context.Context, _ string, _ *madmin.BucketTarget) (string, error) {
   228  		return "bucketName", nil
   229  	}
   230  	url := "https://localhost"
   231  	accessKey := "accessKey"
   232  	secretKey := "secretKey"
   233  	targetBucket := "targetBucket"
   234  	syncMode := "async"
   235  	sourceBucket := "sourceBucket"
   236  	data := models.CreateRemoteBucket{
   237  		TargetURL:         &url,
   238  		TargetBucket:      &targetBucket,
   239  		AccessKey:         &accessKey,
   240  		SecretKey:         &secretKey,
   241  		SyncMode:          &syncMode,
   242  		HealthCheckPeriod: 10,
   243  		SourceBucket:      &sourceBucket,
   244  	}
   245  	res, err := addRemoteBucket(ctx, &suite.adminClient, data)
   246  	suite.assert.NotNil(res)
   247  	suite.assert.Nil(err)
   248  }
   249  
   250  func (suite *RemoteBucketsTestSuite) TestSetMultiBucketReplicationHandlerWithError() {
   251  	params, api := suite.initSetMultiBucketReplicationRequest()
   252  	response := api.BucketSetMultiBucketReplicationHandler.Handle(params, &models.Principal{})
   253  	_, ok := response.(*bucketApi.SetMultiBucketReplicationOK)
   254  	suite.assert.True(ok)
   255  }
   256  
   257  func (suite *RemoteBucketsTestSuite) initSetMultiBucketReplicationRequest() (params bucketApi.SetMultiBucketReplicationParams, api operations.ConsoleAPI) {
   258  	registerAdminBucketRemoteHandlers(&api)
   259  	accessKey := "accessKey"
   260  	secretKey := "secretKey"
   261  	targetURL := "https://localhost"
   262  	syncMode := "async"
   263  	params.HTTPRequest = &http.Request{}
   264  	params.Body = &models.MultiBucketReplication{
   265  		BucketsRelation:   []*models.MultiBucketsRelation{{}},
   266  		AccessKey:         &accessKey,
   267  		SecretKey:         &secretKey,
   268  		Region:            "region",
   269  		TargetURL:         &targetURL,
   270  		SyncMode:          &syncMode,
   271  		Bandwidth:         10,
   272  		HealthCheckPeriod: 10,
   273  	}
   274  	return params, api
   275  }
   276  
   277  func (suite *RemoteBucketsTestSuite) TestListExternalBucketsHandlerWithError() {
   278  	params, api := suite.initListExternalBucketsRequest()
   279  	response := api.BucketListExternalBucketsHandler.Handle(params, &models.Principal{})
   280  	_, ok := response.(*bucketApi.ListExternalBucketsDefault)
   281  	suite.assert.True(ok)
   282  }
   283  
   284  func (suite *RemoteBucketsTestSuite) initListExternalBucketsRequest() (params bucketApi.ListExternalBucketsParams, api operations.ConsoleAPI) {
   285  	registerAdminBucketRemoteHandlers(&api)
   286  	url := "http://localhost:9000"
   287  	accessKey := "accessKey"
   288  	secretKey := "secretKey"
   289  	tls := false
   290  	params.HTTPRequest = &http.Request{}
   291  	params.Body = &models.ListExternalBucketsParams{
   292  		TargetURL: &url,
   293  		AccessKey: &accessKey,
   294  		SecretKey: &secretKey,
   295  		UseTLS:    &tls,
   296  	}
   297  	return params, api
   298  }
   299  
   300  func (suite *RemoteBucketsTestSuite) TestListExternalBucketsWithError() {
   301  	ctx := context.Background()
   302  	minioAccountInfoMock = func(_ context.Context) (madmin.AccountInfo, error) {
   303  		return madmin.AccountInfo{}, errors.New("error")
   304  	}
   305  	res, err := listExternalBuckets(ctx, &suite.adminClient)
   306  	suite.assert.NotNil(err)
   307  	suite.assert.Nil(res)
   308  }
   309  
   310  func (suite *RemoteBucketsTestSuite) TestListExternalBucketsWithoutError() {
   311  	ctx := context.Background()
   312  	minioAccountInfoMock = func(_ context.Context) (madmin.AccountInfo, error) {
   313  		return madmin.AccountInfo{
   314  			Buckets: []madmin.BucketAccessInfo{},
   315  		}, nil
   316  	}
   317  	res, err := listExternalBuckets(ctx, &suite.adminClient)
   318  	suite.assert.Nil(err)
   319  	suite.assert.NotNil(res)
   320  	suite.assert.Equal(suite.mockListBuckets, res)
   321  }
   322  
   323  func (suite *RemoteBucketsTestSuite) TestDeleteBucketReplicationRuleHandlerWithError() {
   324  	params, api := suite.initDeleteBucketReplicationRuleRequest()
   325  	response := api.BucketDeleteBucketReplicationRuleHandler.Handle(params, &models.Principal{})
   326  	_, ok := response.(*bucketApi.DeleteBucketReplicationRuleDefault)
   327  	suite.assert.True(ok)
   328  }
   329  
   330  func (suite *RemoteBucketsTestSuite) initDeleteBucketReplicationRuleRequest() (params bucketApi.DeleteBucketReplicationRuleParams, api operations.ConsoleAPI) {
   331  	registerAdminBucketRemoteHandlers(&api)
   332  	params.HTTPRequest = &http.Request{}
   333  	return params, api
   334  }
   335  
   336  func (suite *RemoteBucketsTestSuite) TestDeleteAllReplicationRulesHandlerWithError() {
   337  	params, api := suite.initDeleteAllReplicationRulesRequest()
   338  	response := api.BucketDeleteAllReplicationRulesHandler.Handle(params, &models.Principal{})
   339  	_, ok := response.(*bucketApi.DeleteAllReplicationRulesDefault)
   340  	suite.assert.True(ok)
   341  }
   342  
   343  func (suite *RemoteBucketsTestSuite) initDeleteAllReplicationRulesRequest() (params bucketApi.DeleteAllReplicationRulesParams, api operations.ConsoleAPI) {
   344  	registerAdminBucketRemoteHandlers(&api)
   345  	params.HTTPRequest = &http.Request{}
   346  	return params, api
   347  }
   348  
   349  func (suite *RemoteBucketsTestSuite) TestDeleteSelectedReplicationRulesHandlerWithError() {
   350  	params, api := suite.initDeleteSelectedReplicationRulesRequest()
   351  	response := api.BucketDeleteSelectedReplicationRulesHandler.Handle(params, &models.Principal{})
   352  	_, ok := response.(*bucketApi.DeleteSelectedReplicationRulesDefault)
   353  	suite.assert.True(ok)
   354  }
   355  
   356  func (suite *RemoteBucketsTestSuite) initDeleteSelectedReplicationRulesRequest() (params bucketApi.DeleteSelectedReplicationRulesParams, api operations.ConsoleAPI) {
   357  	registerAdminBucketRemoteHandlers(&api)
   358  	params.HTTPRequest = &http.Request{}
   359  	params.BucketName = "bucketName"
   360  	params.Rules = &models.BucketReplicationRuleList{
   361  		Rules: []string{"rule1", "rule2"},
   362  	}
   363  
   364  	return params, api
   365  }
   366  
   367  func (suite *RemoteBucketsTestSuite) TestUpdateMultiBucketReplicationHandlerWithError() {
   368  	params, api := suite.initUpdateMultiBucketReplicationRequest()
   369  	response := api.BucketUpdateMultiBucketReplicationHandler.Handle(params, &models.Principal{})
   370  	_, ok := response.(*bucketApi.UpdateMultiBucketReplicationDefault)
   371  	suite.assert.True(ok)
   372  }
   373  
   374  func (suite *RemoteBucketsTestSuite) initUpdateMultiBucketReplicationRequest() (params bucketApi.UpdateMultiBucketReplicationParams, api operations.ConsoleAPI) {
   375  	registerAdminBucketRemoteHandlers(&api)
   376  	r := &http.Request{}
   377  	ctx := context.WithValue(context.Background(), utils.ContextClientIP, "127.0.0.1")
   378  	rc := r.WithContext(ctx)
   379  	params.HTTPRequest = rc
   380  	params.Body = &models.MultiBucketReplicationEdit{}
   381  	return params, api
   382  }
   383  
   384  func TestRemoteBuckets(t *testing.T) {
   385  	suite.Run(t, new(RemoteBucketsTestSuite))
   386  }