mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 12:43:23 +00:00
Merge pull request #62945 from nak3/all-resource-create-role
Automatic merge from submit-queue (batch tested with PRs 67026, 62945, 66917). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. `kubectl create {clusterrole,role}`'s `--resources` flag support asterisk to specify all resources **What this PR does / why we need it**: Currently `kubectl create (cluster)role`'s `--resources` flag does not support asterisk to specify all resources. ``` # kubectl create clusterrole superrole --verb=get --resource=* the server doesn't have a resource type "*" ``` As an user, we create a role with `--resources=*` sometimes, so this PR supports it. Fixes https://github.com/kubernetes/kubernetes/issues/62989 **Special notes for your reviewer**: - This patch does not support `--resource=*` for `SpecialVerbs` - e.g `kubectl create role foo --verb=impersonate --resource=*`, because current code also does not support `kubectl create role foo --verb=impersonate --resource=users,pods` **Release note**: ```release-note `kubectl create {clusterrole,role}`'s `--resources` flag supports asterisk to specify all resources. ```
This commit is contained in:
commit
bd0de223da
@ -204,6 +204,11 @@ func (o *CreateRoleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
|
||||
}
|
||||
resource.Resource = parts[0]
|
||||
|
||||
if resource.Resource == "*" && len(parts) == 1 && len(sections) == 1 {
|
||||
o.Resources = []ResourceOptions{*resource}
|
||||
break
|
||||
}
|
||||
|
||||
o.Resources = append(o.Resources, *resource)
|
||||
}
|
||||
|
||||
@ -279,6 +284,9 @@ func (o *CreateRoleOptions) validateResource() error {
|
||||
if len(r.Resource) == 0 {
|
||||
return fmt.Errorf("resource must be specified if apiGroup/subresource specified")
|
||||
}
|
||||
if r.Resource == "*" {
|
||||
return nil
|
||||
}
|
||||
|
||||
resource := schema.GroupVersionResource{Resource: r.Resource, Group: r.Group}
|
||||
groupVersionResource, err := o.Mapper.ResourceFor(schema.GroupVersionResource{Resource: r.Resource, Group: r.Group})
|
||||
|
@ -360,24 +360,26 @@ func TestComplete(t *testing.T) {
|
||||
tf.Client = &fake.RESTClient{}
|
||||
tf.ClientConfigVal = defaultClientConfig()
|
||||
|
||||
cmd := NewCmdCreateRole(tf, genericclioptions.NewTestIOStreamsDiscard())
|
||||
cmd.Flags().Set("resource", "pods,deployments.extensions")
|
||||
defaultTestResources := "pods,deployments.extensions"
|
||||
|
||||
tests := map[string]struct {
|
||||
params []string
|
||||
resources string
|
||||
roleOptions *CreateRoleOptions
|
||||
expected *CreateRoleOptions
|
||||
expectErr bool
|
||||
}{
|
||||
"test-missing-name": {
|
||||
params: []string{},
|
||||
params: []string{},
|
||||
resources: defaultTestResources,
|
||||
roleOptions: &CreateRoleOptions{
|
||||
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
|
||||
},
|
||||
expectErr: true,
|
||||
},
|
||||
"test-duplicate-verbs": {
|
||||
params: []string{roleName},
|
||||
params: []string{roleName},
|
||||
resources: defaultTestResources,
|
||||
roleOptions: &CreateRoleOptions{
|
||||
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
|
||||
Name: roleName,
|
||||
@ -410,7 +412,8 @@ func TestComplete(t *testing.T) {
|
||||
expectErr: false,
|
||||
},
|
||||
"test-verball": {
|
||||
params: []string{roleName},
|
||||
params: []string{roleName},
|
||||
resources: defaultTestResources,
|
||||
roleOptions: &CreateRoleOptions{
|
||||
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
|
||||
Name: roleName,
|
||||
@ -438,8 +441,151 @@ func TestComplete(t *testing.T) {
|
||||
},
|
||||
expectErr: false,
|
||||
},
|
||||
"test-allresource": {
|
||||
params: []string{roleName},
|
||||
resources: "*,pods",
|
||||
roleOptions: &CreateRoleOptions{
|
||||
PrintFlags: genericclioptions.NewPrintFlags("created"),
|
||||
Name: roleName,
|
||||
Verbs: []string{"*"},
|
||||
},
|
||||
expected: &CreateRoleOptions{
|
||||
Name: roleName,
|
||||
Verbs: []string{"*"},
|
||||
Resources: []ResourceOptions{
|
||||
{
|
||||
Resource: "*",
|
||||
},
|
||||
},
|
||||
ResourceNames: []string{},
|
||||
},
|
||||
expectErr: false,
|
||||
},
|
||||
"test-allresource-subresource": {
|
||||
params: []string{roleName},
|
||||
resources: "*/scale,pods",
|
||||
roleOptions: &CreateRoleOptions{
|
||||
PrintFlags: genericclioptions.NewPrintFlags("created"),
|
||||
Name: roleName,
|
||||
Verbs: []string{"*"},
|
||||
},
|
||||
expected: &CreateRoleOptions{
|
||||
Name: roleName,
|
||||
Verbs: []string{"*"},
|
||||
Resources: []ResourceOptions{
|
||||
{
|
||||
Resource: "*",
|
||||
SubResource: "scale",
|
||||
},
|
||||
{
|
||||
Resource: "pods",
|
||||
},
|
||||
},
|
||||
ResourceNames: []string{},
|
||||
},
|
||||
expectErr: false,
|
||||
},
|
||||
"test-allresrouce-allgroup": {
|
||||
params: []string{roleName},
|
||||
resources: "*.*,pods",
|
||||
roleOptions: &CreateRoleOptions{
|
||||
PrintFlags: genericclioptions.NewPrintFlags("created"),
|
||||
Name: roleName,
|
||||
Verbs: []string{"*"},
|
||||
},
|
||||
expected: &CreateRoleOptions{
|
||||
Name: roleName,
|
||||
Verbs: []string{"*"},
|
||||
Resources: []ResourceOptions{
|
||||
{
|
||||
Resource: "*",
|
||||
Group: "*",
|
||||
},
|
||||
{
|
||||
Resource: "pods",
|
||||
},
|
||||
},
|
||||
ResourceNames: []string{},
|
||||
},
|
||||
expectErr: false,
|
||||
},
|
||||
"test-allresource-allgroup-subresource": {
|
||||
params: []string{roleName},
|
||||
resources: "*.*/scale,pods",
|
||||
roleOptions: &CreateRoleOptions{
|
||||
PrintFlags: genericclioptions.NewPrintFlags("created"),
|
||||
Name: roleName,
|
||||
Verbs: []string{"*"},
|
||||
},
|
||||
expected: &CreateRoleOptions{
|
||||
Name: roleName,
|
||||
Verbs: []string{"*"},
|
||||
Resources: []ResourceOptions{
|
||||
{
|
||||
Resource: "*",
|
||||
Group: "*",
|
||||
SubResource: "scale",
|
||||
},
|
||||
{
|
||||
Resource: "pods",
|
||||
},
|
||||
},
|
||||
ResourceNames: []string{},
|
||||
},
|
||||
expectErr: false,
|
||||
},
|
||||
"test-allresource-specificgroup": {
|
||||
params: []string{roleName},
|
||||
resources: "*.extensions,pods",
|
||||
roleOptions: &CreateRoleOptions{
|
||||
PrintFlags: genericclioptions.NewPrintFlags("created"),
|
||||
Name: roleName,
|
||||
Verbs: []string{"*"},
|
||||
},
|
||||
expected: &CreateRoleOptions{
|
||||
Name: roleName,
|
||||
Verbs: []string{"*"},
|
||||
Resources: []ResourceOptions{
|
||||
{
|
||||
Resource: "*",
|
||||
Group: "extensions",
|
||||
},
|
||||
{
|
||||
Resource: "pods",
|
||||
},
|
||||
},
|
||||
ResourceNames: []string{},
|
||||
},
|
||||
expectErr: false,
|
||||
},
|
||||
"test-allresource-specificgroup-subresource": {
|
||||
params: []string{roleName},
|
||||
resources: "*.extensions/scale,pods",
|
||||
roleOptions: &CreateRoleOptions{
|
||||
PrintFlags: genericclioptions.NewPrintFlags("created"),
|
||||
Name: roleName,
|
||||
Verbs: []string{"*"},
|
||||
},
|
||||
expected: &CreateRoleOptions{
|
||||
Name: roleName,
|
||||
Verbs: []string{"*"},
|
||||
Resources: []ResourceOptions{
|
||||
{
|
||||
Resource: "*",
|
||||
Group: "extensions",
|
||||
SubResource: "scale",
|
||||
},
|
||||
{
|
||||
Resource: "pods",
|
||||
},
|
||||
},
|
||||
ResourceNames: []string{},
|
||||
},
|
||||
expectErr: false,
|
||||
},
|
||||
"test-duplicate-resourcenames": {
|
||||
params: []string{roleName},
|
||||
params: []string{roleName},
|
||||
resources: defaultTestResources,
|
||||
roleOptions: &CreateRoleOptions{
|
||||
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
|
||||
Name: roleName,
|
||||
@ -464,7 +610,8 @@ func TestComplete(t *testing.T) {
|
||||
expectErr: false,
|
||||
},
|
||||
"test-valid-complete-case": {
|
||||
params: []string{roleName},
|
||||
params: []string{roleName},
|
||||
resources: defaultTestResources,
|
||||
roleOptions: &CreateRoleOptions{
|
||||
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
|
||||
Name: roleName,
|
||||
@ -491,6 +638,9 @@ func TestComplete(t *testing.T) {
|
||||
}
|
||||
|
||||
for name, test := range tests {
|
||||
cmd := NewCmdCreateRole(tf, genericclioptions.NewTestIOStreamsDiscard())
|
||||
cmd.Flags().Set("resource", test.resources)
|
||||
|
||||
err := test.roleOptions.Complete(tf, cmd, test.params)
|
||||
if !test.expectErr && err != nil {
|
||||
t.Errorf("%s: unexpected error: %v", name, err)
|
||||
|
Loading…
Reference in New Issue
Block a user