blob: 4eab82e67d6d0b125fa1b393c9853c173230105d [file] [log] [blame]
Serge Bazanskie6030f62020-06-03 17:52:59 +02001// Copyright 2020 The Monogon Project Authors.
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17package reconciler
18
19import (
20 "context"
21
22 rbac "k8s.io/api/rbac/v1"
23 meta "k8s.io/apimachinery/pkg/apis/meta/v1"
24 "k8s.io/client-go/kubernetes"
25)
26
27var (
28 clusterRolePSPDefault = builtinRBACName("psp-default")
29 clusterRoleBindingDefaultPSP = builtinRBACName("default-psp-for-sa")
30 clusterRoleBindingAPIServerKubeletClient = builtinRBACName("apiserver-kubelet-client")
Lorenz Bruncc078df2021-12-23 11:51:55 +010031 clusterRoleBindingOwnerAdmin = builtinRBACName("owner-admin")
Serge Bazanski2cfafc92023-03-21 16:42:47 +010032 clusterRoleCSIProvisioner = builtinRBACName("csi-provisioner")
33 clusterRoleBindingCSIProvisioners = builtinRBACName("csi-provisioner")
34 clusterRoleNetServices = builtinRBACName("netservices")
35 clusterRoleBindingNetServices = builtinRBACName("netservices")
Serge Bazanskie6030f62020-06-03 17:52:59 +020036)
37
38type resourceClusterRoles struct {
39 kubernetes.Interface
40}
41
42func (r resourceClusterRoles) List(ctx context.Context) ([]string, error) {
43 res, err := r.RbacV1().ClusterRoles().List(ctx, listBuiltins)
44 if err != nil {
45 return nil, err
46 }
47 objs := make([]string, len(res.Items))
48 for i, el := range res.Items {
49 objs[i] = el.ObjectMeta.Name
50 }
51 return objs, nil
52}
53
54func (r resourceClusterRoles) Create(ctx context.Context, el interface{}) error {
55 _, err := r.RbacV1().ClusterRoles().Create(ctx, el.(*rbac.ClusterRole), meta.CreateOptions{})
56 return err
57}
58
59func (r resourceClusterRoles) Delete(ctx context.Context, name string) error {
60 return r.RbacV1().ClusterRoles().Delete(ctx, name, meta.DeleteOptions{})
61}
62
63func (r resourceClusterRoles) Expected() map[string]interface{} {
64 return map[string]interface{}{
65 clusterRolePSPDefault: &rbac.ClusterRole{
66 ObjectMeta: meta.ObjectMeta{
67 Name: clusterRolePSPDefault,
68 Labels: builtinLabels(nil),
69 Annotations: map[string]string{
70 "kubernetes.io/description": "This role grants access to the \"default\" PSP.",
71 },
72 },
73 Rules: []rbac.PolicyRule{
74 {
75 APIGroups: []string{"policy"},
76 Resources: []string{"podsecuritypolicies"},
77 ResourceNames: []string{"default"},
78 Verbs: []string{"use"},
79 },
80 },
81 },
Serge Bazanski2cfafc92023-03-21 16:42:47 +010082 clusterRoleCSIProvisioner: &rbac.ClusterRole{
83 ObjectMeta: meta.ObjectMeta{
84 Name: clusterRoleCSIProvisioner,
85 Labels: builtinLabels(nil),
86 Annotations: map[string]string{
87 "kubernetes.io/description": "This role grants access to PersistentVolumes, PersistentVolumeClaims and StorageClassses, as used the the CSI provisioner running on nodes.",
88 },
89 },
90 Rules: []rbac.PolicyRule{
91 {
92 APIGroups: []string{""},
93 Resources: []string{"events"},
94 Verbs: []string{"get", "list", "watch", "create", "update", "patch"},
95 },
96 {
97 APIGroups: []string{"storage.k8s.io"},
98 Resources: []string{"storageclasses"},
99 Verbs: []string{"get", "list", "watch"},
100 },
101 {
102 APIGroups: []string{""},
103 Resources: []string{"persistentvolumes", "persistentvolumeclaims"},
104 Verbs: []string{"*"},
105 },
106 },
107 },
108 clusterRoleNetServices: &rbac.ClusterRole{
109 ObjectMeta: meta.ObjectMeta{
110 Name: clusterRoleNetServices,
111 Labels: builtinLabels(nil),
112 Annotations: map[string]string{
113 "kubernetes.io/description": "This role grants access to the minimum set of resources that are needed to run networking services for a node.",
114 },
115 },
116 Rules: []rbac.PolicyRule{
117 {
118 APIGroups: []string{"discovery.k8s.io"},
119 Resources: []string{"endpointslices"},
120 Verbs: []string{"get", "list", "watch"},
121 },
122 {
123 APIGroups: []string{""},
124 Resources: []string{"services", "nodes", "namespaces"},
125 Verbs: []string{"get", "list", "watch"},
126 },
127 },
128 },
Serge Bazanskie6030f62020-06-03 17:52:59 +0200129 }
130}
131
132type resourceClusterRoleBindings struct {
133 kubernetes.Interface
134}
135
136func (r resourceClusterRoleBindings) List(ctx context.Context) ([]string, error) {
137 res, err := r.RbacV1().ClusterRoleBindings().List(ctx, listBuiltins)
138 if err != nil {
139 return nil, err
140 }
141 objs := make([]string, len(res.Items))
142 for i, el := range res.Items {
143 objs[i] = el.ObjectMeta.Name
144 }
145 return objs, nil
146}
147
148func (r resourceClusterRoleBindings) Create(ctx context.Context, el interface{}) error {
149 _, err := r.RbacV1().ClusterRoleBindings().Create(ctx, el.(*rbac.ClusterRoleBinding), meta.CreateOptions{})
150 return err
151}
152
153func (r resourceClusterRoleBindings) Delete(ctx context.Context, name string) error {
154 return r.RbacV1().ClusterRoleBindings().Delete(ctx, name, meta.DeleteOptions{})
155}
156
157func (r resourceClusterRoleBindings) Expected() map[string]interface{} {
158 return map[string]interface{}{
159 clusterRoleBindingDefaultPSP: &rbac.ClusterRoleBinding{
160 ObjectMeta: meta.ObjectMeta{
161 Name: clusterRoleBindingDefaultPSP,
162 Labels: builtinLabels(nil),
163 Annotations: map[string]string{
164 "kubernetes.io/description": "This binding grants every service account access to the \"default\" PSP. " +
165 "Creation of Pods is still restricted by other RBAC roles. Otherwise no pods (unprivileged or not) " +
166 "can be created.",
167 },
168 },
169 RoleRef: rbac.RoleRef{
170 APIGroup: rbac.GroupName,
171 Kind: "ClusterRole",
172 Name: clusterRolePSPDefault,
173 },
174 Subjects: []rbac.Subject{
175 {
176 APIGroup: rbac.GroupName,
177 Kind: "Group",
178 Name: "system:serviceaccounts",
179 },
180 },
181 },
182 clusterRoleBindingAPIServerKubeletClient: &rbac.ClusterRoleBinding{
183 ObjectMeta: meta.ObjectMeta{
184 Name: clusterRoleBindingAPIServerKubeletClient,
185 Labels: builtinLabels(nil),
186 Annotations: map[string]string{
187 "kubernetes.io/description": "This binding grants the apiserver access to the kubelets. This enables " +
188 "lots of built-in functionality like reading logs or forwarding ports via the API.",
189 },
190 },
191 RoleRef: rbac.RoleRef{
192 APIGroup: rbac.GroupName,
193 Kind: "ClusterRole",
194 Name: "system:kubelet-api-admin",
195 },
196 Subjects: []rbac.Subject{
197 {
198 APIGroup: rbac.GroupName,
199 Kind: "User",
200 // TODO(q3k): describe this name's contract, or unify with whatever creates this.
Serge Bazanski662b5b32020-12-21 13:49:00 +0100201 Name: "metropolis:apiserver-kubelet-client",
Serge Bazanskie6030f62020-06-03 17:52:59 +0200202 },
203 },
204 },
Lorenz Bruncc078df2021-12-23 11:51:55 +0100205 clusterRoleBindingOwnerAdmin: &rbac.ClusterRoleBinding{
206 ObjectMeta: meta.ObjectMeta{
207 Name: clusterRoleBindingOwnerAdmin,
208 Labels: builtinLabels(nil),
209 Annotations: map[string]string{
210 "kubernetes.io/description": "This binding grants the Metropolis Cluster owner access to the " +
211 "cluster-admin role on Kubernetes.",
212 },
213 },
214 RoleRef: rbac.RoleRef{
215 APIGroup: rbac.GroupName,
216 Kind: "ClusterRole",
217 Name: "cluster-admin",
218 },
219 Subjects: []rbac.Subject{
220 {
221 APIGroup: rbac.GroupName,
222 Kind: "User",
223 Name: "owner",
224 },
225 },
226 },
Serge Bazanski2cfafc92023-03-21 16:42:47 +0100227 clusterRoleBindingCSIProvisioners: &rbac.ClusterRoleBinding{
228 ObjectMeta: meta.ObjectMeta{
229 Name: clusterRoleBindingCSIProvisioners,
230 Labels: builtinLabels(nil),
231 Annotations: map[string]string{
232 "kubernetes.io/description": "This role binding grants CSI provisioners running on nodes access to the necessary resources.",
233 },
234 },
235 RoleRef: rbac.RoleRef{
236 APIGroup: rbac.GroupName,
237 Kind: "ClusterRole",
238 Name: clusterRoleCSIProvisioner,
239 },
240 Subjects: []rbac.Subject{
241 {
242 APIGroup: rbac.GroupName,
243 Kind: "Group",
244 Name: "metropolis:csi-provisioner",
245 },
246 },
247 },
248 clusterRoleBindingNetServices: &rbac.ClusterRoleBinding{
249 ObjectMeta: meta.ObjectMeta{
250 Name: clusterRoleBindingNetServices,
251 Labels: builtinLabels(nil),
252 Annotations: map[string]string{
253 "kubernetes.io/description": "This role binding grants node network services access to necessary resources.",
254 },
255 },
256 RoleRef: rbac.RoleRef{
257 APIGroup: rbac.GroupName,
258 Kind: "ClusterRole",
259 Name: clusterRoleNetServices,
260 },
261 Subjects: []rbac.Subject{
262 {
263 APIGroup: rbac.GroupName,
264 Kind: "Group",
265 Name: "metropolis:netservices",
266 },
267 },
268 },
Serge Bazanskie6030f62020-06-03 17:52:59 +0200269 }
270}