Skip to content

Commit

Permalink
fix: Bind kube client configuration flags before instantiating a kube…
Browse files Browse the repository at this point in the history
… client (#42)

Resolves: #41
  • Loading branch information
danielpacak authored and lizrice committed Aug 21, 2019
1 parent 5ab9e06 commit 6228725
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 81 deletions.
94 changes: 36 additions & 58 deletions pkg/cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ type Action struct {
nonResourceURL string
subResource string
resourceName string
gr schema.GroupResource
gr schema.GroupResource

namespace string
allNamespaces bool
Expand Down Expand Up @@ -96,67 +96,44 @@ type whoCan struct {
clioptions.IOStreams
}

func NewWhoCanOptions(configFlags *clioptions.ConfigFlags,
clientConfig clientcmd.ClientConfig,
clientNamespace clientcore.NamespaceInterface,
clientRBAC clientrbac.RbacV1Interface,
namespaceValidator NamespaceValidator,
resourceResolver ResourceResolver,
accessChecker AccessChecker,
policyRuleMatcher PolicyRuleMatcher,
streams clioptions.IOStreams) *whoCan {
return &whoCan{
configFlags: configFlags,
clientConfig: clientConfig,
clientNamespace: clientNamespace,
clientRBAC: clientRBAC,
namespaceValidator: namespaceValidator,
resourceResolver: resourceResolver,
accessChecker: accessChecker,
policyRuleMatcher: policyRuleMatcher,
IOStreams: streams,
}
}

func NewCmdWhoCan(streams clioptions.IOStreams) (*cobra.Command, error) {
configFlags := clioptions.NewConfigFlags(true)

clientConfig, err := configFlags.ToRESTConfig()
if err != nil {
return nil, fmt.Errorf("getting config: %v", err)
}

client, err := kubernetes.NewForConfig(clientConfig)
if err != nil {
return nil, fmt.Errorf("creating client: %v", err)
}

mapper, err := configFlags.ToRESTMapper()
if err != nil {
return nil, fmt.Errorf("getting mapper: %v", err)
}

clientNamespace := client.CoreV1().Namespaces()
accessChecker := NewAccessChecker(client.AuthorizationV1().SelfSubjectAccessReviews())
namespaceValidator := NewNamespaceValidator(clientNamespace)
resourceResolver := NewResourceResolver(client.Discovery(), mapper)

o := NewWhoCanOptions(configFlags,
configFlags.ToRawKubeConfigLoader(),
clientNamespace,
client.RbacV1(),
namespaceValidator,
resourceResolver,
accessChecker,
NewPolicyRuleMatcher(),
streams)
var configFlags *clioptions.ConfigFlags
var o whoCan

cmd := &cobra.Command{
Use: whoCanUsage,
Long: whoCanLong,
Example: whoCanExample,
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
clientConfig, err := configFlags.ToRESTConfig()
if err != nil {
return fmt.Errorf("getting config: %v", err)
}

client, err := kubernetes.NewForConfig(clientConfig)
if err != nil {
return fmt.Errorf("creating client: %v", err)
}

mapper, err := configFlags.ToRESTMapper()
if err != nil {
return fmt.Errorf("getting mapper: %v", err)
}

clientNamespace := client.CoreV1().Namespaces()
namespaceValidator := NewNamespaceValidator(clientNamespace)

o.configFlags = configFlags
o.clientConfig = configFlags.ToRawKubeConfigLoader()
o.clientNamespace = clientNamespace
o.clientRBAC = client.RbacV1()
o.namespaceValidator = namespaceValidator
o.resourceResolver = NewResourceResolver(client.Discovery(), mapper)
o.accessChecker = NewAccessChecker(client.AuthorizationV1().SelfSubjectAccessReviews())
o.policyRuleMatcher = NewPolicyRuleMatcher()
o.IOStreams = streams

if err := o.Complete(args); err != nil {
return err
}
Expand All @@ -171,14 +148,15 @@ func NewCmdWhoCan(streams clioptions.IOStreams) (*cobra.Command, error) {
},
}

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

flag.CommandLine.VisitAll(func(goflag *flag.Flag) {
cmd.PersistentFlags().AddGoFlag(goflag)
flag.CommandLine.VisitAll(func(gf *flag.Flag) {
cmd.Flags().AddGoFlag(gf)
})
configFlags = clioptions.NewConfigFlags(true)
configFlags.AddFlags(cmd.Flags())

return cmd, nil
Expand Down
52 changes: 29 additions & 23 deletions pkg/cmd/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,19 +219,21 @@ func TestComplete(t *testing.T) {
}

// given
o := NewWhoCanOptions(configFlags,
clientConfig,
kubeClient.CoreV1().Namespaces(),
kubeClient.RbacV1(),
namespaceValidator,
resourceResolver,
accessChecker,
policyRuleMatcher,
clioptions.NewTestIOStreamsDiscard())

// and
o.namespace = tt.flags.namespace
o.allNamespaces = tt.flags.allNamespaces
o := whoCan{
Action: Action{
namespace: tt.flags.namespace,
allNamespaces: tt.flags.allNamespaces,
},
configFlags: configFlags,
clientConfig: clientConfig,
clientNamespace: kubeClient.CoreV1().Namespaces(),
clientRBAC: kubeClient.RbacV1(),
namespaceValidator: namespaceValidator,
resourceResolver: resourceResolver,
accessChecker: accessChecker,
policyRuleMatcher: policyRuleMatcher,
IOStreams: clioptions.NewTestIOStreamsDiscard(),
}

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

// given
configFlags := &clioptions.ConfigFlags{}
wc := NewWhoCanOptions(configFlags,
configFlags.ToRawKubeConfigLoader(),
client.CoreV1().Namespaces(),
client.RbacV1(),
namespaceValidator,
resourceResolver,
accessChecker,
policyRuleMatcher,
clioptions.NewTestIOStreamsDiscard())
wc.namespace = tt.namespace
wc := whoCan{
Action: Action{
namespace: tt.namespace,
},
configFlags: configFlags,
clientConfig: configFlags.ToRawKubeConfigLoader(),
clientNamespace: client.CoreV1().Namespaces(),
clientRBAC: client.RbacV1(),
namespaceValidator: namespaceValidator,
resourceResolver: resourceResolver,
accessChecker: accessChecker,
policyRuleMatcher: policyRuleMatcher,
IOStreams: clioptions.NewTestIOStreamsDiscard(),
}

// when
warnings, err := wc.checkAPIAccess()
Expand Down
3 changes: 3 additions & 0 deletions pkg/cmd/resource_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

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

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

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

Expand Down

0 comments on commit 6228725

Please sign in to comment.