Skip to content

Commit

Permalink
cherry-pick #3630 Restrict tigera-operator secret access to namespace…
Browse files Browse the repository at this point in the history
… only (#3653)

* Restrict tigera-operator secret access to namespace only, retain get/watch/list cluster-wide

* Add secrets rolebinding for external prometheus

* Trigger Build
  • Loading branch information
vara2504 authored Dec 18, 2024
1 parent 69eae92 commit 7fe8665
Show file tree
Hide file tree
Showing 33 changed files with 722 additions and 834 deletions.
3 changes: 2 additions & 1 deletion pkg/controller/compliance/compliance_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,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, network.Azure))
opSecretsRB := render.NewPassthrough(render.CreateOperatorSecretsRoleBinding(helper.InstallNamespace()))

hasNoLicense := !utils.IsFeatureActive(license, common.ComplianceFeature)
openshift := r.provider.IsOpenShift()
Expand Down Expand Up @@ -495,7 +496,7 @@ func (r *ReconcileCompliance) Reconcile(ctx context.Context, request reconcile.R
TrustedBundle: bundleMaker,
})

for _, comp := range []render.Component{namespaceComp, certificateComponent, comp} {
for _, comp := range []render.Component{namespaceComp, opSecretsRB, certificateComponent, comp} {
if err := handler.CreateOrUpdateOrDelete(ctx, comp, r.status); err != nil {
r.status.SetDegraded(operatorv1.ResourceUpdateError, "Error creating / updating / deleting resource", err, reqLogger)
return reconcile.Result{}, err
Expand Down
12 changes: 12 additions & 0 deletions pkg/controller/logstorage/initializer/initializing_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,13 +246,25 @@ func (r *LogStorageInitializer) Reconcile(ctx context.Context, request reconcile
return reconcile.Result{}, err
}

esRoleBinding := render.CreateOperatorSecretsRoleBinding(render.ElasticsearchNamespace)
if err = hdler.CreateOrUpdateOrDelete(ctx, render.NewPassthrough(esRoleBinding), r.status); err != nil {
r.status.SetDegraded(operatorv1.ResourceUpdateError, "Error creating / updating resource", err, reqLogger)
return reconcile.Result{}, err
}

// Multitenant clusters do not get kibana, so namespace creation can be skipped.
if !r.multiTenant {
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
}

kbRoleBinding := render.CreateOperatorSecretsRoleBinding(kibana.Namespace)
if err = hdler.CreateOrUpdateOrDelete(ctx, render.NewPassthrough(kbRoleBinding), r.status); err != nil {
r.status.SetDegraded(operatorv1.ResourceUpdateError, "Error creating / updating resource", err, reqLogger)
return reconcile.Result{}, err
}
}

// Write the logstorage back to the datastore with its newly applied defaults.
Expand Down
2 changes: 2 additions & 0 deletions pkg/render/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,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, c.cfg.Installation.Azure),
CreateOperatorSecretsRoleBinding(rmeta.APIServerNamespace(operatorv1.TigeraSecureEnterprise)),
c.tigeraApiServerClusterRole(),
c.tigeraApiServerClusterRoleBinding(),
c.uisettingsgroupGetterClusterRole(),
Expand Down Expand Up @@ -305,6 +306,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, c.cfg.Installation.Azure),
CreateOperatorSecretsRoleBinding(rmeta.APIServerNamespace(operatorv1.Calico)),
}

