Skip to content

Commit 4f24776

Browse files
authored
Default release namespace for namespaced rbac (#579)
* Default to release namespace for namespaced rbac * spacing fix * comments * parenthesis fix * spacing * remove comments * simplify * comments * spacing * dash fix * more than one listed resource needed * changelog * changelog * changelog * codegen * Set resourcesToNamespaces correctly so that --secret-namespaces flag can be set correctly * fix * remove * Add test for namespaced-rbac rendering
1 parent 1b81dd0 commit 4f24776

14 files changed

+476
-176
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
changelog:
2+
- type: NEW_FEATURE
3+
description: "If namespacedRbac.namespaces is an empty list but namespacedRbac.resources is not, we will use a sane default of the Release.Namespace instead of ignoring the namespacedRbac.resources input."
4+
issueLink: https://github.com/solo-io/gloo-mesh-enterprise/issues/15739

codegen/cmd_test.go

+80-15
Original file line numberDiff line numberDiff line change
@@ -3217,10 +3217,39 @@ roleRef:
32173217
cmd := &Command{
32183218
RenderProtos: false,
32193219
Chart: &Chart{
3220+
Data: Data{
3221+
ApiVersion: "v1",
3222+
Description: "",
3223+
Name: "Painting Operator",
3224+
Version: "v0.0.1",
3225+
Home: "https://docs.solo.io/skv2/latest",
3226+
Sources: []string{
3227+
"https://github.com/solo-io/skv2",
3228+
},
3229+
},
32203230
Operators: []Operator{
32213231
{
32223232
Name: "painter",
32233233
CustomEnableCondition: "$painter.enabled",
3234+
Deployment: Deployment{
3235+
Container: Container{
3236+
Image: Image{
3237+
Tag: "v0.0.0",
3238+
Repository: "painter",
3239+
Registry: "quay.io/solo-io",
3240+
PullPolicy: "IfNotPresent",
3241+
},
3242+
},
3243+
},
3244+
Values: map[string]any{
3245+
"painter": map[string]any{
3246+
"enabled": true,
3247+
"namespacedRbac": map[string]any{
3248+
"resources": []string{"secrets"},
3249+
"namespaces": []string{},
3250+
},
3251+
},
3252+
},
32243253
ClusterRbac: []rbacv1.PolicyRule{
32253254
{
32263255
Verbs: []string{"GET"},
@@ -3235,26 +3264,14 @@ roleRef:
32353264
},
32363265
},
32373266
},
3238-
},
3239-
},
3240-
Values: nil,
3241-
Data: Data{
3242-
ApiVersion: "v1",
3243-
Description: "",
3244-
Name: "Painting Operator",
3245-
Version: "v0.0.1",
3246-
Home: "https://docs.solo.io/skv2/latest",
3247-
Sources: []string{
3248-
"https://github.com/solo-io/skv2",
3249-
},
3250-
},
3267+
}},
32513268
},
3252-
ManifestRoot: "codegen/test/chart",
3269+
ManifestRoot: "codegen/test/chart/namespaced-rbac",
32533270
}
32543271

32553272
Expect(cmd.Execute()).NotTo(HaveOccurred(), "failed to execute command")
32563273

3257-
absPath, err := filepath.Abs("./codegen/test/chart/templates/rbac.yaml")
3274+
absPath, err := filepath.Abs("./codegen/test/chart/namespaced-rbac/templates/rbac.yaml")
32583275
Expect(err).NotTo(HaveOccurred(), "failed to get abs path")
32593276

