diff --git a/docs/tenant_crd.adoc b/docs/tenant_crd.adoc
index 1359765e8cf..e01e63ed310 100644
--- a/docs/tenant_crd.adoc
+++ b/docs/tenant_crd.adoc
@@ -689,6 +689,35 @@ Security Context
|===
+[id="{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-poolsmetadata"]
+==== PoolsMetadata
+
+PoolsMetadata (`poolsMetadata`) defines custom labels and annotations for the MinIO pool stateful sets / pods. +
+
+.Appears In:
+****
+- xref:{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-tenantspec[$$TenantSpec$$]
+****
+
+[cols="25a,75a", options="header"]
+|===
+| Field | Description
+
+|*`labels`* __object (keys:string, values:string)__
+|*Optional* +
+
+
+If provided, append these labels to the MinIO statefulset / pods
+
+|*`annotations`* __object (keys:string, values:string)__
+|*Optional* +
+
+
+If provided, append these annotations to the MinIO statefulset / pods
+
+|===
+
+
[id="{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-servicemetadata"]
==== ServiceMetadata
@@ -727,6 +756,18 @@ If provided, append these labels to the Console service
If provided, append these annotations to the Console service
+|*`kesServiceLabels`* __object (keys:string, values:string)__
+|*Optional* +
+
+
+If provided, append these labels to the KES service
+
+|*`kesServiceAnnotations`* __object (keys:string, values:string)__
+|*Optional* +
+
+
+If provided, append these annotations to the KES service
+
|===
@@ -1154,6 +1195,12 @@ Directs the Operator to expose the MinIO and/or Console services. +
Specify custom labels and annotations to append to the MinIO service and/or Console service.
+|*`poolsMetadata`* __xref:{anchor_prefix}-github-com-minio-operator-pkg-apis-minio-min-io-v2-poolsmetadata[$$PoolsMetadata$$]__
+|*Optional* +
+
+
+Specify custom labels and annotations to append to all pool statefulsets and pods.
+
|*`users`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#localobjectreference-v1-core[$$LocalObjectReference$$] array__
|*Optional* +
diff --git a/examples/kustomization/tenant-certmanager/tenant.yaml b/examples/kustomization/tenant-certmanager/tenant.yaml
index 0ec92d16841..409a4f32a8f 100644
--- a/examples/kustomization/tenant-certmanager/tenant.yaml
+++ b/examples/kustomization/tenant-certmanager/tenant.yaml
@@ -4,6 +4,10 @@ metadata:
name: myminio
namespace: minio-tenant
spec:
+ ## Assign labels to the pool
+ poolsMetadata:
+ labels:
+ app: minio
## Disable default tls certificates.
requestAutoCert: false
## Use certificates generated by cert-manager.
diff --git a/helm/operator/templates/minio.min.io_tenants.yaml b/helm/operator/templates/minio.min.io_tenants.yaml
index d4a1f9fc5e4..e295126ce51 100644
--- a/helm/operator/templates/minio.min.io_tenants.yaml
+++ b/helm/operator/templates/minio.min.io_tenants.yaml
@@ -3638,6 +3638,17 @@ spec:
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
+ poolsMetadata:
+ properties:
+ annotations:
+ additionalProperties:
+ type: string
+ type: object
+ labels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
priorityClassName:
type: string
prometheusOperator:
@@ -3736,6 +3747,14 @@ spec:
additionalProperties:
type: string
type: object
+ kesServiceAnnotations:
+ additionalProperties:
+ type: string
+ type: object
+ kesServiceLabels:
+ additionalProperties:
+ type: string
+ type: object
minioServiceAnnotations:
additionalProperties:
type: string
diff --git a/helm/tenant/templates/tenant.yaml b/helm/tenant/templates/tenant.yaml
index f55a26150f0..15c8f79136a 100644
--- a/helm/tenant/templates/tenant.yaml
+++ b/helm/tenant/templates/tenant.yaml
@@ -28,6 +28,12 @@ spec:
## Secret with default environment variable configurations
configuration:
name: {{ .configuration.name }}
+ {{- if hasKey . "poolsMetadata" }}
+ poolsMetadata: {{- if eq (len .poolsMetadata) 0 }} {} {{- end }}
+ {{- with (dig "poolsMetadata" (dict) .) }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ {{- end }}
pools:
{{- range (dig "pools" (list) .) }}
- servers: {{ dig "servers" 4 . }}
diff --git a/helm/tenant/values.yaml b/helm/tenant/values.yaml
index 1572081c615..52d8ca8dd62 100644
--- a/helm/tenant/values.yaml
+++ b/helm/tenant/values.yaml
@@ -70,6 +70,16 @@ tenant:
secretKey: minio123
#existingSecret: true
+ ###
+ # Metadata that will be added to the statefulset and pods of all pools
+ poolsMetadata:
+ ###
+ # Specify `annotations `__ to associate to Tenant pods.
+ annotations: { }
+ ###
+ # Specify `labels `__ to associate to Tenant pods.
+ labels: { }
+
###
# If this variable is set to true, then enable the usage of an existing Kubernetes secret to set environment variables for the Tenant.
# The existing Kubernetes secret name must be placed under .tenant.configuration.name e.g. existing-minio-env-configuration
diff --git a/pkg/apis/minio.min.io/v2/helper.go b/pkg/apis/minio.min.io/v2/helper.go
index 22927919d58..c86a66552ac 100644
--- a/pkg/apis/minio.min.io/v2/helper.go
+++ b/pkg/apis/minio.min.io/v2/helper.go
@@ -878,20 +878,6 @@ func GetClusterDomain() string {
return k8sClusterDomain
}
-// MergeMaps merges two maps and returns the union
-func MergeMaps(a, b map[string]string) map[string]string {
- if a == nil {
- a = map[string]string{}
- }
- if b == nil {
- b = map[string]string{}
- }
- for k, v := range b {
- a[k] = v
- }
- return a
-}
-
// ToMap converts a slice of env vars to a map of Name and value
func ToMap(envs []corev1.EnvVar) map[string]string {
newMap := make(map[string]string)
diff --git a/pkg/apis/minio.min.io/v2/types.go b/pkg/apis/minio.min.io/v2/types.go
index 9aade94a34f..4644f72a58a 100644
--- a/pkg/apis/minio.min.io/v2/types.go
+++ b/pkg/apis/minio.min.io/v2/types.go
@@ -318,6 +318,11 @@ type TenantSpec struct {
ServiceMetadata *ServiceMetadata `json:"serviceMetadata,omitempty"`
// *Optional* +
//
+ // Specify custom labels and annotations to append to all pool statefulsets and pods.
+ // +optional
+ PoolsMetadata *PoolsMetadata `json:"poolsMetadata,omitempty"`
+ // *Optional* +
+ //
// An array of https://kubernetes.io/docs/concepts/configuration/secret/[Kubernetes opaque secrets] to use for generating MinIO users during tenant provisioning. +
//
// Each element in the array is an object consisting of a key-value pair `name: `, where the `` references an opaque Kubernetes secret. +
@@ -395,6 +400,30 @@ type ServiceMetadata struct {
// If provided, append these annotations to the Console service
// +optional
ConsoleServiceAnnotations map[string]string `json:"consoleServiceAnnotations,omitempty"`
+ // *Optional* +
+ //
+ // If provided, append these labels to the KES service
+ // +optional
+ KESServiceLabels map[string]string `json:"kesServiceLabels,omitempty"`
+ // *Optional* +
+ //
+ // If provided, append these annotations to the KES service
+ // +optional
+ KESServiceAnnotations map[string]string `json:"kesServiceAnnotations,omitempty"`
+}
+
+// PoolsMetadata (`poolsMetadata`) defines custom labels and annotations for the MinIO pool stateful sets / pods. +
+type PoolsMetadata struct {
+ // *Optional* +
+ //
+ // If provided, append these labels to the MinIO statefulset / pods
+ // +optional
+ Labels map[string]string `json:"labels,omitempty"`
+ // *Optional* +
+ //
+ // If provided, append these annotations to the MinIO statefulset / pods
+ // +optional
+ Annotations map[string]string `json:"annotations,omitempty"`
}
// LocalCertificateReference (`externalCertSecret`, `externalCaCertSecret`,`clientCertSecret`) contains a Kubernetes secret containing TLS certificates or Certificate Authority files for use with enabling TLS in the MinIO Tenant. +
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..cec7292ab06 100644
--- a/pkg/apis/minio.min.io/v2/zz_generated.deepcopy.go
+++ b/pkg/apis/minio.min.io/v2/zz_generated.deepcopy.go
@@ -441,6 +441,36 @@ 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 *PoolsMetadata) DeepCopyInto(out *PoolsMetadata) {
+ *out = *in
+ if in.Labels != nil {
+ in, out := &in.Labels, &out.Labels
+ *out = make(map[string]string, len(*in))
+ for key, val := range *in {
+ (*out)[key] = val
+ }
+ }
+ if in.Annotations != nil {
+ in, out := &in.Annotations, &out.Annotations
+ *out = make(map[string]string, len(*in))
+ for key, val := range *in {
+ (*out)[key] = val
+ }
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PoolsMetadata.
+func (in *PoolsMetadata) DeepCopy() *PoolsMetadata {
+ if in == nil {
+ return nil
+ }
+ out := new(PoolsMetadata)
+ 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
@@ -472,6 +502,20 @@ func (in *ServiceMetadata) DeepCopyInto(out *ServiceMetadata) {
(*out)[key] = val
}
}
+ if in.KESServiceLabels != nil {
+ in, out := &in.KESServiceLabels, &out.KESServiceLabels
+ *out = make(map[string]string, len(*in))
+ for key, val := range *in {
+ (*out)[key] = val
+ }
+ }
+ if in.KESServiceAnnotations != nil {
+ in, out := &in.KESServiceAnnotations, &out.KESServiceAnnotations
+ *out = make(map[string]string, len(*in))
+ for key, val := range *in {
+ (*out)[key] = val
+ }
+ }
return
}
@@ -742,6 +786,11 @@ func (in *TenantSpec) DeepCopyInto(out *TenantSpec) {
*out = new(ServiceMetadata)
(*in).DeepCopyInto(*out)
}
+ if in.PoolsMetadata != nil {
+ in, out := &in.PoolsMetadata, &out.PoolsMetadata
+ *out = new(PoolsMetadata)
+ (*in).DeepCopyInto(*out)
+ }
if in.Users != nil {
in, out := &in.Users, &out.Users
*out = make([]v1.LocalObjectReference, len(*in))
diff --git a/pkg/client/applyconfiguration/minio.min.io/v2/poolsmetadata.go b/pkg/client/applyconfiguration/minio.min.io/v2/poolsmetadata.go
new file mode 100644
index 00000000000..613013e8ce5
--- /dev/null
+++ b/pkg/client/applyconfiguration/minio.min.io/v2/poolsmetadata.go
@@ -0,0 +1,60 @@
+// 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
+
+// PoolsMetadataApplyConfiguration represents an declarative configuration of the PoolsMetadata type for use
+// with apply.
+type PoolsMetadataApplyConfiguration struct {
+ Labels map[string]string `json:"labels,omitempty"`
+ Annotations map[string]string `json:"annotations,omitempty"`
+}
+
+// PoolsMetadataApplyConfiguration constructs an declarative configuration of the PoolsMetadata type for use with
+// apply.
+func PoolsMetadata() *PoolsMetadataApplyConfiguration {
+ return &PoolsMetadataApplyConfiguration{}
+}
+
+// WithLabels puts the entries into the Labels field in the declarative configuration
+// and returns the receiver, so that objects can be build by chaining "With" function invocations.
+// If called multiple times, the entries provided by each call will be put on the Labels field,
+// overwriting an existing map entries in Labels field with the same key.
+func (b *PoolsMetadataApplyConfiguration) WithLabels(entries map[string]string) *PoolsMetadataApplyConfiguration {
+ if b.Labels == nil && len(entries) > 0 {
+ b.Labels = make(map[string]string, len(entries))
+ }
+ for k, v := range entries {
+ b.Labels[k] = v
+ }
+ return b
+}
+
+// WithAnnotations puts the entries into the Annotations field in the declarative configuration
+// and returns the receiver, so that objects can be build by chaining "With" function invocations.
+// If called multiple times, the entries provided by each call will be put on the Annotations field,
+// overwriting an existing map entries in Annotations field with the same key.
+func (b *PoolsMetadataApplyConfiguration) WithAnnotations(entries map[string]string) *PoolsMetadataApplyConfiguration {
+ if b.Annotations == nil && len(entries) > 0 {
+ b.Annotations = make(map[string]string, len(entries))
+ }
+ for k, v := range entries {
+ b.Annotations[k] = v
+ }
+ return b
+}
diff --git a/pkg/client/applyconfiguration/minio.min.io/v2/servicemetadata.go b/pkg/client/applyconfiguration/minio.min.io/v2/servicemetadata.go
index d04cadf13c7..6fb7a296678 100644
--- a/pkg/client/applyconfiguration/minio.min.io/v2/servicemetadata.go
+++ b/pkg/client/applyconfiguration/minio.min.io/v2/servicemetadata.go
@@ -25,6 +25,8 @@ type ServiceMetadataApplyConfiguration struct {
MinIOServiceAnnotations map[string]string `json:"minioServiceAnnotations,omitempty"`
ConsoleServiceLabels map[string]string `json:"consoleServiceLabels,omitempty"`
ConsoleServiceAnnotations map[string]string `json:"consoleServiceAnnotations,omitempty"`
+ KESServiceLabels map[string]string `json:"kesServiceLabels,omitempty"`
+ KESServiceAnnotations map[string]string `json:"kesServiceAnnotations,omitempty"`
}
// ServiceMetadataApplyConfiguration constructs a declarative configuration of the ServiceMetadata type for use with
@@ -88,3 +90,31 @@ func (b *ServiceMetadataApplyConfiguration) WithConsoleServiceAnnotations(entrie
}
return b
}
+
+// WithKESServiceLabels puts the entries into the KESServiceLabels field in the declarative configuration
+// and returns the receiver, so that objects can be build by chaining "With" function invocations.
+// If called multiple times, the entries provided by each call will be put on the KESServiceLabels field,
+// overwriting an existing map entries in KESServiceLabels field with the same key.
+func (b *ServiceMetadataApplyConfiguration) WithKESServiceLabels(entries map[string]string) *ServiceMetadataApplyConfiguration {
+ if b.KESServiceLabels == nil && len(entries) > 0 {
+ b.KESServiceLabels = make(map[string]string, len(entries))
+ }
+ for k, v := range entries {
+ b.KESServiceLabels[k] = v
+ }
+ return b
+}
+
+// WithKESServiceAnnotations puts the entries into the KESServiceAnnotations field in the declarative configuration
+// and returns the receiver, so that objects can be build by chaining "With" function invocations.
+// If called multiple times, the entries provided by each call will be put on the KESServiceAnnotations field,
+// overwriting an existing map entries in KESServiceAnnotations field with the same key.
+func (b *ServiceMetadataApplyConfiguration) WithKESServiceAnnotations(entries map[string]string) *ServiceMetadataApplyConfiguration {
+ if b.KESServiceAnnotations == nil && len(entries) > 0 {
+ b.KESServiceAnnotations = make(map[string]string, len(entries))
+ }
+ for k, v := range entries {
+ b.KESServiceAnnotations[k] = v
+ }
+ 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 a4f9f955875..74acd245bd0 100644
--- a/pkg/client/applyconfiguration/minio.min.io/v2/tenantspec.go
+++ b/pkg/client/applyconfiguration/minio.min.io/v2/tenantspec.go
@@ -54,6 +54,7 @@ type TenantSpecApplyConfiguration struct {
SideCars *SideCarsApplyConfiguration `json:"sideCars,omitempty"`
ExposeServices *ExposeServicesApplyConfiguration `json:"exposeServices,omitempty"`
ServiceMetadata *ServiceMetadataApplyConfiguration `json:"serviceMetadata,omitempty"`
+ PoolsMetadata *PoolsMetadataApplyConfiguration `json:"poolsMetadata,omitempty"`
Users []v1.LocalObjectReference `json:"users,omitempty"`
Buckets []BucketApplyConfiguration `json:"buckets,omitempty"`
Logging *LoggingApplyConfiguration `json:"logging,omitempty"`
@@ -307,6 +308,14 @@ func (b *TenantSpecApplyConfiguration) WithServiceMetadata(value *ServiceMetadat
return b
}
+// WithPoolsMetadata sets the PoolsMetadata 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 PoolsMetadata field is set to the value of the last call.
+func (b *TenantSpecApplyConfiguration) WithPoolsMetadata(value *PoolsMetadataApplyConfiguration) *TenantSpecApplyConfiguration {
+ b.PoolsMetadata = value
+ return b
+}
+
// WithUsers adds the given value to the Users 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 Users field.
diff --git a/pkg/client/applyconfiguration/utils.go b/pkg/client/applyconfiguration/utils.go
index 98f3d786e06..2a1101983a5 100644
--- a/pkg/client/applyconfiguration/utils.go
+++ b/pkg/client/applyconfiguration/utils.go
@@ -58,6 +58,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &miniominiov2.LoggingApplyConfiguration{}
case v2.SchemeGroupVersion.WithKind("Pool"):
return &miniominiov2.PoolApplyConfiguration{}
+ case v2.SchemeGroupVersion.WithKind("PoolsMetadata"):
+ return &miniominiov2.PoolsMetadataApplyConfiguration{}
case v2.SchemeGroupVersion.WithKind("PoolStatus"):
return &miniominiov2.PoolStatusApplyConfiguration{}
case v2.SchemeGroupVersion.WithKind("ServiceMetadata"):
diff --git a/pkg/resources/services/service.go b/pkg/resources/services/service.go
index 2a7a6021e7c..b5960f628ac 100644
--- a/pkg/resources/services/service.go
+++ b/pkg/resources/services/service.go
@@ -30,18 +30,6 @@ func NewClusterIPForMinIO(t *miniov2.Tenant) *corev1.Service {
port = miniov2.MinIOTLSPortLoadBalancerSVC
name = miniov2.MinIOServiceHTTPSPortName
}
- var internalLabels, labels, annotations map[string]string
-
- internalLabels = t.MinIOPodLabels()
- if t.Spec.ServiceMetadata != nil && t.Spec.ServiceMetadata.MinIOServiceLabels != nil {
- labels = miniov2.MergeMaps(internalLabels, t.Spec.ServiceMetadata.MinIOServiceLabels)
- } else {
- labels = internalLabels
- }
-
- if t.Spec.ServiceMetadata != nil && t.Spec.ServiceMetadata.MinIOServiceAnnotations != nil {
- annotations = t.Spec.ServiceMetadata.MinIOServiceAnnotations
- }
minioPort := corev1.ServicePort{
Port: port,
@@ -51,11 +39,9 @@ func NewClusterIPForMinIO(t *miniov2.Tenant) *corev1.Service {
svc := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
- Labels: labels,
Name: t.MinIOCIServiceName(),
Namespace: t.Namespace,
OwnerReferences: t.OwnerRef(),
- Annotations: annotations,
},
Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{minioPort},
@@ -64,6 +50,12 @@ func NewClusterIPForMinIO(t *miniov2.Tenant) *corev1.Service {
PublishNotReadyAddresses: false,
},
}
+
+ if t.Spec.ServiceMetadata != nil {
+ svc.Labels = t.Spec.ServiceMetadata.MinIOServiceLabels
+ svc.Annotations = t.Spec.ServiceMetadata.MinIOServiceAnnotations
+ }
+
// check if the service is meant to be exposed
if t.Spec.ExposeServices != nil && t.Spec.ExposeServices.MinIO {
svc.Spec.Type = corev1.ServiceTypeLoadBalancer
@@ -73,9 +65,6 @@ func NewClusterIPForMinIO(t *miniov2.Tenant) *corev1.Service {
// NewClusterIPForConsole will return a new cluster IP service for Console Deployment
func NewClusterIPForConsole(t *miniov2.Tenant) *corev1.Service {
- var internalLabels, labels, annotations map[string]string
- internalLabels = t.ConsolePodLabels()
-
consolePort := corev1.ServicePort{
Port: miniov2.ConsolePort,
TargetPort: intstr.FromInt(miniov2.ConsolePort),
@@ -88,23 +77,12 @@ func NewClusterIPForConsole(t *miniov2.Tenant) *corev1.Service {
Name: miniov2.ConsoleServiceTLSPortName,
}
}
- if t.Spec.ServiceMetadata != nil && t.Spec.ServiceMetadata.ConsoleServiceLabels != nil {
- labels = miniov2.MergeMaps(internalLabels, t.Spec.ServiceMetadata.ConsoleServiceLabels)
- } else {
- labels = internalLabels
- }
-
- if t.Spec.ServiceMetadata != nil && t.Spec.ServiceMetadata.ConsoleServiceAnnotations != nil {
- annotations = t.Spec.ServiceMetadata.ConsoleServiceAnnotations
- }
svc := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
- Labels: labels,
Name: t.ConsoleCIServiceName(),
Namespace: t.Namespace,
OwnerReferences: t.OwnerRef(),
- Annotations: annotations,
},
Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{
@@ -114,6 +92,12 @@ func NewClusterIPForConsole(t *miniov2.Tenant) *corev1.Service {
Type: corev1.ServiceTypeClusterIP,
},
}
+
+ if t.Spec.ServiceMetadata != nil {
+ svc.Labels = t.Spec.ServiceMetadata.ConsoleServiceLabels
+ svc.Annotations = t.Spec.ServiceMetadata.ConsoleServiceAnnotations
+ }
+
// check if the service is meant to be exposed
if t.Spec.ExposeServices != nil && t.Spec.ExposeServices.Console {
svc.Spec.Type = corev1.ServiceTypeLoadBalancer
@@ -166,7 +150,6 @@ func NewHeadlessForMinIO(t *miniov2.Tenant) *corev1.Service {
svc := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
- Labels: t.MinIOPodLabels(),
Name: t.MinIOHLServiceName(),
Namespace: t.Namespace,
OwnerReferences: t.OwnerRef(),
@@ -188,7 +171,6 @@ func NewHeadlessForKES(t *miniov2.Tenant) *corev1.Service {
kesPort := corev1.ServicePort{Port: miniov2.KESPort, Name: miniov2.KESServicePortName}
svc := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
- Labels: t.KESPodLabels(),
Name: t.KESHLServiceName(),
Namespace: t.Namespace,
OwnerReferences: t.OwnerRef(),
@@ -200,6 +182,9 @@ func NewHeadlessForKES(t *miniov2.Tenant) *corev1.Service {
ClusterIP: corev1.ClusterIPNone,
},
}
-
+ if t.Spec.ServiceMetadata != nil {
+ svc.Labels = t.Spec.ServiceMetadata.KESServiceLabels
+ svc.Annotations = t.Spec.ServiceMetadata.KESServiceAnnotations
+ }
return svc
}
diff --git a/pkg/resources/statefulsets/minio-statefulset.go b/pkg/resources/statefulsets/minio-statefulset.go
index 7124e351a9a..c9e416fe193 100644
--- a/pkg/resources/statefulsets/minio-statefulset.go
+++ b/pkg/resources/statefulsets/minio-statefulset.go
@@ -24,6 +24,7 @@ import (
miniov2 "github.com/minio/operator/pkg/apis/minio.min.io/v2"
"github.com/minio/operator/pkg/certs"
+ "github.com/minio/operator/pkg/utils"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -61,48 +62,23 @@ func minioEnvironmentVars(t *miniov2.Tenant, skipEnvVars map[string][]byte) []co
// If a user specifies metadata in the spec we return that metadata.
func PodMetadata(t *miniov2.Tenant, pool *miniov2.Pool) metav1.ObjectMeta {
meta := metav1.ObjectMeta{}
- // Copy Labels and Annotations from Tenant
- labels := t.ObjectMeta.Labels
- annotations := t.ObjectMeta.Annotations
-
- if annotations == nil {
- annotations = make(map[string]string)
- }
-
- annotations[miniov2.Revision] = fmt.Sprintf("%d", t.Status.Revision)
-
- if labels == nil {
- labels = make(map[string]string)
- }
- // Add the additional label used by StatefulSet spec selector
- for k, v := range t.MinIOPodLabels() {
- labels[k] = v
- }
- // Add information labels, such as which pool we are building this pod about
- labels[miniov2.PoolLabel] = pool.Name
- // Add the additional label used by Console spec selector
- for k, v := range t.ConsolePodLabels() {
- labels[k] = v
- }
-
- // Add user specific annotations
- if pool.Annotations != nil {
- annotations = miniov2.MergeMaps(annotations, pool.Annotations)
- }
-
- if pool.Labels != nil {
- labels = miniov2.MergeMaps(labels, pool.Labels)
+ if t.Spec.PoolsMetadata != nil {
+ meta.Labels = t.Spec.PoolsMetadata.Labels
+ meta.Annotations = t.Spec.PoolsMetadata.Annotations
}
+ meta.Labels = utils.MergeMaps(meta.Labels, pool.Labels, t.MinIOPodLabels(), t.ConsolePodLabels())
+ meta.Annotations = utils.MergeMaps(meta.Annotations, pool.Annotations)
- meta.Labels = labels
- meta.Annotations = annotations
+ // Set specific information
+ meta.Labels[miniov2.PoolLabel] = pool.Name
+ meta.Annotations[miniov2.Revision] = fmt.Sprintf("%d", t.Status.Revision)
return meta
}
// ContainerMatchLabels Returns the labels that match the Pods in the statefulset
func ContainerMatchLabels(t *miniov2.Tenant, pool *miniov2.Pool) *metav1.LabelSelector {
- labels := miniov2.MergeMaps(t.MinIOPodLabels(), t.ConsolePodLabels())
+ labels := utils.MergeMaps(t.MinIOPodLabels(), t.ConsolePodLabels())
// Add pool information so it's passed down to the underlying PVCs
labels[miniov2.PoolLabel] = pool.Name
return &metav1.LabelSelector{
@@ -628,26 +604,21 @@ func NewPool(args *NewPoolArgs) *appsv1.StatefulSet {
},
}
// Copy labels and annotations from the Tenant.Spec.Metadata
- ssMeta.Labels = t.ObjectMeta.Labels
- ssMeta.Annotations = t.ObjectMeta.Annotations
-
- if ssMeta.Labels == nil {
- ssMeta.Labels = make(map[string]string)
+ // unless `StatefulSetMetadata` is defined, then we'll copy it
+ // from there.
+ if t.Spec.PoolsMetadata != nil {
+ ssMeta.Labels = t.Spec.PoolsMetadata.Labels
+ ssMeta.Annotations = t.Spec.PoolsMetadata.Annotations
}
+ // Add pool specific annotations
+ ssMeta.Annotations = utils.MergeMaps(ssMeta.Annotations, pool.Annotations)
+ ssMeta.Labels = utils.MergeMaps(ssMeta.Labels, pool.Labels)
+
// Add information labels, such as which pool we are building this pod about
ssMeta.Labels[miniov2.PoolLabel] = pool.Name
ssMeta.Labels[miniov2.TenantLabel] = t.Name
- // Add user specific annotations
- if pool.Annotations != nil {
- ssMeta.Annotations = miniov2.MergeMaps(ssMeta.Annotations, pool.Annotations)
- }
-
- if pool.Labels != nil {
- ssMeta.Labels = miniov2.MergeMaps(ssMeta.Labels, pool.Labels)
- }
-
containers := []corev1.Container{
poolMinioServerContainer(t, skipEnvVars, pool, certVolumeSources),
getSideCarContainer(t, pool),
diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go
index f9e86bc64c1..b2e724bd19b 100644
--- a/pkg/utils/utils.go
+++ b/pkg/utils/utils.go
@@ -70,3 +70,14 @@ func CastObjectToMetaV1(obj interface{}) (metav1.Object, error) {
}
return object, nil
}
+
+// MergeMaps merges maps and returns the union
+func MergeMaps(maps ...map[string]string) map[string]string {
+ dest := map[string]string{}
+ for _, m := range maps {
+ for k, v := range m {
+ dest[k] = v
+ }
+ }
+ return dest
+}
diff --git a/resources/base/crds/minio.min.io_tenants.yaml b/resources/base/crds/minio.min.io_tenants.yaml
index d4a1f9fc5e4..e295126ce51 100644
--- a/resources/base/crds/minio.min.io_tenants.yaml
+++ b/resources/base/crds/minio.min.io_tenants.yaml
@@ -3638,6 +3638,17 @@ spec:
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
+ poolsMetadata:
+ properties:
+ annotations:
+ additionalProperties:
+ type: string
+ type: object
+ labels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
priorityClassName:
type: string
prometheusOperator:
@@ -3736,6 +3747,14 @@ spec:
additionalProperties:
type: string
type: object
+ kesServiceAnnotations:
+ additionalProperties:
+ type: string
+ type: object
+ kesServiceLabels:
+ additionalProperties:
+ type: string
+ type: object
minioServiceAnnotations:
additionalProperties:
type: string
diff --git a/testing/common.sh b/testing/common.sh
index 712e066fa8b..54e7ab61f98 100644
--- a/testing/common.sh
+++ b/testing/common.sh
@@ -798,6 +798,7 @@ function install_tenant() {
value=myminio
create_restricted_namespace $namespace
try helm install --namespace $namespace \
+ --set tenant.poolsMetadata.labels.app=minio \
tenant ./helm/tenant
elif [ "$1" = "logs" ]; then
namespace="tenant-lite"