Add size info to bucket list api (#122)

Using madmin.AccountUsageInfo since that api
includes size already.
Also includes integration with UI.
This commit is contained in:
César Nieto
2020-05-18 13:36:18 -07:00
committed by GitHub
parent 35c3b53a23
commit e8491d80cb
8 changed files with 214 additions and 188 deletions

View File

@@ -84,6 +84,7 @@ type MinioAdmin interface {
stopProfiling(ctx context.Context) (io.ReadCloser, error)
serviceTrace(ctx context.Context, allTrace, errTrace bool) <-chan madmin.ServiceTraceInfo
getLogs(ctx context.Context, node string, lineCnt int, logKind string) <-chan madmin.LogInfo
accountUsageInfo(ctx context.Context) (madmin.AccountUsageInfo, error)
// Service Accounts
addServiceAccount(ctx context.Context, policy *iampolicy.Policy) (mauth.Credentials, error)
listServiceAccounts(ctx context.Context) (madmin.ListServiceAccountsResp, error)
@@ -228,6 +229,11 @@ func (ac adminClient) deleteServiceAccount(ctx context.Context, serviceAccount s
return ac.client.DeleteServiceAccount(ctx, serviceAccount)
}
// implements madmin.AccountingUsageInfo()
func (ac adminClient) accountUsageInfo(ctx context.Context) (madmin.AccountUsageInfo, error) {
return ac.client.AccountUsageInfo(ctx)
}
func newMAdminClient(jwt string) (*madmin.AdminClient, error) {
claims, err := auth.JWTAuthenticate(jwt)
if err != nil {

View File

@@ -82,22 +82,17 @@ func registerBucketsHandlers(api *operations.McsAPI) {
})
}
// listBuckets fetches a list of all buckets from MinIO Servers
func listBuckets(ctx context.Context, client MinioClient) ([]*models.Bucket, error) {
// Get list of all buckets owned by an authenticated user.
// This call requires explicit authentication, no anonymous requests are
// allowed for listing buckets.
buckets, err := client.listBucketsWithContext(ctx)
// getaAcountUsageInfo fetches a list of all buckets allowed to that particular client from MinIO Servers
func getaAcountUsageInfo(ctx context.Context, client MinioAdmin) ([]*models.Bucket, error) {
info, err := client.accountUsageInfo(ctx)
if err != nil {
return []*models.Bucket{}, err
}
var bucketInfos []*models.Bucket
for _, bucket := range buckets {
bucketElem := &models.Bucket{Name: swag.String(bucket.Name), CreationDate: bucket.CreationDate.String()}
for _, bucket := range info.Buckets {
bucketElem := &models.Bucket{Name: swag.String(bucket.Name), CreationDate: bucket.Created.String(), Size: int64(bucket.Size)}
bucketInfos = append(bucketInfos, bucketElem)
}
return bucketInfos, nil
}
@@ -105,20 +100,21 @@ func listBuckets(ctx context.Context, client MinioClient) ([]*models.Bucket, err
func getListBucketsResponse(sessionID string) (*models.ListBucketsResponse, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel()
mClient, err := newMinioClient(sessionID)
mAdmin, err := newMAdminClient(sessionID)
if err != nil {
log.Println("error creating MinIO Client:", err)
log.Println("error creating Madmin Client:", err)
return nil, err
}
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient{client: mClient}
buckets, err := listBuckets(ctx, minioClient)
adminClient := adminClient{client: mAdmin}
buckets, err := getaAcountUsageInfo(ctx, adminClient)
if err != nil {
log.Println("error listing buckets:", err)
log.Println("error accountingUsageInfo:", err)
return nil, err
}
// serialize output
listBucketsResponse := &models.ListBucketsResponse{
Buckets: buckets,

View File

@@ -27,6 +27,7 @@ import (
"github.com/go-openapi/swag"
"github.com/minio/mcs/models"
"github.com/minio/minio-go/v6"
"github.com/minio/minio/pkg/madmin"
"github.com/stretchr/testify/assert"
)
@@ -66,41 +67,50 @@ func (mc minioClientMock) getBucketPolicy(bucketName string) (string, error) {
return minioGetBucketPolicyMock(bucketName)
}
var minioAccountUsageInfoMock func(ctx context.Context) (madmin.AccountUsageInfo, error)
// mock function of dataUsageInfo() needed for list bucket's usage
func (ac adminClientMock) accountUsageInfo(ctx context.Context) (madmin.AccountUsageInfo, error) {
return minioAccountUsageInfoMock(ctx)
}
func TestListBucket(t *testing.T) {
assert := assert.New(t)
minClient := minioClientMock{}
adminClient := adminClientMock{}
ctx := context.Background()
// Test-1 : listBuckets() Get response from minio client with two buckets and return the same number on listBuckets()
// mock minIO client
mockBucketList := []minio.BucketInfo{
minio.BucketInfo{Name: "bucket-1", CreationDate: time.Now()},
minio.BucketInfo{Name: "bucket-2", CreationDate: time.Now().Add(time.Hour * 1)},
// Test-1 : getaAcountUsageInfo() Get response from minio client with two buckets
mockBucketList := madmin.AccountUsageInfo{
AccountName: "test",
Buckets: []madmin.BucketUsageInfo{
madmin.BucketUsageInfo{Name: "bucket-1", Created: time.Now(), Size: 1024},
madmin.BucketUsageInfo{Name: "bucket-2", Created: time.Now().Add(time.Hour * 1), Size: 0},
},
}
// mock function response from listBucketsWithContext(ctx)
minioListBucketsWithContextMock = func(ctx context.Context) ([]minio.BucketInfo, error) {
minioAccountUsageInfoMock = func(ctx context.Context) (madmin.AccountUsageInfo, error) {
return mockBucketList, nil
}
// get list buckets response this response should have Name, CreationDate, Size and Access
// as part of of each bucket
function := "listBuckets()"
bucketList, err := listBuckets(ctx, minClient)
function := "getaAcountUsageInfo()"
bucketList, err := getaAcountUsageInfo(ctx, adminClient)
if err != nil {
t.Errorf("Failed on %s:, error occurred: %s", function, err.Error())
}
// verify length of buckets is correct
assert.Equal(len(mockBucketList), len(bucketList), fmt.Sprintf("Failed on %s: length of bucket's lists is not the same", function))
assert.Equal(len(mockBucketList.Buckets), len(bucketList), fmt.Sprintf("Failed on %s: length of bucket's lists is not the same", function))
for i, b := range bucketList {
assert.Equal(mockBucketList[i].Name, *b.Name)
assert.Equal(mockBucketList[i].CreationDate.String(), b.CreationDate)
assert.Equal(mockBucketList.Buckets[i].Name, *b.Name)
assert.Equal(mockBucketList.Buckets[i].Created.String(), b.CreationDate)
assert.Equal(mockBucketList.Buckets[i].Name, *b.Name)
assert.Equal(int64(mockBucketList.Buckets[i].Size), b.Size)
}
// Test-2 : listBuckets() Return and see that the error is handled correctly and returned
minioListBucketsWithContextMock = func(ctx context.Context) ([]minio.BucketInfo, error) {
return nil, errors.New("error")
// Test-2 : getaAcountUsageInfo() Return and see that the error is handled correctly and returned
minioAccountUsageInfoMock = func(ctx context.Context) (madmin.AccountUsageInfo, error) {
return madmin.AccountUsageInfo{}, errors.New("error")
}
_, err = listBuckets(ctx, minClient)
_, err = getaAcountUsageInfo(ctx, adminClient)
if assert.Error(err) {
assert.Equal("error", err.Error())
}