Skip to content

Commit 6228725

Browse files
danielpacaklizrice
authored andcommitted
fix: Bind kube client configuration flags before instantiating a kube client (#42)
Resolves: #41
1 parent 5ab9e06 commit 6228725

File tree

3 files changed

+68
-81
lines changed

3 files changed

+68
-81
lines changed

pkg/cmd/list.go

+36-58
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ type Action struct {
6868
nonResourceURL string
6969
subResource string
7070
resourceName string
71-
gr schema.GroupResource
71+
gr schema.GroupResource
7272

7373
namespace string
7474
allNamespaces bool
@@ -96,67 +96,44 @@ type whoCan struct {
9696
clioptions.IOStreams
9797
}
9898

99-
func NewWhoCanOptions(configFlags *clioptions.ConfigFlags,
100-
clientConfig clientcmd.ClientConfig,
101-
clientNamespace clientcore.NamespaceInterface,
102-
clientRBAC clientrbac.RbacV1Interface,
103-
namespaceValidator NamespaceValidator,
104-
resourceResolver ResourceResolver,
105-
accessChecker AccessChecker,
106-
policyRuleMatcher PolicyRuleMatcher,
107-
streams clioptions.IOStreams) *whoCan {
108-
return &whoCan{
109-
configFlags: configFlags,
110-
clientConfig: clientConfig,
111-
clientNamespace: clientNamespace,
112-
clientRBAC: clientRBAC,
113-
namespaceValidator: namespaceValidator,
114-
resourceResolver: resourceResolver,
115-
accessChecker: accessChecker,
116-
policyRuleMatcher: policyRuleMatcher,
117-
IOStreams: streams,
118-
}
119-
}
120-
12199
func NewCmdWhoCan(streams clioptions.IOStreams) (*cobra.Command, error) {
122-
configFlags := clioptions.NewConfigFlags(true)
123-
124-
clientConfig, err := configFlags.ToRESTConfig()
125-
if err != nil {
126-
return nil, fmt.Errorf("getting config: %v", err)
127-
}
128-
129-
client, err := kubernetes.NewForConfig(clientConfig)
130-
if err != nil {
131-
return nil, fmt.Errorf("creating client: %v", err)
132-
}
133-
134-
mapper, err := configFlags.ToRESTMapper()
135-
if err != nil {
136-
return nil, fmt.Errorf("getting mapper: %v", err)
137-
}
138-
139-
clientNamespace := client.CoreV1().Namespaces()
140-
accessChecker := NewAccessChecker(client.AuthorizationV1().SelfSubjectAccessReviews())
141-
namespaceValidator := NewNamespaceValidator(clientNamespace)
142-
resourceResolver := NewResourceResolver(client.Discovery(), mapper)
143-
144-
o := NewWhoCanOptions(configFlags,
145-
configFlags.ToRawKubeConfigLoader(),
146-
clientNamespace,
147-
client.RbacV1(),
148-
namespaceValidator,
149-
resourceResolver,
150-
accessChecker,
151-
NewPolicyRuleMatcher(),
152-
streams)
100+
var configFlags *clioptions.ConfigFlags
101+
var o whoCan
153102

154103
cmd := &cobra.Command{
155104
Use: whoCanUsage,
156105
Long: whoCanLong,
157106
Example: whoCanExample,
158107
SilenceUsage: true,
159108
RunE: func(cmd *cobra.Command, args []string) error {
109+
clientConfig, err := configFlags.ToRESTConfig()
110+
if err != nil {
111+
return fmt.Errorf("getting config: %v", err)
112+
}
113+
114+
client, err := kubernetes.NewForConfig(clientConfig)
115+
if err != nil {
116+
return fmt.Errorf("creating client: %v", err)
117+
}
118+
119+
mapper, err := configFlags.ToRESTMapper()
120+
if err != nil {
121+
return fmt.Errorf("getting mapper: %v", err)
122+
}
123+
124+
clientNamespace := client.CoreV1().Namespaces()
125+
namespaceValidator := NewNamespaceValidator(clientNamespace)
126+
127+
o.configFlags = configFlags
128+
o.clientConfig = configFlags.ToRawKubeConfigLoader()
129+
o.clientNamespace = clientNamespace
130+
o.clientRBAC = client.RbacV1()
131+
o.namespaceValidator = namespaceValidator
132+
o.resourceResolver = NewResourceResolver(client.Discovery(), mapper)
133+
o.accessChecker = NewAccessChecker(client.AuthorizationV1().SelfSubjectAccessReviews())
134+
o.policyRuleMatcher = NewPolicyRuleMatcher()
135+
o.IOStreams = streams
136+
160137
if err := o.Complete(args); err != nil {
161138
return err
162139
}
@@ -171,14 +148,15 @@ func NewCmdWhoCan(streams clioptions.IOStreams) (*cobra.Command, error) {
171148
},
172149
}
173150

174-
cmd.PersistentFlags().StringVar(&o.subResource, "subresource", o.subResource,
151+
cmd.Flags().StringVar(&o.subResource, "subresource", o.subResource,
175152
"SubResource such as pod/log or deployment/scale")
176-
cmd.PersistentFlags().BoolVarP(&o.allNamespaces, "all-namespaces", "A", false,
153+
cmd.Flags().BoolVarP(&o.allNamespaces, "all-namespaces", "A", o.allNamespaces,
177154
"If true, check the specified action in all namespaces.")
178155

179-
flag.CommandLine.VisitAll(func(goflag *flag.Flag) {
180-
cmd.PersistentFlags().AddGoFlag(goflag)
156+
flag.CommandLine.VisitAll(func(gf *flag.Flag) {
157+
cmd.Flags().AddGoFlag(gf)
181158
})
159+
configFlags = clioptions.NewConfigFlags(true)
182160
configFlags.AddFlags(cmd.Flags())
183161

184162
return cmd, nil

pkg/cmd/list_test.go

+29-23
Original file line numberDiff line numberDiff line change
@@ -219,19 +219,21 @@ func TestComplete(t *testing.T) {
219219
}
220220

221221
// given
222-
o := NewWhoCanOptions(configFlags,
223-
clientConfig,
224-
kubeClient.CoreV1().Namespaces(),
225-
kubeClient.RbacV1(),
226-
namespaceValidator,
227-
resourceResolver,
228-
accessChecker,
229-
policyRuleMatcher,
230-
clioptions.NewTestIOStreamsDiscard())
231-
232-
// and
233-
o.namespace = tt.flags.namespace
234-
o.allNamespaces = tt.flags.allNamespaces
222+
o := whoCan{
223+
Action: Action{
224+
namespace: tt.flags.namespace,
225+
allNamespaces: tt.flags.allNamespaces,
226+
},
227+
configFlags: configFlags,
228+
clientConfig: clientConfig,
229+
clientNamespace: kubeClient.CoreV1().Namespaces(),
230+
clientRBAC: kubeClient.RbacV1(),
231+
namespaceValidator: namespaceValidator,
232+
resourceResolver: resourceResolver,
233+
accessChecker: accessChecker,
234+
policyRuleMatcher: policyRuleMatcher,
235+
IOStreams: clioptions.NewTestIOStreamsDiscard(),
236+
}
235237

236238
// when
237239
err := o.Complete(tt.args)
@@ -398,16 +400,20 @@ func TestWhoCan_checkAPIAccess(t *testing.T) {
398400

399401
// given
400402
configFlags := &clioptions.ConfigFlags{}
401-
wc := NewWhoCanOptions(configFlags,
402-
configFlags.ToRawKubeConfigLoader(),
403-
client.CoreV1().Namespaces(),
404-
client.RbacV1(),
405-
namespaceValidator,
406-
resourceResolver,
407-
accessChecker,
408-
policyRuleMatcher,
409-
clioptions.NewTestIOStreamsDiscard())
410-
wc.namespace = tt.namespace
403+
wc := whoCan{
404+
Action: Action{
405+
namespace: tt.namespace,
406+
},
407+
configFlags: configFlags,
408+
clientConfig: configFlags.ToRawKubeConfigLoader(),
409+
clientNamespace: client.CoreV1().Namespaces(),
410+
clientRBAC: client.RbacV1(),
411+
namespaceValidator: namespaceValidator,
412+
resourceResolver: resourceResolver,
413+
accessChecker: accessChecker,
414+
policyRuleMatcher: policyRuleMatcher,
415+
IOStreams: clioptions.NewTestIOStreamsDiscard(),
416+
}
411417

412418
// when
413419
warnings, err := wc.checkAPIAccess()

pkg/cmd/resource_resolver.go

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cmd
22

33
import (
44
"fmt"
5+
"github.com/golang/glog"
56
rbac "k8s.io/api/rbac/v1"
67
"k8s.io/apimachinery/pkg/api/meta"
78
apismeta "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -43,11 +44,13 @@ func (rv *resourceResolver) Resolve(verb, resource, subResource string) (schema.
4344

4445
gvr, err := rv.resolveGVR(resource)
4546
if err != nil {
47+
glog.V(3).Infof("Error while resolving GVR for resource %s: %v", resource, err)
4648
return schema.GroupResource{}, fmt.Errorf("the server doesn't have a resource type \"%s\"", name)
4749
}
4850

4951
apiResource, err := rv.resolveAPIResource(gvr, subResource)
5052
if err != nil {
53+
glog.V(3).Infof("Error while resolving APIResource for GVR %v and subResource %s: %v", gvr, subResource, err)
5154
return schema.GroupResource{}, fmt.Errorf("the server doesn't have a resource type \"%s\"", name)
5255
}
5356

0 commit comments

Comments
 (0)