Skip to content

Commit

Permalink
Removing credsSecret required field in tenant spec
Browse files Browse the repository at this point in the history
- Removing required credsSecret field in tenant spec
- Migration from creddsSecret to Configuration field for old tenants

Signed-off-by: Lenin Alevski <alevsk.8772@gmail.com>
  • Loading branch information
Alevsk committed Aug 25, 2022
1 parent ec4e74c commit 6746eb6
Show file tree
Hide file tree
Showing 20 changed files with 93 additions and 130 deletions.
1 change: 0 additions & 1 deletion examples/kustomization/base/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@ namespace: minio-tenant
resources:
- namespace.yaml
- tenant-config.yaml
- tenant-minio-creds-secret_deprecated.yaml
- storage-user.yaml
- tenant.yaml

This file was deleted.

3 changes: 0 additions & 3 deletions examples/kustomization/base/tenant.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ spec:
## Secret with credentials and configurations to be used by MinIO Tenant.
configuration:
name: storage-configuration
## DEPRECATED: Secret with credentials to be used by MinIO Tenant.
credsSecret:
name: storage-creds-secret
## Add environment variables to be set in MinIO container (https://github.com/minio/minio/tree/master/docs/config)
env: [ ]
## serviceMetadata allows passing additional labels and annotations to MinIO and Console specific
Expand Down
10 changes: 0 additions & 10 deletions helm/tenant/templates/tenant-secret-deprecated.yaml

This file was deleted.

6 changes: 2 additions & 4 deletions helm/tenant/templates/tenant.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,8 @@ spec:
{{- end }}
## Secret with default environment variable configurations
configuration:
name: {{ .configuration.name }}
## Deprecated credsSecret
credsSecret:
name: "tenant-secret"
name: {{ dig "secrets" "name" "" ($.Values | merge (dict)) }}
{{- end }}
pools:
{{- range (dig "pools" (list) .) }}
- servers: {{ dig "servers" 4 . }}
Expand Down
18 changes: 0 additions & 18 deletions kubectl-minio/cmd/resources/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// NewTenantCredsSecret : deprecated
func NewTenantCredsSecret(opts *TenantOptions) (*corev1.Secret, error) {
return &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: opts.Name + "-creds-secret",
Namespace: opts.NS,
},
TypeMeta: metav1.TypeMeta{
Kind: "Secret",
APIVersion: v1.SchemeGroupVersion.Version,
},
Data: map[string][]byte{
"accesskey": []byte(""),
"secretkey": []byte(""),
},
}, nil
}