// Compile the final arrays based on the variant.
Expand Down
574 changes: 264 additions & 310 deletions pkg/render/apiserver_test.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pkg/render/dex.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ func (c *dexComponent) Objects() ([]client.Object, []client.Object) {
CreateNamespace(DexObjectName, c.cfg.Installation.KubernetesProvider, PSSRestricted, c.cfg.Installation.Azure),
c.allowTigeraNetworkPolicy(c.cfg.Installation.Variant),
networkpolicy.AllowTigeraDefaultDeny(DexNamespace),
CreateOperatorSecretsRoleBinding(DexNamespace),
c.serviceAccount(),
c.deployment(),
c.service(),
Expand Down
86 changes: 35 additions & 51 deletions pkg/render/dex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,33 +206,25 @@ var _ = Describe("dex rendering tests", func() {
component := render.Dex(cfg)
resources, _ := component.Objects()

expectedResources := []struct {
name string
ns string
group string
version string
kind string
}{
{render.DexObjectName, "", "", "v1", "Namespace"},
{render.DexPolicyName, render.DexNamespace, "projectcalico.org", "v3", "NetworkPolicy"},
{networkpolicy.TigeraComponentDefaultDenyPolicyName, render.DexNamespace, "projectcalico.org", "v3", "NetworkPolicy"},
{render.DexObjectName, render.DexNamespace, "", "v1", "ServiceAccount"},
{render.DexObjectName, render.DexNamespace, "apps", "v1", "Deployment"},
{render.DexObjectName, render.DexNamespace, "", "v1", "Service"},
{render.DexObjectName, "", rbac, "v1", "ClusterRole"},
{render.DexObjectName, "", rbac, "v1", "ClusterRoleBinding"},
{render.DexObjectName, render.DexNamespace, "", "v1", "ConfigMap"},
{render.DexObjectName, common.OperatorNamespace(), "", "v1", "Secret"},
{render.OIDCSecretName, common.OperatorNamespace(), "", "v1", "Secret"},
{render.DexObjectName, render.DexNamespace, "", "v1", "Secret"},
{render.OIDCSecretName, render.DexNamespace, "", "v1", "Secret"},
{pullSecretName, render.DexNamespace, "", "v1", "Secret"},
expectedResources := []client.Object{
&corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: render.DexObjectName}, TypeMeta: metav1.TypeMeta{Kind: "Namespace", APIVersion: "v1"}},
&v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Name: render.DexPolicyName, Namespace: render.DexNamespace}, TypeMeta: metav1.TypeMeta{Kind: "NetworkPolicy", APIVersion: "projectcalico.org/v3"}},
&v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Name: networkpolicy.TigeraComponentDefaultDenyPolicyName, Namespace: render.DexNamespace}, TypeMeta: metav1.TypeMeta{Kind: "NetworkPolicy", APIVersion: "projectcalico.org/v3"}},
&corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: render.DexObjectName, Namespace: render.DexNamespace}, TypeMeta: metav1.TypeMeta{Kind: "ServiceAccount", APIVersion: "v1"}},
&appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: render.DexObjectName, Namespace: render.DexNamespace}, TypeMeta: metav1.TypeMeta{Kind: "Deployment", APIVersion: "apps/v1"}},
&corev1.Service{ObjectMeta: metav1.ObjectMeta{Name: render.DexObjectName, Namespace: render.DexNamespace}, TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "v1"}},
&rbacv1.ClusterRole{ObjectMeta: metav1.ObjectMeta{Name: render.DexObjectName}, TypeMeta: metav1.TypeMeta{Kind: "ClusterRole", APIVersion: "rbac.authorization.k8s.io/v1"}},
&rbacv1.ClusterRoleBinding{ObjectMeta: metav1.ObjectMeta{Name: render.DexObjectName}, TypeMeta: metav1.TypeMeta{Kind: "ClusterRoleBinding", APIVersion: "rbac.authorization.k8s.io/v1"}},
&corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: render.DexObjectName, Namespace: render.DexNamespace}, TypeMeta: metav1.TypeMeta{Kind: "ConfigMap", APIVersion: "v1"}},
&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: render.DexObjectName, Namespace: common.OperatorNamespace()}, TypeMeta: metav1.TypeMeta{Kind: "Secret", APIVersion: "v1"}},
&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: render.OIDCSecretName, Namespace: common.OperatorNamespace()}, TypeMeta: metav1.TypeMeta{Kind: "Secret", APIVersion: "v1"}},
&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: render.DexObjectName, Namespace: render.DexNamespace}, TypeMeta: metav1.TypeMeta{Kind: "Secret", APIVersion: "v1"}},
&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: render.OIDCSecretName, Namespace: render.DexNamespace}, TypeMeta: metav1.TypeMeta{Kind: "Secret", APIVersion: "v1"}},
&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: pullSecretName, Namespace: render.DexNamespace}, TypeMeta: metav1.TypeMeta{Kind: "Secret", APIVersion: "v1"}},
&rbacv1.RoleBinding{ObjectMeta: metav1.ObjectMeta{Name: render.TigeraOperatorSecrets, Namespace: render.DexNamespace}},
}

for i, expectedRes := range expectedResources {
rtest.ExpectResourceTypeAndObjectMetadata(resources[i], expectedRes.name, expectedRes.ns, expectedRes.group, expectedRes.version, expectedRes.kind)
}
Expect(len(resources)).To(Equal(len(expectedResources)))
rtest.ExpectResources(resources, expectedResources)

d := rtest.GetResource(resources, "tigera-dex", "tigera-dex", "apps", "v1", "Deployment").(*appsv1.Deployment)

