Skip to content

Commit a3a6bcc

Browse files
author
Eric Stroczynski
authored
[v1.8.x] fix(generate): exclude ServiceAccounts in the CSV from generated bundle (#5126)
Cherry-pick of #5120 Signed-off-by: Eric Stroczynski <ericstroczynski@gmail.com>
1 parent 679e456 commit a3a6bcc

File tree

8 files changed

+39
-42
lines changed

8 files changed

+39
-42
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
entries:
2+
- description: >
3+
In `generate bundle`, exclude ServiceAccounts already in a CSV from generated bundle.
4+
kind: bugfix

internal/cmd/operator-sdk/generate/internal/manifests.go

+1-18
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,6 @@ func GetManifestObjects(c *collector.Manifests, extraSAs []string) (objs []clien
3131
objs = append(objs, &c.V1beta1CustomResourceDefinitions[i])
3232
}
3333

34-
// All ServiceAccounts passed in should be written.
35-
saSet := make(map[string]struct{}, len(extraSAs))
36-
for _, saName := range extraSAs {
37-
saSet[saName] = struct{}{}
38-
}
39-
for i := range c.ServiceAccounts {
40-
sa := c.ServiceAccounts[i]
41-
saSet[sa.GetName()] = struct{}{}
42-
objs = append(objs, &sa)
43-
}
44-
extraSAs = make([]string, len(saSet))
45-
i := 0
46-
for saName := range saSet {
47-
extraSAs[i] = saName
48-
i++
49-
}
50-
5134
// All Services passed in should be written.
5235
for i := range c.Services {
5336
objs = append(objs, &c.Services[i])
@@ -61,7 +44,7 @@ func GetManifestObjects(c *collector.Manifests, extraSAs []string) (objs []clien
6144
}
6245
}
6346

64-
// RBAC objects that are not a part of the CSV should be written.
47+
// RBAC objects (including ServiceAccounts) that are not a part of the CSV should be written.
6548
_, _, rbacObjs := c.SplitCSVPermissionsObjects(extraSAs)
6649
objs = append(objs, rbacObjs...)
6750

internal/generate/clusterserviceversion/clusterserviceversion_updaters_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ var _ = Describe("findMatchingDeploymentAndServiceForWebhook", func() {
379379
port1 := new(int32)
380380
*port1 = 2311
381381
crdToConfigPath := map[string]apiextv1.WebhookConversion{
382-
"crd-test-1": apiextv1.WebhookConversion{
382+
"crd-test-1": {
383383
ClientConfig: &apiextv1.WebhookClientConfig{
384384
Service: &apiextv1.ServiceReference{
385385
Path: &path1,
@@ -388,7 +388,7 @@ var _ = Describe("findMatchingDeploymentAndServiceForWebhook", func() {
388388
},
389389
},
390390

391-
"crd-test-2": apiextv1.WebhookConversion{
391+
"crd-test-2": {
392392
ClientConfig: &apiextv1.WebhookClientConfig{
393393
Service: &apiextv1.ServiceReference{
394394
Path: &path1,

internal/generate/collector/clusterserviceversion.go

+14-6
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,16 @@ const (
3838
// are added to out. Any bindings with some associations, but with non-associations, are added to out unmodified.
3939
func (c *Manifests) SplitCSVPermissionsObjects(extraSAs []string) (inPerms, inCPerms, out []client.Object) {
4040
// Create a set of ServiceAccount names to match against below.
41-
saNameSet := make(map[string]struct{})
41+
csvSAs := make(map[string]struct{})
4242
for _, dep := range c.Deployments {
4343
saName := dep.Spec.Template.Spec.ServiceAccountName
4444
if saName == "" {
4545
saName = defaultServiceAccountName
4646
}
47-
saNameSet[saName] = struct{}{}
47+
csvSAs[saName] = struct{}{}
4848
}
4949
for _, extraSA := range extraSAs {
50-
saNameSet[extraSA] = struct{}{}
50+
csvSAs[extraSA] = struct{}{}
5151
}
5252

5353
// Construct sets for lookups.
@@ -86,9 +86,9 @@ func (c *Manifests) SplitCSVPermissionsObjects(extraSAs []string) (inPerms, inCP
8686
// bound Subjects from partial bindings to easily find concrete bindings that bind non-CSV RBAC.
8787
// Those with no Subjects left will be removed from the partial binding lists; their concrete counterparts should
8888
// be added to out.
89-
inRoleNames := pRoleBindings.getRolesBoundToPartialBindings(roleKind, roleNameMap, saNameSet)
90-
inCRoleNamesNScope := pRoleBindings.getRolesBoundToPartialBindings(cRoleKind, cRoleNameMap, saNameSet)
91-
inCRoleNamesCScope := pCRoleBindings.getRolesBoundToPartialBindings(cRoleKind, cRoleNameMap, saNameSet)
89+
inRoleNames := pRoleBindings.getRolesBoundToPartialBindings(roleKind, roleNameMap, csvSAs)
90+
inCRoleNamesNScope := pRoleBindings.getRolesBoundToPartialBindings(cRoleKind, cRoleNameMap, csvSAs)
91+
inCRoleNamesCScope := pCRoleBindings.getRolesBoundToPartialBindings(cRoleKind, cRoleNameMap, csvSAs)
9292

9393
// Add {Cluster}Roles bound to a ServiceAccount to either namespace- or cluster-scoped permission sets.
9494
for _, roleName := range inRoleNames {
@@ -120,6 +120,14 @@ func (c *Manifests) SplitCSVPermissionsObjects(extraSAs []string) (inPerms, inCP
120120
out = append(out, cRoleBindingMap[pBinding.Name])
121121
}
122122

123+
// All ServiceAccounts not in the CSV should be in out.
124+
for i := range c.ServiceAccounts {
125+
sa := c.ServiceAccounts[i]
126+
if _, csvHasSA := csvSAs[sa.Name]; !csvHasSA {
127+
out = append(out, &sa)
128+
}
129+
}
130+
123131
return inPerms, inCPerms, out
124132
}
125133

internal/generate/collector/clusterserviceversion_test.go

+18-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
. "github.com/onsi/ginkgo"
2222
. "github.com/onsi/gomega"
2323
appsv1 "k8s.io/api/apps/v1"
24+
corev1 "k8s.io/api/core/v1"
2425
rbacv1 "k8s.io/api/rbac/v1"
2526
"sigs.k8s.io/controller-runtime/pkg/client"
2627
)
@@ -160,6 +161,10 @@ var _ = Describe("SplitCSVPermissionsObjects", func() {
160161

161162
complexTestSetup := func() {
162163
c.Deployments = []appsv1.Deployment{newDeploymentWithServiceAccount(depSA)}
164+
c.ServiceAccounts = []corev1.ServiceAccount{
165+
newServiceAccount(depSA),
166+
newServiceAccount(extraSA),
167+
}
163168
role1, role2 := newRole(roleName1), newRole(roleName2)
164169
c.Roles = []rbacv1.Role{role1, role2}
165170
// Use the same names as for Roles to make sure Kind is respected
@@ -198,12 +203,14 @@ var _ = Describe("SplitCSVPermissionsObjects", func() {
198203
Expect(getClusterRoleNames(inPerm)).To(Equal([]string{roleName1}))
199204
Expect(inCPerm).To(HaveLen(1))
200205
Expect(getClusterRoleNames(inCPerm)).To(Equal([]string{roleName1}))
201-
Expect(out).To(HaveLen(5))
206+
Expect(out).To(HaveLen(6))
202207
Expect(getRoleNames(out)).To(Equal([]string{roleName2}))
203208
Expect(getClusterRoleNames(out)).To(Equal([]string{roleName2}))
204209
Expect(getRoleBindingNames(out)).To(Equal([]string{bindingName1, bindingName2}))
205210
Expect(getClusterRoleBindingNames(out)).To(Equal([]string{bindingName2}))
211+
Expect(getServiceAccountNames(out)).To(Equal([]string{extraSA}))
206212
})
213+
207214
It("contains a Deployment serviceAccountName and extra ServiceAccount", func() {
208215
complexTestSetup()
209216
inPerm, inCPerm, out = c.SplitCSVPermissionsObjects([]string{extraSA})
@@ -233,6 +240,10 @@ func getClusterRoleBindingNames(objs []client.Object) []string {
233240
return getNamesForKind("ClusterRoleBinding", objs)
234241
}
235242

243+
func getServiceAccountNames(objs []client.Object) []string {
244+
return getNamesForKind("ServiceAccount", objs)
245+
}
246+
236247
func getNamesForKind(kind string, objs []client.Object) (names []string) {
237248
for _, obj := range objs {
238249
if obj.GetObjectKind().GroupVersionKind().Kind == kind {
@@ -300,3 +311,9 @@ func newSubject(name, kind string) (s rbacv1.Subject) {
300311
func newServiceAccountSubject(name string) (s rbacv1.Subject) {
301312
return newSubject(name, "ServiceAccount")
302313
}
314+
315+
func newServiceAccount(name string) (sa corev1.ServiceAccount) {
316+
sa.SetGroupVersionKind(corev1.SchemeGroupVersion.WithKind("ServiceAccount"))
317+
sa.Name = name
318+
return sa
319+
}

testdata/ansible/memcached-operator/bundle/manifests/memcached-operator-controller-manager_v1_serviceaccount.yaml

-5
This file was deleted.

testdata/go/v3/memcached-operator/bundle/manifests/memcached-operator-controller-manager_v1_serviceaccount.yaml

-5
This file was deleted.

testdata/helm/memcached-operator/bundle/manifests/memcached-operator-controller-manager_v1_serviceaccount.yaml

-5
This file was deleted.

0 commit comments

Comments
 (0)