@@ -32,7 +32,6 @@ import (
3232 "github.com/stackrox/rox/operator/apis/platform/v1alpha1"
3333 "github.com/stackrox/rox/pkg/declarativeconfig"
3434 "github.com/stackrox/rox/pkg/random"
35- "golang.org/x/exp/maps"
3635 "gopkg.in/yaml.v2"
3736 "helm.sh/helm/v3/pkg/chart"
3837 "helm.sh/helm/v3/pkg/chartutil"
@@ -61,10 +60,14 @@ const (
6160 envAnnotationKey = "rhacs.redhat.com/environment"
6261 clusterNameAnnotationKey = "rhacs.redhat.com/cluster-name"
6362 orgNameAnnotationKey = "rhacs.redhat.com/org-name"
64- instanceTypeLabelKey = "rhacs.redhat.com/instance-type"
65- orgIDLabelKey = "rhacs.redhat.com/org-id"
66- tenantIDLabelKey = "rhacs.redhat.com/tenant"
67- centralExpiredAtKey = "rhacs.redhat.com/expired-at"
63+
64+ labelManagedByFleetshardValue = "rhacs-fleetshard"
65+ instanceLabelKey = "app.kubernetes.io/instance"
66+ instanceTypeLabelKey = "rhacs.redhat.com/instance-type"
67+ managedByLabelKey = "app.kubernetes.io/managed-by"
68+ orgIDLabelKey = "rhacs.redhat.com/org-id"
69+ tenantIDLabelKey = "rhacs.redhat.com/tenant"
70+ centralExpiredAtKey = "rhacs.redhat.com/expired-at"
6871
6972 auditLogNotifierKey = "com.redhat.rhacs.auditLogNotifier"
7073 auditLogNotifierName = "Platform Audit Logs"
@@ -196,17 +199,7 @@ func (r *CentralReconciler) Reconcile(ctx context.Context, remoteCentral private
196199 return status , err
197200 }
198201
199- namespaceLabels := map [string ]string {
200- orgIDLabelKey : remoteCentral .Spec .Auth .OwnerOrgId ,
201- tenantIDLabelKey : remoteCentral .Id ,
202- }
203- namespaceAnnotations := map [string ]string {
204- orgNameAnnotationKey : remoteCentral .Spec .Auth .OwnerOrgName ,
205- }
206- if remoteCentral .Metadata .ExpiredAt != nil {
207- namespaceAnnotations [centralExpiredAtKey ] = remoteCentral .Metadata .ExpiredAt .Format (time .RFC3339 )
208- }
209- if err := r .reconcileNamespace (ctx , remoteCentralNamespace , namespaceLabels , namespaceAnnotations ); err != nil {
202+ if err := r .reconcileNamespace (ctx , remoteCentral ); err != nil {
210203 return nil , errors .Wrapf (err , "unable to ensure that namespace %s exists" , remoteCentralNamespace )
211204 }
212205
@@ -1133,17 +1126,11 @@ func (r *CentralReconciler) computeCentralHash(central private.ManagedCentral) (
11331126}
11341127
11351128func (r * CentralReconciler ) getNamespace (name string ) (* corev1.Namespace , error ) {
1136- namespace := & corev1.Namespace {
1137- ObjectMeta : metav1.ObjectMeta {
1138- Name : name ,
1139- },
1140- }
1141- err := r .client .Get (context .Background (), ctrlClient.ObjectKey {Name : name }, namespace )
1142- if err != nil {
1143- // Propagate corev1.Namespace to the caller so that the namespace can be easily created
1144- return namespace , fmt .Errorf ("retrieving resource for namespace %q from Kubernetes: %w" , name , err )
1129+ var namespace corev1.Namespace
1130+ if err := r .client .Get (context .Background (), ctrlClient.ObjectKey {Name : name }, & namespace ); err != nil {
1131+ return nil , fmt .Errorf ("getting namespace %q: %w" , name , err )
11451132 }
1146- return namespace , nil
1133+ return & namespace , nil
11471134}
11481135
11491136func (r * CentralReconciler ) getSecret (namespaceName string , secretName string ) (* corev1.Secret , error ) {
@@ -1178,36 +1165,54 @@ func (r *CentralReconciler) createImagePullSecret(ctx context.Context, namespace
11781165 return nil
11791166}
11801167
1181- func (r * CentralReconciler ) createTenantNamespace (ctx context.Context , namespace * corev1.Namespace ) error {
1182- err := r .client .Create (ctx , namespace )
1183- if err != nil {
1184- return fmt .Errorf ("creating namespace %q: %w" , namespace .ObjectMeta .Name , err )
1185- }
1186- return nil
1187- }
1168+ func (r * CentralReconciler ) reconcileNamespace (ctx context.Context , c private.ManagedCentral ) error {
1169+ desiredNamespace := getDesiredNamespace (c )
11881170
1189- func (r * CentralReconciler ) reconcileNamespace (ctx context.Context , name string , labels map [string ]string , annotations map [string ]string ) error {
1190- namespace , err := r .getNamespace (name )
1171+ existingNamespace , err := r .getNamespace (desiredNamespace .Name )
11911172 if err != nil {
11921173 if apiErrors .IsNotFound (err ) {
1193- namespace .Annotations = annotations
1194- namespace .Labels = labels
1195- return r .createTenantNamespace (ctx , namespace )
1196- }
1197- return fmt .Errorf ("getting namespace %s: %w" , name , err )
1198- } else if ! maps .Equal (labels , namespace .Labels ) ||
1199- ! maps .Equal (annotations , namespace .Annotations ) {
1200- namespace .Annotations = annotations
1201- namespace .Labels = labels
1202- if err = r .client .Update (ctx , namespace , & ctrlClient.UpdateOptions {
1174+ if err := r .client .Create (ctx , desiredNamespace ); err != nil {
1175+ return fmt .Errorf ("creating namespace %q: %w" , desiredNamespace .Name , err )
1176+ }
1177+ return nil
1178+ }
1179+ return fmt .Errorf ("getting namespace %q: %w" , desiredNamespace .Name , err )
1180+ }
1181+
1182+ if stringMapNeedsUpdating (desiredNamespace .Annotations , existingNamespace .Annotations ) || stringMapNeedsUpdating (desiredNamespace .Labels , existingNamespace .Labels ) {
1183+ glog .Infof ("Updating namespace %q" , desiredNamespace .Name )
1184+ if existingNamespace .Annotations == nil {
1185+ existingNamespace .Annotations = map [string ]string {}
1186+ }
1187+ for k , v := range desiredNamespace .Annotations {
1188+ existingNamespace .Annotations [k ] = v
1189+ }
1190+ if existingNamespace .Labels == nil {
1191+ existingNamespace .Labels = map [string ]string {}
1192+ }
1193+ for k , v := range desiredNamespace .Labels {
1194+ existingNamespace .Labels [k ] = v
1195+ }
1196+ if err = r .client .Update (ctx , existingNamespace , & ctrlClient.UpdateOptions {
12031197 FieldManager : "fleetshard-sync" ,
12041198 }); err != nil {
1205- return fmt .Errorf ("updating namespace %s : %w" , name , err )
1199+ return fmt .Errorf ("updating namespace %q : %w" , desiredNamespace . Name , err )
12061200 }
12071201 }
1202+
12081203 return nil
12091204}
12101205
1206+ func getDesiredNamespace (c private.ManagedCentral ) * corev1.Namespace {
1207+ return & corev1.Namespace {
1208+ ObjectMeta : metav1.ObjectMeta {
1209+ Name : c .Metadata .Namespace ,
1210+ Annotations : getNamespaceAnnotations (c ),
1211+ Labels : getNamespaceLabels (c ),
1212+ },
1213+ }
1214+ }
1215+
12111216func (r * CentralReconciler ) ensureImagePullSecretConfigured (ctx context.Context , namespaceName string , secretName string , imagePullSecret []byte ) error {
12121217 // Ensure that the secret exists.
12131218 _ , err := r .getSecret (namespaceName , secretName )
@@ -1682,15 +1687,42 @@ func (r *CentralReconciler) ensureRouteDeleted(ctx context.Context, routeSupplie
16821687 return false , nil
16831688}
16841689
1685- func (r * CentralReconciler ) chartValues (_ private.ManagedCentral ) (chartutil.Values , error ) {
1690+ func getTenantLabels (c private.ManagedCentral ) map [string ]string {
1691+ return map [string ]string {
1692+ managedByLabelKey : labelManagedByFleetshardValue ,
1693+ instanceLabelKey : c .Metadata .Name ,
1694+ orgIDLabelKey : c .Spec .Auth .OwnerOrgId ,
1695+ tenantIDLabelKey : c .Id ,
1696+ instanceTypeLabelKey : c .Spec .InstanceType ,
1697+ }
1698+ }
1699+
1700+ func getTenantAnnotations (c private.ManagedCentral ) map [string ]string {
1701+ return map [string ]string {
1702+ orgNameAnnotationKey : c .Spec .Auth .OwnerOrgName ,
1703+ }
1704+ }
1705+
1706+ func getNamespaceLabels (c private.ManagedCentral ) map [string ]string {
1707+ return getTenantLabels (c )
1708+ }
1709+
1710+ func getNamespaceAnnotations (c private.ManagedCentral ) map [string ]string {
1711+ namespaceAnnotations := getTenantAnnotations (c )
1712+ if c .Metadata .ExpiredAt != nil {
1713+ namespaceAnnotations [centralExpiredAtKey ] = c .Metadata .ExpiredAt .Format (time .RFC3339 )
1714+ }
1715+ return namespaceAnnotations
1716+ }
1717+
1718+ func (r * CentralReconciler ) chartValues (c private.ManagedCentral ) (chartutil.Values , error ) {
16861719 if r .resourcesChart == nil {
16871720 return nil , errors .New ("resources chart is not set" )
16881721 }
16891722 src := r .resourcesChart .Values
16901723 dst := map [string ]interface {}{
1691- "labels" : map [string ]interface {}{
1692- k8s .ManagedByLabelKey : k8s .ManagedByFleetshardValue ,
1693- },
1724+ "labels" : stringMapToMapInterface (getTenantLabels (c )),
1725+ "annotations" : stringMapToMapInterface (getTenantAnnotations (c )),
16941726 }
16951727 if r .egressProxyImage != "" {
16961728 dst ["egressProxy" ] = map [string ]interface {}{
@@ -1700,6 +1732,14 @@ func (r *CentralReconciler) chartValues(_ private.ManagedCentral) (chartutil.Val
17001732 return chartutil .CoalesceTables (dst , src ), nil
17011733}
17021734
1735+ func stringMapToMapInterface (m map [string ]string ) map [string ]interface {} {
1736+ result := make (map [string ]interface {}, len (m ))
1737+ for k , v := range m {
1738+ result [k ] = v
1739+ }
1740+ return result
1741+ }
1742+
17031743func (r * CentralReconciler ) shouldSkipReadyCentral (remoteCentral private.ManagedCentral ) bool {
17041744 return r .wantsAuthProvider == r .hasAuthProvider &&
17051745 isRemoteCentralReady (& remoteCentral )
0 commit comments