Expand Down Expand Up @@ -346,34 +338,26 @@ var _ = Describe("dex rendering tests", func() {
component := render.Dex(cfg)
resources, _ := component.Objects()

expectedResources := []struct {
name string
ns string
group string
version string
kind string
}{
{render.DexObjectName, "", "", "v1", "Namespace"},
{render.DexPolicyName, render.DexNamespace, "projectcalico.org", "v3", "NetworkPolicy"},
{networkpolicy.TigeraComponentDefaultDenyPolicyName, render.DexNamespace, "projectcalico.org", "v3", "NetworkPolicy"},
{render.DexObjectName, render.DexNamespace, "", "v1", "ServiceAccount"},
{render.DexObjectName, render.DexNamespace, "apps", "v1", "Deployment"},
{render.DexObjectName, render.DexNamespace, "", "v1", "Service"},
{render.DexObjectName, "", rbac, "v1", "ClusterRole"},
{render.DexObjectName, "", rbac, "v1", "ClusterRoleBinding"},
{render.DexObjectName, render.DexNamespace, "", "v1", "ConfigMap"},
{render.DexObjectName, common.OperatorNamespace(), "", "v1", "Secret"},
{render.OIDCSecretName, common.OperatorNamespace(), "", "v1", "Secret"},
{render.DexObjectName, render.DexNamespace, "", "v1", "Secret"},
{render.OIDCSecretName, render.DexNamespace, "", "v1", "Secret"},
{pullSecretName, render.DexNamespace, "", "v1", "Secret"},
{"tigera-dex:csr-creator", "", "rbac.authorization.k8s.io", "v1", "ClusterRoleBinding"},
expectedResources := []client.Object{
&corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: render.DexObjectName}, TypeMeta: metav1.TypeMeta{Kind: "Namespace", APIVersion: "v1"}},
&v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Name: render.DexPolicyName, Namespace: render.DexNamespace}, TypeMeta: metav1.TypeMeta{Kind: "NetworkPolicy", APIVersion: "projectcalico.org/v3"}},
&v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Name: networkpolicy.TigeraComponentDefaultDenyPolicyName, Namespace: render.DexNamespace}, TypeMeta: metav1.TypeMeta{Kind: "NetworkPolicy", APIVersion: "projectcalico.org/v3"}},
&corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: render.DexObjectName, Namespace: render.DexNamespace}, TypeMeta: metav1.TypeMeta{Kind: "ServiceAccount", APIVersion: "v1"}},
&appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: render.DexObjectName, Namespace: render.DexNamespace}, TypeMeta: metav1.TypeMeta{Kind: "Deployment", APIVersion: "apps/v1"}},
&corev1.Service{ObjectMeta: metav1.ObjectMeta{Name: render.DexObjectName, Namespace: render.DexNamespace}, TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "v1"}},
&rbacv1.ClusterRole{ObjectMeta: metav1.ObjectMeta{Name: render.DexObjectName}, TypeMeta: metav1.TypeMeta{Kind: "ClusterRole", APIVersion: "rbac.authorization.k8s.io/v1"}},
&rbacv1.ClusterRoleBinding{ObjectMeta: metav1.ObjectMeta{Name: render.DexObjectName}, TypeMeta: metav1.TypeMeta{Kind: "ClusterRoleBinding", APIVersion: "rbac.authorization.k8s.io/v1"}},
&corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: render.DexObjectName, Namespace: render.DexNamespace}, TypeMeta: metav1.TypeMeta{Kind: "ConfigMap", APIVersion: "v1"}},
&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: render.DexObjectName, Namespace: common.OperatorNamespace()}, TypeMeta: metav1.TypeMeta{Kind: "Secret", APIVersion: "v1"}},
&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: render.OIDCSecretName, Namespace: common.OperatorNamespace()}, TypeMeta: metav1.TypeMeta{Kind: "Secret", APIVersion: "v1"}},
&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: render.DexObjectName, Namespace: render.DexNamespace}, TypeMeta: metav1.TypeMeta{Kind: "Secret", APIVersion: "v1"}},
&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: render.OIDCSecretName, Namespace: render.DexNamespace}, TypeMeta: metav1.TypeMeta{Kind: "Secret", APIVersion: "v1"}},
&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: pullSecretName, Namespace: render.DexNamespace}, TypeMeta: metav1.TypeMeta{Kind: "Secret", APIVersion: "v1"}},
&rbacv1.ClusterRoleBinding{ObjectMeta: metav1.ObjectMeta{Name: "tigera-dex:csr-creator"}, TypeMeta: metav1.TypeMeta{Kind: "ClusterRoleBinding", APIVersion: "rbac.authorization.k8s.io/v1"}},
&rbacv1.RoleBinding{ObjectMeta: metav1.ObjectMeta{Name: render.TigeraOperatorSecrets, Namespace: render.DexNamespace}},
}

for i, expectedRes := range expectedResources {
rtest.ExpectResourceTypeAndObjectMetadata(resources[i], expectedRes.name, expectedRes.ns, expectedRes.group, expectedRes.version, expectedRes.kind)
}
Expect(len(resources)).To(Equal(len(expectedResources)))
rtest.ExpectResources(resources, expectedResources)
})

It("should render SecurityContextConstrains properly when provider is OpenShift", func() {
Expand Down
1 change: 1 addition & 0 deletions pkg/render/fluentd.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ func (c *fluentdComponent) Objects() ([]client.Object, []client.Object) {
var objs, toDelete []client.Object
objs = append(objs, CreateNamespace(LogCollectorNamespace, c.cfg.Installation.KubernetesProvider, PSSPrivileged, c.cfg.Installation.Azure))
objs = append(objs, c.allowTigeraPolicy())
objs = append(objs, CreateOperatorSecretsRoleBinding(LogCollectorNamespace))
objs = append(objs, secret.ToRuntimeObjects(secret.CopyToNamespace(LogCollectorNamespace, c.cfg.PullSecrets...)...)...)
objs = append(objs, c.metricsService())

Expand Down
Loading

0 comments on commit 7fe8665

Please sign in to comment.