@@ -9,12 +9,14 @@ import (
9
9
"github.com/spf13/cobra"
10
10
11
11
kapi "k8s.io/kubernetes/pkg/api"
12
+ kapierrors "k8s.io/kubernetes/pkg/api/errors"
12
13
"k8s.io/kubernetes/pkg/api/meta"
13
14
"k8s.io/kubernetes/pkg/apimachinery/registered"
14
15
"k8s.io/kubernetes/pkg/kubectl"
15
16
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
16
17
"k8s.io/kubernetes/pkg/kubectl/resource"
17
18
"k8s.io/kubernetes/pkg/runtime"
19
+ kerrors "k8s.io/kubernetes/pkg/util/errors"
18
20
19
21
authorizationapi "github.com/openshift/origin/pkg/authorization/api"
20
22
policyregistry "github.com/openshift/origin/pkg/authorization/registry/policy"
@@ -173,14 +175,30 @@ func OverwriteBootstrapPolicy(optsGetter restoptions.Getter, policyFile, createB
173
175
}
174
176
runtime .DecodeList (template .Objects , kapi .Codecs .UniversalDecoder ())
175
177
178
+ // For each object, we attempt the following to maximize our ability to persist the desired objects, while minimizing etcd write thrashing:
179
+ // 1. Create the object (no-ops if the object already exists)
180
+ // 2. If the object already exists, attempt to update the object (no-ops if an identical object is already persisted)
181
+ // 3. If we encounter any error updating, delete and recreate
182
+ errs := []error {}
176
183
for _ , item := range template .Objects {
177
184
switch t := item .(type ) {
178
185
case * authorizationapi.Role :
179
186
ctx := kapi .WithNamespace (kapi .NewContext (), t .Namespace )
180
187
if change {
181
- roleStorage .Delete (ctx , t .Name , nil )
182
- if _ , err := roleStorage .CreateRoleWithEscalation (ctx , t ); err != nil {
183
- return err
188
+ // Attempt to create
189
+ _ , err := roleStorage .CreateRoleWithEscalation (ctx , t )
190
+ // Unconditional replace if it already exists
191
+ if kapierrors .IsAlreadyExists (err ) {
192
+ _ , _ , err = roleStorage .UpdateRoleWithEscalation (ctx , t )
193
+ }
194
+ // Delete and recreate as a last resort
195
+ if err != nil {
196
+ roleStorage .Delete (ctx , t .Name , nil )
197
+ _ , err = roleStorage .CreateRoleWithEscalation (ctx , t )
198
+ }
199
+ // Gather any error
200
+ if err != nil {
201
+ errs = append (errs , err )
184
202
}
185
203
} else {
186
204
fmt .Fprintf (out , "Overwrite role %s/%s\n " , t .Namespace , t .Name )
@@ -191,9 +209,20 @@ func OverwriteBootstrapPolicy(optsGetter restoptions.Getter, policyFile, createB
191
209
case * authorizationapi.RoleBinding :
192
210
ctx := kapi .WithNamespace (kapi .NewContext (), t .Namespace )
193
211
if change {
194
- roleBindingStorage .Delete (ctx , t .Name , nil )
195
- if _ , err := roleBindingStorage .CreateRoleBindingWithEscalation (ctx , t ); err != nil {
196
- return err
212
+ // Attempt to create
213
+ _ , err := roleBindingStorage .CreateRoleBindingWithEscalation (ctx , t )
214
+ // Unconditional replace if it already exists
215
+ if kapierrors .IsAlreadyExists (err ) {
216
+ _ , _ , err = roleBindingStorage .UpdateRoleBindingWithEscalation (ctx , t )
217
+ }
218
+ // Delete and recreate as a last resort
219
+ if err != nil {
220
+ roleBindingStorage .Delete (ctx , t .Name , nil )
221
+ _ , err = roleBindingStorage .CreateRoleBindingWithEscalation (ctx , t )
222
+ }
223
+ // Gather any error
224
+ if err != nil {
225
+ errs = append (errs , err )
197
226
}
198
227
} else {
199
228
fmt .Fprintf (out , "Overwrite role binding %s/%s\n " , t .Namespace , t .Name )
@@ -205,9 +234,20 @@ func OverwriteBootstrapPolicy(optsGetter restoptions.Getter, policyFile, createB
205
234
case * authorizationapi.ClusterRole :
206
235
ctx := kapi .WithNamespace (kapi .NewContext (), t .Namespace )
207
236
if change {
208
- clusterRoleStorage .Delete (ctx , t .Name , nil )
209
- if _ , err := clusterRoleStorage .CreateClusterRoleWithEscalation (ctx , t ); err != nil {
210
- return err
237
+ // Attempt to create
238
+ _ , err := clusterRoleStorage .CreateClusterRoleWithEscalation (ctx , t )
239
+ // Unconditional replace if it already exists
240
+ if kapierrors .IsAlreadyExists (err ) {
241
+ _ , _ , err = clusterRoleStorage .UpdateClusterRoleWithEscalation (ctx , t )
242
+ }
243
+ // Delete and recreate as a last resort
244
+ if err != nil {
245
+ clusterRoleStorage .Delete (ctx , t .Name , nil )
246
+ _ , err = clusterRoleStorage .CreateClusterRoleWithEscalation (ctx , t )
247
+ }
248
+ // Gather any error
249
+ if err != nil {
250
+ errs = append (errs , err )
211
251
}
212
252
} else {
213
253
fmt .Fprintf (out , "Overwrite role %s/%s\n " , t .Namespace , t .Name )
@@ -218,9 +258,20 @@ func OverwriteBootstrapPolicy(optsGetter restoptions.Getter, policyFile, createB
218
258
case * authorizationapi.ClusterRoleBinding :
219
259
ctx := kapi .WithNamespace (kapi .NewContext (), t .Namespace )
220
260
if change {
221
- clusterRoleBindingStorage .Delete (ctx , t .Name , nil )
222
- if _ , err := clusterRoleBindingStorage .CreateClusterRoleBindingWithEscalation (ctx , t ); err != nil {
223
- return err
261
+ // Attempt to create
262
+ _ , err := clusterRoleBindingStorage .CreateClusterRoleBindingWithEscalation (ctx , t )
263
+ // Unconditional replace if it already exists
264
+ if kapierrors .IsAlreadyExists (err ) {
265
+ _ , _ , err = clusterRoleBindingStorage .UpdateClusterRoleBindingWithEscalation (ctx , t )
266
+ }
267
+ // Delete and recreate as a last resort
268
+ if err != nil {
269
+ clusterRoleBindingStorage .Delete (ctx , t .Name , nil )
270
+ _ , err = clusterRoleBindingStorage .CreateClusterRoleBindingWithEscalation (ctx , t )
271
+ }
272
+ // Gather any error
273
+ if err != nil {
274
+ errs = append (errs , err )
224
275
}
225
276
} else {
226
277
fmt .Fprintf (out , "Overwrite role binding %s/%s\n " , t .Namespace , t .Name )
@@ -230,13 +281,13 @@ func OverwriteBootstrapPolicy(optsGetter restoptions.Getter, policyFile, createB
230
281
}
231
282
232
283
default :
233
- return fmt .Errorf ("only roles and rolebindings may be created in this mode, not: %v" , reflect .TypeOf (t ))
284
+ errs = append ( errs , fmt .Errorf ("only roles and rolebindings may be created in this mode, not: %v" , reflect .TypeOf (t ) ))
234
285
}
235
286
}
236
287
if ! change {
237
288
fmt .Fprintf (out , "To make the changes described above, pass --force\n " )
238
289
}
239
- return nil
290
+ return kerrors . NewAggregate ( errs )
240
291
})
241
292
}
242
293
0 commit comments