Skip to content

Commit d09e92f

Browse files
author
OpenShift Bot
authored
Merge pull request #8838 from stevekuznetsov/skuznets/partial-crb
Merged by openshift-bot
2 parents df69a8b + 687da78 commit d09e92f

File tree

3 files changed

+48
-13
lines changed

3 files changed

+48
-13
lines changed

pkg/cmd/admin/policy/policy.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func NewCmdPolicy(name, fullName string, f *clientcmd.Factory, out, errout io.Wr
8787
Message: "Upgrade and repair system policy:",
8888
Commands: []*cobra.Command{
8989
NewCmdReconcileClusterRoles(ReconcileClusterRolesRecommendedName, fullName+" "+ReconcileClusterRolesRecommendedName, f, out, errout),
90-
NewCmdReconcileClusterRoleBindings(ReconcileClusterRoleBindingsRecommendedName, fullName+" "+ReconcileClusterRoleBindingsRecommendedName, f, out),
90+
NewCmdReconcileClusterRoleBindings(ReconcileClusterRoleBindingsRecommendedName, fullName+" "+ReconcileClusterRoleBindingsRecommendedName, f, out, errout),
9191
NewCmdReconcileSCC(ReconcileSCCRecommendedName, fullName+" "+ReconcileSCCRecommendedName, f, out),
9292
},
9393
},

pkg/cmd/admin/policy/reconcile_clusterrolebindings.go

