diff --git a/docs/tenant_crd.adoc b/docs/tenant_crd.adoc index 7fd269b8bb6..7394ed25b84 100644 --- a/docs/tenant_crd.adoc +++ b/docs/tenant_crd.adoc @@ -108,6 +108,35 @@ CertificateStatus keeps track of all the certificates managed by the operator |=== +[id="{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-configmapkeyselector"] +==== ConfigMapKeySelector + +Selects a key from a ConfigMap. + +.Appears In: +**** +- xref:{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-envvarsource[$$EnvVarSource$$] +**** + +[cols="25a,75a", options="header"] +|=== +| Field | Description + +|*`name`* __string__ +|Name of the referent. +This field is effectively required, but due to backwards compatibility is +allowed to be empty. Instances of this type with an empty value here are +almost certainly wrong. +TODO: Add other useful fields. apiVersion, kind, uid? +More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names +TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + +|*`key`* __string__ +|The key to select. + +|=== + + [id="{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-customcertificateconfig"] ==== CustomCertificateConfig @@ -190,6 +219,63 @@ Certificate Authorities |=== +[id="{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-envvar"] +==== EnvVar + +EnvVar represents an environment variable present in a Container. + +.Appears In: +**** +- xref:{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-tenantspec[$$TenantSpec$$] +**** + +[cols="25a,75a", options="header"] +|=== +| Field | Description + +|*`name`* __string__ +|Name of the environment variable. Must be a C_IDENTIFIER. + +|*`value`* __string__ +|Variable references $(VAR_NAME) are expanded +using the previously defined environment variables in the container and +any service environment variables. If a variable cannot be resolved, +the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. +"$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". +Escaped references will never be expanded, regardless of whether the variable +exists or not. +Defaults to "". + +|*`valueFrom`* __xref:{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-envvarsource[$$EnvVarSource$$]__ +|Source for the environment variable's value. Cannot be used if value is not empty. + +|=== + + +[id="{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-envvarsource"] +==== EnvVarSource + +EnvVarSource represents a source for the value of an EnvVar. + +.Appears In: +**** +- xref:{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-envvar[$$EnvVar$$] +**** + +[cols="25a,75a", options="header"] +|=== +| Field | Description + +|*`configMapKeyRef`* __xref:{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-configmapkeyselector[$$ConfigMapKeySelector$$]__ +|Selects a key of a ConfigMap. + +|*`secretKeyRef`* __xref:{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-secretkeyselector[$$SecretKeySelector$$]__ +|Selects a key of a secret in the pod's namespace + +|=== + + [id="{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-exposeservices"] ==== ExposeServices @@ -689,6 +775,35 @@ Security Context |=== +[id="{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-secretkeyselector"] +==== SecretKeySelector + +SecretKeySelector selects a key of a Secret. + +.Appears In: +**** +- xref:{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-envvarsource[$$EnvVarSource$$] +**** + +[cols="25a,75a", options="header"] +|=== +| Field | Description + +|*`name`* __string__ +|Name of the referent. +This field is effectively required, but due to backwards compatibility is +allowed to be empty. Instances of this type with an empty value here are +almost certainly wrong. +TODO: Add other useful fields. apiVersion, kind, uid? +More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names +TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + +|*`key`* __string__ +|The key of the secret to select from. Must be a valid secret key. + +|=== + + [id="{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-servicemetadata"] ==== ServiceMetadata @@ -915,7 +1030,7 @@ Specify the secret key to use for pulling images from a private Docker repositor Pod Management Policy for pod created by StatefulSet -|*`env`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#envvar-v1-core[$$EnvVar$$] array__ +|*`env`* __xref:{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-envvar[$$EnvVar$$] array__ |*Optional* + diff --git a/helm/operator/templates/minio.min.io_tenants.yaml b/helm/operator/templates/minio.min.io_tenants.yaml index b55a9f736bd..1b13e257665 100644 --- a/helm/operator/templates/minio.min.io_tenants.yaml +++ b/helm/operator/templates/minio.min.io_tenants.yaml @@ -901,38 +901,10 @@ spec: name: default: "" type: string - optional: - type: boolean required: - key type: object x-kubernetes-map-type: atomic - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic secretKeyRef: properties: key: @@ -940,8 +912,6 @@ spec: name: default: "" type: string - optional: - type: boolean required: - key type: object diff --git a/pkg/apis/minio.min.io/v2/helper.go b/pkg/apis/minio.min.io/v2/helper.go index e8579fad8c8..a4d55f34b06 100644 --- a/pkg/apis/minio.min.io/v2/helper.go +++ b/pkg/apis/minio.min.io/v2/helper.go @@ -523,7 +523,7 @@ func (t *Tenant) HasPrometheusOperatorEnabled() bool { } // GetEnvVars returns the environment variables for tenant deployment. -func (t *Tenant) GetEnvVars() (env []corev1.EnvVar) { +func (t *Tenant) GetEnvVars() (env []EnvVar) { return t.Spec.Env } diff --git a/pkg/apis/minio.min.io/v2/helper_test.go b/pkg/apis/minio.min.io/v2/helper_test.go index d8bc4cccda0..18d22fb720a 100644 --- a/pkg/apis/minio.min.io/v2/helper_test.go +++ b/pkg/apis/minio.min.io/v2/helper_test.go @@ -395,7 +395,7 @@ func TestTenant_HasEnv(t1 *testing.T) { name: "Contains env", fields: fields{ Spec: TenantSpec{ - Env: []corev1.EnvVar{ + Env: []EnvVar{ { Name: "ENV1", Value: "whatever", @@ -412,7 +412,7 @@ func TestTenant_HasEnv(t1 *testing.T) { name: "Does not Contains env", fields: fields{ Spec: TenantSpec{ - Env: []corev1.EnvVar{ + Env: []EnvVar{ { Name: "ENV1", Value: "whatever", diff --git a/pkg/apis/minio.min.io/v2/types.go b/pkg/apis/minio.min.io/v2/types.go index fd03c608b88..eb0ed685ef4 100644 --- a/pkg/apis/minio.min.io/v2/types.go +++ b/pkg/apis/minio.min.io/v2/types.go @@ -128,7 +128,7 @@ type TenantSpec struct { // // If provided, the MinIO Operator adds the specified environment variables when deploying the Tenant resource. // +optional - Env []corev1.EnvVar `json:"env,omitempty"` + Env []EnvVar `json:"env,omitempty"` // *Optional* + // @@ -910,3 +910,54 @@ type SideCars struct { // +optional Resources *corev1.ResourceRequirements `json:"resources,omitempty"` } + +// EnvVar represents an environment variable present in a Container. +type EnvVar struct { + // Name of the environment variable. Must be a C_IDENTIFIER. + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` + + // Optional: no more than one of the following may be specified. + + // Variable references $(VAR_NAME) are expanded + // using the previously defined environment variables in the container and + // any service environment variables. If a variable cannot be resolved, + // the reference in the input string will be unchanged. Double $$ are reduced + // to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + // "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + // Escaped references will never be expanded, regardless of whether the variable + // exists or not. + // Defaults to "". + // +optional + Value string `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"` + // Source for the environment variable's value. Cannot be used if value is not empty. + // +optional + ValueFrom *EnvVarSource `json:"valueFrom,omitempty" protobuf:"bytes,3,opt,name=valueFrom"` +} + +// EnvVarSource represents a source for the value of an EnvVar. +type EnvVarSource struct { + // Selects a key of a ConfigMap. + // +optional + ConfigMapKeyRef *ConfigMapKeySelector `json:"configMapKeyRef,omitempty" protobuf:"bytes,3,opt,name=configMapKeyRef"` + // Selects a key of a secret in the pod's namespace + // +optional + SecretKeyRef *SecretKeySelector `json:"secretKeyRef,omitempty" protobuf:"bytes,4,opt,name=secretKeyRef"` +} + +// Selects a key from a ConfigMap. +// +structType=atomic +type ConfigMapKeySelector struct { + // The ConfigMap to select from. + corev1.LocalObjectReference `json:",inline" protobuf:"bytes,1,opt,name=localObjectReference"` + // The key to select. + Key string `json:"key" protobuf:"bytes,2,opt,name=key"` +} + +// SecretKeySelector selects a key of a Secret. +// +structType=atomic +type SecretKeySelector struct { + // The name of the secret in the pod's namespace to select from. + corev1.LocalObjectReference `json:",inline" protobuf:"bytes,1,opt,name=localObjectReference"` + // The key of the secret to select from. Must be a valid secret key. + Key string `json:"key" protobuf:"bytes,2,opt,name=key"` +} diff --git a/pkg/apis/minio.min.io/v2/zz_generated.deepcopy.go b/pkg/apis/minio.min.io/v2/zz_generated.deepcopy.go index f126817ac5a..a08e022b0d2 100644 --- a/pkg/apis/minio.min.io/v2/zz_generated.deepcopy.go +++ b/pkg/apis/minio.min.io/v2/zz_generated.deepcopy.go @@ -115,6 +115,23 @@ func (in *CertificateStatus) DeepCopy() *CertificateStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigMapKeySelector) DeepCopyInto(out *ConfigMapKeySelector) { + *out = *in + out.LocalObjectReference = in.LocalObjectReference + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigMapKeySelector. +func (in *ConfigMapKeySelector) DeepCopy() *ConfigMapKeySelector { + if in == nil { + return nil + } + out := new(ConfigMapKeySelector) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CustomCertificateConfig) DeepCopyInto(out *CustomCertificateConfig) { *out = *in @@ -185,6 +202,53 @@ func (in *CustomCertificates) DeepCopy() *CustomCertificates { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EnvVar) DeepCopyInto(out *EnvVar) { + *out = *in + if in.ValueFrom != nil { + in, out := &in.ValueFrom, &out.ValueFrom + *out = new(EnvVarSource) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvVar. +func (in *EnvVar) DeepCopy() *EnvVar { + if in == nil { + return nil + } + out := new(EnvVar) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EnvVarSource) DeepCopyInto(out *EnvVarSource) { + *out = *in + if in.ConfigMapKeyRef != nil { + in, out := &in.ConfigMapKeyRef, &out.ConfigMapKeyRef + *out = new(ConfigMapKeySelector) + **out = **in + } + if in.SecretKeyRef != nil { + in, out := &in.SecretKeyRef, &out.SecretKeyRef + *out = new(SecretKeySelector) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvVarSource. +func (in *EnvVarSource) DeepCopy() *EnvVarSource { + if in == nil { + return nil + } + out := new(EnvVarSource) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ExposeServices) DeepCopyInto(out *ExposeServices) { *out = *in @@ -441,6 +505,23 @@ func (in *PoolStatus) DeepCopy() *PoolStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecretKeySelector) DeepCopyInto(out *SecretKeySelector) { + *out = *in + out.LocalObjectReference = in.LocalObjectReference + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretKeySelector. +func (in *SecretKeySelector) DeepCopy() *SecretKeySelector { + if in == nil { + return nil + } + out := new(SecretKeySelector) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServiceMetadata) DeepCopyInto(out *ServiceMetadata) { *out = *in @@ -639,7 +720,7 @@ func (in *TenantSpec) DeepCopyInto(out *TenantSpec) { out.ImagePullSecret = in.ImagePullSecret if in.Env != nil { in, out := &in.Env, &out.Env - *out = make([]v1.EnvVar, len(*in)) + *out = make([]EnvVar, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } diff --git a/pkg/client/applyconfiguration/minio.min.io/v2/configmapkeyselector.go b/pkg/client/applyconfiguration/minio.min.io/v2/configmapkeyselector.go new file mode 100644 index 00000000000..00d1a1fd3fe --- /dev/null +++ b/pkg/client/applyconfiguration/minio.min.io/v2/configmapkeyselector.go @@ -0,0 +1,52 @@ +// This file is part of MinIO Operator +// Copyright (c) 2024 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v2 + +import ( + v1 "k8s.io/api/core/v1" +) + +// ConfigMapKeySelectorApplyConfiguration represents an declarative configuration of the ConfigMapKeySelector type for use +// with apply. +type ConfigMapKeySelectorApplyConfiguration struct { + v1.LocalObjectReference `json:",inline"` + Key *string `json:"key,omitempty"` +} + +// ConfigMapKeySelectorApplyConfiguration constructs an declarative configuration of the ConfigMapKeySelector type for use with +// apply. +func ConfigMapKeySelector() *ConfigMapKeySelectorApplyConfiguration { + return &ConfigMapKeySelectorApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ConfigMapKeySelectorApplyConfiguration) WithName(value string) *ConfigMapKeySelectorApplyConfiguration { + b.Name = &value + return b +} + +// WithKey sets the Key field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Key field is set to the value of the last call. +func (b *ConfigMapKeySelectorApplyConfiguration) WithKey(value string) *ConfigMapKeySelectorApplyConfiguration { + b.Key = &value + return b +} diff --git a/pkg/client/applyconfiguration/minio.min.io/v2/envvar.go b/pkg/client/applyconfiguration/minio.min.io/v2/envvar.go new file mode 100644 index 00000000000..7d2bd6d5de7 --- /dev/null +++ b/pkg/client/applyconfiguration/minio.min.io/v2/envvar.go @@ -0,0 +1,57 @@ +// This file is part of MinIO Operator +// Copyright (c) 2024 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v2 + +// EnvVarApplyConfiguration represents an declarative configuration of the EnvVar type for use +// with apply. +type EnvVarApplyConfiguration struct { + Name *string `json:"name,omitempty"` + Value *string `json:"value,omitempty"` + ValueFrom *EnvVarSourceApplyConfiguration `json:"valueFrom,omitempty"` +} + +// EnvVarApplyConfiguration constructs an declarative configuration of the EnvVar type for use with +// apply. +func EnvVar() *EnvVarApplyConfiguration { + return &EnvVarApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *EnvVarApplyConfiguration) WithName(value string) *EnvVarApplyConfiguration { + b.Name = &value + return b +} + +// WithValue sets the Value field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Value field is set to the value of the last call. +func (b *EnvVarApplyConfiguration) WithValue(value string) *EnvVarApplyConfiguration { + b.Value = &value + return b +} + +// WithValueFrom sets the ValueFrom field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ValueFrom field is set to the value of the last call. +func (b *EnvVarApplyConfiguration) WithValueFrom(value *EnvVarSourceApplyConfiguration) *EnvVarApplyConfiguration { + b.ValueFrom = value + return b +} diff --git a/pkg/client/applyconfiguration/minio.min.io/v2/envvarsource.go b/pkg/client/applyconfiguration/minio.min.io/v2/envvarsource.go new file mode 100644 index 00000000000..184a1ba5809 --- /dev/null +++ b/pkg/client/applyconfiguration/minio.min.io/v2/envvarsource.go @@ -0,0 +1,48 @@ +// This file is part of MinIO Operator +// Copyright (c) 2024 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v2 + +// EnvVarSourceApplyConfiguration represents an declarative configuration of the EnvVarSource type for use +// with apply. +type EnvVarSourceApplyConfiguration struct { + ConfigMapKeyRef *ConfigMapKeySelectorApplyConfiguration `json:"configMapKeyRef,omitempty"` + SecretKeyRef *SecretKeySelectorApplyConfiguration `json:"secretKeyRef,omitempty"` +} + +// EnvVarSourceApplyConfiguration constructs an declarative configuration of the EnvVarSource type for use with +// apply. +func EnvVarSource() *EnvVarSourceApplyConfiguration { + return &EnvVarSourceApplyConfiguration{} +} + +// WithConfigMapKeyRef sets the ConfigMapKeyRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ConfigMapKeyRef field is set to the value of the last call. +func (b *EnvVarSourceApplyConfiguration) WithConfigMapKeyRef(value *ConfigMapKeySelectorApplyConfiguration) *EnvVarSourceApplyConfiguration { + b.ConfigMapKeyRef = value + return b +} + +// WithSecretKeyRef sets the SecretKeyRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the SecretKeyRef field is set to the value of the last call. +func (b *EnvVarSourceApplyConfiguration) WithSecretKeyRef(value *SecretKeySelectorApplyConfiguration) *EnvVarSourceApplyConfiguration { + b.SecretKeyRef = value + return b +} diff --git a/pkg/client/applyconfiguration/minio.min.io/v2/secretkeyselector.go b/pkg/client/applyconfiguration/minio.min.io/v2/secretkeyselector.go new file mode 100644 index 00000000000..dcc593a8062 --- /dev/null +++ b/pkg/client/applyconfiguration/minio.min.io/v2/secretkeyselector.go @@ -0,0 +1,52 @@ +// This file is part of MinIO Operator +// Copyright (c) 2024 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v2 + +import ( + v1 "k8s.io/api/core/v1" +) + +// SecretKeySelectorApplyConfiguration represents an declarative configuration of the SecretKeySelector type for use +// with apply. +type SecretKeySelectorApplyConfiguration struct { + v1.LocalObjectReference `json:",inline"` + Key *string `json:"key,omitempty"` +} + +// SecretKeySelectorApplyConfiguration constructs an declarative configuration of the SecretKeySelector type for use with +// apply. +func SecretKeySelector() *SecretKeySelectorApplyConfiguration { + return &SecretKeySelectorApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *SecretKeySelectorApplyConfiguration) WithName(value string) *SecretKeySelectorApplyConfiguration { + b.Name = &value + return b +} + +// WithKey sets the Key field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Key field is set to the value of the last call. +func (b *SecretKeySelectorApplyConfiguration) WithKey(value string) *SecretKeySelectorApplyConfiguration { + b.Key = &value + return b +} diff --git a/pkg/client/applyconfiguration/minio.min.io/v2/tenantspec.go b/pkg/client/applyconfiguration/minio.min.io/v2/tenantspec.go index abc30b5c57d..45899e76785 100644 --- a/pkg/client/applyconfiguration/minio.min.io/v2/tenantspec.go +++ b/pkg/client/applyconfiguration/minio.min.io/v2/tenantspec.go @@ -31,7 +31,7 @@ type TenantSpecApplyConfiguration struct { Image *string `json:"image,omitempty"` ImagePullSecret *v1.LocalObjectReference `json:"imagePullSecret,omitempty"` PodManagementPolicy *appsv1.PodManagementPolicyType `json:"podManagementPolicy,omitempty"` - Env []v1.EnvVar `json:"env,omitempty"` + Env []EnvVarApplyConfiguration `json:"env,omitempty"` ExternalCertSecret []*miniominiov2.LocalCertificateReference `json:"externalCertSecret,omitempty"` ExternalCaCertSecret []*miniominiov2.LocalCertificateReference `json:"externalCaCertSecret,omitempty"` ExternalClientCertSecret *LocalCertificateReferenceApplyConfiguration `json:"externalClientCertSecret,omitempty"` @@ -109,9 +109,12 @@ func (b *TenantSpecApplyConfiguration) WithPodManagementPolicy(value appsv1.PodM // WithEnv adds the given value to the Env field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the Env field. -func (b *TenantSpecApplyConfiguration) WithEnv(values ...v1.EnvVar) *TenantSpecApplyConfiguration { +func (b *TenantSpecApplyConfiguration) WithEnv(values ...*EnvVarApplyConfiguration) *TenantSpecApplyConfiguration { for i := range values { - b.Env = append(b.Env, values[i]) + if values[i] == nil { + panic("nil value passed to WithEnv") + } + b.Env = append(b.Env, *values[i]) } return b } diff --git a/pkg/client/applyconfiguration/utils.go b/pkg/client/applyconfiguration/utils.go index 1dd2f545ea7..5d4a278c1b1 100644 --- a/pkg/client/applyconfiguration/utils.go +++ b/pkg/client/applyconfiguration/utils.go @@ -55,10 +55,16 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &miniominiov2.CertificateConfigApplyConfiguration{} case v2.SchemeGroupVersion.WithKind("CertificateStatus"): return &miniominiov2.CertificateStatusApplyConfiguration{} + case v2.SchemeGroupVersion.WithKind("ConfigMapKeySelector"): + return &miniominiov2.ConfigMapKeySelectorApplyConfiguration{} case v2.SchemeGroupVersion.WithKind("CustomCertificateConfig"): return &miniominiov2.CustomCertificateConfigApplyConfiguration{} case v2.SchemeGroupVersion.WithKind("CustomCertificates"): return &miniominiov2.CustomCertificatesApplyConfiguration{} + case v2.SchemeGroupVersion.WithKind("EnvVar"): + return &miniominiov2.EnvVarApplyConfiguration{} + case v2.SchemeGroupVersion.WithKind("EnvVarSource"): + return &miniominiov2.EnvVarSourceApplyConfiguration{} case v2.SchemeGroupVersion.WithKind("ExposeServices"): return &miniominiov2.ExposeServicesApplyConfiguration{} case v2.SchemeGroupVersion.WithKind("Features"): @@ -73,6 +79,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &miniominiov2.PoolApplyConfiguration{} case v2.SchemeGroupVersion.WithKind("PoolStatus"): return &miniominiov2.PoolStatusApplyConfiguration{} + case v2.SchemeGroupVersion.WithKind("SecretKeySelector"): + return &miniominiov2.SecretKeySelectorApplyConfiguration{} case v2.SchemeGroupVersion.WithKind("ServiceMetadata"): return &miniominiov2.ServiceMetadataApplyConfiguration{} case v2.SchemeGroupVersion.WithKind("SideCars"): diff --git a/resources/base/crds/minio.min.io_tenants.yaml b/resources/base/crds/minio.min.io_tenants.yaml index b55a9f736bd..1b13e257665 100644 --- a/resources/base/crds/minio.min.io_tenants.yaml +++ b/resources/base/crds/minio.min.io_tenants.yaml @@ -901,38 +901,10 @@ spec: name: default: "" type: string - optional: - type: boolean required: - key type: object x-kubernetes-map-type: atomic - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic secretKeyRef: properties: key: @@ -940,8 +912,6 @@ spec: name: default: "" type: string - optional: - type: boolean required: - key type: object diff --git a/sidecar/pkg/configuration/tenant_configuration.go b/sidecar/pkg/configuration/tenant_configuration.go index c00c24aad0e..60584b66d82 100644 --- a/sidecar/pkg/configuration/tenant_configuration.go +++ b/sidecar/pkg/configuration/tenant_configuration.go @@ -18,7 +18,6 @@ package configuration import ( "context" - "errors" "fmt" "log" "sort" @@ -36,8 +35,8 @@ const ( ) type ( - secretFunc func(ctx context.Context, name string) (*corev1.Secret, error) - configFunc func(ctx context.Context, name string) (*corev1.ConfigMap, error) + secretFunc func(ctx context.Context, name string) *corev1.Secret + configFunc func(ctx context.Context, name string) *corev1.ConfigMap ) // TenantResources returns maps for all configmap/secret resources that @@ -49,31 +48,17 @@ func TenantResources(ctx context.Context, tenant *miniov2.Tenant, cf configFunc, for _, env := range tenant.Spec.Env { if env.ValueFrom != nil { if env.ValueFrom.SecretKeyRef != nil { - secret, err := sf(ctx, env.ValueFrom.SecretKeyRef.Name) - if err != nil { - return nil, nil, err - } - secrets[env.ValueFrom.SecretKeyRef.Name] = secret + secrets[env.ValueFrom.SecretKeyRef.Name] = sf(ctx, env.ValueFrom.SecretKeyRef.Name) } if env.ValueFrom.ConfigMapKeyRef != nil { - configmap, err := cf(ctx, env.ValueFrom.ConfigMapKeyRef.Name) - if err != nil { - return nil, nil, err - } - configMaps[env.ValueFrom.ConfigMapKeyRef.Name] = configmap - } - if env.ValueFrom.FieldRef != nil { - return nil, nil, errors.New("mapping fields is not supported") - } - if env.ValueFrom.ResourceFieldRef != nil { - return nil, nil, errors.New("mapping resource fields is not supported") + configMaps[env.ValueFrom.ConfigMapKeyRef.Name] = cf(ctx, env.ValueFrom.ConfigMapKeyRef.Name) } } } - secret, err := sf(ctx, tenant.Spec.Configuration.Name) - if err != nil { - return nil, nil, err + secret := sf(ctx, tenant.Spec.Configuration.Name) + if secret == nil { + return nil, nil, fmt.Errorf("cannot find configurations secret %s", tenant.Spec.Configuration.Name) } secrets[tenant.Spec.Configuration.Name] = secret @@ -101,12 +86,12 @@ func GetFullTenantConfig(tenant *miniov2.Tenant, configMaps map[string]*corev1.C return configurationFileContent, rootUserFound, rootPwdFound } -func parseConfEnvSecret(secret *corev1.Secret) map[string]corev1.EnvVar { +func parseConfEnvSecret(secret *corev1.Secret) map[string]miniov2.EnvVar { if secret == nil { return nil } data := secret.Data["config.env"] - envMap := make(map[string]corev1.EnvVar) + envMap := make(map[string]miniov2.EnvVar) lines := strings.Split(string(data), "\n") for _, line := range lines { @@ -121,7 +106,7 @@ func parseConfEnvSecret(secret *corev1.Secret) map[string]corev1.EnvVar { log.Printf("Syntax error for variable %s (skipped): %s", name, err) continue } - envMap[name] = corev1.EnvVar{ + envMap[name] = miniov2.EnvVar{ Name: name, Value: value, } @@ -131,11 +116,11 @@ func parseConfEnvSecret(secret *corev1.Secret) map[string]corev1.EnvVar { return envMap } -func buildTenantEnvs(tenant *miniov2.Tenant, cfgEnvExisting map[string]corev1.EnvVar) []corev1.EnvVar { +func buildTenantEnvs(tenant *miniov2.Tenant, cfgEnvExisting map[string]miniov2.EnvVar) []miniov2.EnvVar { // Enable `mc admin update` style updates to MinIO binaries // within the container, only operator is supposed to perform // these operations. - envVarsMap := map[string]corev1.EnvVar{ + envVarsMap := map[string]miniov2.EnvVar{ "MINIO_UPDATE": { Name: "MINIO_UPDATE", Value: "on", @@ -153,7 +138,7 @@ func buildTenantEnvs(tenant *miniov2.Tenant, cfgEnvExisting map[string]corev1.En for _, pool := range tenant.Spec.Pools { if pool.RuntimeClassName != nil && *pool.RuntimeClassName == "crun" { // Set HOME to / - envVarsMap["HOME"] = corev1.EnvVar{ + envVarsMap["HOME"] = miniov2.EnvVar{ Name: "HOME", Value: "/", } @@ -168,7 +153,7 @@ func buildTenantEnvs(tenant *miniov2.Tenant, cfgEnvExisting map[string]corev1.En common.WebhookAPIBucketService, tenant.Namespace, tenant.Name) - envVarsMap[bucketDNSEnv] = corev1.EnvVar{ + envVarsMap[bucketDNSEnv] = miniov2.EnvVar{ Name: bucketDNSEnv, Value: sidecarBucketURL, } @@ -179,7 +164,7 @@ func buildTenantEnvs(tenant *miniov2.Tenant, cfgEnvExisting map[string]corev1.En } // tell MinIO about all the domains meant to hit it if they are not passed manually via .spec.env if len(domains) > 0 { - envVarsMap[miniov2.MinIODomain] = corev1.EnvVar{ + envVarsMap[miniov2.MinIODomain] = miniov2.EnvVar{ Name: miniov2.MinIODomain, Value: strings.Join(domains, ","), } @@ -200,7 +185,7 @@ func buildTenantEnvs(tenant *miniov2.Tenant, cfgEnvExisting map[string]corev1.En serverURL = tenant.Spec.Features.Domains.Minio[0] } } - envVarsMap[miniov2.MinIOServerURL] = corev1.EnvVar{ + envVarsMap[miniov2.MinIOServerURL] = miniov2.EnvVar{ Name: miniov2.MinIOServerURL, Value: serverURL, } @@ -216,33 +201,33 @@ func buildTenantEnvs(tenant *miniov2.Tenant, cfgEnvExisting map[string]corev1.En } consoleDomain = fmt.Sprintf("%s://%s", useSchema, consoleDomain) } - envVarsMap[miniov2.MinIOBrowserRedirectURL] = corev1.EnvVar{ + envVarsMap[miniov2.MinIOBrowserRedirectURL] = miniov2.EnvVar{ Name: miniov2.MinIOBrowserRedirectURL, Value: consoleDomain, } } if tenant.HasKESEnabled() { - envVarsMap["MINIO_KMS_KES_ENDPOINT"] = corev1.EnvVar{ + envVarsMap["MINIO_KMS_KES_ENDPOINT"] = miniov2.EnvVar{ Name: "MINIO_KMS_KES_ENDPOINT", Value: tenant.KESServiceEndpoint(), } - envVarsMap["MINIO_KMS_KES_CERT_FILE"] = corev1.EnvVar{ + envVarsMap["MINIO_KMS_KES_CERT_FILE"] = miniov2.EnvVar{ Name: "MINIO_KMS_KES_CERT_FILE", Value: miniov2.MinIOCertPath + "/client.crt", } - envVarsMap["MINIO_KMS_KES_KEY_FILE"] = corev1.EnvVar{ + envVarsMap["MINIO_KMS_KES_KEY_FILE"] = miniov2.EnvVar{ Name: "MINIO_KMS_KES_KEY_FILE", Value: miniov2.MinIOCertPath + "/client.key", } - envVarsMap["MINIO_KMS_KES_CA_PATH"] = corev1.EnvVar{ + envVarsMap["MINIO_KMS_KES_CA_PATH"] = miniov2.EnvVar{ Name: "MINIO_KMS_KES_CA_PATH", Value: miniov2.MinIOCertPath + "/CAs/kes.crt", } - envVarsMap["MINIO_KMS_KES_CAPATH"] = corev1.EnvVar{ + envVarsMap["MINIO_KMS_KES_CAPATH"] = miniov2.EnvVar{ Name: "MINIO_KMS_KES_CAPATH", Value: miniov2.MinIOCertPath + "/CAs/kes.crt", } - envVarsMap["MINIO_KMS_KES_KEY_NAME"] = corev1.EnvVar{ + envVarsMap["MINIO_KMS_KES_KEY_NAME"] = miniov2.EnvVar{ Name: "MINIO_KMS_KES_KEY_NAME", Value: tenant.Spec.KES.KeyName, } @@ -250,7 +235,7 @@ func buildTenantEnvs(tenant *miniov2.Tenant, cfgEnvExisting map[string]corev1.En // attach tenant args args := strings.Join(statefulsets.GetContainerArgs(tenant, ""), " ") - envVarsMap["MINIO_ARGS"] = corev1.EnvVar{ + envVarsMap["MINIO_ARGS"] = miniov2.EnvVar{ Name: "MINIO_ARGS", Value: args, } @@ -260,7 +245,7 @@ func buildTenantEnvs(tenant *miniov2.Tenant, cfgEnvExisting map[string]corev1.En for _, env := range tenant.GetEnvVars() { envVarsMap[env.Name] = env } - var envVars []corev1.EnvVar + var envVars []miniov2.EnvVar // transform map to array and skip configurations from config.env for _, env := range envVarsMap { if cfgEnvExisting != nil { @@ -283,19 +268,32 @@ func buildTenantEnvs(tenant *miniov2.Tenant, cfgEnvExisting map[string]corev1.En return envVars } -func envVarsToFileContent(envVars []corev1.EnvVar, configMaps map[string]*corev1.ConfigMap, secrets map[string]*corev1.Secret) string { +func envVarsToFileContent(envVars []miniov2.EnvVar, configMaps map[string]*corev1.ConfigMap, secrets map[string]*corev1.Secret) string { var sb strings.Builder for _, env := range envVars { - value := env.Value + var value *string if env.ValueFrom != nil { if env.ValueFrom.ConfigMapKeyRef != nil { - value = configMaps[env.ValueFrom.ConfigMapKeyRef.Name].Data[env.ValueFrom.ConfigMapKeyRef.Key] + if configMap, ok := configMaps[env.ValueFrom.ConfigMapKeyRef.Name]; ok { + if configMapValue, ok := configMap.Data[env.ValueFrom.ConfigMapKeyRef.Key]; ok { + value = &configMapValue + } + } } if env.ValueFrom.SecretKeyRef != nil { - value = string(secrets[env.ValueFrom.SecretKeyRef.Name].Data[env.ValueFrom.SecretKeyRef.Key]) + if secret, ok := secrets[env.ValueFrom.SecretKeyRef.Name]; ok { + if secretValue, ok := secret.Data[env.ValueFrom.SecretKeyRef.Key]; ok { + textValue := string(secretValue) + value = &textValue + } + } } + } else { + value = &env.Value + } + if value != nil { + sb.WriteString(fmt.Sprintf("export %s=\"%s\"\n", env.Name, *value)) } - sb.WriteString(fmt.Sprintf("export %s=\"%s\"\n", env.Name, value)) } return sb.String() } diff --git a/sidecar/pkg/sidecar/sidecar_utils.go b/sidecar/pkg/sidecar/sidecar_utils.go index bf37cccc88a..8b80c924a62 100644 --- a/sidecar/pkg/sidecar/sidecar_utils.go +++ b/sidecar/pkg/sidecar/sidecar_utils.go @@ -247,12 +247,14 @@ func NewSideCarController(kubeClient *kubernetes.Clientset, controllerClient *cl return c } -func (c *Controller) getSecret(_ context.Context, name string) (*corev1.Secret, error) { - return c.secretInformer.Lister().Secrets(c.tenant.Namespace).Get(name) +func (c *Controller) getSecret(_ context.Context, name string) *corev1.Secret { + retValue, _ := c.secretInformer.Lister().Secrets(c.tenant.Namespace).Get(name) + return retValue } -func (c *Controller) getConfigMap(_ context.Context, name string) (*corev1.ConfigMap, error) { - return c.configMapInformer.Lister().ConfigMaps(c.tenant.Namespace).Get(name) +func (c *Controller) getConfigMap(_ context.Context, name string) *corev1.ConfigMap { + retValue, _ := c.configMapInformer.Lister().ConfigMaps(c.tenant.Namespace).Get(name) + return retValue } func (c *Controller) regenCfg() { diff --git a/sidecar/pkg/validator/validator.go b/sidecar/pkg/validator/validator.go index df8c7670c58..ea1e087cac1 100644 --- a/sidecar/pkg/validator/validator.go +++ b/sidecar/pkg/validator/validator.go @@ -69,10 +69,12 @@ func Validate(tenantName string) { tenant.EnsureDefaults() // determine the configmaps and secrets to watch - configMaps, secrets, err := configuration.TenantResources(context.Background(), tenant, func(ctx context.Context, name string) (*corev1.ConfigMap, error) { - return kubeClient.CoreV1().ConfigMaps(tenant.Namespace).Get(ctx, name, metav1.GetOptions{}) - }, func(ctx context.Context, name string) (*corev1.Secret, error) { - return kubeClient.CoreV1().Secrets(tenant.Namespace).Get(ctx, name, metav1.GetOptions{}) + configMaps, secrets, err := configuration.TenantResources(context.Background(), tenant, func(ctx context.Context, name string) *corev1.ConfigMap { + retValue, _ := kubeClient.CoreV1().ConfigMaps(tenant.Namespace).Get(ctx, name, metav1.GetOptions{}) + return retValue + }, func(ctx context.Context, name string) *corev1.Secret { + retValue, _ := kubeClient.CoreV1().Secrets(tenant.Namespace).Get(ctx, name, metav1.GetOptions{}) + return retValue }) if err != nil { log.Println(err)