controller_policy.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*
  2. Copyright 2016 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package bootstrappolicy
  14. import (
  15. "strings"
  16. "k8s.io/klog"
  17. rbacv1 "k8s.io/api/rbac/v1"
  18. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  19. utilfeature "k8s.io/apiserver/pkg/util/feature"
  20. rbacv1helpers "k8s.io/kubernetes/pkg/apis/rbac/v1"
  21. "k8s.io/kubernetes/pkg/features"
  22. )
  23. const saRolePrefix = "system:controller:"
  24. func addControllerRole(controllerRoles *[]rbacv1.ClusterRole, controllerRoleBindings *[]rbacv1.ClusterRoleBinding, role rbacv1.ClusterRole) {
  25. if !strings.HasPrefix(role.Name, saRolePrefix) {
  26. klog.Fatalf(`role %q must start with %q`, role.Name, saRolePrefix)
  27. }
  28. for _, existingRole := range *controllerRoles {
  29. if role.Name == existingRole.Name {
  30. klog.Fatalf("role %q was already registered", role.Name)
  31. }
  32. }
  33. *controllerRoles = append(*controllerRoles, role)
  34. addClusterRoleLabel(*controllerRoles)
  35. *controllerRoleBindings = append(*controllerRoleBindings,
  36. rbacv1helpers.NewClusterBinding(role.Name).SAs("kube-system", role.Name[len(saRolePrefix):]).BindingOrDie())
  37. addClusterRoleBindingLabel(*controllerRoleBindings)
  38. }
  39. func eventsRule() rbacv1.PolicyRule {
  40. return rbacv1helpers.NewRule("create", "update", "patch").Groups(legacyGroup).Resources("events").RuleOrDie()
  41. }
  42. func buildControllerRoles() ([]rbacv1.ClusterRole, []rbacv1.ClusterRoleBinding) {
  43. // controllerRoles is a slice of roles used for controllers
  44. controllerRoles := []rbacv1.ClusterRole{}
  45. // controllerRoleBindings is a slice of roles used for controllers
  46. controllerRoleBindings := []rbacv1.ClusterRoleBinding{}
  47. addControllerRole(&controllerRoles, &controllerRoleBindings, func() rbacv1.ClusterRole {
  48. role := rbacv1.ClusterRole{
  49. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "attachdetach-controller"},
  50. Rules: []rbacv1.PolicyRule{
  51. rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("persistentvolumes", "persistentvolumeclaims").RuleOrDie(),
  52. rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
  53. rbacv1helpers.NewRule("patch", "update").Groups(legacyGroup).Resources("nodes/status").RuleOrDie(),
  54. rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
  55. eventsRule(),
  56. },
  57. }
  58. if utilfeature.DefaultFeatureGate.Enabled(features.CSIPersistentVolume) {
  59. role.Rules = append(role.Rules, rbacv1helpers.NewRule("get", "create", "delete", "list", "watch").Groups(storageGroup).Resources("volumeattachments").RuleOrDie())
  60. if utilfeature.DefaultFeatureGate.Enabled(features.CSIDriverRegistry) {
  61. role.Rules = append(role.Rules, rbacv1helpers.NewRule("get", "watch", "list").Groups("storage.k8s.io").Resources("csidrivers").RuleOrDie())
  62. }
  63. if utilfeature.DefaultFeatureGate.Enabled(features.CSINodeInfo) && utilfeature.DefaultFeatureGate.Enabled(features.CSIMigration) {
  64. role.Rules = append(role.Rules, rbacv1helpers.NewRule("get", "watch", "list").Groups("storage.k8s.io").Resources("csinodes").RuleOrDie())
  65. }
  66. }
  67. return role
  68. }())
  69. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  70. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "clusterrole-aggregation-controller"},
  71. Rules: []rbacv1.PolicyRule{
  72. // this controller must have full permissions to allow it to mutate any role in any way
  73. rbacv1helpers.NewRule("*").Groups("*").Resources("*").RuleOrDie(),
  74. rbacv1helpers.NewRule("*").URLs("*").RuleOrDie(),
  75. },
  76. })
  77. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  78. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "cronjob-controller"},
  79. Rules: []rbacv1.PolicyRule{
  80. rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(batchGroup).Resources("cronjobs").RuleOrDie(),
  81. rbacv1helpers.NewRule("get", "list", "watch", "create", "update", "delete", "patch").Groups(batchGroup).Resources("jobs").RuleOrDie(),
  82. rbacv1helpers.NewRule("update").Groups(batchGroup).Resources("cronjobs/status").RuleOrDie(),
  83. rbacv1helpers.NewRule("update").Groups(batchGroup).Resources("cronjobs/finalizers").RuleOrDie(),
  84. rbacv1helpers.NewRule("list", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
  85. eventsRule(),
  86. },
  87. })
  88. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  89. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "daemon-set-controller"},
  90. Rules: []rbacv1.PolicyRule{
  91. rbacv1helpers.NewRule("get", "list", "watch").Groups(extensionsGroup, appsGroup).Resources("daemonsets").RuleOrDie(),
  92. rbacv1helpers.NewRule("update").Groups(extensionsGroup, appsGroup).Resources("daemonsets/status").RuleOrDie(),
  93. rbacv1helpers.NewRule("update").Groups(extensionsGroup, appsGroup).Resources("daemonsets/finalizers").RuleOrDie(),
  94. rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
  95. rbacv1helpers.NewRule("list", "watch", "create", "delete", "patch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
  96. rbacv1helpers.NewRule("create").Groups(legacyGroup).Resources("pods/binding").RuleOrDie(),
  97. rbacv1helpers.NewRule("get", "list", "watch", "create", "delete", "update", "patch").Groups(appsGroup).Resources("controllerrevisions").RuleOrDie(),
  98. eventsRule(),
  99. },
  100. })
  101. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  102. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "deployment-controller"},
  103. Rules: []rbacv1.PolicyRule{
  104. rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(extensionsGroup, appsGroup).Resources("deployments").RuleOrDie(),
  105. rbacv1helpers.NewRule("update").Groups(extensionsGroup, appsGroup).Resources("deployments/status").RuleOrDie(),
  106. rbacv1helpers.NewRule("update").Groups(extensionsGroup, appsGroup).Resources("deployments/finalizers").RuleOrDie(),
  107. rbacv1helpers.NewRule("get", "list", "watch", "create", "update", "patch", "delete").Groups(appsGroup, extensionsGroup).Resources("replicasets").RuleOrDie(),
  108. // TODO: remove "update" once
  109. // https://github.com/kubernetes/kubernetes/issues/36897 is resolved.
  110. rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("pods").RuleOrDie(),
  111. eventsRule(),
  112. },
  113. })
  114. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  115. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "disruption-controller"},
  116. Rules: []rbacv1.PolicyRule{
  117. rbacv1helpers.NewRule("get", "list", "watch").Groups(extensionsGroup, appsGroup).Resources("deployments").RuleOrDie(),
  118. rbacv1helpers.NewRule("get", "list", "watch").Groups(appsGroup, extensionsGroup).Resources("replicasets").RuleOrDie(),
  119. rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("replicationcontrollers").RuleOrDie(),
  120. rbacv1helpers.NewRule("get", "list", "watch").Groups(policyGroup).Resources("poddisruptionbudgets").RuleOrDie(),
  121. rbacv1helpers.NewRule("get", "list", "watch").Groups(appsGroup).Resources("statefulsets").RuleOrDie(),
  122. rbacv1helpers.NewRule("update").Groups(policyGroup).Resources("poddisruptionbudgets/status").RuleOrDie(),
  123. rbacv1helpers.NewRule("get").Groups("*").Resources("*/scale").RuleOrDie(),
  124. eventsRule(),
  125. },
  126. })
  127. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  128. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "endpoint-controller"},
  129. Rules: []rbacv1.PolicyRule{
  130. rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("services", "pods").RuleOrDie(),
  131. rbacv1helpers.NewRule("get", "list", "create", "update", "delete").Groups(legacyGroup).Resources("endpoints").RuleOrDie(),
  132. rbacv1helpers.NewRule("create").Groups(legacyGroup).Resources("endpoints/restricted").RuleOrDie(),
  133. eventsRule(),
  134. },
  135. })
  136. if utilfeature.DefaultFeatureGate.Enabled(features.ExpandPersistentVolumes) {
  137. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  138. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "expand-controller"},
  139. Rules: []rbacv1.PolicyRule{
  140. rbacv1helpers.NewRule("get", "list", "watch", "update", "patch").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
  141. rbacv1helpers.NewRule("update", "patch").Groups(legacyGroup).Resources("persistentvolumeclaims/status").RuleOrDie(),
  142. rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
  143. // glusterfs
  144. rbacv1helpers.NewRule("get", "list", "watch").Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
  145. rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("services", "endpoints").RuleOrDie(),
  146. rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("secrets").RuleOrDie(),
  147. eventsRule(),
  148. },
  149. })
  150. }
  151. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  152. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "generic-garbage-collector"},
  153. Rules: []rbacv1.PolicyRule{
  154. // the GC controller needs to run list/watches, selective gets, and updates against any resource
  155. rbacv1helpers.NewRule("get", "list", "watch", "patch", "update", "delete").Groups("*").Resources("*").RuleOrDie(),
  156. eventsRule(),
  157. },
  158. })
  159. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  160. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "horizontal-pod-autoscaler"},
  161. Rules: []rbacv1.PolicyRule{
  162. rbacv1helpers.NewRule("get", "list", "watch").Groups(autoscalingGroup).Resources("horizontalpodautoscalers").RuleOrDie(),
  163. rbacv1helpers.NewRule("update").Groups(autoscalingGroup).Resources("horizontalpodautoscalers/status").RuleOrDie(),
  164. rbacv1helpers.NewRule("get", "update").Groups("*").Resources("*/scale").RuleOrDie(),
  165. rbacv1helpers.NewRule("list").Groups(legacyGroup).Resources("pods").RuleOrDie(),
  166. // TODO: restrict this to the appropriate namespace
  167. rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("services/proxy").Names("https:heapster:", "http:heapster:").RuleOrDie(),
  168. // allow listing resource metrics and custom metrics
  169. rbacv1helpers.NewRule("list").Groups(resMetricsGroup).Resources("pods").RuleOrDie(),
  170. rbacv1helpers.NewRule("get", "list").Groups(customMetricsGroup).Resources("*").RuleOrDie(),
  171. eventsRule(),
  172. },
  173. })
  174. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  175. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "job-controller"},
  176. Rules: []rbacv1.PolicyRule{
  177. rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(batchGroup).Resources("jobs").RuleOrDie(),
  178. rbacv1helpers.NewRule("update").Groups(batchGroup).Resources("jobs/status").RuleOrDie(),
  179. rbacv1helpers.NewRule("update").Groups(batchGroup).Resources("jobs/finalizers").RuleOrDie(),
  180. rbacv1helpers.NewRule("list", "watch", "create", "delete", "patch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
  181. eventsRule(),
  182. },
  183. })
  184. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  185. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "namespace-controller"},
  186. Rules: []rbacv1.PolicyRule{
  187. rbacv1helpers.NewRule("get", "list", "watch", "delete").Groups(legacyGroup).Resources("namespaces").RuleOrDie(),
  188. rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("namespaces/finalize", "namespaces/status").RuleOrDie(),
  189. rbacv1helpers.NewRule("get", "list", "delete", "deletecollection").Groups("*").Resources("*").RuleOrDie(),
  190. },
  191. })
  192. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  193. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "node-controller"},
  194. Rules: []rbacv1.PolicyRule{
  195. rbacv1helpers.NewRule("get", "list", "update", "delete", "patch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
  196. rbacv1helpers.NewRule("patch", "update").Groups(legacyGroup).Resources("nodes/status").RuleOrDie(),
  197. // used for pod eviction
  198. rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("pods/status").RuleOrDie(),
  199. rbacv1helpers.NewRule("list", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
  200. eventsRule(),
  201. },
  202. })
  203. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  204. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "persistent-volume-binder"},
  205. Rules: []rbacv1.PolicyRule{
  206. rbacv1helpers.NewRule("get", "list", "watch", "update", "create", "delete").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
  207. rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("persistentvolumes/status").RuleOrDie(),
  208. rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
  209. rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("persistentvolumeclaims/status").RuleOrDie(),
  210. rbacv1helpers.NewRule("list", "watch", "get", "create", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
  211. // glusterfs
  212. rbacv1helpers.NewRule("get", "list", "watch").Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
  213. rbacv1helpers.NewRule("get", "create", "update", "delete").Groups(legacyGroup).Resources("endpoints").RuleOrDie(),
  214. rbacv1helpers.NewRule("get", "create", "delete").Groups(legacyGroup).Resources("services").RuleOrDie(),
  215. rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("secrets").RuleOrDie(),
  216. // openstack
  217. rbacv1helpers.NewRule("get", "list").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
  218. // recyclerClient.WatchPod
  219. rbacv1helpers.NewRule("watch").Groups(legacyGroup).Resources("events").RuleOrDie(),
  220. eventsRule(),
  221. },
  222. })
  223. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  224. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "pod-garbage-collector"},
  225. Rules: []rbacv1.PolicyRule{
  226. rbacv1helpers.NewRule("list", "watch", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
  227. rbacv1helpers.NewRule("list").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
  228. },
  229. })
  230. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  231. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "replicaset-controller"},
  232. Rules: []rbacv1.PolicyRule{
  233. rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(appsGroup, extensionsGroup).Resources("replicasets").RuleOrDie(),
  234. rbacv1helpers.NewRule("update").Groups(appsGroup, extensionsGroup).Resources("replicasets/status").RuleOrDie(),
  235. rbacv1helpers.NewRule("update").Groups(appsGroup, extensionsGroup).Resources("replicasets/finalizers").RuleOrDie(),
  236. rbacv1helpers.NewRule("list", "watch", "patch", "create", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
  237. eventsRule(),
  238. },
  239. })
  240. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  241. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "replication-controller"},
  242. Rules: []rbacv1.PolicyRule{
  243. // 1.0 controllers needed get, update, so without these old controllers break on new servers
  244. rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("replicationcontrollers").RuleOrDie(),
  245. rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("replicationcontrollers/status").RuleOrDie(),
  246. rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("replicationcontrollers/finalizers").RuleOrDie(),
  247. rbacv1helpers.NewRule("list", "watch", "patch", "create", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
  248. eventsRule(),
  249. },
  250. })
  251. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  252. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "resourcequota-controller"},
  253. Rules: []rbacv1.PolicyRule{
  254. // quota can count quota on anything for reconciliation, so it needs full viewing powers
  255. rbacv1helpers.NewRule("list", "watch").Groups("*").Resources("*").RuleOrDie(),
  256. rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("resourcequotas/status").RuleOrDie(),
  257. eventsRule(),
  258. },
  259. })
  260. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  261. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "route-controller"},
  262. Rules: []rbacv1.PolicyRule{
  263. rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
  264. rbacv1helpers.NewRule("patch").Groups(legacyGroup).Resources("nodes/status").RuleOrDie(),
  265. eventsRule(),
  266. },
  267. })
  268. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  269. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "service-account-controller"},
  270. Rules: []rbacv1.PolicyRule{
  271. rbacv1helpers.NewRule("create").Groups(legacyGroup).Resources("serviceaccounts").RuleOrDie(),
  272. eventsRule(),
  273. },
  274. })
  275. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  276. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "service-controller"},
  277. Rules: []rbacv1.PolicyRule{
  278. rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("services").RuleOrDie(),
  279. rbacv1helpers.NewRule("patch", "update").Groups(legacyGroup).Resources("services/status").RuleOrDie(),
  280. rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
  281. eventsRule(),
  282. },
  283. })
  284. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  285. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "statefulset-controller"},
  286. Rules: []rbacv1.PolicyRule{
  287. rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
  288. rbacv1helpers.NewRule("get", "list", "watch").Groups(appsGroup).Resources("statefulsets").RuleOrDie(),
  289. rbacv1helpers.NewRule("update").Groups(appsGroup).Resources("statefulsets/status").RuleOrDie(),
  290. rbacv1helpers.NewRule("update").Groups(appsGroup).Resources("statefulsets/finalizers").RuleOrDie(),
  291. rbacv1helpers.NewRule("get", "create", "delete", "update", "patch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
  292. rbacv1helpers.NewRule("get", "create", "delete", "update", "patch", "list", "watch").Groups(appsGroup).Resources("controllerrevisions").RuleOrDie(),
  293. rbacv1helpers.NewRule("get", "create").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
  294. eventsRule(),
  295. },
  296. })
  297. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  298. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "ttl-controller"},
  299. Rules: []rbacv1.PolicyRule{
  300. rbacv1helpers.NewRule("update", "patch", "list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
  301. eventsRule(),
  302. },
  303. })
  304. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  305. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "certificate-controller"},
  306. Rules: []rbacv1.PolicyRule{
  307. rbacv1helpers.NewRule("get", "list", "watch", "delete").Groups(certificatesGroup).Resources("certificatesigningrequests").RuleOrDie(),
  308. rbacv1helpers.NewRule("update").Groups(certificatesGroup).Resources("certificatesigningrequests/status", "certificatesigningrequests/approval").RuleOrDie(),
  309. rbacv1helpers.NewRule("create").Groups(authorizationGroup).Resources("subjectaccessreviews").RuleOrDie(),
  310. eventsRule(),
  311. },
  312. })
  313. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  314. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "pvc-protection-controller"},
  315. Rules: []rbacv1.PolicyRule{
  316. rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
  317. rbacv1helpers.NewRule("list", "watch", "get").Groups(legacyGroup).Resources("pods").RuleOrDie(),
  318. eventsRule(),
  319. },
  320. })
  321. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  322. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "pv-protection-controller"},
  323. Rules: []rbacv1.PolicyRule{
  324. rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
  325. eventsRule(),
  326. },
  327. })
  328. if utilfeature.DefaultFeatureGate.Enabled(features.TTLAfterFinished) {
  329. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  330. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "ttl-after-finished-controller"},
  331. Rules: []rbacv1.PolicyRule{
  332. rbacv1helpers.NewRule("get", "list", "watch", "delete").Groups(batchGroup).Resources("jobs").RuleOrDie(),
  333. eventsRule(),
  334. },
  335. })
  336. }
  337. if utilfeature.DefaultFeatureGate.Enabled(features.BoundServiceAccountTokenVolume) {
  338. addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
  339. ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "root-ca-cert-publisher"},
  340. Rules: []rbacv1.PolicyRule{
  341. rbacv1helpers.NewRule("create", "update").Groups(legacyGroup).Resources("configmaps").RuleOrDie(),
  342. eventsRule(),
  343. },
  344. })
  345. }
  346. return controllerRoles, controllerRoleBindings
  347. }
  348. // ControllerRoles returns the cluster roles used by controllers
  349. func ControllerRoles() []rbacv1.ClusterRole {
  350. controllerRoles, _ := buildControllerRoles()
  351. return controllerRoles
  352. }
  353. // ControllerRoleBindings returns the role bindings used by controllers
  354. func ControllerRoleBindings() []rbacv1.ClusterRoleBinding {
  355. _, controllerRoleBindings := buildControllerRoles()
  356. return controllerRoleBindings
  357. }