diff --git a/api/v1/installation_types.go b/api/v1/installation_types.go index 16060f8b5a..4984f80e80 100644 --- a/api/v1/installation_types.go +++ b/api/v1/installation_types.go @@ -197,8 +197,30 @@ type InstallationSpec struct { // Kubernetes Service CIDRs. Specifying this is required when using Calico for Windows. // +optional ServiceCIDRs []string `json:"serviceCIDRs,omitempty"` + + // Azure is used to configure azure provider specific options. + // +optional + Azure *Azure `json:"azure,omitempty"` +} + +type Azure struct { + // PolicyMode determines whether the "control-plane" label is applied to namespaces. It offers two options: Default and Manual. + // The Default option adds the "control-plane" label to the required namespaces. + // The Manual option does not apply the "control-plane" label to any namespace. + // Default: Default + // +optional + // +kubebuilder:validation:Enum=Default;Manual + // +kubebuilder:default:=Default + PolicyMode *PolicyMode `json:"policyMode,omitempty"` } +type PolicyMode string + +const ( + Default PolicyMode = "Default" + Manual PolicyMode = "Manual" +) + type Logging struct { // Customized logging specification for calico-cni plugin // +optional diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index 77b6144ca4..e497446974 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -747,6 +747,26 @@ func (in *AuthenticationStatus) DeepCopy() *AuthenticationStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Azure) DeepCopyInto(out *Azure) { + *out = *in + if in.PolicyMode != nil { + in, out := &in.PolicyMode, &out.PolicyMode + *out = new(PolicyMode) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Azure. +func (in *Azure) DeepCopy() *Azure { + if in == nil { + return nil + } + out := new(Azure) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CNILogging) DeepCopyInto(out *CNILogging) { *out = *in @@ -4276,6 +4296,11 @@ func (in *InstallationSpec) DeepCopyInto(out *InstallationSpec) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.Azure != nil { + in, out := &in.Azure, &out.Azure + *out = new(Azure) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstallationSpec. diff --git a/pkg/controller/compliance/compliance_controller.go b/pkg/controller/compliance/compliance_controller.go index f901aedff0..61297b3c0d 100644 --- a/pkg/controller/compliance/compliance_controller.go +++ b/pkg/controller/compliance/compliance_controller.go @@ -444,7 +444,7 @@ func (r *ReconcileCompliance) Reconcile(ctx context.Context, request reconcile.R reqLogger.V(3).Info("rendering components") - namespaceComp := render.NewPassthrough(render.CreateNamespace(helper.InstallNamespace(), network.KubernetesProvider, render.PSSPrivileged)) + namespaceComp := render.NewPassthrough(render.CreateNamespace(helper.InstallNamespace(), network.KubernetesProvider, render.PSSPrivileged, network.Azure)) hasNoLicense := !utils.IsFeatureActive(license, common.ComplianceFeature) openshift := r.provider.IsOpenShift() diff --git a/pkg/controller/installation/core_controller.go b/pkg/controller/installation/core_controller.go index 0f6f35843e..adeab65dfd 100644 --- a/pkg/controller/installation/core_controller.go +++ b/pkg/controller/installation/core_controller.go @@ -721,6 +721,11 @@ func fillDefaults(instance *operator.Installation, currentPools *crdv1.IPPoolLis instance.Spec.NodeUpdateStrategy.Type = appsv1.RollingUpdateDaemonSetStrategyType } + if instance.Spec.KubernetesProvider == operator.ProviderAKS && instance.Spec.Azure == nil { + defaultPolicyMode := operator.Default + instance.Spec.Azure = &operator.Azure{PolicyMode: &defaultPolicyMode} + } + return nil } diff --git a/pkg/controller/installation/core_controller_test.go b/pkg/controller/installation/core_controller_test.go index e7b507e629..22c0254000 100644 --- a/pkg/controller/installation/core_controller_test.go +++ b/pkg/controller/installation/core_controller_test.go @@ -1557,6 +1557,41 @@ var _ = Describe("Testing core-controller installation", func() { Expect(c.List(ctx, &policies)).ToNot(HaveOccurred()) Expect(policies.Items).To(HaveLen(0)) }) + + It("should set default spec.Azure if provider is AKS", func() { + cr.Spec.KubernetesProvider = operator.ProviderAKS + + Expect(c.Create(ctx, cr)).NotTo(HaveOccurred()) + _, err := r.Reconcile(ctx, reconcile.Request{}) + Expect(err).ShouldNot(HaveOccurred()) + + policyMode := operator.Default + azure := &operator.Azure{ + PolicyMode: &policyMode, + } + instance := &operator.Installation{} + + err = c.Get(ctx, types.NamespacedName{Name: "default"}, instance) + Expect(err).ShouldNot(HaveOccurred()) + + Expect(instance.Spec.Azure).NotTo(BeNil()) + Expect(instance.Spec.Azure).To(Equal(azure)) + }) + + It("should not set default spec.Azure if provider is not AKS", func() { + cr.Spec.KubernetesProvider = operator.ProviderEKS + + Expect(c.Create(ctx, cr)).NotTo(HaveOccurred()) + _, err := r.Reconcile(ctx, reconcile.Request{}) + Expect(err).ShouldNot(HaveOccurred()) + + instance := &operator.Installation{} + + err = c.Get(ctx, types.NamespacedName{Name: "default"}, instance) + Expect(err).ShouldNot(HaveOccurred()) + + Expect(instance.Spec.Azure).To(BeNil()) + }) }) Context("Using EKS networking", func() { diff --git a/pkg/controller/installation/validation.go b/pkg/controller/installation/validation.go index a5063f0b43..3b76653893 100644 --- a/pkg/controller/installation/validation.go +++ b/pkg/controller/installation/validation.go @@ -411,6 +411,10 @@ func validateCustomResource(instance *operatorv1.Installation) error { } } + if instance.Spec.KubernetesProvider != operatorv1.ProviderAKS && instance.Spec.Azure != nil { + return fmt.Errorf("Installation spec.Azure should be set only for AKS provider") + } + return nil } diff --git a/pkg/controller/installation/validation_test.go b/pkg/controller/installation/validation_test.go index 50255dd63d..e0a9608e49 100644 --- a/pkg/controller/installation/validation_test.go +++ b/pkg/controller/installation/validation_test.go @@ -407,6 +407,20 @@ var _ = Describe("Installation validation tests", func() { Expect(err).To(HaveOccurred()) }) + It("should allow Spec.Azure to be set for AKS provider", func() { + instance.Spec.KubernetesProvider = operator.ProviderAKS + instance.Spec.Azure = &operator.Azure{} + err := validateCustomResource(instance) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should not allow Spec.Azure to be set for non AKS provider", func() { + instance.Spec.KubernetesProvider = operator.ProviderGKE + instance.Spec.Azure = &operator.Azure{} + err := validateCustomResource(instance) + Expect(err).To(HaveOccurred()) + }) + Describe("validate Calico CNI plugin Type", func() { DescribeTable("test invalid IPAM", func(ipam operator.IPAMPluginType) { diff --git a/pkg/controller/intrusiondetection/intrusiondetection_controller.go b/pkg/controller/intrusiondetection/intrusiondetection_controller.go index 396cf66515..12fa0dea48 100644 --- a/pkg/controller/intrusiondetection/intrusiondetection_controller.go +++ b/pkg/controller/intrusiondetection/intrusiondetection_controller.go @@ -479,6 +479,7 @@ func (r *ReconcileIntrusionDetection) Reconcile(ctx context.Context, request rec Tenant: tenant, HasNoLicense: hasNoLicense, SyslogForwardingIsEnabled: syslogForwardingIsEnabled(lc), + Azure: network.Azure, }) intrusionDetectionComponent := render.IntrusionDetection(intrusionDetectionCfg) diff --git a/pkg/controller/logstorage/initializer/initializing_controller.go b/pkg/controller/logstorage/initializer/initializing_controller.go index 4b87126659..fa2bc3a860 100644 --- a/pkg/controller/logstorage/initializer/initializing_controller.go +++ b/pkg/controller/logstorage/initializer/initializing_controller.go @@ -243,14 +243,14 @@ func (r *LogStorageInitializer) Reconcile(ctx context.Context, request reconcile // Before we can create secrets, we need to ensure the tigera-elasticsearch namespace exists. hdler := utils.NewComponentHandler(reqLogger, r.client, r.scheme, ls) - esNamespace := render.CreateNamespace(render.ElasticsearchNamespace, install.KubernetesProvider, render.PSSPrivileged) + esNamespace := render.CreateNamespace(render.ElasticsearchNamespace, install.KubernetesProvider, render.PSSPrivileged, install.Azure) if err = hdler.CreateOrUpdateOrDelete(ctx, render.NewPassthrough(esNamespace), r.status); err != nil { r.status.SetDegraded(operatorv1.ResourceUpdateError, "Error creating / updating resource", err, reqLogger) return reconcile.Result{}, err } if kibanaEnabled { // Create the Namespace. - kbNamespace := render.CreateNamespace(kibana.Namespace, install.KubernetesProvider, render.PSSBaseline) + kbNamespace := render.CreateNamespace(kibana.Namespace, install.KubernetesProvider, render.PSSBaseline, install.Azure) if err = hdler.CreateOrUpdateOrDelete(ctx, render.NewPassthrough(kbNamespace), r.status); err != nil { r.status.SetDegraded(operatorv1.ResourceUpdateError, "Error creating / updating resource", err, reqLogger) return reconcile.Result{}, err diff --git a/pkg/controller/utils/merge.go b/pkg/controller/utils/merge.go index ad4bb78253..6903a68acf 100644 --- a/pkg/controller/utils/merge.go +++ b/pkg/controller/utils/merge.go @@ -209,6 +209,11 @@ func OverrideInstallationSpec(cfg, override operatorv1.InstallationSpec) operato inst.ServiceCIDRs = override.ServiceCIDRs } + switch compareFields(inst.Azure, override.Azure) { + case BOnlySet, Different: + inst.Azure = override.Azure + } + return inst } diff --git a/pkg/crds/operator/operator.tigera.io_installations.yaml b/pkg/crds/operator/operator.tigera.io_installations.yaml index bb9cd9a974..c6e432840b 100644 --- a/pkg/crds/operator/operator.tigera.io_installations.yaml +++ b/pkg/crds/operator/operator.tigera.io_installations.yaml @@ -42,6 +42,21 @@ spec: description: Specification of the desired state for the Calico or Calico Enterprise installation. properties: + azure: + description: Azure is used to configure azure provider specific options. + properties: + policyMode: + default: Default + description: |- + PolicyMode determines whether the "control-plane" label is applied to namespaces. It offers two options: Default and Manual. + The Default option adds the "control-plane" label to the required namespaces. + The Manual option does not apply the "control-plane" label to any namespace. + Default: Default + enum: + - Default + - Manual + type: string + type: object calicoKubeControllersDeployment: description: |- CalicoKubeControllersDeployment configures the calico-kube-controllers Deployment. If used in @@ -7411,6 +7426,22 @@ spec: description: Computed is the final installation including overlaid resources. properties: + azure: + description: Azure is used to configure azure provider specific + options. + properties: + policyMode: + default: Default + description: |- + PolicyMode determines whether the "control-plane" label is applied to namespaces. It offers two options: Default and Manual. + The Default option adds the "control-plane" label to the required namespaces. + The Manual option does not apply the "control-plane" label to any namespace. + Default: Default + enum: + - Default + - Manual + type: string + type: object calicoKubeControllersDeployment: description: |- CalicoKubeControllersDeployment configures the calico-kube-controllers Deployment. If used in diff --git a/pkg/render/apiserver.go b/pkg/render/apiserver.go index facec9195a..c2c9042ce6 100644 --- a/pkg/render/apiserver.go +++ b/pkg/render/apiserver.go @@ -245,7 +245,7 @@ func (c *apiServerComponent) Objects() ([]client.Object, []client.Object) { // Global enterprise-only objects. globalEnterpriseObjects := []client.Object{ - CreateNamespace(rmeta.APIServerNamespace(operatorv1.TigeraSecureEnterprise), c.cfg.Installation.KubernetesProvider, PSSPrivileged), + CreateNamespace(rmeta.APIServerNamespace(operatorv1.TigeraSecureEnterprise), c.cfg.Installation.KubernetesProvider, PSSPrivileged, c.cfg.Installation.Azure), c.tigeraApiServerClusterRole(), c.tigeraApiServerClusterRoleBinding(), c.uisettingsgroupGetterClusterRole(), @@ -303,7 +303,7 @@ func (c *apiServerComponent) Objects() ([]client.Object, []client.Object) { } // Global OSS-only objects. globalCalicoObjects := []client.Object{ - CreateNamespace(rmeta.APIServerNamespace(operatorv1.Calico), c.cfg.Installation.KubernetesProvider, podSecurityNamespaceLabel), + CreateNamespace(rmeta.APIServerNamespace(operatorv1.Calico), c.cfg.Installation.KubernetesProvider, podSecurityNamespaceLabel, c.cfg.Installation.Azure), } // Compile the final arrays based on the variant. diff --git a/pkg/render/dex.go b/pkg/render/dex.go index a164c6aa6a..915f8b356b 100644 --- a/pkg/render/dex.go +++ b/pkg/render/dex.go @@ -114,7 +114,7 @@ func (*dexComponent) SupportedOSType() rmeta.OSType { func (c *dexComponent) Objects() ([]client.Object, []client.Object) { objs := []client.Object{ - CreateNamespace(DexObjectName, c.cfg.Installation.KubernetesProvider, PSSRestricted), + CreateNamespace(DexObjectName, c.cfg.Installation.KubernetesProvider, PSSRestricted, c.cfg.Installation.Azure), c.allowTigeraNetworkPolicy(c.cfg.Installation.Variant), networkpolicy.AllowTigeraDefaultDeny(DexNamespace), c.serviceAccount(), diff --git a/pkg/render/fluentd.go b/pkg/render/fluentd.go index 6ff90b5857..3bbac132b5 100644 --- a/pkg/render/fluentd.go +++ b/pkg/render/fluentd.go @@ -269,7 +269,7 @@ func (c *fluentdComponent) path(path string) string { func (c *fluentdComponent) Objects() ([]client.Object, []client.Object) { var objs, toDelete []client.Object - objs = append(objs, CreateNamespace(LogCollectorNamespace, c.cfg.Installation.KubernetesProvider, PSSPrivileged)) + objs = append(objs, CreateNamespace(LogCollectorNamespace, c.cfg.Installation.KubernetesProvider, PSSPrivileged, c.cfg.Installation.Azure)) objs = append(objs, c.allowTigeraPolicy()) objs = append(objs, secret.ToRuntimeObjects(secret.CopyToNamespace(LogCollectorNamespace, c.cfg.PullSecrets...)...)...) objs = append(objs, c.metricsService()) diff --git a/pkg/render/guardian.go b/pkg/render/guardian.go index ca3094a39c..69a7e8263e 100644 --- a/pkg/render/guardian.go +++ b/pkg/render/guardian.go @@ -120,7 +120,7 @@ func (c *GuardianComponent) SupportedOSType() rmeta.OSType { func (c *GuardianComponent) Objects() ([]client.Object, []client.Object) { objs := []client.Object{ - CreateNamespace(GuardianNamespace, c.cfg.Installation.KubernetesProvider, PSSRestricted), + CreateNamespace(GuardianNamespace, c.cfg.Installation.KubernetesProvider, PSSRestricted, c.cfg.Installation.Azure), } objs = append(objs, secret.ToRuntimeObjects(secret.CopyToNamespace(GuardianNamespace, c.cfg.PullSecrets...)...)...) @@ -135,7 +135,7 @@ func (c *GuardianComponent) Objects() ([]client.Object, []client.Object) { // Add tigera-manager service account for impersonation. In managed clusters, the tigera-manager // service account is always within the tigera-manager namespace - regardless of (multi)tenancy mode. - CreateNamespace(ManagerNamespace, c.cfg.Installation.KubernetesProvider, PSSRestricted), + CreateNamespace(ManagerNamespace, c.cfg.Installation.KubernetesProvider, PSSRestricted, c.cfg.Installation.Azure), managerServiceAccount(ManagerNamespace), managerClusterRole(true, c.cfg.Installation.KubernetesProvider, nil), managerClusterRoleBinding([]string{ManagerNamespace}), diff --git a/pkg/render/intrusion_detection.go b/pkg/render/intrusion_detection.go index 0cde4d7dfb..6a99c03e80 100644 --- a/pkg/render/intrusion_detection.go +++ b/pkg/render/intrusion_detection.go @@ -1303,6 +1303,7 @@ type IntrusionDetectionNamespaceConfiguration struct { Namespace string KubernetesProvider operatorv1.Provider HasNoLicense bool + Azure *operatorv1.Azure } func (c *intrusionDetectionNamespaceComponent) ResolveImages(is *operatorv1.ImageSet) error { @@ -1324,7 +1325,7 @@ func (c *intrusionDetectionNamespaceComponent) Objects() ([]client.Object, []cli objs := []client.Object{} if !c.cfg.Tenant.MultiTenant() { // In multi-tenant environments, the namespace is pre-created. So, only create it if we're not in a multi-tenant environment. - objs = append(objs, CreateNamespace(c.cfg.Namespace, c.cfg.KubernetesProvider, PodSecurityStandard(pss))) + objs = append(objs, CreateNamespace(c.cfg.Namespace, c.cfg.KubernetesProvider, PodSecurityStandard(pss), c.cfg.Azure)) } if c.cfg.HasNoLicense { diff --git a/pkg/render/intrusiondetection/dpi/dpi.go b/pkg/render/intrusiondetection/dpi/dpi.go index a7dd727e41..18be3f9322 100644 --- a/pkg/render/intrusiondetection/dpi/dpi.go +++ b/pkg/render/intrusiondetection/dpi/dpi.go @@ -105,9 +105,9 @@ func (d *dpiComponent) Objects() (objsToCreate, objsToDelete []client.Object) { } if d.cfg.HasNoLicense { - toDelete = append(toDelete, render.CreateNamespace(DeepPacketInspectionNamespace, d.cfg.Installation.KubernetesProvider, render.PSSPrivileged)) + toDelete = append(toDelete, render.CreateNamespace(DeepPacketInspectionNamespace, d.cfg.Installation.KubernetesProvider, render.PSSPrivileged, d.cfg.Installation.Azure)) } else { - toCreate = append(toCreate, render.CreateNamespace(DeepPacketInspectionNamespace, d.cfg.Installation.KubernetesProvider, render.PSSPrivileged)) + toCreate = append(toCreate, render.CreateNamespace(DeepPacketInspectionNamespace, d.cfg.Installation.KubernetesProvider, render.PSSPrivileged, d.cfg.Installation.Azure)) } // This secret is deprecated in this namespace and should be removed in upgrade scenarios diff --git a/pkg/render/logstorage.go b/pkg/render/logstorage.go index aa003b999e..c7fbf47c64 100644 --- a/pkg/render/logstorage.go +++ b/pkg/render/logstorage.go @@ -234,7 +234,7 @@ func (es *elasticsearchComponent) Objects() ([]client.Object, []client.Object) { } // Elasticsearch CRs - toCreate = append(toCreate, CreateNamespace(ElasticsearchNamespace, es.cfg.Installation.KubernetesProvider, PSSPrivileged)) + toCreate = append(toCreate, CreateNamespace(ElasticsearchNamespace, es.cfg.Installation.KubernetesProvider, PSSPrivileged, es.cfg.Installation.Azure)) toCreate = append(toCreate, es.elasticsearchAllowTigeraPolicy()) toCreate = append(toCreate, es.elasticsearchInternalAllowTigeraPolicy()) toCreate = append(toCreate, networkpolicy.AllowTigeraDefaultDeny(ElasticsearchNamespace)) @@ -1184,7 +1184,7 @@ func (m *managedClusterLogStorage) Objects() (objsToCreate []client.Object, objs toCreate := []client.Object{} roles, bindings, clusterRB := m.linseedExternalRolesAndBindings() toCreate = append(toCreate, - CreateNamespace(ElasticsearchNamespace, m.cfg.Installation.KubernetesProvider, PSSPrivileged), + CreateNamespace(ElasticsearchNamespace, m.cfg.Installation.KubernetesProvider, PSSPrivileged, m.cfg.Installation.Azure), m.elasticsearchExternalService(), m.linseedExternalService(), ) diff --git a/pkg/render/logstorage/eck/eck.go b/pkg/render/logstorage/eck/eck.go index 29b7d829eb..9c67e3f607 100644 --- a/pkg/render/logstorage/eck/eck.go +++ b/pkg/render/logstorage/eck/eck.go @@ -95,7 +95,7 @@ func (e *eck) Objects() ([]client.Object, []client.Object) { var toCreate, toDelete []client.Object toCreate = append(toCreate, - render.CreateNamespace(OperatorNamespace, e.cfg.Installation.KubernetesProvider, render.PSSRestricted), + render.CreateNamespace(OperatorNamespace, e.cfg.Installation.KubernetesProvider, render.PSSRestricted, e.cfg.Installation.Azure), e.operatorAllowTigeraPolicy(), ) diff --git a/pkg/render/logstorage/externalelasticsearch/externalelasticsearch.go b/pkg/render/logstorage/externalelasticsearch/externalelasticsearch.go index 02b855e452..0e5f42a912 100644 --- a/pkg/render/logstorage/externalelasticsearch/externalelasticsearch.go +++ b/pkg/render/logstorage/externalelasticsearch/externalelasticsearch.go @@ -48,7 +48,7 @@ func (e externalElasticsearch) ResolveImages(is *operatorv1.ImageSet) error { } func (e externalElasticsearch) Objects() (toCreate, toDelete []client.Object) { - toCreate = append(toCreate, render.CreateNamespace(render.ElasticsearchNamespace, e.installation.KubernetesProvider, render.PSSBaseline)) + toCreate = append(toCreate, render.CreateNamespace(render.ElasticsearchNamespace, e.installation.KubernetesProvider, render.PSSBaseline, e.installation.Azure)) toCreate = append(toCreate, e.clusterConfig.ConfigMap()) toCreate = append(toCreate, e.oidcUserRole()) toCreate = append(toCreate, e.oidcUserRoleBinding()) diff --git a/pkg/render/logstorage/kibana/kibana.go b/pkg/render/logstorage/kibana/kibana.go index 7eb306f8db..bf64b9cd6d 100644 --- a/pkg/render/logstorage/kibana/kibana.go +++ b/pkg/render/logstorage/kibana/kibana.go @@ -156,7 +156,7 @@ func (k *kibana) Objects() ([]client.Object, []client.Object) { // - securityContext.capabilities.drop=["ALL"] // - securityContext.runAsNonRoot=true // - securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost" - toCreate = append(toCreate, render.CreateNamespace(Namespace, k.cfg.Installation.KubernetesProvider, render.PSSBaseline)) + toCreate = append(toCreate, render.CreateNamespace(Namespace, k.cfg.Installation.KubernetesProvider, render.PSSBaseline, k.cfg.Installation.Azure)) toCreate = append(toCreate, k.allowTigeraPolicy()) toCreate = append(toCreate, networkpolicy.AllowTigeraDefaultDeny(Namespace)) toCreate = append(toCreate, k.serviceAccount()) diff --git a/pkg/render/manager.go b/pkg/render/manager.go index 21c4682214..c316fc2804 100644 --- a/pkg/render/manager.go +++ b/pkg/render/manager.go @@ -214,7 +214,7 @@ func (c *managerComponent) Objects() ([]client.Object, []client.Object) { if !c.cfg.Tenant.MultiTenant() { // In multi-tenant environments, the namespace is pre-created. So, only create it if we're not in a multi-tenant environment. - objs = append(objs, CreateNamespace(c.cfg.Namespace, c.cfg.Installation.KubernetesProvider, PSSRestricted)) + objs = append(objs, CreateNamespace(c.cfg.Namespace, c.cfg.Installation.KubernetesProvider, PSSRestricted, c.cfg.Installation.Azure)) // For multi-tenant environments, the management cluster itself isn't shown in the UI so we only need to create these // when there is no tenant. diff --git a/pkg/render/monitor/monitor.go b/pkg/render/monitor/monitor.go index bd3d8ea5ed..9c0ea19efc 100644 --- a/pkg/render/monitor/monitor.go +++ b/pkg/render/monitor/monitor.go @@ -181,7 +181,7 @@ func (mc *monitorComponent) Objects() ([]client.Object, []client.Object) { // - securityContext.capabilities.drop=["ALL"] // - securityContext.runAsNonRoot=true // - securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost" - render.CreateNamespace(common.TigeraPrometheusNamespace, mc.cfg.Installation.KubernetesProvider, render.PSSBaseline), + render.CreateNamespace(common.TigeraPrometheusNamespace, mc.cfg.Installation.KubernetesProvider, render.PSSBaseline, mc.cfg.Installation.Azure), } // Create role and role bindings first. diff --git a/pkg/render/namespaces.go b/pkg/render/namespaces.go index 87bac86629..e46fe0b580 100644 --- a/pkg/render/namespaces.go +++ b/pkg/render/namespaces.go @@ -53,7 +53,7 @@ func (c *namespaceComponent) SupportedOSType() rmeta.OSType { func (c *namespaceComponent) Objects() ([]client.Object, []client.Object) { ns := []client.Object{ - CreateNamespace(common.CalicoNamespace, c.cfg.Installation.KubernetesProvider, PSSPrivileged), + CreateNamespace(common.CalicoNamespace, c.cfg.Installation.KubernetesProvider, PSSPrivileged, c.cfg.Installation.Azure), } // If we're terminating, we don't want to delete the namespace right away. @@ -85,7 +85,7 @@ const ( PSSRestricted = "restricted" ) -func CreateNamespace(name string, provider operatorv1.Provider, pss PodSecurityStandard) *corev1.Namespace { +func CreateNamespace(name string, provider operatorv1.Provider, pss PodSecurityStandard, azure *operatorv1.Azure) *corev1.Namespace { ns := &corev1.Namespace{ TypeMeta: metav1.TypeMeta{Kind: "Namespace", APIVersion: "v1"}, ObjectMeta: metav1.ObjectMeta{ @@ -108,7 +108,16 @@ func CreateNamespace(name string, provider operatorv1.Provider, pss PodSecurityS ns.Annotations["security.openshift.io/scc.podSecurityLabelSync"] = "false" ns.Labels["openshift.io/run-level"] = "0" case operatorv1.ProviderAKS: - ns.Labels["control-plane"] = "true" + if applyAzurePolicy(azure, pss) { + ns.Labels["control-plane"] = "true" + } } return ns } + +func applyAzurePolicy(azure *operatorv1.Azure, pss PodSecurityStandard) bool { + if azure == nil || azure.PolicyMode == nil || *azure.PolicyMode == operatorv1.Default { + return PSSPrivileged == pss + } + return false +} diff --git a/pkg/render/namespaces_test.go b/pkg/render/namespaces_test.go index d6fec94887..08692962ed 100644 --- a/pkg/render/namespaces_test.go +++ b/pkg/render/namespaces_test.go @@ -58,7 +58,7 @@ var _ = Describe("Namespace rendering tests", func() { Expect(meta.GetAnnotations()["security.openshift.io/scc.podSecurityLabelSync"]).To(Equal("false")) }) - It("should render a namespace for aks", func() { + It("should render a namespace for aks with control-plane label when Azure is nil and PodSecurityStandard is privileged", func() { cfg.Installation.KubernetesProvider = operatorv1.ProviderAKS component := render.Namespaces(cfg) resources, _ := component.Objects() @@ -68,4 +68,46 @@ var _ = Describe("Namespace rendering tests", func() { Expect(meta.GetLabels()).NotTo(ContainElement("openshift.io/run-level")) Expect(meta.GetLabels()["control-plane"]).To(Equal("true")) }) + + It("should render a namespace for aks with control-plane label when Azure.PolicyMode is nil and PodSecurityStandard is privileged", func() { + cfg.Installation.KubernetesProvider = operatorv1.ProviderAKS + cfg.Installation.Azure = &operatorv1.Azure{} + component := render.Namespaces(cfg) + resources, _ := component.Objects() + Expect(len(resources)).To(Equal(1)) + rtest.ExpectResourceTypeAndObjectMetadata(resources[0], "calico-system", "", "", "v1", "Namespace") + meta := resources[0].(metav1.ObjectMetaAccessor).GetObjectMeta() + Expect(meta.GetLabels()).NotTo(ContainElement("openshift.io/run-level")) + Expect(meta.GetLabels()["control-plane"]).To(Equal("true")) + }) + + It("should render a namespace for aks with control-plane label when Azure.PolicyMode is Default and PodSecurityStandard is privileged", func() { + cfg.Installation.KubernetesProvider = operatorv1.ProviderAKS + policyMode := operatorv1.Default + cfg.Installation.Azure = &operatorv1.Azure{ + PolicyMode: &policyMode, + } + component := render.Namespaces(cfg) + resources, _ := component.Objects() + Expect(len(resources)).To(Equal(1)) + rtest.ExpectResourceTypeAndObjectMetadata(resources[0], "calico-system", "", "", "v1", "Namespace") + meta := resources[0].(metav1.ObjectMetaAccessor).GetObjectMeta() + Expect(meta.GetLabels()).NotTo(ContainElement("openshift.io/run-level")) + Expect(meta.GetLabels()["control-plane"]).To(Equal("true")) + }) + + It("should render a namespace for aks without control-plane label when Azure.PolicyMode is Manual", func() { + cfg.Installation.KubernetesProvider = operatorv1.ProviderAKS + policyMode := operatorv1.Manual + cfg.Installation.Azure = &operatorv1.Azure{ + PolicyMode: &policyMode, + } + component := render.Namespaces(cfg) + resources, _ := component.Objects() + Expect(len(resources)).To(Equal(1)) + rtest.ExpectResourceTypeAndObjectMetadata(resources[0], "calico-system", "", "", "v1", "Namespace") + meta := resources[0].(metav1.ObjectMetaAccessor).GetObjectMeta() + Expect(meta.GetLabels()).NotTo(ContainElement("openshift.io/run-level")) + Expect(meta.GetLabels()).NotTo(ContainElement("control-plane")) + }) }) diff --git a/pkg/render/packet_capture_api.go b/pkg/render/packet_capture_api.go index addec7dfcb..08cfda7f7c 100644 --- a/pkg/render/packet_capture_api.go +++ b/pkg/render/packet_capture_api.go @@ -105,7 +105,7 @@ func (pc *packetCaptureApiComponent) SupportedOSType() rmeta.OSType { func (pc *packetCaptureApiComponent) Objects() ([]client.Object, []client.Object) { objs := []client.Object{ - CreateNamespace(PacketCaptureNamespace, pc.cfg.Installation.KubernetesProvider, PSSRestricted), + CreateNamespace(PacketCaptureNamespace, pc.cfg.Installation.KubernetesProvider, PSSRestricted, pc.cfg.Installation.Azure), } objs = append(objs, secret.ToRuntimeObjects(secret.CopyToNamespace(PacketCaptureNamespace, pc.cfg.PullSecrets...)...)...) diff --git a/pkg/render/policyrecommendation.go b/pkg/render/policyrecommendation.go index cbdf2609e0..9b710c6698 100644 --- a/pkg/render/policyrecommendation.go +++ b/pkg/render/policyrecommendation.go @@ -111,7 +111,7 @@ func (pr *policyRecommendationComponent) Objects() ([]client.Object, []client.Ob // Management and managed clusters need API access to the resources defined in the policy // recommendation cluster role objs := []client.Object{ - CreateNamespace(pr.cfg.Namespace, pr.cfg.Installation.KubernetesProvider, PSSRestricted), + CreateNamespace(pr.cfg.Namespace, pr.cfg.Installation.KubernetesProvider, PSSRestricted, pr.cfg.Installation.Azure), pr.serviceAccount(), pr.clusterRole(), pr.clusterRoleBinding(),