+42-11
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ import (
44
"errors"
55
"fmt"
66
"io"
7+
"strings"
78

89
"github.com/spf13/cobra"
910

1011
kapi "k8s.io/kubernetes/pkg/api"
1112
kapierrors "k8s.io/kubernetes/pkg/api/errors"
1213
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
14+
kutilerrors "k8s.io/kubernetes/pkg/util/errors"
1315
"k8s.io/kubernetes/pkg/util/sets"
1416

1517
authorizationapi "github.com/openshift/origin/pkg/authorization/api"
@@ -23,6 +25,7 @@ import (
2325
// ReconcileClusterRoleBindingsRecommendedName is the recommended command name
2426
const ReconcileClusterRoleBindingsRecommendedName = "reconcile-cluster-role-bindings"
2527

28+
// ReconcileClusterRoleBindingsOptions contains all the necessary functionality for the OpenShift cli reconcile-cluster-role-bindings command
2629
type ReconcileClusterRoleBindingsOptions struct {
2730
// RolesToReconcile says which roles should have their default bindings reconciled.
2831
// An empty or nil slice means reconcile all of them.
@@ -34,6 +37,7 @@ type ReconcileClusterRoleBindingsOptions struct {
3437
ExcludeSubjects []kapi.ObjectReference
3538

3639
Out io.Writer
40+
Err io.Writer
3741
Output string
3842

3943
RoleBindingClient client.ClusterRoleBindingInterface
@@ -66,9 +70,10 @@ You can see which recommended cluster role bindings have changed by choosing an
6670
)
6771

6872
// NewCmdReconcileClusterRoleBindings implements the OpenShift cli reconcile-cluster-role-bindings command
69-
func NewCmdReconcileClusterRoleBindings(name, fullName string, f *clientcmd.Factory, out io.Writer) *cobra.Command {
73+
func NewCmdReconcileClusterRoleBindings(name, fullName string, f *clientcmd.Factory, out, err io.Writer) *cobra.Command {
7074
o := &ReconcileClusterRoleBindingsOptions{
7175
Out: out,
76+
Err: err,
7277
Union: true,
7378
}
7479

@@ -143,15 +148,15 @@ func (o *ReconcileClusterRoleBindingsOptions) Validate() error {
143148
return nil
144149
}
145150

146-
// ReconcileClusterRoleBindingsOptions contains all the necessary functionality for the OpenShift cli reconcile-cluster-role-bindings command
147151
func (o *ReconcileClusterRoleBindingsOptions) RunReconcileClusterRoleBindings(cmd *cobra.Command, f *clientcmd.Factory) error {
148-
changedClusterRoleBindings, err := o.ChangedClusterRoleBindings()
149-
if err != nil {
150-
return err
152+
changedClusterRoleBindings, fetchErr := o.ChangedClusterRoleBindings()
153+
if fetchErr != nil && !IsClusterRoleBindingLookupError(fetchErr) {
154+
// we got an error that isn't due to a partial match, so we can't continue
155+
return fetchErr
151156
}
152157

153158
if len(changedClusterRoleBindings) == 0 {
154-
return nil
159+
return fetchErr
155160
}
156161

157162
if (len(o.Output) != 0) && !o.Confirmed {
@@ -162,19 +167,22 @@ func (o *ReconcileClusterRoleBindingsOptions) RunReconcileClusterRoleBindings(cm
162167
mapper, _ := f.Object(false)
163168
fn := cmdutil.VersionedPrintObject(f.PrintObject, cmd, mapper, o.Out)
164169
if err := fn(list); err != nil {
165-
return err
170+
return kutilerrors.NewAggregate([]error{fetchErr, err})
166171
}
167172
}
168173

169174
if o.Confirmed {
170-
return o.ReplaceChangedRoleBindings(changedClusterRoleBindings)
175+
if err := o.ReplaceChangedRoleBindings(changedClusterRoleBindings); err != nil {
176+
return kutilerrors.NewAggregate([]error{fetchErr, err})
177+
}
171178
}
172179

173-
return nil
180+
return fetchErr
174181
}
175182

176183
// ChangedClusterRoleBindings returns the role bindings that must be created and/or updated to
177-
// match the recommended bootstrap policy
184+
// match the recommended bootstrap policy. If roles to reconcile are provided, but not all are
185+
// found, all partial results are returned.
178186
func (o *ReconcileClusterRoleBindingsOptions) ChangedClusterRoleBindings() ([]*authorizationapi.ClusterRoleBinding, error) {
179187
changedRoleBindings := []*authorizationapi.ClusterRoleBinding{}
180188

@@ -212,7 +220,7 @@ func (o *ReconcileClusterRoleBindingsOptions) ChangedClusterRoleBindings() ([]*a
212220

213221
if len(rolesNotFound) != 0 {
214222
// return the known changes and the error so that a caller can decide if he wants a partial update
215-
return changedRoleBindings, fmt.Errorf("did not find requested cluster role %s", rolesNotFound.List())
223+
return changedRoleBindings, NewClusterRoleBindingLookupError(rolesNotFound.List())
216224
}
217225

218226
return changedRoleBindings, nil
@@ -331,3 +339,26 @@ func DiffObjectReferenceLists(list1 []kapi.ObjectReference, list2 []kapi.ObjectR
331339
}
332340
return
333341
}
342+
343+
func NewClusterRoleBindingLookupError(rolesNotFound []string) error {
344+
return &clusterRoleBindingLookupError{
345+
rolesNotFound: rolesNotFound,
346+
}
347+
}
348+
349+
type clusterRoleBindingLookupError struct {
350+
rolesNotFound []string
351+
}
352+
353+
func (e *clusterRoleBindingLookupError) Error() string {
354+
return fmt.Sprintf("did not find requested cluster roles: %s", strings.Join(e.rolesNotFound, ", "))
355+
}
356+
357+
func IsClusterRoleBindingLookupError(err error) bool {
358+
if err == nil {
359+
return false
360+
}
361+
362+
_, ok := err.(*clusterRoleBindingLookupError)
363+
return ok
364+
}

pkg/diagnostics/cluster/rolebindings.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ func (d *ClusterRoleBindings) Check() types.DiagnosticResult {
5656
}
5757

5858
changedClusterRoleBindings, err := reconcileOptions.ChangedClusterRoleBindings()
59-
if err != nil {
59+
if policycmd.IsClusterRoleBindingLookupError(err) {
60+
// we got a partial match, so we log the error that stopped us from getting a full match
61+
// but continue to interpret the partial results that we did get
62+
r.Warn("CRBD1008", err, fmt.Sprintf("Error finding ClusterRoleBindings: %v", err))
63+
} else if err != nil {
6064
r.Error("CRBD1000", err, fmt.Sprintf("Error inspecting ClusterRoleBindings: %v", err))
6165
return r
6266
}

0 commit comments

Comments
 (0)