32603277
rbac, err := os.ReadFile(absPath)
@@ -3358,6 +3375,54 @@ roleRef:
33583375
Expect(string(rbac)).To(ContainSubstring(clusterRoleBinding2Tmpl))
33593376
Expect(string(rbac)).To(ContainSubstring(roleTmpl))
33603377
Expect(string(rbac)).To(ContainSubstring(roleBindingTmpl))
3378+
3379+
helmValues := map[string]interface{}{
3380+
"painter": map[string]any{
3381+
"enabled": true,
3382+
"namespacedRbac": []any{
3383+
map[string]any{
3384+
"resources": []string{"secrets"},
3385+
"namespaces": []string{},
3386+
},
3387+
},
3388+
},
3389+
}
3390+
renderedManifests := helmTemplate("codegen/test/chart/namespaced-rbac", helmValues)
3391+
renderedRole := `
3392+
kind: Role
3393+
apiVersion: rbac.authorization.k8s.io/v1
3394+
metadata:
3395+
name: painter-release-name-default-namespaced
3396+
namespace: default
3397+
labels:
3398+
app: painter
3399+
rules:
3400+
- apiGroups:
3401+
- ""
3402+
resources:
3403+
- secrets
3404+
verbs:
3405+
- GET
3406+
- LIST
3407+
- WATCH`
3408+
renderedRoleBinding := `
3409+
kind: RoleBinding
3410+
apiVersion: rbac.authorization.k8s.io/v1
3411+
metadata:
3412+
name: painter-release-name-default-namespaced
3413+
namespace: default
3414+
labels:
3415+
app: painter
3416+
subjects:
3417+
- kind: ServiceAccount
3418+
name: painter
3419+
namespace: default
3420+
roleRef:
3421+
kind: Role
3422+
name: painter-release-name-default-namespaced
3423+
apiGroup: rbac.authorization.k8s.io`
3424+
Expect(string(renderedManifests)).To(ContainSubstring(renderedRole))
3425+
Expect(string(renderedManifests)).To(ContainSubstring(renderedRoleBinding))
33613426
})
33623427
})
33633428

codegen/templates/chart/operator-rbac.yamltmpl

+5
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ Prefixed with '#' to avoid printing variable values in yaml, per https://github.
9191
[[- end ]]
9292