// NewTenantConfigurationSecret will return a new secret a MinIO Tenant
func NewTenantConfigurationSecret(opts *TenantOptions) (*corev1.Secret, error) {
accessKey, secretKey, err := miniov2.GenerateCredentials()
Expand Down
3 changes: 0 additions & 3 deletions kubectl-minio/cmd/resources/tenant.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,6 @@ func NewTenant(opts *TenantOptions, userSecret *v1.Secret) (*miniov2.Tenant, err
Configuration: &v1.LocalObjectReference{
Name: opts.ConfigurationSecretName,
},
CredsSecret: &v1.LocalObjectReference{
Name: opts.Name + "-creds-secret",
},
Pools: []miniov2.Pool{Pool(opts, volumesPerServer, *capacityPerVolume)},
RequestAutoCert: &autoCert,
Mountpath: helpers.MinIOMountPath,
Expand Down
20 changes: 2 additions & 18 deletions kubectl-minio/cmd/tenant-create.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,6 @@ func (c *createCmd) run(args []string) error {
if err != nil {
return err
}
// deprecated tenant credsSecret required for deploying tenant, will be removed in operator v5.x.x
tenantCredsSecret, err := resources.NewTenantCredsSecret(&c.tenantOpts)
if err != nil {
return err
}
// generate tenant configuration
tenantConfiguration, err := resources.NewTenantConfigurationSecret(&c.tenantOpts)
if err != nil {
Expand All @@ -159,7 +154,7 @@ func (c *createCmd) run(args []string) error {
}
// create resources
if !c.output {
return createTenant(operatorClient, kubeClient, tenant, tenantCredsSecret, tenantConfiguration, tenantUserCredentials)
return createTenant(operatorClient, kubeClient, tenant, tenantConfiguration, tenantUserCredentials)
}
tenantYAML, err := yaml.Marshal(&tenant)
if err != nil {
Expand All @@ -169,10 +164,6 @@ func (c *createCmd) run(args []string) error {
if err != nil {
return err
}
tenantCredsSecretYAML, err := yaml.Marshal(&tenantCredsSecret)
if err != nil {
return err
}
tenantUserYAML, err := yaml.Marshal(&tenantUserCredentials)
if err != nil {
return err
Expand All @@ -181,21 +172,14 @@ func (c *createCmd) run(args []string) error {
fmt.Println("---")
fmt.Println(string(tenantConfigurationYAML))
fmt.Println("---")
fmt.Println(string(tenantCredsSecretYAML))
fmt.Println("---")
fmt.Println(string(tenantUserYAML))
return nil
}

func createTenant(operatorClient *operatorv1.Clientset, kubeClient *kubernetes.Clientset, tenant *miniov2.Tenant, tenantCredsSecret, tenantConfiguration, console *corev1.Secret) error {
func createTenant(operatorClient *operatorv1.Clientset, kubeClient *kubernetes.Clientset, tenant *miniov2.Tenant, tenantConfiguration, console *corev1.Secret) error {
if _, err := kubeClient.CoreV1().Namespaces().Get(context.Background(), tenant.Namespace, metav1.GetOptions{}); err != nil {
return fmt.Errorf("namespace %s not found, please create the namespace using 'kubectl create ns %s'", tenant.Namespace, tenant.Namespace)
}
// deprecated tenant credsSecret required for deploying tenant
// The credsSecret field will be removed in operator v5.x.x
if _, err := kubeClient.CoreV1().Secrets(tenant.Namespace).Create(context.Background(), tenantCredsSecret, metav1.CreateOptions{}); err != nil {
return err
}
if _, err := kubeClient.CoreV1().Secrets(tenant.Namespace).Create(context.Background(), tenantConfiguration, metav1.CreateOptions{}); err != nil {
return err
}
Expand Down
6 changes: 0 additions & 6 deletions kubectl-minio/cmd/tenant-delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,6 @@ func deleteTenant(client *operatorv1.Clientset, kclient *kubernetes.Clientset, d

fmt.Println("Deleting MinIO Tenant: ", name)

// Delete credentials secret, ignore any errors.
kclient.CoreV1().Secrets(d.ns).Delete(context.Background(), tenant.Spec.CredsSecret.Name,
metav1.DeleteOptions{})

fmt.Println("Deleting MinIO Tenant Credentials Secret: ", tenant.Spec.CredsSecret.Name)

if tenant.HasConfigurationSecret() {
kclient.CoreV1().Secrets(d.ns).Delete(context.Background(), tenant.Spec.Configuration.Name,
metav1.DeleteOptions{})
Expand Down
10 changes: 2 additions & 8 deletions pkg/apis/minio.min.io/v1/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,6 @@ func genEllipsis(start, end int) string {
return "{" + strconv.Itoa(start) + "..." + strconv.Itoa(end) + "}"
}

// HasCredsSecret returns true if the user has provided a secret
// for a Tenant else false
func (t *Tenant) HasCredsSecret() bool {
return t.Spec.CredsSecret != nil
}

// HasConfigurationSecret returns true if the user has provided a configuration
// for a Tenant else false
func (t *Tenant) HasConfigurationSecret() bool {
Expand Down Expand Up @@ -555,8 +549,8 @@ func (t *Tenant) Validate() error {
return errors.New("zones must be configured")
}

if t.Spec.CredsSecret == nil {
return errors.New("please set credsSecret secret with credentials for Tenant")
if t.Spec.Configuration == nil {
return errors.New("please set configuration secret with credentials for Tenant")
}

// Every zone must contain a Volume Claim Template
Expand Down
3 changes: 3 additions & 0 deletions pkg/apis/minio.min.io/v2/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ const DefaultMinIOUpdateURL = "https://dl.min.io/server/minio/release/" + runtim
// MinIOHLSvcNameSuffix specifies the suffix added to Tenant name to create a headless service
const MinIOHLSvcNameSuffix = "-hl"

// TenantConfigurationSecretSuffix specifies the suffix added to tenant name to create the configuration secret name
const TenantConfigurationSecretSuffix = "-configuration"

// Console Related Constants

// ConsoleTenantLabel is applied to the Console pods of a Tenant cluster
Expand Down
4 changes: 2 additions & 2 deletions pkg/apis/minio.min.io/v2/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -867,8 +867,8 @@ func (t *Tenant) Validate() error {
return errors.New("pools must be configured")
}

if t.Spec.CredsSecret == nil {
return errors.New("please set credsSecret secret with credentials for Tenant")
if !t.HasConfigurationSecret() && !t.HasCredsSecret() {
return errors.New("please set 'configuration' secret with credentials for Tenant")
}

// Every pool must contain a Volume Claim Template
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/minio.min.io/v2/names.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@ func (t *Tenant) LogHLServiceName() string {
return t.Name + LogHLSvcNameSuffix
}

// ConfigurationSecretName returns name of secret used to store the tenant configuration
func (t *Tenant) ConfigurationSecretName() string {
return fmt.Sprintf("%s%s", t.Name, TenantConfigurationSecretSuffix)
}

// LogSecretName returns name of secret shared by Log PG server and log-search-api server
func (t *Tenant) LogSecretName() string {
return fmt.Sprintf("%s-%s", t.Name, "log-secret")
Expand Down
2 changes: 1 addition & 1 deletion pkg/apis/minio.min.io/v2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ type TenantSpec struct {
// Pod Management Policy for pod created by StatefulSet
// +optional
PodManagementPolicy appsv1.PodManagementPolicyType `json:"podManagementPolicy,omitempty"`
// *Required* +
// *optional* +
//
// Specify a https://kubernetes.io/docs/concepts/configuration/secret/[Kubernetes opaque secret] to use for setting the MinIO root access key and secret key. Specify the secret as `name: <secret>`. The Kubernetes secret must contain the following fields: +
//
Expand Down
5 changes: 5 additions & 0 deletions pkg/controller/cluster/main-controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ const (
StatusUpdatingAffinity = "Updating Pod Affinity"
StatusNotOwned = "Statefulset not controlled by operator"
StatusFailedAlreadyExists = "Another MinIO Tenant already exists in the namespace"
StatusTenantCredentialsNotSet = "Tenant credentials are not set properly"
StatusInconsistentMinIOVersions = "Different versions across MinIO Pools"
StatusRestartingMinIO = "Restarting MinIO"
StatusDecommissioningNotAllowed = "Pool Decommissioning Not Allowed"
Expand Down Expand Up @@ -761,6 +762,10 @@ func (c *Controller) syncHandler(key string) error {

adminClnt, err := tenant.NewMinIOAdmin(tenantConfiguration, c.getTransport())
if err != nil {
if _, uerr := c.updateTenantStatus(ctx, tenant, StatusTenantCredentialsNotSet, 0); uerr != nil {
return uerr
}
klog.Errorf("Error initializing minio admin client: %v", err)
return err
}

Expand Down
5 changes: 2 additions & 3 deletions pkg/controller/cluster/monitoring.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,8 @@ func (c *Controller) updateHealthStatusForTenant(tenant *miniov2.Tenant) error {

adminClnt, err := tenant.NewMinIOAdmin(tenantConfiguration, c.getTransport())
if err != nil {
// show the error and continue
klog.Infof("'%s/%s': %v", tenant.Namespace, tenant.Name, err)
return nil
klog.Errorf("Error instantiating adminClnt '%s/%s': %v", tenant.Namespace, tenant.Name, err)
return err
}

aClnt, err := madmin.NewAnonymousClient(tenant.MinIOServerHostAddress(), tenant.TLS())
Expand Down
3 changes: 1 addition & 2 deletions pkg/controller/cluster/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,7 @@ func (c *Controller) createUsers(ctx context.Context, tenant *miniov2.Tenant, te
// get a new admin client
adminClient, err := tenant.NewMinIOAdmin(tenantConfiguration, c.getTransport())
if err != nil {
// show the error and continue
klog.Errorf("Error instantiating madmin: %v", err)
klog.Errorf("Error instantiating adminClnt: %v", err)
return err
}

Expand Down
16 changes: 2 additions & 14 deletions pkg/controller/cluster/tenants.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,27 +44,15 @@ func (c *Controller) getTenantConfiguration(ctx context.Context, tenant *miniov2

// getTenantCredentials returns a combination of env, credsSecret and Configuration tenant credentials
func (c *Controller) getTenantCredentials(ctx context.Context, tenant *miniov2.Tenant) (map[string][]byte, error) {
// Configuration for tenant can be passed using 3 different sources, tenant.spec.env, k8s credsSecret and config.env secret
// Configuration for tenant can be passed using 2 different sources, tenant.spec.env and config.env secret
// If the user provides duplicated configuration the override order will be:
// tenant.Spec.Env < credsSecret (k8s secret) < config.env file (k8s secret)
// tenant.Spec.Env < config.env file (k8s secret)
tenantConfiguration := map[string][]byte{}

for _, config := range tenant.GetEnvVars() {
tenantConfiguration[config.Name] = []byte(config.Value)
}

if tenant.HasCredsSecret() {
minioSecretName := tenant.Spec.CredsSecret.Name
minioSecret, err := c.kubeClientSet.CoreV1().Secrets(tenant.Namespace).Get(ctx, minioSecretName, metav1.GetOptions{})
if err != nil {
return nil, err
}
configFromCredsSecret := minioSecret.Data
for key, val := range configFromCredsSecret {
tenantConfiguration[key] = val
}
}

// Load tenant configuration from file
config, err := c.getTenantConfiguration(ctx, tenant)
if err != nil {
Expand Down
67 changes: 66 additions & 1 deletion pkg/controller/cluster/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ package cluster

import (
"context"
"fmt"
"regexp"

"github.com/blang/semver/v4"
corev1 "k8s.io/api/core/v1"

"github.com/blang/semver/v4"
"github.com/hashicorp/go-version"

"k8s.io/klog/v2"
Expand All @@ -38,6 +40,7 @@ const (
version428 = "v4.2.8"
version429 = "v4.2.9"
version430 = "v4.3.0"
version45 = "v4.5"
)

type upgradeFunction func(ctx context.Context, tenant *miniov2.Tenant) (*miniov2.Tenant, error)
Expand All @@ -51,6 +54,7 @@ func (c *Controller) checkForUpgrades(ctx context.Context, tenant *miniov2.Tenan
version428: c.upgrade428,
version429: c.upgrade429,
version430: c.upgrade430,
version45: c.upgrade45,
}

// if the version is empty, do all upgrades
Expand All @@ -60,6 +64,7 @@ func (c *Controller) checkForUpgrades(ctx context.Context, tenant *miniov2.Tenan
upgradesToDo = append(upgradesToDo, version428)
upgradesToDo = append(upgradesToDo, version429)
upgradesToDo = append(upgradesToDo, version430)
upgradesToDo = append(upgradesToDo, version45)
} else {
currentSyncVersion, err := version.NewVersion(tenant.Status.SyncVersion)
if err != nil {
Expand All @@ -72,6 +77,7 @@ func (c *Controller) checkForUpgrades(ctx context.Context, tenant *miniov2.Tenan
version428,
version429,
version430,
version45,
}
for _, v := range versionsThatNeedUpgrades {
vp, _ := version.NewVersion(v)
Expand Down Expand Up @@ -296,3 +302,62 @@ func (c *Controller) upgrade430(ctx context.Context, tenant *miniov2.Tenant) (*m

return c.updateTenantSyncVersion(ctx, tenant, version430)
}

// Upgrades the sync version to v4.5
// in this version we finally deprecated tenant.spec.credsSecret field.
func (c *Controller) upgrade45(ctx context.Context, tenant *miniov2.Tenant) (*miniov2.Tenant, error) {
if tenant.HasConfigurationSecret() {
return c.updateTenantSyncVersion(ctx, tenant, version45)
}
if !tenant.HasCredsSecret() {
return nil, fmt.Errorf("'%s/%s' error migrating tenant credsSecret, credsSecret does not exist", tenant.Namespace, tenant.Name)
}
// Create new configuration secret based on the existing credsSecret
credsSecret, err := c.kubeClientSet.CoreV1().Secrets(tenant.Namespace).Get(ctx, tenant.Spec.CredsSecret.Name, metav1.GetOptions{})
if err != nil && !k8serrors.IsNotFound(err) {
return nil, err
}
var accessKey string
var secretKey string
if _, ok := credsSecret.Data["accesskey"]; ok {
accessKey = string(credsSecret.Data["accesskey"])
}
if _, ok := credsSecret.Data["secretkey"]; ok {
secretKey = string(credsSecret.Data["secretkey"])
}
if accessKey == "" || secretKey == "" {
return nil, fmt.Errorf("accessKey/secretKey are empty - '%s/%s' error in migrating tenant credsSecret to newer configuration", tenant.Namespace, tenant.Name)
}
tenantConfiguration := map[string]string{}
tenantConfiguration["MINIO_ROOT_USER"] = accessKey
tenantConfiguration["MINIO_ROOT_PASSWORD"] = secretKey
configurationSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: tenant.ConfigurationSecretName(),
Namespace: tenant.Namespace,
},
TypeMeta: metav1.TypeMeta{
Kind: "Secret",
APIVersion: corev1.SchemeGroupVersion.Version,
},
Data: map[string][]byte{
"config.env": []byte(miniov2.GenerateTenantConfigurationFile(tenantConfiguration)),
},
}
_, err = c.kubeClientSet.CoreV1().Secrets(tenant.Namespace).Create(ctx, configurationSecret, metav1.CreateOptions{})
if err != nil {
return nil, err
}
// Update tenant fields
tenantCopy := tenant.DeepCopy()
tenantCopy.EnsureDefaults()
tenantCopy.Spec.Configuration = &corev1.LocalObjectReference{
Name: tenantCopy.ConfigurationSecretName(),
}
tenantCopy.Spec.CredsSecret = nil
_, err = c.minioClientSet.MinioV2().Tenants(tenant.Namespace).Update(ctx, tenantCopy, metav1.UpdateOptions{})
if err != nil {
return nil, fmt.Errorf("error updating tenant '%s/%s', could not update tenant.spec.configuration field: %v", tenant.Namespace, tenant.Name, err)
}
return c.updateTenantSyncVersion(ctx, tenant, version45)
}
Loading

0 comments on commit 6746eb6

Please sign in to comment.