Merge pull request #101643 from carlory/fix-1035

Fix auth can-i provides potentially misleading output with impersonate
This commit is contained in:
Kubernetes Prow Robot 2021-05-03 07:50:03 -07:00 committed by GitHub
commit 271476446b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 87 additions and 4 deletions

View File

@ -98,6 +98,8 @@ var (
resourceVerbs = sets.NewString("get", "list", "watch", "create", "update", "patch", "delete", "deletecollection", "use", "bind", "impersonate", "*")
nonResourceURLVerbs = sets.NewString("get", "put", "post", "head", "options", "delete", "patch", "*")
// holds all the server-supported resources that cannot be discovered by clients. i.e. users and groups for the impersonate verb
nonStandardResourceNames = sets.NewString("users", "groups")
)
// NewCmdCanI returns an initialized Command for 'auth can-i' sub command
@ -304,10 +306,12 @@ func (o *CanIOptions) resourceFor(mapper meta.RESTMapper, resourceArg string) sc
var err error
gvr, err = mapper.ResourceFor(groupResource.WithVersion(""))
if err != nil {
if len(groupResource.Group) == 0 {
fmt.Fprintf(o.ErrOut, "Warning: the server doesn't have a resource type '%s'\n", groupResource.Resource)
} else {
fmt.Fprintf(o.ErrOut, "Warning: the server doesn't have a resource type '%s' in group '%s'\n", groupResource.Resource, groupResource.Group)
if !nonStandardResourceNames.Has(groupResource.String()) {
if len(groupResource.Group) == 0 {
fmt.Fprintf(o.ErrOut, "Warning: the server doesn't have a resource type '%s'\n", groupResource.Resource)
} else {
fmt.Fprintf(o.ErrOut, "Warning: the server doesn't have a resource type '%s' in group '%s'\n", groupResource.Resource, groupResource.Group)
}
}
return schema.GroupVersionResource{Resource: resourceArg}
}

View File

@ -230,6 +230,85 @@ func TestRunAccessList(t *testing.T) {
})
}
func TestRunResourceFor(t *testing.T) {
tests := []struct {
name string
o *CanIOptions
resourceArg string
expectGVR schema.GroupVersionResource
expectedErrOut string
}{
{
name: "any resources",
o: &CanIOptions{},
resourceArg: "*",
expectGVR: schema.GroupVersionResource{
Resource: "*",
},
},
{
name: "server-supported standard resources without group",
o: &CanIOptions{},
resourceArg: "pods",
expectGVR: schema.GroupVersionResource{
Version: "v1",
Resource: "pods",
},
},
{
name: "server-supported standard resources with group",
o: &CanIOptions{},
resourceArg: "jobs",
expectGVR: schema.GroupVersionResource{
Group: "batch",
Version: "v1",
Resource: "jobs",
},
},
{
name: "server-supported nonstandard resources",
o: &CanIOptions{},
resourceArg: "users",
expectGVR: schema.GroupVersionResource{
Resource: "users",
},
},
{
name: "invalid resources",
o: &CanIOptions{},
resourceArg: "invalid",
expectGVR: schema.GroupVersionResource{
Resource: "invalid",
},
expectedErrOut: "Warning: the server doesn't have a resource type 'invalid'\n",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
ioStreams, _, _, buf := genericclioptions.NewTestIOStreams()
test.o.IOStreams = ioStreams
restMapper, err := tf.ToRESTMapper()
if err != nil {
t.Errorf("got unexpected error when do tf.ToRESTMapper(): %v", err)
return
}
gvr := test.o.resourceFor(restMapper, test.resourceArg)
if gvr != test.expectGVR {
t.Errorf("expected %v\n but got %v\n", test.expectGVR, gvr)
}
if buf.String() != test.expectedErrOut {
t.Errorf("expected %v\n but got %v\n", test.expectedErrOut, buf.String())
}
})
}
}
func getSelfSubjectRulesReview() *authorizationv1.SelfSubjectRulesReview {
return &authorizationv1.SelfSubjectRulesReview{
Status: authorizationv1.SubjectRulesReviewStatus{