From 27659b859caf562cd9f2005f78f5f58f2b3427c7 Mon Sep 17 00:00:00 2001 From: Maciej Zimnoch Date: Tue, 5 Aug 2025 18:44:44 +0200 Subject: [PATCH 1/3] Add support for ClusterRole AggregationRule during bundle generation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ClusterRoles that use an AggregationRule often do not have any rules defined directly. Instead, their rules are aggregated from other ClusterRoles that match the AggregationRule’s label selector. The existing generator logic only included rules from ClusterRoles that were explicitly bound via ClusterRoleBindings to the ServiceAccounts used by Deployments. Since ClusterRoles with an AggregationRule typically lack direct rule definitions, the resulting permission bundle ended up being empty. This update adds support for handling ClusterRoles that use an AggregationRule. Signed-off-by: Maciej Zimnoch --- ...port-aggregated-rules-of-clusterroles.yaml | 41 ++++++++++ .../clusterserviceversion_updaters.go | 79 +++++++++++++++++-- .../clusterserviceversion_updaters_test.go | 69 ++++++++++++++-- 3 files changed, 177 insertions(+), 12 deletions(-) create mode 100644 changelog/fragments/01-support-aggregated-rules-of-clusterroles.yaml diff --git a/changelog/fragments/01-support-aggregated-rules-of-clusterroles.yaml b/changelog/fragments/01-support-aggregated-rules-of-clusterroles.yaml new file mode 100644 index 00000000000..a916a5aaf2d --- /dev/null +++ b/changelog/fragments/01-support-aggregated-rules-of-clusterroles.yaml @@ -0,0 +1,41 @@ +# entries is a list of entries to include in +# release notes and/or the migration guide +entries: + - description: > + The bundle generator now includes policy rules from ClusterRoles originating through AggregationRule. + Previously, only policy rules of ClusterRoles explicitly bound to ServiceAccounts via ClusterRoleBindings were included. + With this update, the generator also aggregates and applies rules from matching ClusterRoles, + ensuring proper RBAC coverage. + + + # kind is one of: + # - addition + # - change + # - deprecation + # - removal + # - bugfix + kind: addition + + # Is this a breaking change? + breaking: false + + # NOTE: ONLY USE `pull_request_override` WHEN ADDING THIS + # FILE FOR A PREVIOUSLY MERGED PULL_REQUEST! + # + # The generator auto-detects the PR number from the commit + # message in which this file was originally added. + # + # What is the pull request number (without the "#")? + # pull_request_override: 0 + + + # Migration can be defined to automatically add a section to + # the migration guide. This is required for breaking changes. +# migration: +# header: Header text for the migration section +# body: | +# Body of the migration section. This should be formatted as markdown and can +# span multiple lines. +# +# Using the YAML string '|' operator means that newlines in this string will +# be honored and interpretted as newlines in the rendered markdown. diff --git a/internal/generate/clusterserviceversion/clusterserviceversion_updaters.go b/internal/generate/clusterserviceversion/clusterserviceversion_updaters.go index 98d7540705d..60d94588721 100644 --- a/internal/generate/clusterserviceversion/clusterserviceversion_updaters.go +++ b/internal/generate/clusterserviceversion/clusterserviceversion_updaters.go @@ -18,6 +18,7 @@ import ( "encoding/json" "errors" "fmt" + "slices" "sort" "strings" "time" @@ -31,6 +32,9 @@ import ( corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/api/equality" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "sigs.k8s.io/controller-runtime/pkg/client" "github.com/operator-framework/operator-sdk/internal/generate/collector" @@ -57,8 +61,14 @@ func apply(c *collector.Manifests, csv *operatorsv1alpha1.ClusterServiceVersion, switch strategy.StrategyName { case operatorsv1alpha1.InstallStrategyNameDeployment: inPerms, inCPerms, _ := c.SplitCSVPermissionsObjects(extraSAs) - applyRoles(c, inPerms, &strategy.StrategySpec, extraSAs) - applyClusterRoles(c, inCPerms, &strategy.StrategySpec, extraSAs) + err := applyRoles(c, inPerms, &strategy.StrategySpec, extraSAs) + if err != nil { + return fmt.Errorf("can't apply roles: %w", err) + } + err = applyClusterRoles(c, inCPerms, &strategy.StrategySpec, extraSAs) + if err != nil { + return fmt.Errorf("can't apply cluster roles: %w", err) + } applyDeployments(c, &strategy.StrategySpec) } csv.Spec.InstallStrategy = strategy @@ -88,7 +98,7 @@ const defaultServiceAccountName = "default" // applyRoles applies Roles to strategy's permissions field by combining Roles bound to ServiceAccounts // into one set of permissions. -func applyRoles(c *collector.Manifests, objs []client.Object, strategy *operatorsv1alpha1.StrategyDetailsDeployment, extraSAs []string) { //nolint:dupl +func applyRoles(c *collector.Manifests, objs []client.Object, strategy *operatorsv1alpha1.StrategyDetailsDeployment, extraSAs []string) error { //nolint:dupl roleSet := make(map[string]rbacv1.Role) cRoleSet := make(map[string]rbacv1.ClusterRole) for i := range objs { @@ -120,8 +130,16 @@ func applyRoles(c *collector.Manifests, objs []client.Object, strategy *operator hasRole = has case "ClusterRole": role, has := cRoleSet[binding.RoleRef.Name] - rules = role.Rules + hasRole = has + if has { + var err error + rules, err = getClusterRoleRules(role, c.ClusterRoles) + if err != nil { + return fmt.Errorf("can't get ClusterRole rules: %w", err) + } + } + default: continue } @@ -143,11 +161,13 @@ func applyRoles(c *collector.Manifests, objs []client.Object, strategy *operator return perms[i].ServiceAccountName < perms[j].ServiceAccountName }) strategy.Permissions = perms + + return nil } // applyClusterRoles applies ClusterRoles to strategy's clusterPermissions field by combining ClusterRoles // bound to ServiceAccounts into one set of clusterPermissions. -func applyClusterRoles(c *collector.Manifests, objs []client.Object, strategy *operatorsv1alpha1.StrategyDetailsDeployment, extraSAs []string) { //nolint:dupl +func applyClusterRoles(c *collector.Manifests, objs []client.Object, strategy *operatorsv1alpha1.StrategyDetailsDeployment, extraSAs []string) error { //nolint:dupl roleSet := make(map[string]rbacv1.ClusterRole) for i := range objs { switch t := objs[i].(type) { @@ -166,7 +186,12 @@ func applyClusterRoles(c *collector.Manifests, objs []client.Object, strategy *o continue } if role, hasRole := roleSet[binding.RoleRef.Name]; hasRole { - perm.Rules = append(perm.Rules, role.Rules...) + rules, err := getClusterRoleRules(role, c.ClusterRoles) + if err != nil { + return fmt.Errorf("can't get ClusterRole rules: %w", err) + } + + perm.Rules = append(perm.Rules, rules...) saToPermissions[subject.Name] = perm } } @@ -183,6 +208,48 @@ func applyClusterRoles(c *collector.Manifests, objs []client.Object, strategy *o return perms[i].ServiceAccountName < perms[j].ServiceAccountName }) strategy.ClusterPermissions = perms + + return nil +} + +// getClusterRoleRules returns all PolicyRules for a given ClusterRole, including rules from aggregated ClusterRoles +// as specified by the AggregationRule, ensuring no duplicate rules are added. +func getClusterRoleRules(clusterRole rbacv1.ClusterRole, clusterRoles []rbacv1.ClusterRole) ([]rbacv1.PolicyRule, error) { + rules := make([]rbacv1.PolicyRule, 0, len(clusterRole.Rules)) + rules = append(rules, clusterRole.Rules...) + + if clusterRole.AggregationRule == nil { + return rules, nil + } + + for _, crSelector := range clusterRole.AggregationRule.ClusterRoleSelectors { + labelSelector, err := metav1.LabelSelectorAsSelector(&crSelector) + if err != nil { + return nil, fmt.Errorf("can't create label selector from ClusterRole %q AggregationRule: %w", clusterRole.Name, err) + } + + for _, cr := range clusterRoles { + if cr.Name == clusterRole.Name { + continue + } + + if !labelSelector.Matches(labels.Set(cr.Labels)) { + continue + } + + for _, rule := range cr.Rules { + ruleExists := slices.ContainsFunc(rules, func(r rbacv1.PolicyRule) bool { + return equality.Semantic.DeepEqual(rule, r) + }) + + if !ruleExists { + rules = append(rules, rule) + } + } + } + } + + return rules, nil } // initPermissionSet initializes a map of ServiceAccount name to permissions, which are empty. diff --git a/internal/generate/clusterserviceversion/clusterserviceversion_updaters_test.go b/internal/generate/clusterserviceversion/clusterserviceversion_updaters_test.go index 212e32a6e0d..b02c57fbe1e 100644 --- a/internal/generate/clusterserviceversion/clusterserviceversion_updaters_test.go +++ b/internal/generate/clusterserviceversion/clusterserviceversion_updaters_test.go @@ -24,6 +24,7 @@ import ( rbacv1 "k8s.io/api/rbac/v1" apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "sigs.k8s.io/controller-runtime/pkg/client" @@ -65,6 +66,9 @@ var _ = Describe("apply functions", func() { saName1 = "service-account-1" roleName1 = "role-1" cRoleName1 = "cluster-role-1" + cRoleName2 = "cluster-role-2" + cRoleName3 = "cluster-role-3" + cRoleName4 = "cluster-role-4" ) BeforeEach(func() { @@ -79,7 +83,8 @@ var _ = Describe("apply functions", func() { rules := []rbacv1.PolicyRule{{Verbs: []string{"create"}}} perms := []client.Object{newRole(roleName1, rules...)} c.RoleBindings = []rbacv1.RoleBinding{newRoleBinding("role-binding", newRoleRef(roleName1), newServiceAccountSubject(saName1))} - applyRoles(c, perms, strategy, nil) + err := applyRoles(c, perms, strategy, nil) + Expect(err).NotTo(HaveOccurred()) Expect(strategy.Permissions).To(Equal([]operatorsv1alpha1.StrategyDeploymentPermissions{ {ServiceAccountName: saName1, Rules: rules}, })) @@ -90,7 +95,55 @@ var _ = Describe("apply functions", func() { rules := []rbacv1.PolicyRule{{Verbs: []string{"create"}}} perms := []client.Object{newClusterRole(cRoleName1, rules...)} c.ClusterRoleBindings = []rbacv1.ClusterRoleBinding{newClusterRoleBinding("cluster-role-binding", newClusterRoleRef(cRoleName1), newServiceAccountSubject(saName1))} - applyClusterRoles(c, perms, strategy, nil) + err := applyClusterRoles(c, perms, strategy, nil) + Expect(err).NotTo(HaveOccurred()) + Expect(strategy.ClusterPermissions).To(Equal([]operatorsv1alpha1.StrategyDeploymentPermissions{ + {ServiceAccountName: saName1, Rules: rules}, + })) + }) + It("adds rules from aggregated ClusterRoles eliminating duplicates to the CSV deployment strategy", func() { + c.Deployments = []appsv1.Deployment{newDeploymentWithServiceAccount(depName1, saName1)} + c.ServiceAccounts = []corev1.ServiceAccount{newServiceAccount(saName1)} + rules := []rbacv1.PolicyRule{{Verbs: []string{"create"}}, {Verbs: []string{"update"}}} + var emptyRules []rbacv1.PolicyRule + perms := []client.Object{ + func() *rbacv1.ClusterRole { + cr := newClusterRole(cRoleName1, emptyRules...) + cr.AggregationRule = &rbacv1.AggregationRule{ + ClusterRoleSelectors: []metav1.LabelSelector{ + { + MatchLabels: map[string]string{ + "aggregate-to-cluster-role-1": "true", + }, + }, + }, + } + return cr + }(), + func() *rbacv1.ClusterRole { + cr := newClusterRole(cRoleName2, rules...) + cr.Labels = map[string]string{ + "aggregate-to-cluster-role-1": "true", + } + return cr + }(), + func() *rbacv1.ClusterRole { + cr := newClusterRole(cRoleName3, rules...) + cr.Labels = map[string]string{ + "aggregate-to-cluster-role-1": "true", + } + return cr + }(), + // ClusterRole not bound to any ServiceAccount, nor matching any ClusterRule AggregationRule, + // it shouldn't land in strategy ClusterPermissions. + newClusterRole(cRoleName4, []rbacv1.PolicyRule{{Verbs: []string{"delete"}}}...), + } + for _, cr := range perms { + c.ClusterRoles = append(c.ClusterRoles, *cr.(*rbacv1.ClusterRole)) + } + c.ClusterRoleBindings = []rbacv1.ClusterRoleBinding{newClusterRoleBinding("cluster-role-binding", newClusterRoleRef(cRoleName1), newServiceAccountSubject(saName1))} + err := applyClusterRoles(c, perms, strategy, nil) + Expect(err).NotTo(HaveOccurred()) Expect(strategy.ClusterPermissions).To(Equal([]operatorsv1alpha1.StrategyDeploymentPermissions{ {ServiceAccountName: saName1, Rules: rules}, })) @@ -128,8 +181,10 @@ var _ = Describe("apply functions", func() { newClusterRoleBinding("cluster-role-binding-2", newClusterRoleRef(cRoleName2), newServiceAccountSubject(extraSAName)), newClusterRoleBinding("cluster-role-binding-3", newClusterRoleRef(cRoleName3), newServiceAccountSubject(extraSAName)), } - applyRoles(c, perms, strategy, []string{extraSAName}) - applyClusterRoles(c, cperms, strategy, []string{extraSAName}) + err := applyRoles(c, perms, strategy, []string{extraSAName}) + Expect(err).NotTo(HaveOccurred()) + err = applyClusterRoles(c, cperms, strategy, []string{extraSAName}) + Expect(err).NotTo(HaveOccurred()) Expect(strategy.Permissions).To(Equal([]operatorsv1alpha1.StrategyDeploymentPermissions{ {ServiceAccountName: saName1, Rules: rules}, {ServiceAccountName: extraSAName, Rules: rules}, @@ -146,14 +201,16 @@ var _ = Describe("apply functions", func() { c.Deployments = []appsv1.Deployment{newDeploymentWithServiceAccount(depName1, saName1)} c.ServiceAccounts = []corev1.ServiceAccount{newServiceAccount(saName1)} c.RoleBindings = []rbacv1.RoleBinding{newRoleBinding("role-binding", newRoleRef(roleName1), newServiceAccountSubject(saName1))} - applyRoles(c, nil, strategy, nil) + err := applyRoles(c, nil, strategy, nil) + Expect(err).NotTo(HaveOccurred()) Expect(strategy.Permissions).To(Equal([]operatorsv1alpha1.StrategyDeploymentPermissions{})) }) It("adds no ClusterPermissions to the CSV deployment strategy", func() { c.Deployments = []appsv1.Deployment{newDeploymentWithServiceAccount(depName1, saName1)} c.ServiceAccounts = []corev1.ServiceAccount{newServiceAccount(saName1)} c.ClusterRoleBindings = []rbacv1.ClusterRoleBinding{newClusterRoleBinding("cluster-role-binding", newClusterRoleRef(cRoleName1), newServiceAccountSubject(saName1))} - applyClusterRoles(c, nil, strategy, nil) + err := applyClusterRoles(c, nil, strategy, nil) + Expect(err).NotTo(HaveOccurred()) Expect(strategy.ClusterPermissions).To(Equal([]operatorsv1alpha1.StrategyDeploymentPermissions{})) }) }) From 8eefe316fb27070397ef28fc30e396cb63f2ef62 Mon Sep 17 00:00:00 2001 From: Maciej Zimnoch Date: Thu, 28 Aug 2025 14:01:40 +0200 Subject: [PATCH 2/3] Add ClusterRole having AggregatedRule to integration tests Signed-off-by: Maciej Zimnoch --- .../aggregation-subrole.clusterole.yaml | 13 +++++++ .../aggregation.clusterolebinding.yaml | 12 ++++++ .../manifests/aggregation.clusterrole.yaml | 8 ++++ .../aggregation.kustomization.patch.yaml | 4 ++ .../manifests/registry.go | 19 ++++++++++ .../memcached_with_customization.go | 38 +++++++++++++++++++ 6 files changed, 94 insertions(+) create mode 100644 hack/generate/samples/internal/go/memcached-with-customization/manifests/aggregation-subrole.clusterole.yaml create mode 100644 hack/generate/samples/internal/go/memcached-with-customization/manifests/aggregation.clusterolebinding.yaml create mode 100644 hack/generate/samples/internal/go/memcached-with-customization/manifests/aggregation.clusterrole.yaml create mode 100644 hack/generate/samples/internal/go/memcached-with-customization/manifests/aggregation.kustomization.patch.yaml create mode 100644 hack/generate/samples/internal/go/memcached-with-customization/manifests/registry.go diff --git a/hack/generate/samples/internal/go/memcached-with-customization/manifests/aggregation-subrole.clusterole.yaml b/hack/generate/samples/internal/go/memcached-with-customization/manifests/aggregation-subrole.clusterole.yaml new file mode 100644 index 00000000000..cabcdd7d39d --- /dev/null +++ b/hack/generate/samples/internal/go/memcached-with-customization/manifests/aggregation-subrole.clusterole.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: aggregation-memcached-subrole + labels: + rbac.example.memcached.com/aggregate-to-aggregation-memcached: "true" +rules: + - apiGroups: + - "" + resources: + - pods + verbs: + - update diff --git a/hack/generate/samples/internal/go/memcached-with-customization/manifests/aggregation.clusterolebinding.yaml b/hack/generate/samples/internal/go/memcached-with-customization/manifests/aggregation.clusterolebinding.yaml new file mode 100644 index 00000000000..f0f40600230 --- /dev/null +++ b/hack/generate/samples/internal/go/memcached-with-customization/manifests/aggregation.clusterolebinding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: aggregation-memcached +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: aggregation-memcached +subjects: + - kind: ServiceAccount + name: controller-manager + namespace: system diff --git a/hack/generate/samples/internal/go/memcached-with-customization/manifests/aggregation.clusterrole.yaml b/hack/generate/samples/internal/go/memcached-with-customization/manifests/aggregation.clusterrole.yaml new file mode 100644 index 00000000000..481524b1d72 --- /dev/null +++ b/hack/generate/samples/internal/go/memcached-with-customization/manifests/aggregation.clusterrole.yaml @@ -0,0 +1,8 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: aggregation-memcached +aggregationRule: + clusterRoleSelectors: + - matchLabels: + rbac.example.memcached.com/aggregate-to-aggregation-memcached: "true" diff --git a/hack/generate/samples/internal/go/memcached-with-customization/manifests/aggregation.kustomization.patch.yaml b/hack/generate/samples/internal/go/memcached-with-customization/manifests/aggregation.kustomization.patch.yaml new file mode 100644 index 00000000000..15ff4388b95 --- /dev/null +++ b/hack/generate/samples/internal/go/memcached-with-customization/manifests/aggregation.kustomization.patch.yaml @@ -0,0 +1,4 @@ + +- aggregation.clusterrolebinding.yaml +- aggregation-subrole.clusterrole.yaml +- aggregation.clusterrole.yaml diff --git a/hack/generate/samples/internal/go/memcached-with-customization/manifests/registry.go b/hack/generate/samples/internal/go/memcached-with-customization/manifests/registry.go new file mode 100644 index 00000000000..a717d1a9aff --- /dev/null +++ b/hack/generate/samples/internal/go/memcached-with-customization/manifests/registry.go @@ -0,0 +1,19 @@ +package manifests + +import ( + _ "embed" +) + +var ( + //go:embed "aggregation.clusterrole.yaml" + AggregationClusterRoleString string + + //go:embed "aggregation-subrole.clusterole.yaml" + AggregationSubroleClusterRoleString string + + //go:embed "aggregation.clusterolebinding.yaml" + AggregationClusterRoleBindingString string + + //go:embed "aggregation.kustomization.patch.yaml" + AggregationKustomizationPatchString string +) diff --git a/hack/generate/samples/internal/go/memcached-with-customization/memcached_with_customization.go b/hack/generate/samples/internal/go/memcached-with-customization/memcached_with_customization.go index 097e56bf6a7..a00c397d143 100644 --- a/hack/generate/samples/internal/go/memcached-with-customization/memcached_with_customization.go +++ b/hack/generate/samples/internal/go/memcached-with-customization/memcached_with_customization.go @@ -21,6 +21,7 @@ import ( "path/filepath" "strings" + "github.com/operator-framework/operator-sdk/hack/generate/samples/internal/go/memcached-with-customization/manifests" log "github.com/sirupsen/logrus" kbutil "sigs.k8s.io/kubebuilder/v4/pkg/plugin/util" @@ -139,6 +140,9 @@ func (mh *Memcached) Run() { mh.implementingWebhooks() + log.Infof("implementing the aggregated cluster rule") + mh.implementingAggregatedClusterRules() + mh.uncommentDefaultKustomizationV4() mh.uncommentManifestsKustomizationv4() @@ -780,6 +784,40 @@ func (mh *Memcached) customizingMakefile() { pkg.CheckError("adding metrics documentation", err) } +func (mh *Memcached) implementingAggregatedClusterRules() { + rbacDirPath := filepath.Join(mh.ctx.Dir, "config", "rbac") + + var filePerm os.FileMode = 0600 + + err := os.WriteFile( + filepath.Join(rbacDirPath, "aggregation.clusterrole.yaml"), + []byte(manifests.AggregationClusterRoleString), + filePerm, + ) + pkg.CheckError("creating aggregation clusterrole", err) + + err = os.WriteFile( + filepath.Join(rbacDirPath, "aggregation-subrole.clusterrole.yaml"), + []byte(manifests.AggregationSubroleClusterRoleString), + filePerm, + ) + pkg.CheckError("creating aggregation clusterrole subrole", err) + + err = os.WriteFile( + filepath.Join(rbacDirPath, "aggregation.clusterrolebinding.yaml"), + []byte(manifests.AggregationClusterRoleBindingString), + filePerm, + ) + pkg.CheckError("creating aggregation clusterrolebinding", err) + + kustomizationPath := filepath.Join(rbacDirPath, "kustomization.yaml") + err = kbutil.InsertCode(kustomizationPath, + `- memcached_viewer_role.yaml`, + manifests.AggregationKustomizationPatchString, + ) + pkg.CheckError("adding metrics documentation", err) +} + const metricsFragment = ` package monitoring From ed1fffb7f40dcd10d3e98f991f004820a94a5f4e Mon Sep 17 00:00:00 2001 From: Maciej Zimnoch Date: Thu, 28 Aug 2025 14:04:45 +0200 Subject: [PATCH 3/3] Update autogenerated Signed-off-by: Maciej Zimnoch --- ...e_rbac.authorization.k8s.io_v1_clusterrole.yaml | 14 ++++++++++++++ .../memcached-operator.clusterserviceversion.yaml | 6 ++++++ .../rbac/aggregation-subrole.clusterrole.yaml | 13 +++++++++++++ .../config/rbac/aggregation.clusterrole.yaml | 8 ++++++++ .../rbac/aggregation.clusterrolebinding.yaml | 12 ++++++++++++ .../config/rbac/kustomization.yaml | 4 ++++ ...e_rbac.authorization.k8s.io_v1_clusterrole.yaml | 14 ++++++++++++++ .../memcached-operator.clusterserviceversion.yaml | 6 ++++++ .../rbac/aggregation-subrole.clusterrole.yaml | 13 +++++++++++++ .../config/rbac/aggregation.clusterrole.yaml | 8 ++++++++ .../rbac/aggregation.clusterrolebinding.yaml | 12 ++++++++++++ .../config/rbac/kustomization.yaml | 4 ++++ 12 files changed, 114 insertions(+) create mode 100644 testdata/go/v4/memcached-operator/bundle/manifests/memcached-operator-aggregation-memcached-subrole_rbac.authorization.k8s.io_v1_clusterrole.yaml create mode 100644 testdata/go/v4/memcached-operator/config/rbac/aggregation-subrole.clusterrole.yaml create mode 100644 testdata/go/v4/memcached-operator/config/rbac/aggregation.clusterrole.yaml create mode 100644 testdata/go/v4/memcached-operator/config/rbac/aggregation.clusterrolebinding.yaml create mode 100644 testdata/go/v4/monitoring/memcached-operator/bundle/manifests/memcached-operator-aggregation-memcached-subrole_rbac.authorization.k8s.io_v1_clusterrole.yaml create mode 100644 testdata/go/v4/monitoring/memcached-operator/config/rbac/aggregation-subrole.clusterrole.yaml create mode 100644 testdata/go/v4/monitoring/memcached-operator/config/rbac/aggregation.clusterrole.yaml create mode 100644 testdata/go/v4/monitoring/memcached-operator/config/rbac/aggregation.clusterrolebinding.yaml diff --git a/testdata/go/v4/memcached-operator/bundle/manifests/memcached-operator-aggregation-memcached-subrole_rbac.authorization.k8s.io_v1_clusterrole.yaml b/testdata/go/v4/memcached-operator/bundle/manifests/memcached-operator-aggregation-memcached-subrole_rbac.authorization.k8s.io_v1_clusterrole.yaml new file mode 100644 index 00000000000..49b0289f000 --- /dev/null +++ b/testdata/go/v4/memcached-operator/bundle/manifests/memcached-operator-aggregation-memcached-subrole_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -0,0 +1,14 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + labels: + rbac.example.memcached.com/aggregate-to-aggregation-memcached: "true" + name: memcached-operator-aggregation-memcached-subrole +rules: +- apiGroups: + - "" + resources: + - pods + verbs: + - update diff --git a/testdata/go/v4/memcached-operator/bundle/manifests/memcached-operator.clusterserviceversion.yaml b/testdata/go/v4/memcached-operator/bundle/manifests/memcached-operator.clusterserviceversion.yaml index e11f4c61ae5..e4ad144f496 100644 --- a/testdata/go/v4/memcached-operator/bundle/manifests/memcached-operator.clusterserviceversion.yaml +++ b/testdata/go/v4/memcached-operator/bundle/manifests/memcached-operator.clusterserviceversion.yaml @@ -58,6 +58,12 @@ spec: spec: clusterPermissions: - rules: + - apiGroups: + - "" + resources: + - pods + verbs: + - update - apiGroups: - "" resources: diff --git a/testdata/go/v4/memcached-operator/config/rbac/aggregation-subrole.clusterrole.yaml b/testdata/go/v4/memcached-operator/config/rbac/aggregation-subrole.clusterrole.yaml new file mode 100644 index 00000000000..cabcdd7d39d --- /dev/null +++ b/testdata/go/v4/memcached-operator/config/rbac/aggregation-subrole.clusterrole.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: aggregation-memcached-subrole + labels: + rbac.example.memcached.com/aggregate-to-aggregation-memcached: "true" +rules: + - apiGroups: + - "" + resources: + - pods + verbs: + - update diff --git a/testdata/go/v4/memcached-operator/config/rbac/aggregation.clusterrole.yaml b/testdata/go/v4/memcached-operator/config/rbac/aggregation.clusterrole.yaml new file mode 100644 index 00000000000..481524b1d72 --- /dev/null +++ b/testdata/go/v4/memcached-operator/config/rbac/aggregation.clusterrole.yaml @@ -0,0 +1,8 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: aggregation-memcached +aggregationRule: + clusterRoleSelectors: + - matchLabels: + rbac.example.memcached.com/aggregate-to-aggregation-memcached: "true" diff --git a/testdata/go/v4/memcached-operator/config/rbac/aggregation.clusterrolebinding.yaml b/testdata/go/v4/memcached-operator/config/rbac/aggregation.clusterrolebinding.yaml new file mode 100644 index 00000000000..f0f40600230 --- /dev/null +++ b/testdata/go/v4/memcached-operator/config/rbac/aggregation.clusterrolebinding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: aggregation-memcached +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: aggregation-memcached +subjects: + - kind: ServiceAccount + name: controller-manager + namespace: system diff --git a/testdata/go/v4/memcached-operator/config/rbac/kustomization.yaml b/testdata/go/v4/memcached-operator/config/rbac/kustomization.yaml index 1117168f18d..c9b9ff43951 100644 --- a/testdata/go/v4/memcached-operator/config/rbac/kustomization.yaml +++ b/testdata/go/v4/memcached-operator/config/rbac/kustomization.yaml @@ -25,4 +25,8 @@ resources: - memcached_admin_role.yaml - memcached_editor_role.yaml - memcached_viewer_role.yaml +- aggregation.clusterrolebinding.yaml +- aggregation-subrole.clusterrole.yaml +- aggregation.clusterrole.yaml + diff --git a/testdata/go/v4/monitoring/memcached-operator/bundle/manifests/memcached-operator-aggregation-memcached-subrole_rbac.authorization.k8s.io_v1_clusterrole.yaml b/testdata/go/v4/monitoring/memcached-operator/bundle/manifests/memcached-operator-aggregation-memcached-subrole_rbac.authorization.k8s.io_v1_clusterrole.yaml new file mode 100644 index 00000000000..49b0289f000 --- /dev/null +++ b/testdata/go/v4/monitoring/memcached-operator/bundle/manifests/memcached-operator-aggregation-memcached-subrole_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -0,0 +1,14 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + labels: + rbac.example.memcached.com/aggregate-to-aggregation-memcached: "true" + name: memcached-operator-aggregation-memcached-subrole +rules: +- apiGroups: + - "" + resources: + - pods + verbs: + - update diff --git a/testdata/go/v4/monitoring/memcached-operator/bundle/manifests/memcached-operator.clusterserviceversion.yaml b/testdata/go/v4/monitoring/memcached-operator/bundle/manifests/memcached-operator.clusterserviceversion.yaml index 404c08536c4..674a3664966 100644 --- a/testdata/go/v4/monitoring/memcached-operator/bundle/manifests/memcached-operator.clusterserviceversion.yaml +++ b/testdata/go/v4/monitoring/memcached-operator/bundle/manifests/memcached-operator.clusterserviceversion.yaml @@ -58,6 +58,12 @@ spec: spec: clusterPermissions: - rules: + - apiGroups: + - "" + resources: + - pods + verbs: + - update - apiGroups: - "" resources: diff --git a/testdata/go/v4/monitoring/memcached-operator/config/rbac/aggregation-subrole.clusterrole.yaml b/testdata/go/v4/monitoring/memcached-operator/config/rbac/aggregation-subrole.clusterrole.yaml new file mode 100644 index 00000000000..cabcdd7d39d --- /dev/null +++ b/testdata/go/v4/monitoring/memcached-operator/config/rbac/aggregation-subrole.clusterrole.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: aggregation-memcached-subrole + labels: + rbac.example.memcached.com/aggregate-to-aggregation-memcached: "true" +rules: + - apiGroups: + - "" + resources: + - pods + verbs: + - update diff --git a/testdata/go/v4/monitoring/memcached-operator/config/rbac/aggregation.clusterrole.yaml b/testdata/go/v4/monitoring/memcached-operator/config/rbac/aggregation.clusterrole.yaml new file mode 100644 index 00000000000..481524b1d72 --- /dev/null +++ b/testdata/go/v4/monitoring/memcached-operator/config/rbac/aggregation.clusterrole.yaml @@ -0,0 +1,8 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: aggregation-memcached +aggregationRule: + clusterRoleSelectors: + - matchLabels: + rbac.example.memcached.com/aggregate-to-aggregation-memcached: "true" diff --git a/testdata/go/v4/monitoring/memcached-operator/config/rbac/aggregation.clusterrolebinding.yaml b/testdata/go/v4/monitoring/memcached-operator/config/rbac/aggregation.clusterrolebinding.yaml new file mode 100644 index 00000000000..f0f40600230 --- /dev/null +++ b/testdata/go/v4/monitoring/memcached-operator/config/rbac/aggregation.clusterrolebinding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: aggregation-memcached +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: aggregation-memcached +subjects: + - kind: ServiceAccount + name: controller-manager + namespace: system diff --git a/testdata/go/v4/monitoring/memcached-operator/config/rbac/kustomization.yaml b/testdata/go/v4/monitoring/memcached-operator/config/rbac/kustomization.yaml index 05ec94bb578..a813a454e1b 100644 --- a/testdata/go/v4/monitoring/memcached-operator/config/rbac/kustomization.yaml +++ b/testdata/go/v4/monitoring/memcached-operator/config/rbac/kustomization.yaml @@ -27,4 +27,8 @@ resources: - memcached_admin_role.yaml - memcached_editor_role.yaml - memcached_viewer_role.yaml +- aggregation.clusterrolebinding.yaml +- aggregation-subrole.clusterrole.yaml +- aggregation.clusterrole.yaml +