66
77 "k8s.io/apimachinery/pkg/api/errors"
88
9+ "reflect"
10+
911 corev1 "k8s.io/api/core/v1"
1012 rbacv1 "k8s.io/api/rbac/v1"
1113 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -94,6 +96,8 @@ func (r *RBACInstaller) ApplyNamespace(ctx context.Context, namespace *corev1.Na
9496 return nil , fmt .Errorf ("failed to convert unstructured to Namespace: %w" , err )
9597 }
9698 return namespace , nil
99+ } else if err != nil {
100+ return nil , fmt .Errorf ("failed to Get Namespace: %w" , err )
97101 }
98102
99103 res , err := cli .Update (ctx , u , metav1.UpdateOptions {})
@@ -123,7 +127,8 @@ func (i *RBACInstaller) ApplyRole(ctx context.Context, role *rbacv1.Role) (*rbac
123127 },
124128 ).Namespace (role .Namespace )
125129
126- if _ , err = cli .Get (ctx , role .Name , metav1.GetOptions {}); errors .IsNotFound (err ) {
130+ existingU , err := cli .Get (ctx , role .Name , metav1.GetOptions {})
131+ if errors .IsNotFound (err ) {
127132 res , err := cli .Create (ctx , u , metav1.CreateOptions {})
128133 if err != nil {
129134 return nil , fmt .Errorf ("failed to Create Role: %w" , err )
@@ -136,8 +141,34 @@ func (i *RBACInstaller) ApplyRole(ctx context.Context, role *rbacv1.Role) (*rbac
136141 }
137142
138143 return role , nil
144+ } else if err != nil {
145+ return nil , fmt .Errorf ("failed to Get Role: %w" , err )
146+ }
147+
148+ existingRole := & rbacv1.Role {}
149+ err = runtime .DefaultUnstructuredConverter .FromUnstructured (existingU .Object , existingRole )
150+ if err != nil {
151+ return nil , fmt .Errorf ("failed to convert unstructured to Role: %w" , err )
152+ }
153+
154+ modified := false
155+ for _ , rule := range role .Rules {
156+ if ! ruleExists (existingRole .Rules , rule ) {
157+ existingRole .Rules = append (existingRole .Rules , rule )
158+ modified = true
159+ }
139160 }
140161
162+ if ! modified {
163+ return existingRole , nil
164+ }
165+
166+ m , err = runtime .DefaultUnstructuredConverter .ToUnstructured (existingRole )
167+ if err != nil {
168+ return nil , fmt .Errorf ("failed to convert Role to unstructured: %w" , err )
169+ }
170+ u .Object = m
171+
141172 res , err := cli .Update (ctx , u , metav1.UpdateOptions {})
142173 if err != nil {
143174 return nil , fmt .Errorf ("failed to Update Role: %w" , err )
@@ -180,6 +211,8 @@ func (i *RBACInstaller) ApplyRoleBinding(ctx context.Context, roleBinding *rbacv
180211 }
181212
182213 return roleBinding , nil
214+ } else if err != nil {
215+ return nil , fmt .Errorf ("failed to Get RoleBinding: %w" , err )
183216 }
184217
185218 res , err := cli .Update (ctx , u , metav1.UpdateOptions {})
@@ -211,7 +244,8 @@ func (i *RBACInstaller) ApplyClusterRole(ctx context.Context, clusterRole *rbacv
211244 },
212245 )
213246
214- if _ , err := cli .Get (ctx , clusterRole .Name , metav1.GetOptions {}); errors .IsNotFound (err ) {
247+ existingU , err := cli .Get (ctx , clusterRole .Name , metav1.GetOptions {})
248+ if errors .IsNotFound (err ) {
215249 res , err := cli .Create (ctx , u , metav1.CreateOptions {})
216250 if err != nil {
217251 return nil , fmt .Errorf ("failed to Create ClusterRole: %w" , err )
@@ -224,8 +258,34 @@ func (i *RBACInstaller) ApplyClusterRole(ctx context.Context, clusterRole *rbacv
224258 }
225259
226260 return clusterRole , nil
261+ } else if err != nil {
262+ return nil , fmt .Errorf ("failed to Get ClusterRole: %w" , err )
227263 }
228264
265+ existingClusterRole := & rbacv1.ClusterRole {}
266+ err = runtime .DefaultUnstructuredConverter .FromUnstructured (existingU .Object , existingClusterRole )
267+ if err != nil {
268+ return nil , fmt .Errorf ("failed to convert unstructured to ClusterRole: %w" , err )
269+ }
270+
271+ modified := false
272+ for _ , rule := range clusterRole .Rules {
273+ if ! ruleExists (existingClusterRole .Rules , rule ) {
274+ existingClusterRole .Rules = append (existingClusterRole .Rules , rule )
275+ modified = true
276+ }
277+ }
278+
279+ if ! modified {
280+ return existingClusterRole , nil
281+ }
282+
283+ m , err = runtime .DefaultUnstructuredConverter .ToUnstructured (existingClusterRole )
284+ if err != nil {
285+ return nil , fmt .Errorf ("failed to convert ClusterRole to unstructured: %w" , err )
286+ }
287+ u .Object = m
288+
229289 res , err := cli .Update (ctx , u , metav1.UpdateOptions {})
230290 if err != nil {
231291 return nil , fmt .Errorf ("failed to Update ClusterRole: %w" , err )
@@ -267,6 +327,8 @@ func (i *RBACInstaller) ApplyClusterRoleBinding(ctx context.Context, clusterRole
267327 }
268328
269329 return clusterRoleBinding , nil
330+ } else if err != nil {
331+ return nil , fmt .Errorf ("failed to Get ClusterRoleBinding: %w" , err )
270332 }
271333
272334 res , err := cli .Update (ctx , u , metav1.UpdateOptions {})
@@ -381,3 +443,12 @@ func (i *RBACInstaller) DeleteClusterRoleBinding(ctx context.Context, name strin
381443 }
382444 return nil
383445}
446+
447+ func ruleExists (rules []rbacv1.PolicyRule , target rbacv1.PolicyRule ) bool {
448+ for _ , rule := range rules {
449+ if reflect .DeepEqual (rule , target ) {
450+ return true
451+ }
452+ }
453+ return false
454+ }
0 commit comments