9393
{{- range $entry := $[[ $operatorVar ]].namespacedRbac }}
94+
[[- /* If resources were chosen but no namespaces were chosen, default to restricting those resources to the Release.Namespace. */]]
95+
{{- if and (eq (len $entry.namespaces) 0) (ge (len $entry.resources) 1) }}
96+
{{- set $[[ $operatorVar ]]NsToResources $.Release.Namespace ($entry.resources | mustUniq) }}
97+
{{- end }}
98+
[[- /* Otherwise, iterate through each of the namespaces and resources listed */]]
9499
{{- range $ns := $entry.namespaces }}
95100
{{- set $[[ $operatorVar ]]NsToResources $ns (concat $entry.resources (get $[[ $operatorVar ]]NsToResources $ns | default list) | mustUniq) }}
96101
{{- end }}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Code generated by skv2. DO NOT EDIT.
2+
3+
apiVersion: v1
4+
home: https://docs.solo.io/skv2/latest
5+
name: Painting Operator
6+
sources:
7+
- https://github.com/solo-io/skv2
8+
version: v0.0.1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Code generated by skv2. DO NOT EDIT.
2+
3+
4+
5+
{{/* Below are library functions provided by skv2 */}}
6+
7+
{{- /*
8+
9+
"skv2.utils.merge" takes an array of three values:
10+
- the top context
11+
- the yaml block that will be merged in (override)
12+
- the name of the base template (source)
13+
14+
note: the source must be a named template (helm partial). This is necessary for the merging logic.
15+
16+
The behaviour is as follows, to align with already existing helm behaviour:
17+
- If no source is found (template is empty), the merged output will be empty
18+
- If no overrides are specified, the source is rendered as is
19+
- If overrides are specified and source is not empty, overrides will be merged in to the source.
20+
21+
Overrides can replace / add to deeply nested dictionaries, but will completely replace lists.
22+
Examples:
23+
24+
┌─────────────────────┬───────────────────────┬────────────────────────┐
25+
│ Source (template) │ Overrides │ Result │
26+
├─────────────────────┼───────────────────────┼────────────────────────┤
27+
│ metadata: │ metadata: │ metadata: │
28+
│ labels: │ labels: │ labels: │
29+
│ app: gloo │ app: gloo1 │ app: gloo1 │
30+
│ cluster: useast │ author: infra-team │ author: infra-team │
31+
│ │ │ cluster: useast │
32+
├─────────────────────┼───────────────────────┼────────────────────────┤
33+
│ lists: │ lists: │ lists: │
34+
│ groceries: │ groceries: │ groceries: │
35+
│ - apple │ - grapes │ - grapes │
36+
│ - banana │ │ │
37+
└─────────────────────┴───────────────────────┴────────────────────────┘
38+
39+
skv2.utils.merge is a fork of a helm library chart function (https://github.com/helm/charts/blob/master/incubator/common/templates/_util.tpl).
40+
This includes some optimizations to speed up chart rendering time, and merges in a value (overrides) with a named template, unlike the upstream
41+
version, which merges two named templates.
42+
43+
*/ -}}
44+
{{- define "skv2.utils.merge" -}}
45+
{{- $top := first . -}}
46+
{{- $overrides := (index . 1) -}}
47+
{{- $tpl := fromYaml (include (index . 2) $top) -}}
48+
{{- if or (empty $overrides) (empty $tpl) -}}
49+
{{ include (index . 2) $top }} {{/* render source as is */}}
50+
{{- else -}}
51+
{{- $merged := merge $overrides $tpl -}}
52+
{{- toYaml $merged -}} {{/* render source with overrides as YAML */}}
53+
{{- end -}}
54+
{{- end -}}
55+
56+
{{- define "painter.namespacesForResource" }}
57+
{{- $resourcesToNamespaces := dict }}
58+
{{- range $entry := $.Values.painter.namespacedRbac }}
59+
{{- range $resource := $entry.resources }}
60+
{{- $_ := set $resourcesToNamespaces $resource (concat $entry.namespaces (get $resourcesToNamespaces $resource | default list) | mustUniq) }}
61+
{{- end }}
62+
{{- end }}
63+
{{- get $resourcesToNamespaces .Resource | join "," }}
64+
{{- end }}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# Code generated by skv2. DO NOT EDIT.
2+
3+
4+
5+
{{- $painter := $.Values.painter }}
6+
---
7+
8+
{{- define "painter.deploymentSpec" }}
9+
# Deployment manifest for painter
10+
11+
apiVersion: apps/v1
12+
kind: Deployment
13+
metadata:
14+
labels:
15+
app: painter
16+
annotations:
17+
app.kubernetes.io/name: painter
18+
name: painter
19+
namespace: {{ default .Release.Namespace $.Values.painter.namespace }}
20+
spec:
21+
selector:
22+
matchLabels:
23+
app: painter
24+
template:
25+
metadata:
26+
labels:
27+
app: painter
28+
annotations:
29+
app.kubernetes.io/name: painter
30+
spec:
31+
serviceAccountName: painter
32+
{{- /* Override the default podSecurityContext config if it is set. */}}
33+
{{- if or ($.Values.painter.podSecurityContext) (eq "map[]" (printf "%v" $.Values.painter.podSecurityContext)) }}
34+
securityContext:
35+
{{ toYaml $.Values.painter.podSecurityContext | indent 8 }}
36+
{{- end }}
37+
containers:
38+
{{- $painter := $.Values.painter }}
39+
{{- $painterImage := $painter.image }}
40+
- name: painter
41+
image: {{ $painterImage.registry }}/{{ $painterImage.repository }}:{{ $painterImage.tag }}
42+
imagePullPolicy: {{ $painterImage.pullPolicy }}
43+
{{- if or $painter.env $painter.extraEnvs }}
44+
env:
45+
{{- end }}
46+
{{- if $painter.env }}
47+
{{- toYaml $painter.env | nindent 10 }}
48+
{{- end }}
49+
{{- range $name, $item := $painter.extraEnvs }}
50+
- name: {{ $name }}
51+
{{- $item | toYaml | nindent 12 }}
52+
{{- end }}
53+
resources:
54+
{{- if $painter.resources }}
55+
{{ toYaml $painter.resources | indent 10}}
56+
{{- else}}
57+
requests:
58+
cpu: 500m
59+
memory: 256Mi
60+
{{- end }}
61+
{{- /*
62+
Render securityContext configs if it is set.
63+
If securityContext is not set, render the default securityContext.
64+
If securityContext is set to 'false', render an empty map.
65+
*/}}
66+
securityContext:
67+
{{- if or ($painter.securityContext) (eq "map[]" (printf "%v" $painter.securityContext)) }}
68+
{{ toYaml $painter.securityContext | indent 10}}
69+
{{/* Because securityContext is nil by default we can only perform following conversion if it is a boolean. Skip conditional otherwise. */}}
70+
{{- else if eq (ternary $painter.securityContext true (eq "bool" (printf "%T" $painter.securityContext))) false }}
71+
{}
72+
{{- else}}
73+
runAsNonRoot: true
74+
{{- if not $painter.floatingUserId }}
75+
runAsUser: {{ printf "%.0f" (float64 $painter.runAsUser) }}
76+
{{- end }}
77+
readOnlyRootFilesystem: true
78+
allowPrivilegeEscalation: false
79+
capabilities:
80+
drop:
81+
- ALL
82+
{{- end }}
83+
{{- $pullSecrets := (list) -}}
84+
{{- if $painterImage.pullSecret }}
85+
{{- $pullSecrets = concat $pullSecrets (list (dict "name" $painterImage.pullSecret)) -}}
86+
{{- end }}
87+
{{- if $painter.imagePullSecrets }}
88+
{{- $pullSecrets = concat $pullSecrets $painter.imagePullSecrets -}}
89+
{{- end }}
90+
{{- if gt (len $pullSecrets) 0 -}}
91+
{{- (dict "imagePullSecrets" $pullSecrets) | toYaml | nindent 6 }}
92+
{{- end }}
93+
{{- end }} {{/* define "painter.deploymentSpec" */}}
94+
95+
{{/* Render painter deployment template with overrides from values*/}}
96+
{{ if $painter.enabled }}
97+
{{- $painterDeploymentOverrides := dict }}
98+
{{- if $painter.deploymentOverrides }}
99+
{{- $painterDeploymentOverrides = $painter.deploymentOverrides }}
100+
{{- end }}
101+
---
102+
{{ include "skv2.utils.merge" (list . $painterDeploymentOverrides "painter.deploymentSpec") }}
103+
{{- end }}
104+
---
105+
{{ if $painter.enabled }}
106+
apiVersion: v1
107+
kind: ServiceAccount
108+
metadata:
109+
labels:
110+
app: painter
111+
{{- if $painter.serviceAccount}}
112+
{{- if $painter.serviceAccount.extraAnnotations }}
113+
annotations:
114+
{{- range $key, $value := $painter.serviceAccount.extraAnnotations }}
115+
{{ $key }}: {{ $value }}
116+
{{- end }}
117+
{{- end }}
118+
{{- end}}
119+
name: painter
120+
namespace: {{ default .Release.Namespace $.Values.painter.namespace }}
121+
{{- end }}
122+
123+
124+
{{- define "painter.serviceSpec"}}
125+
126+
{{- end }} {{/* define "painter.serviceSpec" */}}
127+
{{ if $painter.enabled }}
128+
{{/* Render painter service template with overrides from values*/}}
129+
{{- $painterServiceOverrides := dict }}
130+
{{- if $painter.serviceOverrides }}
131+
{{- $painterServiceOverrides = $painter.serviceOverrides }}
132+
{{- end }}
133+
134+
---
135+
136+
{{ include "skv2.utils.merge" (list . $painterServiceOverrides "painter.serviceSpec") }}
137+
{{- end }}
138+

0 commit comments

Comments
 (0)