Upgrade Operator to 3.0.1 (#201)

This commit is contained in:
Daniel Valdivia
2020-07-25 14:38:16 -07:00
committed by GitHub
parent 3ac64b3848
commit bc8429bd6b
34 changed files with 833 additions and 826 deletions

View File

@@ -41,7 +41,7 @@ import (
"github.com/minio/mcs/models"
"github.com/minio/mcs/restapi/operations"
"github.com/minio/mcs/restapi/operations/admin_api"
operator "github.com/minio/minio-operator/pkg/apis/operator.min.io/v1"
operator "github.com/minio/operator/pkg/apis/minio.min.io/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@@ -115,7 +115,7 @@ func registerTenantHandlers(api *operations.McsAPI) {
// deleteTenantAction performs the actions of deleting a tenant
func deleteTenantAction(ctx context.Context, operatorClient OperatorClient, nameSpace, instanceName string) error {
err := operatorClient.MinIOInstanceDelete(ctx, nameSpace, instanceName, metav1.DeleteOptions{})
err := operatorClient.TenantDelete(ctx, nameSpace, instanceName, metav1.DeleteOptions{})
if err != nil {
return err
}
@@ -134,7 +134,7 @@ func getDeleteTenantResponse(session *models.Principal, params admin_api.DeleteT
return deleteTenantAction(context.Background(), opClient, params.Namespace, params.Tenant)
}
func getMinioInstanceScheme(mi *operator.MinIOInstance) string {
func getTenantScheme(mi *operator.Tenant) string {
scheme := "http"
if mi.AutoCert() || mi.ExternalCert() {
scheme = "https"
@@ -169,52 +169,60 @@ func getTenantAdminClient(ctx context.Context, client K8sClient, namespace, tena
return mAdmin, nil
}
func getMinioInstance(ctx context.Context, operatorClient OperatorClient, namespace, tenantName string) (*operator.MinIOInstance, error) {
minInst, err := operatorClient.MinIOInstanceGet(ctx, namespace, tenantName, metav1.GetOptions{})
func getTenant(ctx context.Context, operatorClient OperatorClient, namespace, tenantName string) (*operator.Tenant, error) {
minInst, err := operatorClient.TenantGet(ctx, namespace, tenantName, metav1.GetOptions{})
if err != nil {
return nil, err
}
return minInst, nil
}
func getTenantInfo(minioInstance *operator.MinIOInstance, tenantInfo *usageInfo) *models.Tenant {
func getTenantInfo(tenant *operator.Tenant, tenantInfo *usageInfo) *models.Tenant {
var instanceCount int64
var volumeCount int64
for _, zone := range minioInstance.Spec.Zones {
for _, zone := range tenant.Spec.Zones {
instanceCount = instanceCount + int64(zone.Servers)
volumeCount = volumeCount + int64(zone.Servers*int32(minioInstance.Spec.VolumesPerServer))
volumeCount = volumeCount + int64(zone.Servers*zone.VolumesPerServer)
}
var zones []*models.Zone
for _, z := range minioInstance.Spec.Zones {
zones = append(zones, &models.Zone{
Name: swag.String(z.Name),
Servers: swag.Int64(int64(z.Servers)),
})
var totalSize int64
for _, z := range tenant.Spec.Zones {
zoneModel := &models.Zone{
Name: z.Name,
Servers: swag.Int64(int64(z.Servers)),
VolumesPerServer: &z.VolumesPerServer,
VolumeConfiguration: &models.ZoneVolumeConfiguration{},
}
if z.VolumeClaimTemplate != nil {
zoneModel.VolumeConfiguration.Size = swag.Int64(z.VolumeClaimTemplate.Spec.Resources.Requests.Storage().Value())
if z.VolumeClaimTemplate.Spec.StorageClassName != nil {
zoneModel.VolumeConfiguration.StorageClassName = *z.VolumeClaimTemplate.Spec.StorageClassName
}
}
zones = append(zones, zoneModel)
zoneSize := int64(z.Servers) * int64(z.VolumesPerServer) * z.VolumeClaimTemplate.Spec.Resources.Requests.Storage().Value()
totalSize = totalSize + zoneSize
}
return &models.Tenant{
CreationDate: minioInstance.ObjectMeta.CreationTimestamp.String(),
InstanceCount: instanceCount,
Name: minioInstance.Name,
VolumesPerServer: int64(minioInstance.Spec.VolumesPerServer),
VolumeCount: volumeCount,
VolumeSize: minioInstance.Spec.VolumeClaimTemplate.Spec.Resources.Requests.Storage().Value(),
TotalSize: int64(minioInstance.Spec.VolumeClaimTemplate.Spec.Resources.Requests.Storage().Value() * volumeCount),
ZoneCount: int64(len(minioInstance.Spec.Zones)),
CurrentState: minioInstance.Status.CurrentState,
Zones: zones,
Namespace: minioInstance.ObjectMeta.Namespace,
Image: minioInstance.Spec.Image,
UsedSize: tenantInfo.DisksUsage,
StorageClass: swag.StringValue(minioInstance.Spec.VolumeClaimTemplate.Spec.StorageClassName),
CreationDate: tenant.ObjectMeta.CreationTimestamp.String(),
Name: tenant.Name,
TotalSize: totalSize,
CurrentState: tenant.Status.CurrentState,
Zones: zones,
Namespace: tenant.ObjectMeta.Namespace,
Image: tenant.Spec.Image,
UsedSize: tenantInfo.DisksUsage,
}
}
func getTenantInfoResponse(session *models.Principal, params admin_api.TenantInfoParams) (*models.Tenant, error) {
// 20 seconds timeout
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
// 5 seconds timeout
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
opClientClientSet, err := cluster.OperatorClient(session.SessionToken)
@@ -234,13 +242,28 @@ func getTenantInfoResponse(session *models.Principal, params admin_api.TenantInf
client: clientset,
}
minInst, err := getMinioInstance(ctx, opClient, params.Namespace, params.Tenant)
minTenant, err := getTenant(ctx, opClient, params.Namespace, params.Tenant)
if err != nil {
log.Println("error getting minioInstance:", err)
log.Println("error getting minioTenant:", err)
return nil, err
}
minioInstanceScheme := getMinioInstanceScheme(minInst)
mAdmin, err := getTenantAdminClient(ctx, k8sClient, params.Namespace, params.Tenant, minInst.Spec.ServiceName, minioInstanceScheme)
tenantScheme := getTenantScheme(minTenant)
svcName := minTenant.Spec.ServiceName
if svcName == "" {
svcName = minTenant.Name
// TODO:
// 1 get tenant services
// 2 filter out cluster ip svc
}
mAdmin, err := getTenantAdminClient(
ctx,
k8sClient,
params.Namespace,
params.Tenant,
svcName,
tenantScheme)
if err != nil {
log.Println("error getting tenant's admin client:", err)
return nil, err
@@ -254,7 +277,7 @@ func getTenantInfoResponse(session *models.Principal, params admin_api.TenantInf
log.Println("error getting admin info:", err)
return nil, err
}
info := getTenantInfo(minInst, adminInfo)
info := getTenantInfo(minTenant, adminInfo)
return info, nil
}
@@ -267,20 +290,20 @@ func listTenants(ctx context.Context, operatorClient OperatorClient, namespace s
listOpts.Limit = int64(*limit)
}
minInstances, err := operatorClient.MinIOInstanceList(ctx, namespace, listOpts)
minTenants, err := operatorClient.TenantList(ctx, namespace, listOpts)
if err != nil {
return nil, err
}
var tenants []*models.TenantList
for _, minInst := range minInstances.Items {
for _, minInst := range minTenants.Items {
var instanceCount int64
var volumeCount int64
for _, zone := range minInst.Spec.Zones {
instanceCount = instanceCount + int64(zone.Servers)
volumeCount = volumeCount + int64(zone.Servers*int32(minInst.Spec.VolumesPerServer))
volumeCount = volumeCount + int64(zone.Servers*zone.VolumesPerServer)
}
tenants = append(tenants, &models.TenantList{
@@ -289,7 +312,6 @@ func listTenants(ctx context.Context, operatorClient OperatorClient, namespace s
ZoneCount: int64(len(minInst.Spec.Zones)),
InstanceCount: instanceCount,
VolumeCount: volumeCount,
VolumeSize: minInst.Spec.VolumeClaimTemplate.Spec.Resources.Requests.Storage().Value(),
CurrentState: minInst.Status.CurrentState,
Namespace: minInst.ObjectMeta.Namespace,
})
@@ -380,59 +402,33 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
return nil, err
}
enableSSL := true
enableSSL := false
if params.Body.EnableSsl != nil {
enableSSL = *params.Body.EnableSsl
}
enableMCS := true
if params.Body.EnableMcs != nil {
enableMCS = *params.Body.EnableMcs
}
volumeSize, err := resource.ParseQuantity(*params.Body.VolumeConfiguration.Size)
if err != nil {
return nil, err
if params.Body.EnableConsole != nil {
enableMCS = *params.Body.EnableConsole
}
// TODO: Calculate this ourselves?
memorySize, err := resource.ParseQuantity(getTenantMemorySize())
if err != nil {
return nil, err
}
volTemp := corev1.PersistentVolumeClaimSpec{
AccessModes: []corev1.PersistentVolumeAccessMode{
corev1.ReadWriteOnce,
},
Resources: corev1.ResourceRequirements{
Requests: corev1.ResourceList{
corev1.ResourceStorage: volumeSize,
corev1.ResourceMemory: memorySize,
},
},
}
if params.Body.VolumeConfiguration.StorageClass != "" {
volTemp.StorageClassName = &params.Body.VolumeConfiguration.StorageClass
}
//Construct a MinIO Instance with everything we are getting from parameters
minInst := operator.MinIOInstance{
minInst := operator.Tenant{
ObjectMeta: metav1.ObjectMeta{
Name: *params.Body.Name,
},
Spec: operator.MinIOInstanceSpec{
Spec: operator.TenantSpec{
Image: minioImage,
Mountpath: "/export",
CredsSecret: &corev1.LocalObjectReference{
Name: secretName,
},
RequestAutoCert: enableSSL,
VolumeClaimTemplate: &corev1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "data",
},
Spec: volTemp,
},
},
}
// optionals are set below
@@ -460,10 +456,11 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
return nil, err
}
minInst.Spec.MCS = &operator.MCSConfig{
Replicas: 2,
Image: "minio/mcs:v0.1.1",
MCSSecret: &corev1.LocalObjectReference{Name: mcsSecretName},
const consoleVersion = "minio/mcs:v0.2.1"
minInst.Spec.Console = &operator.ConsoleConfiguration{
Replicas: 2,
Image: consoleVersion,
ConsoleSecret: &corev1.LocalObjectReference{Name: mcsSecretName},
}
}
@@ -474,18 +471,39 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
// set the zones if they are provided
if len(params.Body.Zones) > 0 {
for _, zone := range params.Body.Zones {
volumeSize := resource.NewQuantity(*zone.VolumeConfiguration.Size, resource.DecimalExponent)
volTemp := corev1.PersistentVolumeClaimSpec{
AccessModes: []corev1.PersistentVolumeAccessMode{
corev1.ReadWriteOnce,
},
Resources: corev1.ResourceRequirements{
Requests: corev1.ResourceList{
corev1.ResourceStorage: *volumeSize,
},
},
}
if zone.VolumeConfiguration.StorageClassName != "" {
volTemp.StorageClassName = &zone.VolumeConfiguration.StorageClassName
}
minInst.Spec.Zones = append(minInst.Spec.Zones, operator.Zone{
Name: *zone.Name,
Servers: int32(*zone.Servers),
Name: zone.Name,
Servers: int32(*zone.Servers),
VolumesPerServer: *zone.VolumesPerServer,
VolumeClaimTemplate: &corev1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "data",
},
Spec: volTemp,
},
Resources: corev1.ResourceRequirements{
Requests: corev1.ResourceList{
corev1.ResourceMemory: memorySize,
},
},
})
}
}
// Set Volumes Per Server if provided, default 1
minInst.Spec.VolumesPerServer = 1
if params.Body.VolumesPerServer > 0 {
minInst.Spec.VolumesPerServer = int(params.Body.VolumesPerServer)
}
// Set Mount Path if provided
if params.Body.MounthPath != "" {
minInst.Spec.Mountpath = params.Body.MounthPath
@@ -503,7 +521,7 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
return nil, err
}
_, err = opClient.OperatorV1().MinIOInstances(ns).Create(context.Background(), &minInst, metav1.CreateOptions{})
_, err = opClient.MinioV1().Tenants(ns).Create(context.Background(), &minInst, metav1.CreateOptions{})
if err != nil {
return nil, err
}
@@ -522,10 +540,10 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
}, nil
}
// updateTenantAction does an update on the minioInstance by patching the desired changes
// updateTenantAction does an update on the minioTenant by patching the desired changes
func updateTenantAction(ctx context.Context, operatorClient OperatorClient, httpCl cluster.HTTPClientI, nameSpace string, params admin_api.UpdateTenantParams) error {
imageToUpdate := params.Body.Image
minInst, err := operatorClient.MinIOInstanceGet(ctx, nameSpace, params.Tenant, metav1.GetOptions{})
minInst, err := operatorClient.TenantGet(ctx, nameSpace, params.Tenant, metav1.GetOptions{})
if err != nil {
return err
}
@@ -545,7 +563,7 @@ func updateTenantAction(ctx context.Context, operatorClient OperatorClient, http
if err != nil {
return err
}
_, err = operatorClient.MinIOInstancePatch(ctx, nameSpace, minInst.Name, types.MergePatchType, payloadBytes, metav1.PatchOptions{})
_, err = operatorClient.TenantPatch(ctx, nameSpace, minInst.Name, types.MergePatchType, payloadBytes, metav1.PatchOptions{})
if err != nil {
return err
}
@@ -569,7 +587,7 @@ func getUpdateTenantResponse(session *models.Principal, params admin_api.UpdateT
},
}
if err := updateTenantAction(ctx, opClient, httpC, params.Namespace, params); err != nil {
log.Println("error patching MinioInstance:", err)
log.Println("error patching Tenant:", err)
return err
}
return nil
@@ -577,13 +595,13 @@ func getUpdateTenantResponse(session *models.Principal, params admin_api.UpdateT
// addTenantZone creates a zone to a defined tenant
func addTenantZone(ctx context.Context, operatorClient OperatorClient, params admin_api.TenantAddZoneParams) error {
minInst, err := operatorClient.MinIOInstanceGet(ctx, params.Namespace, params.Tenant, metav1.GetOptions{})
minInst, err := operatorClient.TenantGet(ctx, params.Namespace, params.Tenant, metav1.GetOptions{})
if err != nil {
return err
}
minInst.Spec.Zones = append(minInst.Spec.Zones, operator.Zone{
Name: *params.Body.Name,
Name: params.Body.Name,
Servers: int32(*params.Body.Servers),
})
@@ -592,7 +610,7 @@ func addTenantZone(ctx context.Context, operatorClient OperatorClient, params ad
return err
}
_, err = operatorClient.MinIOInstancePatch(ctx, params.Namespace, minInst.Name, types.MergePatchType, payloadBytes, metav1.PatchOptions{})
_, err = operatorClient.TenantPatch(ctx, params.Namespace, minInst.Name, types.MergePatchType, payloadBytes, metav1.PatchOptions{})
if err != nil {
return err
}
@@ -610,7 +628,7 @@ func getTenantAddZoneResponse(session *models.Principal, params admin_api.Tenant
client: opClientClientSet,
}
if err := addTenantZone(ctx, opClient, params); err != nil {
log.Println("error patching MinioInstance:", err)
log.Println("error patching Tenant:", err)
return err
}
return nil

View File

@@ -19,6 +19,7 @@ package restapi
import (
"bytes"
"context"
"encoding/json"
"errors"
"io/ioutil"
"net/http"
@@ -29,40 +30,40 @@ import (
"github.com/minio/mcs/cluster"
"github.com/minio/mcs/models"
"github.com/minio/mcs/restapi/operations/admin_api"
operator "github.com/minio/minio-operator/pkg/apis/operator.min.io/v1"
v1 "github.com/minio/minio-operator/pkg/apis/operator.min.io/v1"
operator "github.com/minio/operator/pkg/apis/minio.min.io/v1"
v1 "github.com/minio/operator/pkg/apis/minio.min.io/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
)
var opClientMinioInstanceDeleteMock func(ctx context.Context, namespace string, instanceName string, options metav1.DeleteOptions) error
var opClientMinioInstanceGetMock func(ctx context.Context, namespace string, instanceName string, options metav1.GetOptions) (*v1.MinIOInstance, error)
var opClientMinioInstancePatchMock func(ctx context.Context, namespace string, instanceName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.MinIOInstance, error)
var opClientMinioInstanceListMock func(ctx context.Context, namespace string, opts metav1.ListOptions) (*v1.MinIOInstanceList, error)
var opClientTenantDeleteMock func(ctx context.Context, namespace string, tenantName string, options metav1.DeleteOptions) error
var opClientTenantGetMock func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*v1.Tenant, error)
var opClientTenantPatchMock func(ctx context.Context, namespace string, tenantName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.Tenant, error)
var opClientTenantListMock func(ctx context.Context, namespace string, opts metav1.ListOptions) (*v1.TenantList, error)
var httpClientGetMock func(url string) (resp *http.Response, err error)
var k8sclientGetSecretMock func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error)
var k8sclientGetServiceMock func(ctx context.Context, namespace, serviceName string, opts metav1.GetOptions) (*corev1.Service, error)
// mock function of MinioInstanceDelete()
func (ac opClientMock) MinIOInstanceDelete(ctx context.Context, namespace string, instanceName string, options metav1.DeleteOptions) error {
return opClientMinioInstanceDeleteMock(ctx, namespace, instanceName, options)
// mock function of TenantDelete()
func (ac opClientMock) TenantDelete(ctx context.Context, namespace string, tenantName string, options metav1.DeleteOptions) error {
return opClientTenantDeleteMock(ctx, namespace, tenantName, options)
}
// mock function of MinIOInstanceGet()
func (ac opClientMock) MinIOInstanceGet(ctx context.Context, namespace string, instanceName string, options metav1.GetOptions) (*v1.MinIOInstance, error) {
return opClientMinioInstanceGetMock(ctx, namespace, instanceName, options)
// mock function of TenantGet()
func (ac opClientMock) TenantGet(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*v1.Tenant, error) {
return opClientTenantGetMock(ctx, namespace, tenantName, options)
}
// mock function of MinioInstancePatch()
func (ac opClientMock) MinIOInstancePatch(ctx context.Context, namespace string, instanceName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.MinIOInstance, error) {
return opClientMinioInstancePatchMock(ctx, namespace, instanceName, pt, data, options)
// mock function of TenantPatch()
func (ac opClientMock) TenantPatch(ctx context.Context, namespace string, tenantName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.Tenant, error) {
return opClientTenantPatchMock(ctx, namespace, tenantName, pt, data, options)
}
// mock function of MinioInstanceList()
func (ac opClientMock) MinIOInstanceList(ctx context.Context, namespace string, opts metav1.ListOptions) (*v1.MinIOInstanceList, error) {
return opClientMinioInstanceListMock(ctx, namespace, opts)
// mock function of TenantList()
func (ac opClientMock) TenantList(ctx context.Context, namespace string, opts metav1.ListOptions) (*v1.TenantList, error) {
return opClientTenantListMock(ctx, namespace, opts)
}
// mock function of get()
@@ -250,8 +251,8 @@ func Test_TenantInfoTenantAdminClient(t *testing.T) {
func Test_TenantInfo(t *testing.T) {
testTimeStamp := metav1.Now()
type args struct {
minioInstance *operator.MinIOInstance
tenantInfo *usageInfo
minioTenant *operator.Tenant
tenantInfo *usageInfo
}
tests := []struct {
name string
@@ -261,33 +262,34 @@ func Test_TenantInfo(t *testing.T) {
{
name: "Get tenant Info",
args: args{
minioInstance: &operator.MinIOInstance{
minioTenant: &operator.Tenant{
ObjectMeta: metav1.ObjectMeta{
CreationTimestamp: testTimeStamp,
Name: "tenant1",
Namespace: "minio-ns",
},
Spec: operator.MinIOInstanceSpec{
Spec: operator.TenantSpec{
Zones: []operator.Zone{
{
Name: "zone1",
Servers: int32(2),
},
},
VolumesPerServer: 4,
VolumeClaimTemplate: &corev1.PersistentVolumeClaim{
Spec: corev1.PersistentVolumeClaimSpec{
Resources: corev1.ResourceRequirements{
Requests: map[corev1.ResourceName]resource.Quantity{
corev1.ResourceStorage: resource.MustParse("1Mi"),
Name: "zone1",
Servers: int32(2),
VolumesPerServer: 4,
VolumeClaimTemplate: &corev1.PersistentVolumeClaim{
Spec: corev1.PersistentVolumeClaimSpec{
Resources: corev1.ResourceRequirements{
Requests: map[corev1.ResourceName]resource.Quantity{
corev1.ResourceStorage: resource.MustParse("1Mi"),
},
},
StorageClassName: swag.String("standard"),
},
},
StorageClassName: swag.String("standard"),
},
},
Image: "minio/minio:RELEASE.2020-06-14T18-32-17Z",
},
Status: operator.MinIOInstanceStatus{
Status: operator.TenantStatus{
CurrentState: "ready",
},
},
@@ -296,33 +298,34 @@ func Test_TenantInfo(t *testing.T) {
},
},
want: &models.Tenant{
CreationDate: testTimeStamp.String(),
InstanceCount: 2, // number of servers
Name: "tenant1",
VolumesPerServer: int64(4),
VolumeCount: int64(8),
VolumeSize: int64(1048576),
TotalSize: int64(8388608),
ZoneCount: int64(1),
CurrentState: "ready",
CreationDate: testTimeStamp.String(),
Name: "tenant1",
TotalSize: int64(8388608),
CurrentState: "ready",
Zones: []*models.Zone{
{
Name: swag.String("zone1"),
Servers: swag.Int64(int64(2)),
Name: "zone1",
Servers: swag.Int64(int64(2)),
VolumesPerServer: swag.Int32(4),
VolumeConfiguration: &models.ZoneVolumeConfiguration{
StorageClassName: "standard",
Size: swag.Int64(1024 * 1024),
},
},
},
Namespace: "minio-ns",
Image: "minio/minio:RELEASE.2020-06-14T18-32-17Z",
UsedSize: int64(1024),
StorageClass: "standard",
Namespace: "minio-ns",
Image: "minio/minio:RELEASE.2020-06-14T18-32-17Z",
UsedSize: int64(1024),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := getTenantInfo(tt.args.minioInstance, tt.args.tenantInfo)
got := getTenantInfo(tt.args.minioTenant, tt.args.tenantInfo)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("got %v want %v", got, tt.want)
ji, _ := json.Marshal(got)
vi, _ := json.Marshal(tt.want)
t.Errorf("got %s want %s", ji, vi)
}
})
}
@@ -332,11 +335,11 @@ func Test_deleteTenantAction(t *testing.T) {
opClient := opClientMock{}
type args struct {
ctx context.Context
operatorClient OperatorClient
nameSpace string
instanceName string
mockMinioInstanceDelete func(ctx context.Context, namespace string, instanceName string, options metav1.DeleteOptions) error
ctx context.Context
operatorClient OperatorClient
nameSpace string
tenantName string
mockTenantDelete func(ctx context.Context, namespace string, tenantName string, options metav1.DeleteOptions) error
}
tests := []struct {
name string
@@ -349,8 +352,8 @@ func Test_deleteTenantAction(t *testing.T) {
ctx: context.Background(),
operatorClient: opClient,
nameSpace: "default",
instanceName: "minio-instance",
mockMinioInstanceDelete: func(ctx context.Context, namespace string, instanceName string, options metav1.DeleteOptions) error {
tenantName: "minio-tenant",
mockTenantDelete: func(ctx context.Context, namespace string, tenantName string, options metav1.DeleteOptions) error {
return nil
},
},
@@ -362,8 +365,8 @@ func Test_deleteTenantAction(t *testing.T) {
ctx: context.Background(),
operatorClient: opClient,
nameSpace: "default",
instanceName: "minio-instance",
mockMinioInstanceDelete: func(ctx context.Context, namespace string, instanceName string, options metav1.DeleteOptions) error {
tenantName: "minio-tenant",
mockTenantDelete: func(ctx context.Context, namespace string, tenantName string, options metav1.DeleteOptions) error {
return errors.New("something happened")
},
},
@@ -371,9 +374,9 @@ func Test_deleteTenantAction(t *testing.T) {
},
}
for _, tt := range tests {
opClientMinioInstanceDeleteMock = tt.args.mockMinioInstanceDelete
opClientTenantDeleteMock = tt.args.mockTenantDelete
t.Run(tt.name, func(t *testing.T) {
if err := deleteTenantAction(tt.args.ctx, tt.args.operatorClient, tt.args.nameSpace, tt.args.instanceName); (err != nil) != tt.wantErr {
if err := deleteTenantAction(tt.args.ctx, tt.args.operatorClient, tt.args.nameSpace, tt.args.tenantName); (err != nil) != tt.wantErr {
t.Errorf("deleteTenantAction() error = %v, wantErr %v", err, tt.wantErr)
}
})
@@ -384,12 +387,12 @@ func Test_TenantAddZone(t *testing.T) {
opClient := opClientMock{}
type args struct {
ctx context.Context
operatorClient OperatorClient
nameSpace string
mockMinioInstancePatch func(ctx context.Context, namespace string, instanceName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.MinIOInstance, error)
mockMinioInstanceGet func(ctx context.Context, namespace string, instanceName string, options metav1.GetOptions) (*v1.MinIOInstance, error)
params admin_api.TenantAddZoneParams
ctx context.Context
operatorClient OperatorClient
nameSpace string
mockTenantPatch func(ctx context.Context, namespace string, tenantName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.Tenant, error)
mockTenantGet func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*v1.Tenant, error)
params admin_api.TenantAddZoneParams
}
tests := []struct {
name string
@@ -402,15 +405,15 @@ func Test_TenantAddZone(t *testing.T) {
ctx: context.Background(),
operatorClient: opClient,
nameSpace: "default",
mockMinioInstancePatch: func(ctx context.Context, namespace string, instanceName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.MinIOInstance, error) {
return &v1.MinIOInstance{}, nil
mockTenantPatch: func(ctx context.Context, namespace string, tenantName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.Tenant, error) {
return &v1.Tenant{}, nil
},
mockMinioInstanceGet: func(ctx context.Context, namespace string, instanceName string, options metav1.GetOptions) (*v1.MinIOInstance, error) {
return &v1.MinIOInstance{}, nil
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*v1.Tenant, error) {
return &v1.Tenant{}, nil
},
params: admin_api.TenantAddZoneParams{
Body: &models.Zone{
Name: swag.String("zone-1"),
Name: "zone-1",
Servers: swag.Int64(int64(4)),
},
},
@@ -423,15 +426,15 @@ func Test_TenantAddZone(t *testing.T) {
ctx: context.Background(),
operatorClient: opClient,
nameSpace: "default",
mockMinioInstancePatch: func(ctx context.Context, namespace string, instanceName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.MinIOInstance, error) {
mockTenantPatch: func(ctx context.Context, namespace string, tenantName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.Tenant, error) {
return nil, errors.New("errors")
},
mockMinioInstanceGet: func(ctx context.Context, namespace string, instanceName string, options metav1.GetOptions) (*v1.MinIOInstance, error) {
return &v1.MinIOInstance{}, nil
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*v1.Tenant, error) {
return &v1.Tenant{}, nil
},
params: admin_api.TenantAddZoneParams{
Body: &models.Zone{
Name: swag.String("zone-1"),
Name: "zone-1",
Servers: swag.Int64(int64(4)),
},
},
@@ -444,15 +447,15 @@ func Test_TenantAddZone(t *testing.T) {
ctx: context.Background(),
operatorClient: opClient,
nameSpace: "default",
mockMinioInstancePatch: func(ctx context.Context, namespace string, instanceName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.MinIOInstance, error) {
mockTenantPatch: func(ctx context.Context, namespace string, tenantName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.Tenant, error) {
return nil, errors.New("errors")
},
mockMinioInstanceGet: func(ctx context.Context, namespace string, instanceName string, options metav1.GetOptions) (*v1.MinIOInstance, error) {
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*v1.Tenant, error) {
return nil, errors.New("errors")
},
params: admin_api.TenantAddZoneParams{
Body: &models.Zone{
Name: swag.String("zone-1"),
Name: "zone-1",
Servers: swag.Int64(int64(4)),
},
},
@@ -461,8 +464,8 @@ func Test_TenantAddZone(t *testing.T) {
},
}
for _, tt := range tests {
opClientMinioInstanceGetMock = tt.args.mockMinioInstanceGet
opClientMinioInstancePatchMock = tt.args.mockMinioInstancePatch
opClientTenantGetMock = tt.args.mockTenantGet
opClientTenantPatchMock = tt.args.mockTenantPatch
t.Run(tt.name, func(t *testing.T) {
if err := addTenantZone(tt.args.ctx, tt.args.operatorClient, tt.args.params); (err != nil) != tt.wantErr {
t.Errorf("addTenantZone() error = %v, wantErr %v", err, tt.wantErr)
@@ -476,15 +479,15 @@ func Test_UpdateTenantAction(t *testing.T) {
httpClientM := httpClientMock{}
type args struct {
ctx context.Context
operatorClient OperatorClient
httpCl cluster.HTTPClientI
nameSpace string
instanceName string
mockMinioInstancePatch func(ctx context.Context, namespace string, instanceName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.MinIOInstance, error)
mockMinioInstanceGet func(ctx context.Context, namespace string, instanceName string, options metav1.GetOptions) (*v1.MinIOInstance, error)
mockHTTPClientGet func(url string) (resp *http.Response, err error)
params admin_api.UpdateTenantParams
ctx context.Context
operatorClient OperatorClient
httpCl cluster.HTTPClientI
nameSpace string
tenantName string
mockTenantPatch func(ctx context.Context, namespace string, tenantName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.Tenant, error)
mockTenantGet func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*v1.Tenant, error)
mockHTTPClientGet func(url string) (resp *http.Response, err error)
params admin_api.UpdateTenantParams
}
tests := []struct {
name string
@@ -498,12 +501,12 @@ func Test_UpdateTenantAction(t *testing.T) {
operatorClient: opClient,
httpCl: httpClientM,
nameSpace: "default",
instanceName: "minio-instance",
mockMinioInstancePatch: func(ctx context.Context, namespace string, instanceName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.MinIOInstance, error) {
return &v1.MinIOInstance{}, nil
tenantName: "minio-tenant",
mockTenantPatch: func(ctx context.Context, namespace string, tenantName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.Tenant, error) {
return &v1.Tenant{}, nil
},
mockMinioInstanceGet: func(ctx context.Context, namespace string, instanceName string, options metav1.GetOptions) (*v1.MinIOInstance, error) {
return &v1.MinIOInstance{}, nil
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*v1.Tenant, error) {
return &v1.Tenant{}, nil
},
mockHTTPClientGet: func(url string) (resp *http.Response, err error) {
return &http.Response{}, nil
@@ -517,17 +520,17 @@ func Test_UpdateTenantAction(t *testing.T) {
wantErr: false,
},
{
name: "Error occurs getting minioInstance",
name: "Error occurs getting minioTenant",
args: args{
ctx: context.Background(),
operatorClient: opClient,
httpCl: httpClientM,
nameSpace: "default",
instanceName: "minio-instance",
mockMinioInstancePatch: func(ctx context.Context, namespace string, instanceName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.MinIOInstance, error) {
return &v1.MinIOInstance{}, nil
tenantName: "minio-tenant",
mockTenantPatch: func(ctx context.Context, namespace string, tenantName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.Tenant, error) {
return &v1.Tenant{}, nil
},
mockMinioInstanceGet: func(ctx context.Context, namespace string, instanceName string, options metav1.GetOptions) (*v1.MinIOInstance, error) {
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*v1.Tenant, error) {
return nil, errors.New("error-get")
},
mockHTTPClientGet: func(url string) (resp *http.Response, err error) {
@@ -542,18 +545,18 @@ func Test_UpdateTenantAction(t *testing.T) {
wantErr: true,
},
{
name: "Error occurs patching minioInstance",
name: "Error occurs patching minioTenant",
args: args{
ctx: context.Background(),
operatorClient: opClient,
httpCl: httpClientM,
nameSpace: "default",
instanceName: "minio-instance",
mockMinioInstancePatch: func(ctx context.Context, namespace string, instanceName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.MinIOInstance, error) {
tenantName: "minio-tenant",
mockTenantPatch: func(ctx context.Context, namespace string, tenantName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.Tenant, error) {
return nil, errors.New("error-get")
},
mockMinioInstanceGet: func(ctx context.Context, namespace string, instanceName string, options metav1.GetOptions) (*v1.MinIOInstance, error) {
return &v1.MinIOInstance{}, nil
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*v1.Tenant, error) {
return &v1.Tenant{}, nil
},
mockHTTPClientGet: func(url string) (resp *http.Response, err error) {
return &http.Response{}, nil
@@ -573,12 +576,12 @@ func Test_UpdateTenantAction(t *testing.T) {
operatorClient: opClient,
httpCl: httpClientM,
nameSpace: "default",
instanceName: "minio-instance",
mockMinioInstancePatch: func(ctx context.Context, namespace string, instanceName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.MinIOInstance, error) {
return &v1.MinIOInstance{}, nil
tenantName: "minio-tenant",
mockTenantPatch: func(ctx context.Context, namespace string, tenantName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.Tenant, error) {
return &v1.Tenant{}, nil
},
mockMinioInstanceGet: func(ctx context.Context, namespace string, instanceName string, options metav1.GetOptions) (*v1.MinIOInstance, error) {
return &v1.MinIOInstance{}, nil
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*v1.Tenant, error) {
return &v1.Tenant{}, nil
},
mockHTTPClientGet: func(url string) (resp *http.Response, err error) {
r := ioutil.NopCloser(bytes.NewReader([]byte(`./minio.RELEASE.2020-06-18T02-23-35Z"`)))
@@ -601,12 +604,12 @@ func Test_UpdateTenantAction(t *testing.T) {
operatorClient: opClient,
httpCl: httpClientM,
nameSpace: "default",
instanceName: "minio-instance",
mockMinioInstancePatch: func(ctx context.Context, namespace string, instanceName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.MinIOInstance, error) {
return &v1.MinIOInstance{}, nil
tenantName: "minio-tenant",
mockTenantPatch: func(ctx context.Context, namespace string, tenantName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.Tenant, error) {
return &v1.Tenant{}, nil
},
mockMinioInstanceGet: func(ctx context.Context, namespace string, instanceName string, options metav1.GetOptions) (*v1.MinIOInstance, error) {
return &v1.MinIOInstance{}, nil
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*v1.Tenant, error) {
return &v1.Tenant{}, nil
},
mockHTTPClientGet: func(url string) (resp *http.Response, err error) {
return nil, errors.New("error")
@@ -621,8 +624,8 @@ func Test_UpdateTenantAction(t *testing.T) {
},
}
for _, tt := range tests {
opClientMinioInstanceGetMock = tt.args.mockMinioInstanceGet
opClientMinioInstancePatchMock = tt.args.mockMinioInstancePatch
opClientTenantGetMock = tt.args.mockTenantGet
opClientTenantPatchMock = tt.args.mockTenantPatch
httpClientGetMock = tt.args.mockHTTPClientGet
t.Run(tt.name, func(t *testing.T) {
if err := updateTenantAction(tt.args.ctx, tt.args.operatorClient, tt.args.httpCl, tt.args.nameSpace, tt.args.params); (err != nil) != tt.wantErr {

View File

@@ -30,8 +30,9 @@ import (
"github.com/minio/mcs/pkg/auth"
xjwt "github.com/minio/mcs/pkg/auth/jwt"
"github.com/minio/mcs/pkg/auth/ldap"
"github.com/minio/minio-go/v6"
"github.com/minio/minio-go/v6/pkg/credentials"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
"github.com/minio/minio-go/v7/pkg/notification"
)
func init() {
@@ -47,9 +48,9 @@ type MinioClient interface {
listBucketsWithContext(ctx context.Context) ([]minio.BucketInfo, error)
makeBucketWithContext(ctx context.Context, bucketName, location string) error
setBucketPolicyWithContext(ctx context.Context, bucketName, policy string) error
removeBucket(bucketName string) error
getBucketNotification(bucketName string) (bucketNotification minio.BucketNotification, err error)
getBucketPolicy(bucketName string) (string, error)
removeBucket(ctx context.Context, bucketName string) error
getBucketNotification(ctx context.Context, bucketName string) (config notification.Configuration, err error)
getBucketPolicy(ctx context.Context, bucketName string) (string, error)
}
// Interface implementation
@@ -62,32 +63,34 @@ type minioClient struct {
// implements minio.ListBucketsWithContext(ctx)
func (c minioClient) listBucketsWithContext(ctx context.Context) ([]minio.BucketInfo, error) {
return c.client.ListBucketsWithContext(ctx)
return c.client.ListBuckets(ctx)
}
// implements minio.MakeBucketWithContext(ctx, bucketName, location)
func (c minioClient) makeBucketWithContext(ctx context.Context, bucketName, location string) error {
return c.client.MakeBucketWithContext(ctx, bucketName, location)
return c.client.MakeBucket(ctx, bucketName, minio.MakeBucketOptions{
Region: location,
})
}
// implements minio.SetBucketPolicyWithContext(ctx, bucketName, policy)
func (c minioClient) setBucketPolicyWithContext(ctx context.Context, bucketName, policy string) error {
return c.client.SetBucketPolicyWithContext(ctx, bucketName, policy)
return c.client.SetBucketPolicy(ctx, bucketName, policy)
}
// implements minio.RemoveBucket(bucketName)
func (c minioClient) removeBucket(bucketName string) error {
return c.client.RemoveBucket(bucketName)
func (c minioClient) removeBucket(ctx context.Context, bucketName string) error {
return c.client.RemoveBucket(ctx, bucketName)
}
// implements minio.GetBucketNotification(bucketName)
func (c minioClient) getBucketNotification(bucketName string) (bucketNotification minio.BucketNotification, err error) {
return c.client.GetBucketNotification(bucketName)
func (c minioClient) getBucketNotification(ctx context.Context, bucketName string) (config notification.Configuration, err error) {
return c.client.GetBucketNotification(ctx, bucketName)
}
// implements minio.GetBucketPolicy(bucketName)
func (c minioClient) getBucketPolicy(bucketName string) (string, error) {
return c.client.GetBucketPolicy(bucketName)
func (c minioClient) getBucketPolicy(ctx context.Context, bucketName string) (string, error) {
return c.client.GetBucketPolicy(ctx, bucketName)
}
// MCS3Client interface with all functions to be implemented
@@ -160,8 +163,10 @@ func (s mcsSTSAssumeRole) IsExpired() bool {
}
// STSClient contains http.client configuration need it by STSAssumeRole
var STSClient = PrepareSTSClient()
var MinioEndpoint = getMinIOServer()
var (
STSClient = PrepareSTSClient()
MinioEndpoint = getMinIOServer()
)
func newMcsCredentials(accessKey, secretKey, location string) (*credentials.Credentials, error) {
// Future authentication methods can be added under this switch statement
@@ -229,14 +234,14 @@ func getMcsCredentialsFromSession(claims *models.Principal) *credentials.Credent
// from the provided jwt
func newMinioClient(claims *models.Principal) (*minio.Client, error) {
creds := getMcsCredentialsFromSession(claims)
minioClient, err := minio.NewWithOptions(getMinIOEndpoint(), &minio.Options{
Creds: creds,
Secure: getMinIOEndpointIsSecure(),
minioClient, err := minio.New(getMinIOEndpoint(), &minio.Options{
Creds: creds,
Secure: getMinIOEndpointIsSecure(),
Transport: STSClient.Transport,
})
if err != nil {
return nil, err
}
minioClient.SetCustomTransport(STSClient.Transport)
return minioClient, nil
}

View File

@@ -40,7 +40,7 @@ var TLSPort = "9443"
var TLSRedirect = "off"
// defaultTenantMemorySize default value used
// when generating minioInstance request
// when generating minioTenant request
var defaultTenantMemorySize = "16Gi"
func getAccessKey() string {
@@ -234,7 +234,7 @@ func getSecureExpectCTHeader() string {
}
// getTenantMemorySize Memory size value to be used when generating the
// MinioInstance request
// Tenant request
func getTenantMemorySize() string {
return env.Get(McsTenantMemorySize, defaultTenantMemorySize)
}

View File

@@ -17,6 +17,6 @@
package restapi
const (
// McsTenantMemorySize Memory size to be used when creating MinioInstance request
// McsTenantMemorySize Memory size to be used when creating Tenant request
McsTenantMemorySize = "MCS_TENANT_MEMORY_SIZE"
)

View File

@@ -726,7 +726,7 @@ func init() {
"tags": [
"UserAPI"
],
"summary": "Login to mcs",
"summary": "Login to Console",
"operationId": "Login",
"parameters": [
{
@@ -827,7 +827,7 @@ func init() {
"tags": [
"UserAPI"
],
"summary": "Logout from mcs.",
"summary": "Logout from Console.",
"operationId": "Logout",
"responses": {
"200": {
@@ -1929,8 +1929,8 @@ func init() {
"type": "object",
"required": [
"name",
"volume_configuration",
"namespace"
"namespace",
"zones"
],
"properties": {
"access_key": {
@@ -1942,7 +1942,7 @@ func init() {
"type": "string"
}
},
"enable_mcs": {
"enable_console": {
"type": "boolean",
"default": true
},
@@ -1969,23 +1969,6 @@ func init() {
"service_name": {
"type": "string"
},
"volume_configuration": {
"type": "object",
"required": [
"size"
],
"properties": {
"size": {
"type": "string"
},
"storage_class": {
"type": "string"
}
}
},
"volumes_per_server": {
"type": "integer"
},
"zones": {
"type": "array",
"items": {
@@ -2575,18 +2558,12 @@ func init() {
"image": {
"type": "string"
},
"instance_count": {
"type": "integer"
},
"name": {
"type": "string"
},
"namespace": {
"type": "string"
},
"storage_class": {
"type": "string"
},
"total_size": {
"type": "integer",
"format": "int64"
@@ -2595,19 +2572,6 @@ func init() {
"type": "integer",
"format": "int64"
},
"volume_count": {
"type": "integer"
},
"volume_size": {
"type": "integer",
"format": "int64"
},
"volumes_per_server": {
"type": "integer"
},
"zone_count": {
"type": "integer"
},
"zones": {
"type": "array",
"items": {
@@ -2727,8 +2691,9 @@ func init() {
"zone": {
"type": "object",
"required": [
"name",
"servers"
"servers",
"volumes_per_server",
"volume_configuration"
],
"properties": {
"name": {
@@ -2736,6 +2701,24 @@ func init() {
},
"servers": {
"type": "integer"
},
"volume_configuration": {
"type": "object",
"required": [
"size"
],
"properties": {
"size": {
"type": "integer"
},
"storage_class_name": {
"type": "string"
}
}
},
"volumes_per_server": {
"type": "integer",
"format": "int32"
}
}
}
@@ -3446,7 +3429,7 @@ func init() {
"tags": [
"UserAPI"
],
"summary": "Login to mcs",
"summary": "Login to Console",
"operationId": "Login",
"parameters": [
{
@@ -3547,7 +3530,7 @@ func init() {
"tags": [
"UserAPI"
],
"summary": "Logout from mcs.",
"summary": "Logout from Console.",
"operationId": "Logout",
"responses": {
"200": {
@@ -4463,16 +4446,16 @@ func init() {
}
},
"definitions": {
"CreateTenantRequestVolumeConfiguration": {
"ZoneVolumeConfiguration": {
"type": "object",
"required": [
"size"
],
"properties": {
"size": {
"type": "string"
"type": "integer"
},
"storage_class": {
"storage_class_name": {
"type": "string"
}
}
@@ -4663,8 +4646,8 @@ func init() {
"type": "object",
"required": [
"name",
"volume_configuration",
"namespace"
"namespace",
"zones"
],
"properties": {
"access_key": {
@@ -4676,7 +4659,7 @@ func init() {
"type": "string"
}
},
"enable_mcs": {
"enable_console": {
"type": "boolean",
"default": true
},
@@ -4703,23 +4686,6 @@ func init() {
"service_name": {
"type": "string"
},
"volume_configuration": {
"type": "object",
"required": [
"size"
],
"properties": {
"size": {
"type": "string"
},
"storage_class": {
"type": "string"
}
}
},
"volumes_per_server": {
"type": "integer"
},
"zones": {
"type": "array",
"items": {
@@ -5309,18 +5275,12 @@ func init() {
"image": {
"type": "string"
},
"instance_count": {
"type": "integer"
},
"name": {
"type": "string"
},
"namespace": {
"type": "string"
},
"storage_class": {
"type": "string"
},
"total_size": {
"type": "integer",
"format": "int64"
@@ -5329,19 +5289,6 @@ func init() {
"type": "integer",
"format": "int64"
},
"volume_count": {
"type": "integer"
},
"volume_size": {
"type": "integer",
"format": "int64"
},
"volumes_per_server": {
"type": "integer"
},
"zone_count": {
"type": "integer"
},
"zones": {
"type": "array",
"items": {
@@ -5461,8 +5408,9 @@ func init() {
"zone": {
"type": "object",
"required": [
"name",
"servers"
"servers",
"volumes_per_server",
"volume_configuration"
],
"properties": {
"name": {
@@ -5470,6 +5418,24 @@ func init() {
},
"servers": {
"type": "integer"
},
"volume_configuration": {
"type": "object",
"required": [
"size"
],
"properties": {
"size": {
"type": "integer"
},
"storage_class_name": {
"type": "string"
}
}
},
"volumes_per_server": {
"type": "integer",
"format": "int32"
}
}
}

View File

@@ -48,7 +48,7 @@ func NewLogin(ctx *middleware.Context, handler LoginHandler) *Login {
/*Login swagger:route POST /login UserAPI login
Login to mcs
Login to Console
*/
type Login struct {

View File

@@ -50,7 +50,7 @@ func NewLogout(ctx *middleware.Context, handler LogoutHandler) *Logout {
/*Logout swagger:route POST /logout UserAPI logout
Logout from mcs.
Logout from Console.
*/
type Logout struct {

View File

@@ -19,8 +19,8 @@ package restapi
import (
"context"
v1 "github.com/minio/minio-operator/pkg/apis/operator.min.io/v1"
operatorClientset "github.com/minio/minio-operator/pkg/client/clientset/versioned"
v1 "github.com/minio/operator/pkg/apis/minio.min.io/v1"
operatorClientset "github.com/minio/operator/pkg/client/clientset/versioned"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
)
@@ -29,36 +29,36 @@ import (
// by mock when testing, it should include all OperatorClient respective api calls
// that are used within this project.
type OperatorClient interface {
MinIOInstanceDelete(ctx context.Context, namespace string, instanceName string, options metav1.DeleteOptions) error
MinIOInstanceGet(ctx context.Context, namespace string, instanceName string, options metav1.GetOptions) (*v1.MinIOInstance, error)
MinIOInstancePatch(ctx context.Context, namespace string, instanceName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.MinIOInstance, error)
MinIOInstanceList(ctx context.Context, namespace string, opts metav1.ListOptions) (*v1.MinIOInstanceList, error)
TenantDelete(ctx context.Context, namespace string, instanceName string, options metav1.DeleteOptions) error
TenantGet(ctx context.Context, namespace string, instanceName string, options metav1.GetOptions) (*v1.Tenant, error)
TenantPatch(ctx context.Context, namespace string, instanceName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.Tenant, error)
TenantList(ctx context.Context, namespace string, opts metav1.ListOptions) (*v1.TenantList, error)
}
// Interface implementation
//
// Define the structure of a operator client and define the functions that are actually used
// from the minio-operator.
// from the minio operator.
type operatorClient struct {
client *operatorClientset.Clientset
}
// MinIOInstanceDelete implements the minio instance delete action from minio-operator
func (c *operatorClient) MinIOInstanceDelete(ctx context.Context, namespace string, instanceName string, options metav1.DeleteOptions) error {
return c.client.OperatorV1().MinIOInstances(namespace).Delete(ctx, instanceName, options)
// TenantDelete implements the minio instance delete action from minio operator
func (c *operatorClient) TenantDelete(ctx context.Context, namespace string, instanceName string, options metav1.DeleteOptions) error {
return c.client.MinioV1().Tenants(namespace).Delete(ctx, instanceName, options)
}
// MinIOInstanceGet implements the minio instance get action from minio-operator
func (c *operatorClient) MinIOInstanceGet(ctx context.Context, namespace string, instanceName string, options metav1.GetOptions) (*v1.MinIOInstance, error) {
return c.client.OperatorV1().MinIOInstances(namespace).Get(ctx, instanceName, options)
// TenantGet implements the minio instance get action from minio operator
func (c *operatorClient) TenantGet(ctx context.Context, namespace string, instanceName string, options metav1.GetOptions) (*v1.Tenant, error) {
return c.client.MinioV1().Tenants(namespace).Get(ctx, instanceName, options)
}
// MinIOInstancePatch implements the minio instance patch action from minio-operator
func (c *operatorClient) MinIOInstancePatch(ctx context.Context, namespace string, instanceName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.MinIOInstance, error) {
return c.client.OperatorV1().MinIOInstances(namespace).Patch(ctx, instanceName, pt, data, options)
// TenantPatch implements the minio instance patch action from minio operator
func (c *operatorClient) TenantPatch(ctx context.Context, namespace string, instanceName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.Tenant, error) {
return c.client.MinioV1().Tenants(namespace).Patch(ctx, instanceName, pt, data, options)
}
// MinIOInstanceList implements the minio instance list action from minio-operator
func (c *operatorClient) MinIOInstanceList(ctx context.Context, namespace string, opts metav1.ListOptions) (*v1.MinIOInstanceList, error) {
return c.client.OperatorV1().MinIOInstances(namespace).List(ctx, opts)
// TenantList implements the minio instance list action from minio operator
func (c *operatorClient) TenantList(ctx context.Context, namespace string, opts metav1.ListOptions) (*v1.TenantList, error) {
return c.client.MinioV1().Tenants(namespace).List(ctx, opts)
}

View File

@@ -30,7 +30,7 @@ import (
"github.com/minio/mcs/models"
"github.com/minio/mcs/restapi/operations"
"github.com/minio/mcs/restapi/operations/user_api"
"github.com/minio/minio-go/v6/pkg/policy"
"github.com/minio/minio-go/v7/pkg/policy"
minioIAMPolicy "github.com/minio/minio/pkg/iam/policy"
)
@@ -211,10 +211,7 @@ func getBucketSetPolicyResponse(session *models.Principal, bucketName string, re
// removeBucket deletes a bucket
func removeBucket(client MinioClient, bucketName string) error {
if err := client.removeBucket(bucketName); err != nil {
return err
}
return nil
return client.removeBucket(context.Background(), bucketName)
}
// getDeleteBucketResponse performs removeBucket() to delete a bucket
@@ -239,7 +236,7 @@ func getDeleteBucketResponse(session *models.Principal, params user_api.DeleteBu
// getBucketInfo return bucket information including name, policy access, size and creation date
func getBucketInfo(client MinioClient, bucketName string) (*models.Bucket, error) {
policyStr, err := client.getBucketPolicy(bucketName)
policyStr, err := client.getBucketPolicy(context.Background(), bucketName)
if err != nil {
return nil, err
}

View File

@@ -26,7 +26,7 @@ import (
"github.com/minio/mcs/models"
"github.com/minio/mcs/restapi/operations"
"github.com/minio/mcs/restapi/operations/user_api"
"github.com/minio/minio-go/v6"
"github.com/minio/minio-go/v7/pkg/notification"
)
func registerBucketEventsHandlers(api *operations.McsAPI) {
@@ -58,22 +58,22 @@ func registerBucketEventsHandlers(api *operations.McsAPI) {
// listBucketEvents fetches a list of all events set for a bucket and serializes them for a proper output
func listBucketEvents(client MinioClient, bucketName string) ([]*models.NotificationConfig, error) {
var configs []*models.NotificationConfig
bn, err := client.getBucketNotification(bucketName)
bn, err := client.getBucketNotification(context.Background(), bucketName)
if err != nil {
return nil, err
}
// Generate pretty event names from event types
prettyEventNames := func(eventsTypes []minio.NotificationEventType) []models.NotificationEventType {
prettyEventNames := func(eventsTypes []notification.EventType) []models.NotificationEventType {
var result []models.NotificationEventType
for _, eventType := range eventsTypes {
var eventTypePretty models.NotificationEventType
switch eventType {
case minio.ObjectAccessedAll:
case notification.ObjectAccessedAll:
eventTypePretty = models.NotificationEventTypeGet
case minio.ObjectCreatedAll:
case notification.ObjectCreatedAll:
eventTypePretty = models.NotificationEventTypePut
case minio.ObjectRemovedAll:
case notification.ObjectRemovedAll:
eventTypePretty = models.NotificationEventTypeDelete
}
result = append(result, eventTypePretty)
@@ -82,7 +82,7 @@ func listBucketEvents(client MinioClient, bucketName string) ([]*models.Notifica
}
// part of implementation taken from minio/mc
// s3Client.ListNotificationConfigs()... to serialize configurations
getFilters := func(config minio.NotificationConfig) (prefix, suffix string) {
getFilters := func(config notification.Config) (prefix, suffix string) {
if config.Filter == nil {
return
}
@@ -97,27 +97,27 @@ func listBucketEvents(client MinioClient, bucketName string) ([]*models.Notifica
}
return prefix, suffix
}
for _, config := range bn.TopicConfigs {
prefix, suffix := getFilters(config.NotificationConfig)
configs = append(configs, &models.NotificationConfig{ID: config.ID,
Arn: swag.String(config.Topic),
Events: prettyEventNames(config.Events),
for _, embed := range bn.TopicConfigs {
prefix, suffix := getFilters(embed.Config)
configs = append(configs, &models.NotificationConfig{ID: embed.ID,
Arn: swag.String(embed.Topic),
Events: prettyEventNames(embed.Events),
Prefix: prefix,
Suffix: suffix})
}
for _, config := range bn.QueueConfigs {
prefix, suffix := getFilters(config.NotificationConfig)
configs = append(configs, &models.NotificationConfig{ID: config.ID,
Arn: swag.String(config.Queue),
Events: prettyEventNames(config.Events),
for _, embed := range bn.QueueConfigs {
prefix, suffix := getFilters(embed.Config)
configs = append(configs, &models.NotificationConfig{ID: embed.ID,
Arn: swag.String(embed.Queue),
Events: prettyEventNames(embed.Events),
Prefix: prefix,
Suffix: suffix})
}
for _, config := range bn.LambdaConfigs {
prefix, suffix := getFilters(config.NotificationConfig)
configs = append(configs, &models.NotificationConfig{ID: config.ID,
Arn: swag.String(config.Lambda),
Events: prettyEventNames(config.Events),
for _, embed := range bn.LambdaConfigs {
prefix, suffix := getFilters(embed.Config)
configs = append(configs, &models.NotificationConfig{ID: embed.ID,
Arn: swag.String(embed.Lambda),
Events: prettyEventNames(embed.Events),
Prefix: prefix,
Suffix: suffix})
}

View File

@@ -26,16 +26,16 @@ import (
"github.com/go-openapi/swag"
"github.com/minio/mc/pkg/probe"
"github.com/minio/mcs/models"
"github.com/minio/minio-go/v6"
"github.com/minio/minio-go/v7/pkg/notification"
"github.com/stretchr/testify/assert"
)
// assigning mock at runtime instead of compile time
var minioGetBucketNotificationMock func(bucketName string) (bucketNotification minio.BucketNotification, err error)
var minioGetBucketNotificationMock func(ctx context.Context, bucketName string) (bucketNotification notification.Configuration, err error)
// mock function of getBucketNotification()
func (mc minioClientMock) getBucketNotification(bucketName string) (bucketNotification minio.BucketNotification, err error) {
return minioGetBucketNotificationMock(bucketName)
func (mc minioClientMock) getBucketNotification(ctx context.Context, bucketName string) (bucketNotification notification.Configuration, err error) {
return minioGetBucketNotificationMock(ctx, bucketName)
}
//// Mock mc S3Client functions ////
@@ -144,27 +144,27 @@ func TestListBucketEvents(t *testing.T) {
////// Test-1 : listBucketEvents() get list of events for a particular bucket only one config
// mock bucketNotification response from MinIO
mockBucketN := minio.BucketNotification{
LambdaConfigs: []minio.LambdaConfig{},
TopicConfigs: []minio.TopicConfig{},
QueueConfigs: []minio.QueueConfig{
minio.QueueConfig{
mockBucketN := notification.Configuration{
LambdaConfigs: []notification.LambdaConfig{},
TopicConfigs: []notification.TopicConfig{},
QueueConfigs: []notification.QueueConfig{
notification.QueueConfig{
Queue: "arn:minio:sqs::test:postgresql",
NotificationConfig: minio.NotificationConfig{
Config: notification.Config{
ID: "",
Events: []minio.NotificationEventType{
minio.ObjectAccessedAll,
minio.ObjectCreatedAll,
minio.ObjectRemovedAll,
Events: []notification.EventType{
notification.ObjectAccessedAll,
notification.ObjectCreatedAll,
notification.ObjectRemovedAll,
},
Filter: &minio.Filter{
S3Key: minio.S3Key{
FilterRules: []minio.FilterRule{
minio.FilterRule{
Filter: &notification.Filter{
S3Key: notification.S3Key{
FilterRules: []notification.FilterRule{
notification.FilterRule{
Name: "suffix",
Value: ".jpg",
},
minio.FilterRule{
notification.FilterRule{
Name: "prefix",
Value: "file/",
},
@@ -188,7 +188,7 @@ func TestListBucketEvents(t *testing.T) {
},
},
}
minioGetBucketNotificationMock = func(bucketName string) (bucketNotification minio.BucketNotification, err error) {
minioGetBucketNotificationMock = func(ctx context.Context, bucketName string) (bucketNotification notification.Configuration, err error) {
return mockBucketN, nil
}
eventConfigs, err := listBucketEvents(minClient, "bucket")
@@ -209,16 +209,16 @@ func TestListBucketEvents(t *testing.T) {
}
////// Test-2 : listBucketEvents() get list of events no filters
mockBucketN = minio.BucketNotification{
LambdaConfigs: []minio.LambdaConfig{},
TopicConfigs: []minio.TopicConfig{},
QueueConfigs: []minio.QueueConfig{
minio.QueueConfig{
mockBucketN = notification.Configuration{
LambdaConfigs: []notification.LambdaConfig{},
TopicConfigs: []notification.TopicConfig{},
QueueConfigs: []notification.QueueConfig{
notification.QueueConfig{
Queue: "arn:minio:sqs::test:postgresql",
NotificationConfig: minio.NotificationConfig{
Config: notification.Config{
ID: "",
Events: []minio.NotificationEventType{
minio.ObjectRemovedAll,
Events: []notification.EventType{
notification.ObjectRemovedAll,
},
},
},
@@ -235,7 +235,7 @@ func TestListBucketEvents(t *testing.T) {
},
},
}
minioGetBucketNotificationMock = func(bucketName string) (bucketNotification minio.BucketNotification, err error) {
minioGetBucketNotificationMock = func(ctx context.Context, bucketName string) (bucketNotification notification.Configuration, err error) {
return mockBucketN, nil
}
eventConfigs, err = listBucketEvents(minClient, "bucket")
@@ -256,23 +256,23 @@ func TestListBucketEvents(t *testing.T) {
}
////// Test-3 : listBucketEvents() get list of events
mockBucketN = minio.BucketNotification{
LambdaConfigs: []minio.LambdaConfig{
minio.LambdaConfig{
mockBucketN = notification.Configuration{
LambdaConfigs: []notification.LambdaConfig{
notification.LambdaConfig{
Lambda: "lambda",
NotificationConfig: minio.NotificationConfig{
Config: notification.Config{
ID: "",
Events: []minio.NotificationEventType{
minio.ObjectRemovedAll,
Events: []notification.EventType{
notification.ObjectRemovedAll,
},
Filter: &minio.Filter{
S3Key: minio.S3Key{
FilterRules: []minio.FilterRule{
minio.FilterRule{
Filter: &notification.Filter{
S3Key: notification.S3Key{
FilterRules: []notification.FilterRule{
notification.FilterRule{
Name: "suffix",
Value: ".png",
},
minio.FilterRule{
notification.FilterRule{
Name: "prefix",
Value: "lambda/",
},
@@ -282,22 +282,22 @@ func TestListBucketEvents(t *testing.T) {
},
},
},
TopicConfigs: []minio.TopicConfig{
minio.TopicConfig{
TopicConfigs: []notification.TopicConfig{
notification.TopicConfig{
Topic: "topic",
NotificationConfig: minio.NotificationConfig{
Config: notification.Config{
ID: "",
Events: []minio.NotificationEventType{
minio.ObjectRemovedAll,
Events: []notification.EventType{
notification.ObjectRemovedAll,
},
Filter: &minio.Filter{
S3Key: minio.S3Key{
FilterRules: []minio.FilterRule{
minio.FilterRule{
Filter: &notification.Filter{
S3Key: notification.S3Key{
FilterRules: []notification.FilterRule{
notification.FilterRule{
Name: "suffix",
Value: ".gif",
},
minio.FilterRule{
notification.FilterRule{
Name: "prefix",
Value: "topic/",
},
@@ -307,17 +307,17 @@ func TestListBucketEvents(t *testing.T) {
},
},
},
QueueConfigs: []minio.QueueConfig{
minio.QueueConfig{
QueueConfigs: []notification.QueueConfig{
notification.QueueConfig{
Queue: "arn:minio:sqs::test:postgresql",
NotificationConfig: minio.NotificationConfig{
Config: notification.Config{
ID: "",
Events: []minio.NotificationEventType{
minio.ObjectRemovedAll,
Events: []notification.EventType{
notification.ObjectRemovedAll,
},
Filter: &minio.Filter{
S3Key: minio.S3Key{
FilterRules: []minio.FilterRule{},
Filter: &notification.Filter{
S3Key: notification.S3Key{
FilterRules: []notification.FilterRule{},
},
},
},
@@ -354,7 +354,7 @@ func TestListBucketEvents(t *testing.T) {
},
},
}
minioGetBucketNotificationMock = func(bucketName string) (bucketNotification minio.BucketNotification, err error) {
minioGetBucketNotificationMock = func(ctx context.Context, bucketName string) (bucketNotification notification.Configuration, err error) {
return mockBucketN, nil
}
eventConfigs, err = listBucketEvents(minClient, "bucket")
@@ -375,8 +375,8 @@ func TestListBucketEvents(t *testing.T) {
}
////// Test-2 : listBucketEvents() Returns error and see that the error is handled correctly and returned
minioGetBucketNotificationMock = func(bucketName string) (bucketNotification minio.BucketNotification, err error) {
return minio.BucketNotification{}, errors.New("error")
minioGetBucketNotificationMock = func(ctx context.Context, bucketName string) (bucketNotification notification.Configuration, err error) {
return notification.Configuration{}, errors.New("error")
}
_, err = listBucketEvents(minClient, "bucket")
if assert.Error(err) {

View File

@@ -26,7 +26,7 @@ import (
"github.com/go-openapi/swag"
"github.com/minio/mcs/models"
"github.com/minio/minio-go/v6"
"github.com/minio/minio-go/v7"
"github.com/minio/minio/pkg/madmin"
"github.com/stretchr/testify/assert"
)
@@ -58,12 +58,12 @@ func (mc minioClientMock) setBucketPolicyWithContext(ctx context.Context, bucket
}
// mock function of removeBucket()
func (mc minioClientMock) removeBucket(bucketName string) error {
func (mc minioClientMock) removeBucket(ctx context.Context, bucketName string) error {
return minioRemoveBucketMock(bucketName)
}
// imock function of getBucketPolicy()
func (mc minioClientMock) getBucketPolicy(bucketName string) (string, error) {
func (mc minioClientMock) getBucketPolicy(ctx context.Context, bucketName string) (string, error) {
return minioGetBucketPolicyMock(bucketName)
}

View File

@@ -23,7 +23,7 @@ import (
"github.com/minio/mcs/pkg/auth"
"github.com/minio/mcs/pkg/auth/idp/oauth2"
"github.com/minio/minio-go/v6/pkg/credentials"
"github.com/minio/minio-go/v7/pkg/credentials"
"github.com/minio/minio/cmd/config"
"github.com/minio/minio/pkg/madmin"
"github.com/stretchr/testify/assert"