diff --git a/.github/workflows/jobs.yaml b/.github/workflows/jobs.yaml index d550fb7b0..cf70f4754 100644 --- a/.github/workflows/jobs.yaml +++ b/.github/workflows/jobs.yaml @@ -1542,7 +1542,7 @@ jobs: go tool cover -func=all.out | grep total > tmp2 result=`cat tmp2 | awk 'END {print $3}'` result=${result%\%} - threshold=63.2 + threshold=63.7 echo "Result:" echo "$result%" if (( $(echo "$result >= $threshold" |bc -l) )); then diff --git a/operatorapi/tenants.go b/operatorapi/tenants.go index 9112cf658..9cabd2568 100644 --- a/operatorapi/tenants.go +++ b/operatorapi/tenants.go @@ -666,7 +666,7 @@ func getTenantSecurity(ctx context.Context, clientSet K8sClientI, tenant *miniov return nil, err } // Security Context used by MinIO server - if tenant.Spec.Pools[0].SecurityContext != nil { + if len(tenant.Spec.Pools) > 0 && tenant.Spec.Pools[0].SecurityContext != nil { tenantSecurityContext = convertK8sSCToModelSC(tenant.Spec.Pools[0].SecurityContext) } return &models.TenantSecurityResponse{ @@ -861,15 +861,15 @@ func getTenantIdentityProviderResponse(session *models.Principal, params operato opClient := &operatorClient{ client: opClientClientSet, } - minTenant, err := getTenant(ctx, opClient, params.Namespace, params.Tenant) + // get Kubernetes Client + clientSet, err := cluster.K8sClient(session.STSSessionToken) if err != nil { return nil, restapi.ErrorWithContext(ctx, err) } - // get Kubernetes Client - clientSet, err := cluster.K8sClient(session.STSSessionToken) k8sClient := k8sClient{ client: clientSet, } + minTenant, err := getTenant(ctx, opClient, params.Namespace, params.Tenant) if err != nil { return nil, restapi.ErrorWithContext(ctx, err) } @@ -1083,15 +1083,15 @@ func getTenantSecurityResponse(session *models.Principal, params operator_api.Te opClient := &operatorClient{ client: opClientClientSet, } - minTenant, err := getTenant(ctx, opClient, params.Namespace, params.Tenant) + // get Kubernetes Client + clientSet, err := cluster.K8sClient(session.STSSessionToken) if err != nil { return nil, restapi.ErrorWithContext(ctx, err) } - // get Kubernetes Client - clientSet, err := cluster.K8sClient(session.STSSessionToken) k8sClient := k8sClient{ client: clientSet, } + minTenant, err := getTenant(ctx, opClient, params.Namespace, params.Tenant) if err != nil { return nil, restapi.ErrorWithContext(ctx, err) } diff --git a/operatorapi/tenants_2_test.go b/operatorapi/tenants_2_test.go index dec667291..1fb66b63d 100644 --- a/operatorapi/tenants_2_test.go +++ b/operatorapi/tenants_2_test.go @@ -27,8 +27,10 @@ import ( "github.com/minio/console/models" "github.com/minio/console/operatorapi/operations" "github.com/minio/console/operatorapi/operations/operator_api" + miniov2 "github.com/minio/operator/pkg/apis/minio.min.io/v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" + corev1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -420,6 +422,79 @@ func (suite *TenantTestSuite) initTenantSecurityRequest() (params operator_api.T return params, api } +func (suite *TenantTestSuite) TestGetTenantSecurityWithWrongServerCertificates() { + ctx := context.Background() + tenant := &miniov2.Tenant{ + ObjectMeta: metav1.ObjectMeta{ + Name: "mock-tenant", + Namespace: "mock-namespace", + }, + Spec: miniov2.TenantSpec{ + ExternalCertSecret: []*miniov2.LocalCertificateReference{{}}, + }, + } + k8sclientGetSecretMock = func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) { + return nil, errors.New("mock-error") + } + _, err := getTenantSecurity(ctx, suite.k8sclient, tenant) + suite.assert.NotNil(err) +} + +func (suite *TenantTestSuite) TestGetTenantSecurityWithWrongClientCertificates() { + ctx := context.Background() + tenant := &miniov2.Tenant{ + ObjectMeta: metav1.ObjectMeta{ + Name: "mock-tenant", + Namespace: "mock-namespace", + }, + Spec: miniov2.TenantSpec{ + ExternalClientCertSecrets: []*miniov2.LocalCertificateReference{{}}, + }, + } + k8sclientGetSecretMock = func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) { + return nil, errors.New("mock-error") + } + _, err := getTenantSecurity(ctx, suite.k8sclient, tenant) + suite.assert.NotNil(err) +} + +func (suite *TenantTestSuite) TestGetTenantSecurityWithWrongCACertificates() { + ctx := context.Background() + tenant := &miniov2.Tenant{ + ObjectMeta: metav1.ObjectMeta{ + Name: "mock-tenant", + Namespace: "mock-namespace", + }, + Spec: miniov2.TenantSpec{ + ExternalCaCertSecret: []*miniov2.LocalCertificateReference{{}}, + }, + } + k8sclientGetSecretMock = func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) { + return nil, errors.New("mock-error") + } + _, err := getTenantSecurity(ctx, suite.k8sclient, tenant) + suite.assert.NotNil(err) +} + +func (suite *TenantTestSuite) TestGetTenantSecurityWithoutError() { + ctx := context.Background() + tenant := &miniov2.Tenant{ + ObjectMeta: metav1.ObjectMeta{ + Name: "mock-tenant", + Namespace: "mock-namespace", + }, + Spec: miniov2.TenantSpec{ + ExternalCaCertSecret: []*miniov2.LocalCertificateReference{}, + }, + } + k8sclientGetSecretMock = func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) { + return nil, errors.New("mock-error") + } + sec, err := getTenantSecurity(ctx, suite.k8sclient, tenant) + suite.assert.NotNil(sec) + suite.assert.Nil(err) +} + func (suite *TenantTestSuite) TestUpdateTenantSecurityHandlerWithError() { params, api := suite.initUpdateTenantSecurityRequest() response := api.OperatorAPIUpdateTenantSecurityHandler.Handle(params, &models.Principal{}) @@ -465,6 +540,57 @@ func (suite *TenantTestSuite) initTenantIdentityProviderRequest() (params operat return params, api } +func (suite *TenantTestSuite) TestGetTenantIdentityProviderWithIDPConfig() { + ctx := context.Background() + tenant := &miniov2.Tenant{ + ObjectMeta: metav1.ObjectMeta{ + Name: "mock-tenant", + Namespace: "mock-namespace", + }, + Spec: miniov2.TenantSpec{ + Env: []corev1.EnvVar{ + {Name: "MINIO_IDENTITY_OPENID_CONFIG_URL", Value: "mock"}, + {Name: "MINIO_IDENTITY_OPENID_REDIRECT_URI", Value: "mock"}, + {Name: "MINIO_IDENTITY_OPENID_CLAIM_NAME", Value: "mock"}, + {Name: "MINIO_IDENTITY_OPENID_CLIENT_ID", Value: "mock"}, + {Name: "MINIO_IDENTITY_OPENID_CLIENT_SECRET", Value: "mock"}, + }, + }, + } + res, err := getTenantIdentityProvider(ctx, suite.k8sclient, tenant) + suite.assert.NotNil(res) + suite.assert.NotNil(res.Oidc) + suite.assert.Nil(err) +} + +func (suite *TenantTestSuite) TestGetTenantIdentityProviderWithLDAPConfig() { + ctx := context.Background() + tenant := &miniov2.Tenant{ + ObjectMeta: metav1.ObjectMeta{ + Name: "mock-tenant", + Namespace: "mock-namespace", + }, + Spec: miniov2.TenantSpec{ + Env: []corev1.EnvVar{ + {Name: "MINIO_IDENTITY_LDAP_GROUP_SEARCH_BASE_DN", Value: "mock"}, + {Name: "MINIO_IDENTITY_LDAP_GROUP_SEARCH_FILTER", Value: "mock"}, + {Name: "MINIO_IDENTITY_LDAP_LOOKUP_BIND_DN", Value: "mock"}, + {Name: "MINIO_IDENTITY_LDAP_LOOKUP_BIND_PASSWORD", Value: "mock"}, + {Name: "MINIO_IDENTITY_LDAP_SERVER_INSECURE", Value: "mock"}, + {Name: "MINIO_IDENTITY_LDAP_SERVER_STARTTLS", Value: "mock"}, + {Name: "MINIO_IDENTITY_LDAP_TLS_SKIP_VERIFY", Value: "mock"}, + {Name: "MINIO_IDENTITY_LDAP_SERVER_ADDR", Value: "mock"}, + {Name: "MINIO_IDENTITY_LDAP_USER_DN_SEARCH_BASE_DN", Value: "mock"}, + {Name: "MINIO_IDENTITY_LDAP_USER_DN_SEARCH_FILTER", Value: "mock"}, + }, + }, + } + res, err := getTenantIdentityProvider(ctx, suite.k8sclient, tenant) + suite.assert.NotNil(res) + suite.assert.NotNil(res.ActiveDirectory) + suite.assert.Nil(err) +} + func (suite *TenantTestSuite) TestUpdateTenantIdentityProviderHandlerWithError() { params, api := suite.initUpdateTenantIdentityProviderRequest() response := api.OperatorAPIUpdateTenantIdentityProviderHandler.Handle(params, &models.Principal{})