diff --git a/contrib/completions/bash/oadm b/contrib/completions/bash/oadm index 89c1821b8a5a..335e6f974e84 100644 --- a/contrib/completions/bash/oadm +++ b/contrib/completions/bash/oadm @@ -1846,6 +1846,24 @@ _oadm_groups_new() flags_with_completion=() flags_completion=() + flags+=("--no-headers") + local_nonpersistent_flags+=("--no-headers") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--output-version=") + local_nonpersistent_flags+=("--output-version=") + flags+=("--show-all") + flags+=("-a") + local_nonpersistent_flags+=("--show-all") + flags+=("--show-labels") + local_nonpersistent_flags+=("--show-labels") + flags+=("--sort-by=") + local_nonpersistent_flags+=("--sort-by=") + flags+=("--template=") + flags_with_completion+=("--template") + flags_completion+=("_filedir") + local_nonpersistent_flags+=("--template=") flags+=("--api-version=") flags+=("--as=") flags+=("--certificate-authority=") diff --git a/contrib/completions/bash/oc b/contrib/completions/bash/oc index 39d0c2e783c2..9c2f33b2f85f 100644 --- a/contrib/completions/bash/oc +++ b/contrib/completions/bash/oc @@ -1942,6 +1942,24 @@ _oc_adm_groups_new() flags_with_completion=() flags_completion=() + flags+=("--no-headers") + local_nonpersistent_flags+=("--no-headers") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--output-version=") + local_nonpersistent_flags+=("--output-version=") + flags+=("--show-all") + flags+=("-a") + local_nonpersistent_flags+=("--show-all") + flags+=("--show-labels") + local_nonpersistent_flags+=("--show-labels") + flags+=("--sort-by=") + local_nonpersistent_flags+=("--sort-by=") + flags+=("--template=") + flags_with_completion+=("--template") + flags_completion+=("_filedir") + local_nonpersistent_flags+=("--template=") flags+=("--api-version=") flags+=("--as=") flags+=("--certificate-authority=") diff --git a/contrib/completions/bash/openshift b/contrib/completions/bash/openshift index 09da48b33d90..62d0dbb34f14 100644 --- a/contrib/completions/bash/openshift +++ b/contrib/completions/bash/openshift @@ -1846,6 +1846,24 @@ _openshift_admin_groups_new() flags_with_completion=() flags_completion=() + flags+=("--no-headers") + local_nonpersistent_flags+=("--no-headers") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--output-version=") + local_nonpersistent_flags+=("--output-version=") + flags+=("--show-all") + flags+=("-a") + local_nonpersistent_flags+=("--show-all") + flags+=("--show-labels") + local_nonpersistent_flags+=("--show-labels") + flags+=("--sort-by=") + local_nonpersistent_flags+=("--sort-by=") + flags+=("--template=") + flags_with_completion+=("--template") + flags_completion+=("_filedir") + local_nonpersistent_flags+=("--template=") flags+=("--api-version=") flags+=("--as=") flags+=("--certificate-authority=") @@ -6214,6 +6232,24 @@ _openshift_cli_adm_groups_new() flags_with_completion=() flags_completion=() + flags+=("--no-headers") + local_nonpersistent_flags+=("--no-headers") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--output-version=") + local_nonpersistent_flags+=("--output-version=") + flags+=("--show-all") + flags+=("-a") + local_nonpersistent_flags+=("--show-all") + flags+=("--show-labels") + local_nonpersistent_flags+=("--show-labels") + flags+=("--sort-by=") + local_nonpersistent_flags+=("--sort-by=") + flags+=("--template=") + flags_with_completion+=("--template") + flags_completion+=("_filedir") + local_nonpersistent_flags+=("--template=") flags+=("--api-version=") flags+=("--as=") flags+=("--certificate-authority=") diff --git a/contrib/completions/zsh/oadm b/contrib/completions/zsh/oadm index a61497b0d55b..6fc88307555b 100644 --- a/contrib/completions/zsh/oadm +++ b/contrib/completions/zsh/oadm @@ -2007,6 +2007,24 @@ _oadm_groups_new() flags_with_completion=() flags_completion=() + flags+=("--no-headers") + local_nonpersistent_flags+=("--no-headers") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--output-version=") + local_nonpersistent_flags+=("--output-version=") + flags+=("--show-all") + flags+=("-a") + local_nonpersistent_flags+=("--show-all") + flags+=("--show-labels") + local_nonpersistent_flags+=("--show-labels") + flags+=("--sort-by=") + local_nonpersistent_flags+=("--sort-by=") + flags+=("--template=") + flags_with_completion+=("--template") + flags_completion+=("_filedir") + local_nonpersistent_flags+=("--template=") flags+=("--api-version=") flags+=("--as=") flags+=("--certificate-authority=") diff --git a/contrib/completions/zsh/oc b/contrib/completions/zsh/oc index 66bb6437c640..3bbf1cc0255e 100644 --- a/contrib/completions/zsh/oc +++ b/contrib/completions/zsh/oc @@ -2103,6 +2103,24 @@ _oc_adm_groups_new() flags_with_completion=() flags_completion=() + flags+=("--no-headers") + local_nonpersistent_flags+=("--no-headers") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--output-version=") + local_nonpersistent_flags+=("--output-version=") + flags+=("--show-all") + flags+=("-a") + local_nonpersistent_flags+=("--show-all") + flags+=("--show-labels") + local_nonpersistent_flags+=("--show-labels") + flags+=("--sort-by=") + local_nonpersistent_flags+=("--sort-by=") + flags+=("--template=") + flags_with_completion+=("--template") + flags_completion+=("_filedir") + local_nonpersistent_flags+=("--template=") flags+=("--api-version=") flags+=("--as=") flags+=("--certificate-authority=") diff --git a/contrib/completions/zsh/openshift b/contrib/completions/zsh/openshift index 1f113764fe69..41004d00c0c9 100644 --- a/contrib/completions/zsh/openshift +++ b/contrib/completions/zsh/openshift @@ -2007,6 +2007,24 @@ _openshift_admin_groups_new() flags_with_completion=() flags_completion=() + flags+=("--no-headers") + local_nonpersistent_flags+=("--no-headers") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--output-version=") + local_nonpersistent_flags+=("--output-version=") + flags+=("--show-all") + flags+=("-a") + local_nonpersistent_flags+=("--show-all") + flags+=("--show-labels") + local_nonpersistent_flags+=("--show-labels") + flags+=("--sort-by=") + local_nonpersistent_flags+=("--sort-by=") + flags+=("--template=") + flags_with_completion+=("--template") + flags_completion+=("_filedir") + local_nonpersistent_flags+=("--template=") flags+=("--api-version=") flags+=("--as=") flags+=("--certificate-authority=") @@ -6375,6 +6393,24 @@ _openshift_cli_adm_groups_new() flags_with_completion=() flags_completion=() + flags+=("--no-headers") + local_nonpersistent_flags+=("--no-headers") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--output-version=") + local_nonpersistent_flags+=("--output-version=") + flags+=("--show-all") + flags+=("-a") + local_nonpersistent_flags+=("--show-all") + flags+=("--show-labels") + local_nonpersistent_flags+=("--show-labels") + flags+=("--sort-by=") + local_nonpersistent_flags+=("--sort-by=") + flags+=("--template=") + flags_with_completion+=("--template") + flags_completion+=("_filedir") + local_nonpersistent_flags+=("--template=") flags+=("--api-version=") flags+=("--as=") flags+=("--certificate-authority=") diff --git a/docs/generated/oadm_by_example_content.adoc b/docs/generated/oadm_by_example_content.adoc index a8c3668b062c..7adccb71eef2 100644 --- a/docs/generated/oadm_by_example_content.adoc +++ b/docs/generated/oadm_by_example_content.adoc @@ -237,6 +237,9 @@ Create a new group # Add a group with two users oadm groups new my-group user1 user2 + + # Add a group with one user and shorter output + oadm groups new my-group user1 -o name ---- ==== diff --git a/docs/generated/oc_by_example_content.adoc b/docs/generated/oc_by_example_content.adoc index 9858df971f25..ada2467995e9 100644 --- a/docs/generated/oc_by_example_content.adoc +++ b/docs/generated/oc_by_example_content.adoc @@ -237,6 +237,9 @@ Create a new group # Add a group with two users oc adm groups new my-group user1 user2 + + # Add a group with one user and shorter output + oc adm groups new my-group user1 -o name ---- ==== diff --git a/docs/man/man1/oadm-groups-new.1 b/docs/man/man1/oadm-groups-new.1 index 70de4fca858a..3b796e56cbb1 100644 --- a/docs/man/man1/oadm-groups-new.1 +++ b/docs/man/man1/oadm-groups-new.1 @@ -19,6 +19,39 @@ Create a new group. This command will create a new group with an optional list of users. +.SH OPTIONS +.PP +\fB\-\-no\-headers\fP=false + When using the default output, don't print headers. + +.PP +\fB\-o\fP, \fB\-\-output\fP="" + Output format. One of: json|yaml|wide|name|go\-template=...|go\-template\-file=...|jsonpath=...|jsonpath\-file=... See golang template [ +\[la]http://golang.org/pkg/text/template/#pkg-overview\[ra]] and jsonpath template [ +\[la]http://releases.k8s.io/release-1.3/docs/user-guide/jsonpath.md\[ra]]. + +.PP +\fB\-\-output\-version\fP="" + Output the formatted object with the given group version (for ex: 'extensions/v1beta1'). + +.PP +\fB\-a\fP, \fB\-\-show\-all\fP=false + When printing, show all resources (default hide terminated pods.) + +.PP +\fB\-\-show\-labels\fP=false + When printing, show all labels as the last column (default hide labels column) + +.PP +\fB\-\-sort\-by\fP="" + If non\-empty, sort list types using this field specification. The field specification is expressed as a JSONPath expression (e.g. '{.metadata.name}'). The field in the API resource specified by this JSONPath expression must be an integer or a string. + +.PP +\fB\-\-template\fP="" + Template string or path to template file to use when \-o=go\-template, \-o=go\-template\-file. The template format is golang templates [ +\[la]http://golang.org/pkg/text/template/#pkg-overview\[ra]]. + + .SH OPTIONS INHERITED FROM PARENT COMMANDS .PP \fB\-\-api\-version\fP="" @@ -96,6 +129,9 @@ This command will create a new group with an optional list of users. # Add a group with two users oadm groups new my\-group user1 user2 + # Add a group with one user and shorter output + oadm groups new my\-group user1 \-o name + .fi .RE diff --git a/docs/man/man1/oc-adm-groups-new.1 b/docs/man/man1/oc-adm-groups-new.1 index 35435a544646..392e95e785ec 100644 --- a/docs/man/man1/oc-adm-groups-new.1 +++ b/docs/man/man1/oc-adm-groups-new.1 @@ -19,6 +19,39 @@ Create a new group. This command will create a new group with an optional list of users. +.SH OPTIONS +.PP +\fB\-\-no\-headers\fP=false + When using the default output, don't print headers. + +.PP +\fB\-o\fP, \fB\-\-output\fP="" + Output format. One of: json|yaml|wide|name|go\-template=...|go\-template\-file=...|jsonpath=...|jsonpath\-file=... See golang template [ +\[la]http://golang.org/pkg/text/template/#pkg-overview\[ra]] and jsonpath template [ +\[la]http://releases.k8s.io/release-1.3/docs/user-guide/jsonpath.md\[ra]]. + +.PP +\fB\-\-output\-version\fP="" + Output the formatted object with the given group version (for ex: 'extensions/v1beta1'). + +.PP +\fB\-a\fP, \fB\-\-show\-all\fP=true + When printing, show all resources (false means hide terminated pods.) + +.PP +\fB\-\-show\-labels\fP=false + When printing, show all labels as the last column (default hide labels column) + +.PP +\fB\-\-sort\-by\fP="" + If non\-empty, sort list types using this field specification. The field specification is expressed as a JSONPath expression (e.g. '{.metadata.name}'). The field in the API resource specified by this JSONPath expression must be an integer or a string. + +.PP +\fB\-\-template\fP="" + Template string or path to template file to use when \-o=go\-template, \-o=go\-template\-file. The template format is golang templates [ +\[la]http://golang.org/pkg/text/template/#pkg-overview\[ra]]. + + .SH OPTIONS INHERITED FROM PARENT COMMANDS .PP \fB\-\-api\-version\fP="" @@ -96,6 +129,9 @@ This command will create a new group with an optional list of users. # Add a group with two users oc adm groups new my\-group user1 user2 + # Add a group with one user and shorter output + oc adm groups new my\-group user1 \-o name + .fi .RE diff --git a/docs/man/man1/openshift-admin-groups-new.1 b/docs/man/man1/openshift-admin-groups-new.1 index 5d58dbf3caa3..e3cebadedf7a 100644 --- a/docs/man/man1/openshift-admin-groups-new.1 +++ b/docs/man/man1/openshift-admin-groups-new.1 @@ -19,6 +19,39 @@ Create a new group. This command will create a new group with an optional list of users. +.SH OPTIONS +.PP +\fB\-\-no\-headers\fP=false + When using the default output, don't print headers. + +.PP +\fB\-o\fP, \fB\-\-output\fP="" + Output format. One of: json|yaml|wide|name|go\-template=...|go\-template\-file=...|jsonpath=...|jsonpath\-file=... See golang template [ +\[la]http://golang.org/pkg/text/template/#pkg-overview\[ra]] and jsonpath template [ +\[la]http://releases.k8s.io/release-1.3/docs/user-guide/jsonpath.md\[ra]]. + +.PP +\fB\-\-output\-version\fP="" + Output the formatted object with the given group version (for ex: 'extensions/v1beta1'). + +.PP +\fB\-a\fP, \fB\-\-show\-all\fP=false + When printing, show all resources (default hide terminated pods.) + +.PP +\fB\-\-show\-labels\fP=false + When printing, show all labels as the last column (default hide labels column) + +.PP +\fB\-\-sort\-by\fP="" + If non\-empty, sort list types using this field specification. The field specification is expressed as a JSONPath expression (e.g. '{.metadata.name}'). The field in the API resource specified by this JSONPath expression must be an integer or a string. + +.PP +\fB\-\-template\fP="" + Template string or path to template file to use when \-o=go\-template, \-o=go\-template\-file. The template format is golang templates [ +\[la]http://golang.org/pkg/text/template/#pkg-overview\[ra]]. + + .SH OPTIONS INHERITED FROM PARENT COMMANDS .PP \fB\-\-api\-version\fP="" @@ -96,6 +129,9 @@ This command will create a new group with an optional list of users. # Add a group with two users openshift admin groups new my\-group user1 user2 + # Add a group with one user and shorter output + openshift admin groups new my\-group user1 \-o name + .fi .RE diff --git a/docs/man/man1/openshift-cli-adm-groups-new.1 b/docs/man/man1/openshift-cli-adm-groups-new.1 index 91da3951ce61..5d232a163548 100644 --- a/docs/man/man1/openshift-cli-adm-groups-new.1 +++ b/docs/man/man1/openshift-cli-adm-groups-new.1 @@ -19,6 +19,39 @@ Create a new group. This command will create a new group with an optional list of users. +.SH OPTIONS +.PP +\fB\-\-no\-headers\fP=false + When using the default output, don't print headers. + +.PP +\fB\-o\fP, \fB\-\-output\fP="" + Output format. One of: json|yaml|wide|name|go\-template=...|go\-template\-file=...|jsonpath=...|jsonpath\-file=... See golang template [ +\[la]http://golang.org/pkg/text/template/#pkg-overview\[ra]] and jsonpath template [ +\[la]http://releases.k8s.io/release-1.3/docs/user-guide/jsonpath.md\[ra]]. + +.PP +\fB\-\-output\-version\fP="" + Output the formatted object with the given group version (for ex: 'extensions/v1beta1'). + +.PP +\fB\-a\fP, \fB\-\-show\-all\fP=true + When printing, show all resources (false means hide terminated pods.) + +.PP +\fB\-\-show\-labels\fP=false + When printing, show all labels as the last column (default hide labels column) + +.PP +\fB\-\-sort\-by\fP="" + If non\-empty, sort list types using this field specification. The field specification is expressed as a JSONPath expression (e.g. '{.metadata.name}'). The field in the API resource specified by this JSONPath expression must be an integer or a string. + +.PP +\fB\-\-template\fP="" + Template string or path to template file to use when \-o=go\-template, \-o=go\-template\-file. The template format is golang templates [ +\[la]http://golang.org/pkg/text/template/#pkg-overview\[ra]]. + + .SH OPTIONS INHERITED FROM PARENT COMMANDS .PP \fB\-\-api\-version\fP="" @@ -96,6 +129,9 @@ This command will create a new group with an optional list of users. # Add a group with two users openshift cli adm groups new my\-group user1 user2 + # Add a group with one user and shorter output + openshift cli adm groups new my\-group user1 \-o name + .fi .RE diff --git a/pkg/cmd/admin/groups/new.go b/pkg/cmd/admin/groups/new.go index 258a00e84e14..59778c236e38 100644 --- a/pkg/cmd/admin/groups/new.go +++ b/pkg/cmd/admin/groups/new.go @@ -5,7 +5,9 @@ import ( "fmt" "io" + "k8s.io/kubernetes/pkg/kubectl" kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" + "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/sets" "github.com/spf13/cobra" @@ -26,7 +28,10 @@ This command will create a new group with an optional list of users.` %[1]s my-group # Add a group with two users - %[1]s my-group user1 user2` + %[1]s my-group user1 user2 + + # Add a group with one user and shorter output + %[1]s my-group user1 -o name` ) type NewGroupOptions struct { @@ -34,10 +39,13 @@ type NewGroupOptions struct { Group string Users []string + + Out io.Writer + Printer kubectl.ResourcePrinterFunc } func NewCmdNewGroup(name, fullName string, f *clientcmd.Factory, out io.Writer) *cobra.Command { - options := &NewGroupOptions{} + options := &NewGroupOptions{Out: out} cmd := &cobra.Command{ Use: name + " GROUP [USER ...]", @@ -45,18 +53,20 @@ func NewCmdNewGroup(name, fullName string, f *clientcmd.Factory, out io.Writer) Long: newLong, Example: fmt.Sprintf(newExample, fullName), Run: func(cmd *cobra.Command, args []string) { - if err := options.Complete(f, args); err != nil { + if err := options.Complete(f, cmd, args); err != nil { kcmdutil.CheckErr(kcmdutil.UsageError(cmd, err.Error())) } - + kcmdutil.CheckErr(options.Validate()) kcmdutil.CheckErr(options.AddGroup()) }, } + kcmdutil.AddPrinterFlags(cmd) + return cmd } -func (o *NewGroupOptions) Complete(f *clientcmd.Factory, args []string) error { +func (o *NewGroupOptions) Complete(f *clientcmd.Factory, cmd *cobra.Command, args []string) error { if len(args) < 1 { return errors.New("You must specify at least one argument: GROUP [USER ...]") } @@ -72,6 +82,40 @@ func (o *NewGroupOptions) Complete(f *clientcmd.Factory, args []string) error { } o.GroupClient = osClient.Groups() + + outputFormat := kcmdutil.GetFlagString(cmd, "output") + templateFile := kcmdutil.GetFlagString(cmd, "template") + printer, _, err := kubectl.GetPrinter(outputFormat, templateFile) + if err != nil { + return err + } + + if printer != nil { + o.Printer = printer.PrintObj + } else { + o.Printer = func(obj runtime.Object, out io.Writer) error { + mapper, _ := f.Object(false) + return f.PrintObject(cmd, mapper, obj, out) + } + } + + return nil +} + +func (o *NewGroupOptions) Validate() error { + if len(o.Group) == 0 { + return fmt.Errorf("Group is required") + } + if o.GroupClient == nil { + return fmt.Errorf("GroupClient is required") + } + if o.Out == nil { + return fmt.Errorf("Out is required") + } + if o.Printer == nil { + return fmt.Errorf("Printer is required") + } + return nil } @@ -89,6 +133,10 @@ func (o *NewGroupOptions) AddGroup() error { group.Users = append(group.Users, user) } - _, err := o.GroupClient.Create(group) - return err + actualGroup, err := o.GroupClient.Create(group) + if err != nil { + return err + } + + return o.Printer(actualGroup, o.Out) } diff --git a/test/cmd/admin.sh b/test/cmd/admin.sh index b5402df5d513..903819ce4c80 100755 --- a/test/cmd/admin.sh +++ b/test/cmd/admin.sh @@ -8,6 +8,7 @@ trap os::test::junit::reconcile_output EXIT oc delete project/example project/ui-test-project project/recreated-project oc delete sa/router -n default oc delete node/fake-node + oc delete groups/shortoutputgroup oc delete groups/group1 oc delete groups/cascaded-group oc delete groups/orphaned-group @@ -107,7 +108,11 @@ echo "certs: ok" os::test::junit::declare_suite_end os::test::junit::declare_suite_start "cmd/admin/groups" -os::cmd::expect_success 'oadm groups new group1 foo bar' +os::cmd::expect_success_and_text 'oadm groups new shortoutputgroup -o name' 'group/shortoutputgroup' +os::cmd::expect_failure_and_text 'oadm groups new shortoutputgroup' 'Error from server: groups "shortoutputgroup" already exists' +os::cmd::expect_failure_and_text 'oadm groups new errorgroup -o blah' 'error: output format "blah" not recognized' +os::cmd::expect_failure_and_text 'oc get groups/errorgroup' 'groups "errorgroup" not found' +os::cmd::expect_success_and_text 'oadm groups new group1 foo bar' 'group1.*foo, bar' os::cmd::expect_success_and_text 'oc get groups/group1 --no-headers' 'foo, bar' os::cmd::expect_success 'oadm groups add-users group1 baz' os::cmd::expect_success_and_text 'oc get groups/group1 --no-headers' 'baz' @@ -408,8 +413,8 @@ os::test::junit::declare_suite_start "cmd/admin/user-group-cascade" os::cmd::expect_success 'oc login -u cascaded-user -p pw' os::cmd::expect_success 'oc login -u orphaned-user -p pw' os::cmd::expect_success 'oc login -u system:admin' -os::cmd::expect_success 'oadm groups new cascaded-group cascaded-user orphaned-user' -os::cmd::expect_success 'oadm groups new orphaned-group cascaded-user orphaned-user' +os::cmd::expect_success_and_text 'oadm groups new cascaded-group cascaded-user orphaned-user' 'cascaded-group.*cascaded-user, orphaned-user' +os::cmd::expect_success_and_text 'oadm groups new orphaned-group cascaded-user orphaned-user' 'orphaned-group.*cascaded-user, orphaned-user' # Add roles, sccs to users/groups os::cmd::expect_success 'oadm policy add-scc-to-user restricted cascaded-user orphaned-user' os::cmd::expect_success 'oadm policy add-scc-to-group restricted cascaded-group orphaned-group' diff --git a/test/integration/groups_test.go b/test/integration/groups_test.go index 729b4270f2b0..47874ed81833 100644 --- a/test/integration/groups_test.go +++ b/test/integration/groups_test.go @@ -1,10 +1,12 @@ package integration import ( + "io" "reflect" "testing" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/runtime" authorizationapi "github.com/openshift/origin/pkg/authorization/api" groupscmd "github.com/openshift/origin/pkg/cmd/admin/groups" @@ -192,6 +194,9 @@ func TestGroupCommands(t *testing.T) { GroupClient: clusterAdminClient.Groups(), Group: "group1", Users: []string{"first", "second", "third", "first"}, + Printer: func(runtime.Object, io.Writer) error { + return nil + }, } if err := newGroup.AddGroup(); err != nil { t.Fatalf("unexpected error: %v", err)