1
16
17 package bootstrappolicy
18
19 import (
20 "strings"
21
22 "k8s.io/klog/v2"
23
24 capi "k8s.io/api/certificates/v1beta1"
25 rbacv1 "k8s.io/api/rbac/v1"
26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27 genericfeatures "k8s.io/apiserver/pkg/features"
28 utilfeature "k8s.io/apiserver/pkg/util/feature"
29 rbacv1helpers "k8s.io/kubernetes/pkg/apis/rbac/v1"
30 "k8s.io/kubernetes/pkg/controlplane/controller/legacytokentracking"
31 "k8s.io/kubernetes/pkg/features"
32 )
33
34 const saRolePrefix = "system:controller:"
35
36 func addControllerRole(controllerRoles *[]rbacv1.ClusterRole, controllerRoleBindings *[]rbacv1.ClusterRoleBinding, role rbacv1.ClusterRole) {
37 if !strings.HasPrefix(role.Name, saRolePrefix) {
38 klog.Fatalf(`role %q must start with %q`, role.Name, saRolePrefix)
39 }
40
41 for _, existingRole := range *controllerRoles {
42 if role.Name == existingRole.Name {
43 klog.Fatalf("role %q was already registered", role.Name)
44 }
45 }
46
47 *controllerRoles = append(*controllerRoles, role)
48 addClusterRoleLabel(*controllerRoles)
49
50 *controllerRoleBindings = append(*controllerRoleBindings,
51 rbacv1helpers.NewClusterBinding(role.Name).SAs("kube-system", role.Name[len(saRolePrefix):]).BindingOrDie())
52 addClusterRoleBindingLabel(*controllerRoleBindings)
53 }
54
55 func eventsRule() rbacv1.PolicyRule {
56 return rbacv1helpers.NewRule("create", "update", "patch").Groups(legacyGroup, eventsGroup).Resources("events").RuleOrDie()
57 }
58
59 func buildControllerRoles() ([]rbacv1.ClusterRole, []rbacv1.ClusterRoleBinding) {
60
61 controllerRoles := []rbacv1.ClusterRole{}
62
63 controllerRoleBindings := []rbacv1.ClusterRoleBinding{}
64
65 addControllerRole(&controllerRoles, &controllerRoleBindings, func() rbacv1.ClusterRole {
66 role := rbacv1.ClusterRole{
67 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "attachdetach-controller"},
68 Rules: []rbacv1.PolicyRule{
69 rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("persistentvolumes", "persistentvolumeclaims").RuleOrDie(),
70 rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
71 rbacv1helpers.NewRule("patch", "update").Groups(legacyGroup).Resources("nodes/status").RuleOrDie(),
72 rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
73 eventsRule(),
74 rbacv1helpers.NewRule("get", "create", "delete", "list", "watch").Groups(storageGroup).Resources("volumeattachments").RuleOrDie(),
75 },
76 }
77
78 role.Rules = append(role.Rules, rbacv1helpers.NewRule("get", "watch", "list").Groups("storage.k8s.io").Resources("csidrivers").RuleOrDie())
79 role.Rules = append(role.Rules, rbacv1helpers.NewRule("get", "watch", "list").Groups("storage.k8s.io").Resources("csinodes").RuleOrDie())
80
81 return role
82 }())
83
84 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
85 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "clusterrole-aggregation-controller"},
86 Rules: []rbacv1.PolicyRule{
87
88 rbacv1helpers.NewRule("escalate", "get", "list", "watch", "update", "patch").Groups(rbacGroup).Resources("clusterroles").RuleOrDie(),
89 },
90 })
91 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
92 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "cronjob-controller"},
93 Rules: []rbacv1.PolicyRule{
94 rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(batchGroup).Resources("cronjobs").RuleOrDie(),
95 rbacv1helpers.NewRule("get", "list", "watch", "create", "update", "delete", "patch").Groups(batchGroup).Resources("jobs").RuleOrDie(),
96 rbacv1helpers.NewRule("update").Groups(batchGroup).Resources("cronjobs/status").RuleOrDie(),
97 rbacv1helpers.NewRule("update").Groups(batchGroup).Resources("cronjobs/finalizers").RuleOrDie(),
98 rbacv1helpers.NewRule("list", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
99 eventsRule(),
100 },
101 })
102 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
103 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "daemon-set-controller"},
104 Rules: []rbacv1.PolicyRule{
105 rbacv1helpers.NewRule("get", "list", "watch").Groups(extensionsGroup, appsGroup).Resources("daemonsets").RuleOrDie(),
106 rbacv1helpers.NewRule("update").Groups(extensionsGroup, appsGroup).Resources("daemonsets/status").RuleOrDie(),
107 rbacv1helpers.NewRule("update").Groups(extensionsGroup, appsGroup).Resources("daemonsets/finalizers").RuleOrDie(),
108 rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
109 rbacv1helpers.NewRule("list", "watch", "create", "delete", "patch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
110 rbacv1helpers.NewRule("create").Groups(legacyGroup).Resources("pods/binding").RuleOrDie(),
111 rbacv1helpers.NewRule("get", "list", "watch", "create", "delete", "update", "patch").Groups(appsGroup).Resources("controllerrevisions").RuleOrDie(),
112 eventsRule(),
113 },
114 })
115 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
116 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "deployment-controller"},
117 Rules: []rbacv1.PolicyRule{
118 rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(extensionsGroup, appsGroup).Resources("deployments").RuleOrDie(),
119 rbacv1helpers.NewRule("update").Groups(extensionsGroup, appsGroup).Resources("deployments/status").RuleOrDie(),
120 rbacv1helpers.NewRule("update").Groups(extensionsGroup, appsGroup).Resources("deployments/finalizers").RuleOrDie(),
121 rbacv1helpers.NewRule("get", "list", "watch", "create", "update", "patch", "delete").Groups(appsGroup, extensionsGroup).Resources("replicasets").RuleOrDie(),
122
123
124 rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("pods").RuleOrDie(),
125 eventsRule(),
126 },
127 })
128 addControllerRole(&controllerRoles, &controllerRoleBindings, func() rbacv1.ClusterRole {
129 role := rbacv1.ClusterRole{
130 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "disruption-controller"},
131 Rules: []rbacv1.PolicyRule{
132 rbacv1helpers.NewRule("get", "list", "watch").Groups(extensionsGroup, appsGroup).Resources("deployments").RuleOrDie(),
133 rbacv1helpers.NewRule("get", "list", "watch").Groups(appsGroup, extensionsGroup).Resources("replicasets").RuleOrDie(),
134 rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("replicationcontrollers").RuleOrDie(),
135 rbacv1helpers.NewRule("get", "list", "watch").Groups(policyGroup).Resources("poddisruptionbudgets").RuleOrDie(),
136 rbacv1helpers.NewRule("get", "list", "watch").Groups(appsGroup).Resources("statefulsets").RuleOrDie(),
137 rbacv1helpers.NewRule("update").Groups(policyGroup).Resources("poddisruptionbudgets/status").RuleOrDie(),
138 rbacv1helpers.NewRule("get").Groups("*").Resources("*/scale").RuleOrDie(),
139 eventsRule(),
140 },
141 }
142 if utilfeature.DefaultFeatureGate.Enabled(features.PodDisruptionConditions) {
143 role.Rules = append(role.Rules, rbacv1helpers.NewRule("patch", "update").Groups(legacyGroup).Resources("pods/status").RuleOrDie())
144 }
145 return role
146 }())
147 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
148 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "endpoint-controller"},
149 Rules: []rbacv1.PolicyRule{
150 rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("services", "pods").RuleOrDie(),
151 rbacv1helpers.NewRule("get", "list", "create", "update", "delete").Groups(legacyGroup).Resources("endpoints").RuleOrDie(),
152 rbacv1helpers.NewRule("create").Groups(legacyGroup).Resources("endpoints/restricted").RuleOrDie(),
153 eventsRule(),
154 },
155 })
156
157 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
158 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "endpointslice-controller"},
159 Rules: []rbacv1.PolicyRule{
160 rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("services", "pods", "nodes").RuleOrDie(),
161
162
163 rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("services/finalizers").RuleOrDie(),
164 rbacv1helpers.NewRule("get", "list", "create", "update", "delete").Groups(discoveryGroup).Resources("endpointslices").RuleOrDie(),
165 eventsRule(),
166 },
167 })
168
169 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
170 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "endpointslicemirroring-controller"},
171 Rules: []rbacv1.PolicyRule{
172 rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("services", "endpoints").RuleOrDie(),
173
174
175 rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("services/finalizers").RuleOrDie(),
176
177
178
179 rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("endpoints/finalizers").RuleOrDie(),
180 rbacv1helpers.NewRule("get", "list", "create", "update", "delete").Groups(discoveryGroup).Resources("endpointslices").RuleOrDie(),
181 eventsRule(),
182 },
183 })
184
185 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
186 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "expand-controller"},
187 Rules: []rbacv1.PolicyRule{
188 rbacv1helpers.NewRule("get", "list", "watch", "update", "patch").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
189 rbacv1helpers.NewRule("update", "patch").Groups(legacyGroup).Resources("persistentvolumeclaims/status").RuleOrDie(),
190 rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
191
192 rbacv1helpers.NewRule("get", "list", "watch").Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
193 rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("services", "endpoints").RuleOrDie(),
194 rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("secrets").RuleOrDie(),
195 eventsRule(),
196 },
197 })
198
199 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
200 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "ephemeral-volume-controller"},
201 Rules: []rbacv1.PolicyRule{
202 rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
203 rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("pods/finalizers").RuleOrDie(),
204 rbacv1helpers.NewRule("get", "list", "watch", "create").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
205 eventsRule(),
206 },
207 })
208
209 if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) {
210 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
211 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "resource-claim-controller"},
212 Rules: []rbacv1.PolicyRule{
213 rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
214 rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("pods/finalizers").RuleOrDie(),
215 rbacv1helpers.NewRule("get", "list", "watch", "create", "delete").Groups(resourceGroup).Resources("resourceclaims").RuleOrDie(),
216 rbacv1helpers.NewRule("get", "list", "watch", "create", "update", "patch").Groups(resourceGroup).Resources("podschedulingcontexts").RuleOrDie(),
217 rbacv1helpers.NewRule("update", "patch").Groups(resourceGroup).Resources("resourceclaims", "resourceclaims/status").RuleOrDie(),
218 rbacv1helpers.NewRule("update", "patch").Groups(legacyGroup).Resources("pods/status").RuleOrDie(),
219 eventsRule(),
220 },
221 })
222 }
223
224 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
225 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "generic-garbage-collector"},
226 Rules: []rbacv1.PolicyRule{
227
228 rbacv1helpers.NewRule("get", "list", "watch", "patch", "update", "delete").Groups("*").Resources("*").RuleOrDie(),
229 eventsRule(),
230 },
231 })
232 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
233 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "horizontal-pod-autoscaler"},
234 Rules: []rbacv1.PolicyRule{
235 rbacv1helpers.NewRule("get", "list", "watch").Groups(autoscalingGroup).Resources("horizontalpodautoscalers").RuleOrDie(),
236 rbacv1helpers.NewRule("update").Groups(autoscalingGroup).Resources("horizontalpodautoscalers/status").RuleOrDie(),
237 rbacv1helpers.NewRule("get", "update").Groups("*").Resources("*/scale").RuleOrDie(),
238 rbacv1helpers.NewRule("list").Groups(legacyGroup).Resources("pods").RuleOrDie(),
239
240 rbacv1helpers.NewRule("list").Groups(resMetricsGroup).Resources("pods").RuleOrDie(),
241 rbacv1helpers.NewRule("get", "list").Groups(customMetricsGroup).Resources("*").RuleOrDie(),
242 rbacv1helpers.NewRule("get", "list").Groups(externalMetricsGroup).Resources("*").RuleOrDie(),
243 eventsRule(),
244 },
245 })
246 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
247 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "job-controller"},
248 Rules: []rbacv1.PolicyRule{
249 rbacv1helpers.NewRule("get", "list", "watch", "update", "patch").Groups(batchGroup).Resources("jobs").RuleOrDie(),
250 rbacv1helpers.NewRule("update").Groups(batchGroup).Resources("jobs/status").RuleOrDie(),
251 rbacv1helpers.NewRule("update").Groups(batchGroup).Resources("jobs/finalizers").RuleOrDie(),
252 rbacv1helpers.NewRule("list", "watch", "create", "delete", "patch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
253 eventsRule(),
254 },
255 })
256 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
257 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "namespace-controller"},
258 Rules: []rbacv1.PolicyRule{
259 rbacv1helpers.NewRule("get", "list", "watch", "delete").Groups(legacyGroup).Resources("namespaces").RuleOrDie(),
260 rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("namespaces/finalize", "namespaces/status").RuleOrDie(),
261 rbacv1helpers.NewRule("get", "list", "delete", "deletecollection").Groups("*").Resources("*").RuleOrDie(),
262 },
263 })
264 addControllerRole(&controllerRoles, &controllerRoleBindings, func() rbacv1.ClusterRole {
265 role := rbacv1.ClusterRole{
266 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "node-controller"},
267 Rules: []rbacv1.PolicyRule{
268 rbacv1helpers.NewRule("get", "list", "update", "delete", "patch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
269 rbacv1helpers.NewRule("patch", "update").Groups(legacyGroup).Resources("nodes/status").RuleOrDie(),
270
271 rbacv1helpers.NewRule("patch", "update").Groups(legacyGroup).Resources("pods/status").RuleOrDie(),
272 rbacv1helpers.NewRule("list", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
273 eventsRule(),
274 },
275 }
276 if utilfeature.DefaultFeatureGate.Enabled(features.PodDisruptionConditions) {
277 role.Rules = append(role.Rules, rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("pods").RuleOrDie())
278 }
279 return role
280 }())
281 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
282 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "persistent-volume-binder"},
283 Rules: []rbacv1.PolicyRule{
284 rbacv1helpers.NewRule("get", "list", "watch", "update", "create", "delete").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
285 rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("persistentvolumes/status").RuleOrDie(),
286 rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
287 rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("persistentvolumeclaims/status").RuleOrDie(),
288 rbacv1helpers.NewRule("list", "watch", "get", "create", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
289
290
291 rbacv1helpers.NewRule("get", "list", "watch").Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
292 rbacv1helpers.NewRule("get", "create", "update", "delete").Groups(legacyGroup).Resources("endpoints").RuleOrDie(),
293 rbacv1helpers.NewRule("get", "create", "delete").Groups(legacyGroup).Resources("services").RuleOrDie(),
294 rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("secrets").RuleOrDie(),
295
296 rbacv1helpers.NewRule("get", "list").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
297
298
299 rbacv1helpers.NewRule("watch").Groups(legacyGroup).Resources("events").RuleOrDie(),
300
301 eventsRule(),
302 },
303 })
304 addControllerRole(&controllerRoles, &controllerRoleBindings, func() rbacv1.ClusterRole {
305 role := rbacv1.ClusterRole{
306 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "pod-garbage-collector"},
307 Rules: []rbacv1.PolicyRule{
308 rbacv1helpers.NewRule("list", "watch", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
309 rbacv1helpers.NewRule("get", "list").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
310 },
311 }
312 if utilfeature.DefaultFeatureGate.Enabled(features.PodDisruptionConditions) {
313 role.Rules = append(role.Rules, rbacv1helpers.NewRule("patch").Groups(legacyGroup).Resources("pods/status").RuleOrDie())
314 }
315 return role
316 }())
317 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
318 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "replicaset-controller"},
319 Rules: []rbacv1.PolicyRule{
320 rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(appsGroup, extensionsGroup).Resources("replicasets").RuleOrDie(),
321 rbacv1helpers.NewRule("update").Groups(appsGroup, extensionsGroup).Resources("replicasets/status").RuleOrDie(),
322 rbacv1helpers.NewRule("update").Groups(appsGroup, extensionsGroup).Resources("replicasets/finalizers").RuleOrDie(),
323 rbacv1helpers.NewRule("list", "watch", "patch", "create", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
324 eventsRule(),
325 },
326 })
327 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
328 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "replication-controller"},
329 Rules: []rbacv1.PolicyRule{
330
331 rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("replicationcontrollers").RuleOrDie(),
332 rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("replicationcontrollers/status").RuleOrDie(),
333 rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("replicationcontrollers/finalizers").RuleOrDie(),
334 rbacv1helpers.NewRule("list", "watch", "patch", "create", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
335 eventsRule(),
336 },
337 })
338 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
339 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "resourcequota-controller"},
340 Rules: []rbacv1.PolicyRule{
341
342 rbacv1helpers.NewRule("list", "watch").Groups("*").Resources("*").RuleOrDie(),
343 rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("resourcequotas/status").RuleOrDie(),
344 eventsRule(),
345 },
346 })
347 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
348 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "route-controller"},
349 Rules: []rbacv1.PolicyRule{
350 rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
351 rbacv1helpers.NewRule("patch").Groups(legacyGroup).Resources("nodes/status").RuleOrDie(),
352 eventsRule(),
353 },
354 })
355 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
356 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "service-account-controller"},
357 Rules: []rbacv1.PolicyRule{
358 rbacv1helpers.NewRule("create").Groups(legacyGroup).Resources("serviceaccounts").RuleOrDie(),
359 eventsRule(),
360 },
361 })
362 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
363 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "service-controller"},
364 Rules: []rbacv1.PolicyRule{
365 rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("services").RuleOrDie(),
366 rbacv1helpers.NewRule("patch", "update").Groups(legacyGroup).Resources("services/status").RuleOrDie(),
367 rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
368 eventsRule(),
369 },
370 })
371 if utilfeature.DefaultFeatureGate.Enabled(features.MultiCIDRServiceAllocator) {
372 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
373 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "service-cidrs-controller"},
374 Rules: []rbacv1.PolicyRule{
375 rbacv1helpers.NewRule("get", "list", "watch", "patch", "update").Groups(networkingGroup).Resources("servicecidrs").RuleOrDie(),
376 rbacv1helpers.NewRule("patch", "update").Groups(networkingGroup).Resources("servicecidrs/finalizers").RuleOrDie(),
377 rbacv1helpers.NewRule("patch", "update").Groups(networkingGroup).Resources("servicecidrs/status").RuleOrDie(),
378 rbacv1helpers.NewRule("get", "list", "watch").Groups(networkingGroup).Resources("ipaddresses").RuleOrDie(),
379 eventsRule(),
380 },
381 })
382 }
383 addControllerRole(&controllerRoles, &controllerRoleBindings, func() rbacv1.ClusterRole {
384 role := rbacv1.ClusterRole{
385 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "statefulset-controller"},
386 Rules: []rbacv1.PolicyRule{
387 rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
388 rbacv1helpers.NewRule("get", "list", "watch").Groups(appsGroup).Resources("statefulsets").RuleOrDie(),
389 rbacv1helpers.NewRule("update").Groups(appsGroup).Resources("statefulsets/status").RuleOrDie(),
390 rbacv1helpers.NewRule("update").Groups(appsGroup).Resources("statefulsets/finalizers").RuleOrDie(),
391 rbacv1helpers.NewRule("get", "create", "delete", "update", "patch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
392 rbacv1helpers.NewRule("get", "create", "delete", "update", "patch", "list", "watch").Groups(appsGroup).Resources("controllerrevisions").RuleOrDie(),
393 rbacv1helpers.NewRule("get", "create").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
394 eventsRule(),
395 },
396 }
397
398 if utilfeature.DefaultFeatureGate.Enabled(features.StatefulSetAutoDeletePVC) {
399 role.Rules = append(role.Rules, rbacv1helpers.NewRule("update", "delete").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie())
400 }
401
402 return role
403 }())
404 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
405 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "ttl-controller"},
406 Rules: []rbacv1.PolicyRule{
407 rbacv1helpers.NewRule("update", "patch", "list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
408 eventsRule(),
409 },
410 })
411 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
412 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "certificate-controller"},
413 Rules: []rbacv1.PolicyRule{
414 rbacv1helpers.NewRule("get", "list", "watch", "delete").Groups(certificatesGroup).Resources("certificatesigningrequests").RuleOrDie(),
415 rbacv1helpers.NewRule("update").Groups(certificatesGroup).Resources("certificatesigningrequests/status", "certificatesigningrequests/approval").RuleOrDie(),
416 rbacv1helpers.NewRule("approve").Groups(certificatesGroup).Resources("signers").Names(capi.KubeAPIServerClientKubeletSignerName).RuleOrDie(),
417 rbacv1helpers.NewRule("sign").Groups(certificatesGroup).Resources("signers").Names(
418 capi.LegacyUnknownSignerName,
419 capi.KubeAPIServerClientSignerName,
420 capi.KubeAPIServerClientKubeletSignerName,
421 capi.KubeletServingSignerName,
422 ).RuleOrDie(),
423 rbacv1helpers.NewRule("create").Groups(authorizationGroup).Resources("subjectaccessreviews").RuleOrDie(),
424 eventsRule(),
425 },
426 })
427 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
428 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "pvc-protection-controller"},
429 Rules: []rbacv1.PolicyRule{
430 rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
431 rbacv1helpers.NewRule("list", "watch", "get").Groups(legacyGroup).Resources("pods").RuleOrDie(),
432 eventsRule(),
433 },
434 })
435 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
436 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "pv-protection-controller"},
437 Rules: []rbacv1.PolicyRule{
438 rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
439 eventsRule(),
440 },
441 })
442 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
443 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "ttl-after-finished-controller"},
444 Rules: []rbacv1.PolicyRule{
445 rbacv1helpers.NewRule("get", "list", "watch", "delete").Groups(batchGroup).Resources("jobs").RuleOrDie(),
446 eventsRule(),
447 },
448 })
449 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
450 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "root-ca-cert-publisher"},
451 Rules: []rbacv1.PolicyRule{
452 rbacv1helpers.NewRule("create", "update").Groups(legacyGroup).Resources("configmaps").RuleOrDie(),
453 eventsRule(),
454 },
455 })
456 if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.ValidatingAdmissionPolicy) {
457 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
458 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "validatingadmissionpolicy-status-controller"},
459 Rules: []rbacv1.PolicyRule{
460 rbacv1helpers.NewRule("get", "list", "watch").Groups(admissionRegistrationGroup).
461 Resources("validatingadmissionpolicies").RuleOrDie(),
462 rbacv1helpers.NewRule("get", "patch", "update").Groups(admissionRegistrationGroup).
463 Resources("validatingadmissionpolicies/status").RuleOrDie(),
464 eventsRule(),
465 },
466 })
467 }
468 if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.StorageVersionAPI) &&
469 utilfeature.DefaultFeatureGate.Enabled(genericfeatures.APIServerIdentity) {
470 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
471 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "storage-version-garbage-collector"},
472 Rules: []rbacv1.PolicyRule{
473 rbacv1helpers.NewRule("get", "list", "watch").Groups(coordinationGroup).Resources("leases").RuleOrDie(),
474 rbacv1helpers.NewRule("get", "list", "watch", "patch", "update", "delete").Groups(internalAPIServerGroup).
475 Resources("storageversions").RuleOrDie(),
476 rbacv1helpers.NewRule("get", "patch", "update").Groups(internalAPIServerGroup).
477 Resources("storageversions/status").RuleOrDie(),
478 },
479 })
480 }
481
482 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
483 ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "legacy-service-account-token-cleaner"},
484 Rules: []rbacv1.PolicyRule{
485 rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("configmaps").Names(legacytokentracking.ConfigMapName).RuleOrDie(),
486 rbacv1helpers.NewRule("patch", "delete").Groups(legacyGroup).Resources("secrets").RuleOrDie(),
487 },
488 })
489
490 if utilfeature.DefaultFeatureGate.Enabled(features.StorageVersionMigrator) {
491 addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
492 ObjectMeta: metav1.ObjectMeta{
493 Name: saRolePrefix + "storage-version-migrator-controller",
494 },
495 Rules: []rbacv1.PolicyRule{
496 rbacv1helpers.NewRule("list", "patch").Groups("*").Resources("*").RuleOrDie(),
497 rbacv1helpers.NewRule("update").Groups(storageVersionMigrationGroup).Resources("storageversionmigrations/status").RuleOrDie(),
498 },
499 })
500 }
501
502 return controllerRoles, controllerRoleBindings
503 }
504
505
506 func ControllerRoles() []rbacv1.ClusterRole {
507 controllerRoles, _ := buildControllerRoles()
508 return controllerRoles
509 }
510
511
512 func ControllerRoleBindings() []rbacv1.ClusterRoleBinding {
513 _, controllerRoleBindings := buildControllerRoles()
514 return controllerRoleBindings
515 }
516
View as plain text