diff --git a/cmd/account/cli.go b/cmd/account/cli.go index 0a8dbae3..087dd739 100644 --- a/cmd/account/cli.go +++ b/cmd/account/cli.go @@ -6,17 +6,17 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/spf13/cobra" + "github.com/openshift/osdctl/internal/utils/globalflags" + k8spkg "github.com/openshift/osdctl/pkg/k8s" + awsprovider "github.com/openshift/osdctl/pkg/provider/aws" "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/klog" cmdutil "k8s.io/kubectl/pkg/cmd/util" - - k8spkg "github.com/openshift/osdctl/pkg/k8s" - awsprovider "github.com/openshift/osdctl/pkg/provider/aws" ) // newCmdCli implements the Cli command which generates temporary STS cli credentials for the specified account cr -func newCmdCli(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags) *cobra.Command { - ops := newCliOptions(streams, flags) +func newCmdCli(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, globalOpts *globalflags.GlobalOptions) *cobra.Command { + ops := newCliOptions(streams, flags, globalOpts) cliCmd := &cobra.Command{ Use: "cli", Short: "Generate temporary AWS CLI credentials on demand", @@ -30,7 +30,6 @@ func newCmdCli(streams genericclioptions.IOStreams, flags *genericclioptions.Con ops.k8sclusterresourcefactory.AttachCobraCliFlags(cliCmd) - cliCmd.Flags().StringVarP(&ops.output, "out", "o", "default", "Output format [default | json | env]") cliCmd.Flags().BoolVarP(&ops.verbose, "verbose", "", false, "Verbose output") return cliCmd @@ -44,14 +43,16 @@ type cliOptions struct { verbose bool genericclioptions.IOStreams + GlobalOptions *globalflags.GlobalOptions } -func newCliOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags) *cliOptions { +func newCliOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, globalOpts *globalflags.GlobalOptions) *cliOptions { return &cliOptions{ k8sclusterresourcefactory: k8spkg.ClusterResourceFactoryOptions{ Flags: flags, }, - IOStreams: streams, + IOStreams: streams, + GlobalOptions: globalOpts, } } @@ -70,6 +71,8 @@ func (o *cliOptions) complete(cmd *cobra.Command) error { } } + o.output = o.GlobalOptions.Output + return nil } @@ -94,7 +97,7 @@ func (o *cliOptions) run() error { } } - if o.output == "default" { + if o.output == "" { fmt.Fprintf(o.IOStreams.Out, "Temporary AWS Credentials:\n%s\n", creds) } diff --git a/cmd/account/cmd.go b/cmd/account/cmd.go index 864c3340..f3d90d00 100644 --- a/cmd/account/cmd.go +++ b/cmd/account/cmd.go @@ -9,10 +9,11 @@ import ( "github.com/openshift/osdctl/cmd/account/list" "github.com/openshift/osdctl/cmd/account/mgmt" "github.com/openshift/osdctl/cmd/account/servicequotas" + "github.com/openshift/osdctl/internal/utils/globalflags" ) // NewCmdAccount implements the base account command -func NewCmdAccount(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client) *cobra.Command { +func NewCmdAccount(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client, globalOpts *globalflags.GlobalOptions) *cobra.Command { accountCmd := &cobra.Command{ Use: "account", Short: "AWS Account related utilities", @@ -21,14 +22,14 @@ func NewCmdAccount(streams genericclioptions.IOStreams, flags *genericclioptions Run: help, } - accountCmd.AddCommand(get.NewCmdGet(streams, flags, client)) - accountCmd.AddCommand(list.NewCmdList(streams, flags, client)) + accountCmd.AddCommand(get.NewCmdGet(streams, flags, client, globalOpts)) + accountCmd.AddCommand(list.NewCmdList(streams, flags, client, globalOpts)) accountCmd.AddCommand(servicequotas.NewCmdServiceQuotas(streams, flags)) - accountCmd.AddCommand(mgmt.NewCmdMgmt(streams, flags)) + accountCmd.AddCommand(mgmt.NewCmdMgmt(streams, flags, globalOpts)) accountCmd.AddCommand(newCmdReset(streams, flags, client)) accountCmd.AddCommand(newCmdSet(streams, flags, client)) accountCmd.AddCommand(newCmdConsole(streams, flags)) - accountCmd.AddCommand(newCmdCli(streams, flags)) + accountCmd.AddCommand(newCmdCli(streams, flags, globalOpts)) accountCmd.AddCommand(newCmdCleanVeleroSnapshots(streams)) accountCmd.AddCommand(newCmdVerifySecrets(streams, flags, client)) accountCmd.AddCommand(newCmdRotateSecret(streams, flags, client)) diff --git a/cmd/account/get/account-claim.go b/cmd/account/get/account-claim.go index b237e505..cf31c400 100644 --- a/cmd/account/get/account-claim.go +++ b/cmd/account/get/account-claim.go @@ -7,18 +7,18 @@ import ( awsv1alpha1 "github.com/openshift/aws-account-operator/pkg/apis/aws/v1alpha1" "github.com/spf13/cobra" + "github.com/openshift/osdctl/cmd/common" + "github.com/openshift/osdctl/internal/utils/globalflags" + "github.com/openshift/osdctl/pkg/printer" "k8s.io/cli-runtime/pkg/genericclioptions" cmdutil "k8s.io/kubectl/pkg/cmd/util" "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/openshift/osdctl/cmd/common" - "github.com/openshift/osdctl/pkg/printer" ) // newCmdGetAccountClaim implements the get account-claim command which get // the Account Claim CR related to the specified AWS Account ID -func newCmdGetAccountClaim(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client) *cobra.Command { - ops := newGetAccountClaimOptions(streams, flags, client) +func newCmdGetAccountClaim(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client, globalOpts *globalflags.GlobalOptions) *cobra.Command { + ops := newGetAccountClaimOptions(streams, flags, client, globalOpts) getAccountClaimCmd := &cobra.Command{ Use: "account-claim", Short: "Get AWS Account Claim CR", @@ -31,7 +31,6 @@ func newCmdGetAccountClaim(streams genericclioptions.IOStreams, flags *genericcl } ops.printFlags.AddFlags(getAccountClaimCmd) - getAccountClaimCmd.Flags().StringVarP(&ops.output, "output", "o", "", "Output format. One of: json|yaml|jsonpath=...|jsonpath-file=... see jsonpath template [http://kubernetes.io/docs/user-guide/jsonpath].") getAccountClaimCmd.Flags().StringVar(&ops.accountNamespace, "account-namespace", common.AWSAccountNamespace, "The namespace to keep AWS accounts. The default value is aws-account-operator.") getAccountClaimCmd.Flags().StringVarP(&ops.accountName, "account", "a", "", "Account CR Name") @@ -51,15 +50,17 @@ type getAccountClaimOptions struct { flags *genericclioptions.ConfigFlags printFlags *printer.PrintFlags genericclioptions.IOStreams - kubeCli client.Client + kubeCli client.Client + GlobalOptions *globalflags.GlobalOptions } -func newGetAccountClaimOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client) *getAccountClaimOptions { +func newGetAccountClaimOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client, globalOpts *globalflags.GlobalOptions) *getAccountClaimOptions { return &getAccountClaimOptions{ - flags: flags, - printFlags: printer.NewPrintFlags(), - IOStreams: streams, - kubeCli: client, + flags: flags, + printFlags: printer.NewPrintFlags(), + IOStreams: streams, + kubeCli: client, + GlobalOptions: globalOpts, } } @@ -71,6 +72,7 @@ func (o *getAccountClaimOptions) complete(cmd *cobra.Command, _ []string) error return cmdutil.UsageErrorf(cmd, "AWS account ID and Account CR Name cannot be set at the same time") } + o.output = o.GlobalOptions.Output return nil } diff --git a/cmd/account/get/account-claim_test.go b/cmd/account/get/account-claim_test.go index 67fd19cb..f560d91f 100644 --- a/cmd/account/get/account-claim_test.go +++ b/cmd/account/get/account-claim_test.go @@ -9,6 +9,7 @@ import ( . "github.com/onsi/gomega" mockk8s "github.com/openshift/osdctl/cmd/clusterdeployment/mock/k8s" + "github.com/openshift/osdctl/internal/utils/globalflags" "k8s.io/cli-runtime/pkg/genericclioptions" ) @@ -17,6 +18,7 @@ func TestGetAccountClaimCmdComplete(t *testing.T) { mockCtrl := gomock.NewController(t) streams := genericclioptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr} kubeFlags := genericclioptions.NewConfigFlags(false) + globalFlags := globalflags.GlobalOptions{Output: ""} testCases := []struct { title string option *getAccountClaimOptions @@ -26,8 +28,10 @@ func TestGetAccountClaimCmdComplete(t *testing.T) { { title: "account id and account cr name empty at the same time", option: &getAccountClaimOptions{ - accountID: "", - accountName: "", + accountID: "", + accountName: "", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: true, errContent: "AWS account ID and Account CR Name cannot be empty at the same time", @@ -35,8 +39,10 @@ func TestGetAccountClaimCmdComplete(t *testing.T) { { title: "account id and account cr name set at the same time", option: &getAccountClaimOptions{ - accountID: "foo", - accountName: "bar", + accountID: "foo", + accountName: "bar", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: true, errContent: "AWS account ID and Account CR Name cannot be set at the same time", @@ -44,8 +50,9 @@ func TestGetAccountClaimCmdComplete(t *testing.T) { { title: "succeed", option: &getAccountClaimOptions{ - accountID: "foo", - flags: kubeFlags, + accountID: "foo", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: false, }, @@ -53,7 +60,7 @@ func TestGetAccountClaimCmdComplete(t *testing.T) { for _, tc := range testCases { t.Run(tc.title, func(t *testing.T) { - cmd := newCmdGetAccountClaim(streams, kubeFlags, mockk8s.NewMockClient(mockCtrl)) + cmd := newCmdGetAccountClaim(streams, kubeFlags, mockk8s.NewMockClient(mockCtrl), &globalFlags) err := tc.option.complete(cmd, nil) if tc.errExpected { g.Expect(err).Should(HaveOccurred()) diff --git a/cmd/account/get/account.go b/cmd/account/get/account.go index b3f1fa11..d29784c4 100644 --- a/cmd/account/get/account.go +++ b/cmd/account/get/account.go @@ -12,14 +12,15 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "github.com/openshift/osdctl/cmd/common" + "github.com/openshift/osdctl/internal/utils/globalflags" "github.com/openshift/osdctl/pkg/k8s" "github.com/openshift/osdctl/pkg/printer" ) // newCmdGetAccount implements the get account command which get the Account CR // related to the specified AWS Account ID or the specified Account Claim CR -func newCmdGetAccount(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client) *cobra.Command { - ops := newGetAccountOptions(streams, flags, client) +func newCmdGetAccount(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client, globalOpts *globalflags.GlobalOptions) *cobra.Command { + ops := newGetAccountOptions(streams, flags, client, globalOpts) getAccountCmd := &cobra.Command{ Use: "account", Short: "Get AWS Account CR", @@ -32,7 +33,6 @@ func newCmdGetAccount(streams genericclioptions.IOStreams, flags *genericcliopti } ops.printFlags.AddFlags(getAccountCmd) - getAccountCmd.Flags().StringVarP(&ops.output, "output", "o", "", "Output format. One of: json|yaml|jsonpath=...|jsonpath-file=... see jsonpath template [http://kubernetes.io/docs/user-guide/jsonpath].") getAccountCmd.Flags().StringVar(&ops.accountNamespace, "account-namespace", common.AWSAccountNamespace, "The namespace to keep AWS accounts. The default value is aws-account-operator.") getAccountCmd.Flags().StringVarP(&ops.accountID, "account-id", "i", "", "AWS account ID") @@ -54,15 +54,17 @@ type getAccountOptions struct { flags *genericclioptions.ConfigFlags printFlags *printer.PrintFlags genericclioptions.IOStreams - kubeCli client.Client + kubeCli client.Client + GlobalOptions *globalflags.GlobalOptions } -func newGetAccountOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client) *getAccountOptions { +func newGetAccountOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client, globalOpts *globalflags.GlobalOptions) *getAccountOptions { return &getAccountOptions{ - flags: flags, - printFlags: printer.NewPrintFlags(), - IOStreams: streams, - kubeCli: client, + flags: flags, + printFlags: printer.NewPrintFlags(), + IOStreams: streams, + kubeCli: client, + GlobalOptions: globalOpts, } } @@ -76,6 +78,7 @@ func (o *getAccountOptions) complete(cmd *cobra.Command, _ []string) error { return cmdutil.UsageErrorf(cmd, "AWS account ID and AccountClaim CR Name cannot be set at the same time") } + o.output = o.GlobalOptions.Output return nil } diff --git a/cmd/account/get/account_test.go b/cmd/account/get/account_test.go index fb882225..6a30a17b 100644 --- a/cmd/account/get/account_test.go +++ b/cmd/account/get/account_test.go @@ -9,6 +9,7 @@ import ( . "github.com/onsi/gomega" mockk8s "github.com/openshift/osdctl/cmd/clusterdeployment/mock/k8s" + "github.com/openshift/osdctl/internal/utils/globalflags" "k8s.io/cli-runtime/pkg/genericclioptions" ) @@ -17,6 +18,7 @@ func TestGetAccountCmdComplete(t *testing.T) { mockCtrl := gomock.NewController(t) streams := genericclioptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr} kubeFlags := genericclioptions.NewConfigFlags(false) + globalFlags := globalflags.GlobalOptions{Output: ""} testCases := []struct { title string option *getAccountOptions @@ -28,6 +30,8 @@ func TestGetAccountCmdComplete(t *testing.T) { option: &getAccountOptions{ accountID: "", accountClaimName: "", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: true, errContent: "AWS account ID and AccountClaim CR Name cannot be empty at the same time", @@ -37,6 +41,8 @@ func TestGetAccountCmdComplete(t *testing.T) { option: &getAccountOptions{ accountID: "foo", accountClaimName: "bar", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: true, errContent: "AWS account ID and AccountClaim CR Name cannot be set at the same time", @@ -44,8 +50,9 @@ func TestGetAccountCmdComplete(t *testing.T) { { title: "succeed", option: &getAccountOptions{ - accountID: "foo", - flags: kubeFlags, + accountID: "foo", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: false, }, @@ -54,6 +61,7 @@ func TestGetAccountCmdComplete(t *testing.T) { option: &getAccountOptions{ accountClaimName: "foo", flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: false, }, @@ -61,7 +69,7 @@ func TestGetAccountCmdComplete(t *testing.T) { for _, tc := range testCases { t.Run(tc.title, func(t *testing.T) { - cmd := newCmdGetAccount(streams, kubeFlags, mockk8s.NewMockClient(mockCtrl)) + cmd := newCmdGetAccount(streams, kubeFlags, mockk8s.NewMockClient(mockCtrl), &globalFlags) err := tc.option.complete(cmd, nil) if tc.errExpected { g.Expect(err).Should(HaveOccurred()) diff --git a/cmd/account/get/cmd.go b/cmd/account/get/cmd.go index b71999f5..24b976dc 100644 --- a/cmd/account/get/cmd.go +++ b/cmd/account/get/cmd.go @@ -4,6 +4,7 @@ import ( "github.com/spf13/cobra" "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/openshift/osdctl/internal/utils/globalflags" "k8s.io/cli-runtime/pkg/genericclioptions" ) @@ -12,7 +13,7 @@ const ( ) // NewCmdGet implements the get command to get AWS Account related resources -func NewCmdGet(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client) *cobra.Command { +func NewCmdGet(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client, globalOpts *globalflags.GlobalOptions) *cobra.Command { getCmd := &cobra.Command{ Use: "get", Short: "Get resources", @@ -21,10 +22,10 @@ func NewCmdGet(streams genericclioptions.IOStreams, flags *genericclioptions.Con Run: help, } - getCmd.AddCommand(newCmdGetAccount(streams, flags, client)) - getCmd.AddCommand(newCmdGetAccountClaim(streams, flags, client)) - getCmd.AddCommand(newCmdGetLegalEntity(streams, flags, client)) - getCmd.AddCommand(newCmdGetSecrets(streams, flags, client)) + getCmd.AddCommand(newCmdGetAccount(streams, flags, client, globalOpts)) + getCmd.AddCommand(newCmdGetAccountClaim(streams, flags, client, globalOpts)) + getCmd.AddCommand(newCmdGetLegalEntity(streams, flags, client, globalOpts)) + getCmd.AddCommand(newCmdGetSecrets(streams, flags, client, globalOpts)) getCmd.AddCommand(newCmdGetAWSAccount(streams, flags, client)) return getCmd diff --git a/cmd/account/get/legal-entity.go b/cmd/account/get/legal-entity.go index d940bce3..ac512deb 100644 --- a/cmd/account/get/legal-entity.go +++ b/cmd/account/get/legal-entity.go @@ -6,6 +6,7 @@ import ( awsv1alpha1 "github.com/openshift/aws-account-operator/pkg/apis/aws/v1alpha1" outputflag "github.com/openshift/osdctl/cmd/getoutput" + "github.com/openshift/osdctl/internal/utils/globalflags" "github.com/spf13/cobra" "k8s.io/cli-runtime/pkg/genericclioptions" @@ -18,8 +19,8 @@ import ( // newCmdGetLegalEntity implements the get legal-entity command which get // the legal entity information related to the specified AWS Account ID -func newCmdGetLegalEntity(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client) *cobra.Command { - ops := newGetLegalEntityOptions(streams, flags, client) +func newCmdGetLegalEntity(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client, globalOpts *globalflags.GlobalOptions) *cobra.Command { + ops := newGetLegalEntityOptions(streams, flags, client, globalOpts) getLegalEntityCmd := &cobra.Command{ Use: "legal-entity", Short: "Get AWS Account Legal Entity", @@ -46,7 +47,8 @@ type getLegalEntityOptions struct { flags *genericclioptions.ConfigFlags genericclioptions.IOStreams - kubeCli client.Client + kubeCli client.Client + GlobalOptions *globalflags.GlobalOptions } type legalEntityResponse struct { @@ -60,11 +62,12 @@ func (f legalEntityResponse) String() string { } -func newGetLegalEntityOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client) *getLegalEntityOptions { +func newGetLegalEntityOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client, globalOpts *globalflags.GlobalOptions) *getLegalEntityOptions { return &getLegalEntityOptions{ - flags: flags, - IOStreams: streams, - kubeCli: client, + flags: flags, + IOStreams: streams, + kubeCli: client, + GlobalOptions: globalOpts, } } @@ -73,12 +76,7 @@ func (o *getLegalEntityOptions) complete(cmd *cobra.Command, _ []string) error { return cmdutil.UsageErrorf(cmd, accountIDRequired) } - output, err := outputflag.GetOutput(cmd) - if err != nil { - return err - } - o.output = output - + o.output = o.GlobalOptions.Output return nil } diff --git a/cmd/account/get/legal-entity_test.go b/cmd/account/get/legal-entity_test.go index 142882a2..86c733b9 100644 --- a/cmd/account/get/legal-entity_test.go +++ b/cmd/account/get/legal-entity_test.go @@ -9,6 +9,7 @@ import ( . "github.com/onsi/gomega" mockk8s "github.com/openshift/osdctl/cmd/clusterdeployment/mock/k8s" + "github.com/openshift/osdctl/internal/utils/globalflags" "k8s.io/cli-runtime/pkg/genericclioptions" ) @@ -17,6 +18,7 @@ func TestGetLegalEntityCmdComplete(t *testing.T) { mockCtrl := gomock.NewController(t) streams := genericclioptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr} kubeFlags := genericclioptions.NewConfigFlags(false) + globalFlags := globalflags.GlobalOptions{Output: ""} testCases := []struct { title string option *getSecretsOptions @@ -26,7 +28,9 @@ func TestGetLegalEntityCmdComplete(t *testing.T) { { title: "empty account id", option: &getSecretsOptions{ - accountID: "", + accountID: "", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: true, errContent: accountIDRequired, @@ -34,8 +38,9 @@ func TestGetLegalEntityCmdComplete(t *testing.T) { { title: "succeed", option: &getSecretsOptions{ - accountID: "foo", - flags: kubeFlags, + accountID: "foo", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: false, }, @@ -43,7 +48,7 @@ func TestGetLegalEntityCmdComplete(t *testing.T) { for _, tc := range testCases { t.Run(tc.title, func(t *testing.T) { - cmd := newCmdGetLegalEntity(streams, kubeFlags, mockk8s.NewMockClient(mockCtrl)) + cmd := newCmdGetLegalEntity(streams, kubeFlags, mockk8s.NewMockClient(mockCtrl), &globalFlags) err := tc.option.complete(cmd, nil) if tc.errExpected { g.Expect(err).Should(HaveOccurred()) diff --git a/cmd/account/get/secrets.go b/cmd/account/get/secrets.go index 1ec9e7ea..aa5b296d 100644 --- a/cmd/account/get/secrets.go +++ b/cmd/account/get/secrets.go @@ -7,14 +7,15 @@ import ( awsv1alpha1 "github.com/openshift/aws-account-operator/pkg/apis/aws/v1alpha1" "github.com/spf13/cobra" + "github.com/openshift/osdctl/cmd/common" + "github.com/openshift/osdctl/internal/utils/globalflags" + "github.com/openshift/osdctl/pkg/printer" v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" "k8s.io/cli-runtime/pkg/genericclioptions" cmdutil "k8s.io/kubectl/pkg/cmd/util" "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/openshift/osdctl/cmd/common" ) const ( @@ -23,8 +24,8 @@ const ( // newCmdGetSecrets implements the get secrets command which get // the name of secrets related to the specified AWS Account ID -func newCmdGetSecrets(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client) *cobra.Command { - ops := newGetSecretsOptions(streams, flags, client) +func newCmdGetSecrets(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client, globalOpts *globalflags.GlobalOptions) *cobra.Command { + ops := newGetSecretsOptions(streams, flags, client, globalOpts) getSecretsCmd := &cobra.Command{ Use: "secrets", Short: "Get AWS Account CR related secrets", @@ -47,20 +48,21 @@ func newCmdGetSecrets(streams genericclioptions.IOStreams, flags *genericcliopti type getSecretsOptions struct { accountID string accountNamespace string - secretName string - - output string + output string - flags *genericclioptions.ConfigFlags + flags *genericclioptions.ConfigFlags + printFlags *printer.PrintFlags genericclioptions.IOStreams - kubeCli client.Client + kubeCli client.Client + GlobalOptions *globalflags.GlobalOptions } -func newGetSecretsOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client) *getSecretsOptions { +func newGetSecretsOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client, globalOpts *globalflags.GlobalOptions) *getSecretsOptions { return &getSecretsOptions{ - flags: flags, - IOStreams: streams, - kubeCli: client, + flags: flags, + IOStreams: streams, + kubeCli: client, + GlobalOptions: globalOpts, } } @@ -69,6 +71,7 @@ func (o *getSecretsOptions) complete(cmd *cobra.Command, _ []string) error { return cmdutil.UsageErrorf(cmd, accountIDRequired) } + o.output = o.GlobalOptions.Output return nil } @@ -106,7 +109,16 @@ func (o *getSecretsOptions) run() error { return err } } - fmt.Fprintln(o.IOStreams.Out, secret.Name) + if o.output == "" { + fmt.Fprintln(o.IOStreams.Out, secret.Name) + } + + resourcePrinter, err := o.printFlags.ToPrinter(o.output) + if err != nil { + return err + } + + return resourcePrinter.PrintObj(&secret, o.Out) } return nil diff --git a/cmd/account/get/secrets_test.go b/cmd/account/get/secrets_test.go index 1f4fe471..b94445a7 100644 --- a/cmd/account/get/secrets_test.go +++ b/cmd/account/get/secrets_test.go @@ -9,6 +9,7 @@ import ( . "github.com/onsi/gomega" mockk8s "github.com/openshift/osdctl/cmd/clusterdeployment/mock/k8s" + "github.com/openshift/osdctl/internal/utils/globalflags" "k8s.io/cli-runtime/pkg/genericclioptions" ) @@ -17,6 +18,7 @@ func TestGetSecretsCmdComplete(t *testing.T) { mockCtrl := gomock.NewController(t) streams := genericclioptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr} kubeFlags := genericclioptions.NewConfigFlags(false) + globalFlags := globalflags.GlobalOptions{Output: ""} testCases := []struct { title string option *getSecretsOptions @@ -26,7 +28,9 @@ func TestGetSecretsCmdComplete(t *testing.T) { { title: "empty account id", option: &getSecretsOptions{ - accountID: "", + accountID: "", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: true, errContent: accountIDRequired, @@ -34,8 +38,9 @@ func TestGetSecretsCmdComplete(t *testing.T) { { title: "succeed", option: &getSecretsOptions{ - accountID: "foo", - flags: kubeFlags, + accountID: "foo", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: false, }, @@ -43,7 +48,7 @@ func TestGetSecretsCmdComplete(t *testing.T) { for _, tc := range testCases { t.Run(tc.title, func(t *testing.T) { - cmd := newCmdGetSecrets(streams, kubeFlags, mockk8s.NewMockClient(mockCtrl)) + cmd := newCmdGetSecrets(streams, kubeFlags, mockk8s.NewMockClient(mockCtrl), &globalFlags) err := tc.option.complete(cmd, nil) if tc.errExpected { g.Expect(err).Should(HaveOccurred()) diff --git a/cmd/account/list/account-claim.go b/cmd/account/list/account-claim.go index 6c6d7d6d..a059e204 100644 --- a/cmd/account/list/account-claim.go +++ b/cmd/account/list/account-claim.go @@ -10,12 +10,13 @@ import ( cmdutil "k8s.io/kubectl/pkg/cmd/util" "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/openshift/osdctl/internal/utils/globalflags" "github.com/openshift/osdctl/pkg/printer" ) // newCmdListAccount implements the list account command to list account claim crs -func newCmdListAccountClaim(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client) *cobra.Command { - ops := newListAccountClaimOptions(streams, flags, client) +func newCmdListAccountClaim(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client, globalOpts *globalflags.GlobalOptions) *cobra.Command { + ops := newListAccountClaimOptions(streams, flags, client, globalOpts) listAccountClaimCmd := &cobra.Command{ Use: "account-claim", Short: "List AWS Account Claim CR", @@ -34,18 +35,22 @@ func newCmdListAccountClaim(streams genericclioptions.IOStreams, flags *genericc // listAccountOptions defines the struct for running list account command type listAccountClaimOptions struct { - state string + state string + output string - flags *genericclioptions.ConfigFlags + flags *genericclioptions.ConfigFlags + printFlags *printer.PrintFlags genericclioptions.IOStreams - kubeCli client.Client + kubeCli client.Client + GlobalOptions *globalflags.GlobalOptions } -func newListAccountClaimOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client) *listAccountClaimOptions { +func newListAccountClaimOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client, globalOpts *globalflags.GlobalOptions) *listAccountClaimOptions { return &listAccountClaimOptions{ - flags: flags, - IOStreams: streams, - kubeCli: client, + flags: flags, + IOStreams: streams, + kubeCli: client, + GlobalOptions: globalOpts, } } @@ -62,6 +67,7 @@ func (o *listAccountClaimOptions) complete(cmd *cobra.Command, _ []string) error return cmdutil.UsageErrorf(cmd, "unsupported account claim state "+o.state) } + o.output = o.GlobalOptions.Output return nil } @@ -89,11 +95,17 @@ func (o *listAccountClaimOptions) run() error { }) // this is used to mark whether there are matched accounts or not - matched = true - } - - if matched { - return p.Flush() + if matched { + if o.output == "" { + return p.Flush() + } + resourcePrinter, err := o.printFlags.ToPrinter(o.output) + if err != nil { + return err + } + + return resourcePrinter.PrintObj(&claim, o.Out) + } } return nil } diff --git a/cmd/account/list/account-claim_test.go b/cmd/account/list/account-claim_test.go index a7cf5bca..a8ee4b82 100644 --- a/cmd/account/list/account-claim_test.go +++ b/cmd/account/list/account-claim_test.go @@ -9,6 +9,7 @@ import ( . "github.com/onsi/gomega" mockk8s "github.com/openshift/osdctl/cmd/clusterdeployment/mock/k8s" + "github.com/openshift/osdctl/internal/utils/globalflags" "k8s.io/cli-runtime/pkg/genericclioptions" ) @@ -17,6 +18,7 @@ func TestGetAccountClaimCmdComplete(t *testing.T) { mockCtrl := gomock.NewController(t) streams := genericclioptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr} kubeFlags := genericclioptions.NewConfigFlags(false) + globalFlags := globalflags.GlobalOptions{Output: ""} testCases := []struct { title string option *listAccountClaimOptions @@ -26,7 +28,9 @@ func TestGetAccountClaimCmdComplete(t *testing.T) { { title: "incorrect state", option: &listAccountClaimOptions{ - state: "foo", + state: "foo", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: true, errContent: "unsupported account claim state foo", @@ -34,32 +38,36 @@ func TestGetAccountClaimCmdComplete(t *testing.T) { { title: "empty state", option: &listAccountClaimOptions{ - state: "", - flags: kubeFlags, + state: "", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: false, }, { title: "error state", option: &listAccountClaimOptions{ - state: "Error", - flags: kubeFlags, + state: "Error", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: false, }, { title: "pending state", option: &listAccountClaimOptions{ - state: "Pending", - flags: kubeFlags, + state: "Pending", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: false, }, { title: "ready state", option: &listAccountClaimOptions{ - state: "Ready", - flags: kubeFlags, + state: "Ready", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: false, }, @@ -67,7 +75,7 @@ func TestGetAccountClaimCmdComplete(t *testing.T) { for _, tc := range testCases { t.Run(tc.title, func(t *testing.T) { - cmd := newCmdListAccountClaim(streams, kubeFlags, mockk8s.NewMockClient(mockCtrl)) + cmd := newCmdListAccountClaim(streams, kubeFlags, mockk8s.NewMockClient(mockCtrl), &globalFlags) err := tc.option.complete(cmd, nil) if tc.errExpected { g.Expect(err).Should(HaveOccurred()) diff --git a/cmd/account/list/account.go b/cmd/account/list/account.go index 7d88f62f..7f999f83 100644 --- a/cmd/account/list/account.go +++ b/cmd/account/list/account.go @@ -7,19 +7,19 @@ import ( awsv1alpha1 "github.com/openshift/aws-account-operator/pkg/apis/aws/v1alpha1" "github.com/spf13/cobra" + "github.com/openshift/osdctl/cmd/common" + "github.com/openshift/osdctl/internal/utils/globalflags" + "github.com/openshift/osdctl/pkg/printer" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/printers" cmdutil "k8s.io/kubectl/pkg/cmd/util" "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/openshift/osdctl/cmd/common" - "github.com/openshift/osdctl/pkg/printer" ) // newCmdListAccount implements the list account command to list account crs -func newCmdListAccount(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client) *cobra.Command { - ops := newListAccountOptions(streams, flags, client) +func newCmdListAccount(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client, globalOpts *globalflags.GlobalOptions) *cobra.Command { + ops := newListAccountOptions(streams, flags, client, globalOpts) listAccountCmd := &cobra.Command{ Use: "account", Short: "List AWS Account CR", @@ -32,7 +32,6 @@ func newCmdListAccount(streams genericclioptions.IOStreams, flags *genericcliopt } ops.printFlags.AddFlags(listAccountCmd) - listAccountCmd.Flags().StringVarP(&ops.output, "output", "o", "", "Output format. One of: json|yaml|jsonpath=...|jsonpath-file=... see jsonpath template [http://kubernetes.io/docs/user-guide/jsonpath].") listAccountCmd.Flags().StringVar(&ops.accountNamespace, "account-namespace", common.AWSAccountNamespace, "The namespace to keep AWS accounts. The default value is aws-account-operator.") listAccountCmd.Flags().StringVarP(&ops.reused, "reuse", "r", "", @@ -57,15 +56,17 @@ type listAccountOptions struct { flags *genericclioptions.ConfigFlags printFlags *printer.PrintFlags genericclioptions.IOStreams - kubeCli client.Client + kubeCli client.Client + GlobalOptions *globalflags.GlobalOptions } -func newListAccountOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client) *listAccountOptions { +func newListAccountOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client, globalOpts *globalflags.GlobalOptions) *listAccountOptions { return &listAccountOptions{ - flags: flags, - printFlags: printer.NewPrintFlags(), - IOStreams: streams, - kubeCli: client, + flags: flags, + printFlags: printer.NewPrintFlags(), + IOStreams: streams, + kubeCli: client, + GlobalOptions: globalOpts, } } @@ -95,6 +96,7 @@ func (o *listAccountOptions) complete(cmd *cobra.Command, _ []string) error { return cmdutil.UsageErrorf(cmd, "unsupported claimed status filter "+o.claimed) } + o.output = o.GlobalOptions.Output return nil } diff --git a/cmd/account/list/account_test.go b/cmd/account/list/account_test.go index 66a5b4ae..0914d13c 100644 --- a/cmd/account/list/account_test.go +++ b/cmd/account/list/account_test.go @@ -9,22 +9,16 @@ import ( . "github.com/onsi/gomega" mockk8s "github.com/openshift/osdctl/cmd/clusterdeployment/mock/k8s" + "github.com/openshift/osdctl/internal/utils/globalflags" "k8s.io/cli-runtime/pkg/genericclioptions" ) -type Flags struct { - configFlags *genericclioptions.ConfigFlags - output string -} - func TestGetAccountCmdComplete(t *testing.T) { g := NewGomegaWithT(t) mockCtrl := gomock.NewController(t) streams := genericclioptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr} - var flags Flags - flags.configFlags = genericclioptions.NewConfigFlags(false) - flags.output = "text" - + kubeFlags := genericclioptions.NewConfigFlags(false) + globalFlags := globalflags.GlobalOptions{Output: ""} testCases := []struct { title string option *listAccountOptions @@ -34,7 +28,9 @@ func TestGetAccountCmdComplete(t *testing.T) { { title: "incorrect state", option: &listAccountOptions{ - state: "foo", + state: "foo", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: true, errContent: "unsupported account state foo", @@ -42,31 +38,36 @@ func TestGetAccountCmdComplete(t *testing.T) { { title: "empty state", option: &listAccountOptions{ - state: "", - flags: flags.configFlags, + state: "", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: false, }, { title: "all state", option: &listAccountOptions{ - state: "all", - flags: flags.configFlags, + state: "all", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: false, }, { title: "Ready state", option: &listAccountOptions{ - state: "Ready", - flags: flags.configFlags, + state: "Ready", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: false, }, { title: "bad reuse", option: &listAccountOptions{ - reused: "foo", + reused: "foo", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: true, errContent: "unsupported reused status filter foo", @@ -74,7 +75,9 @@ func TestGetAccountCmdComplete(t *testing.T) { { title: "bad reused status", option: &listAccountOptions{ - reused: "foo", + reused: "foo", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: true, errContent: "unsupported reused status filter foo", @@ -82,7 +85,9 @@ func TestGetAccountCmdComplete(t *testing.T) { { title: "bad claimed status", option: &listAccountOptions{ - claimed: "foo", + claimed: "foo", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: true, errContent: "unsupported claimed status filter foo", @@ -90,26 +95,29 @@ func TestGetAccountCmdComplete(t *testing.T) { { title: "good reused true", option: &listAccountOptions{ - reused: "true", - flags: flags.configFlags, + reused: "true", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: false, }, { title: "good claim", option: &listAccountOptions{ - claimed: "false", - flags: flags.configFlags, + claimed: "false", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: false, }, { title: "success", option: &listAccountOptions{ - state: "Ready", - reused: "true", - claimed: "false", - flags: flags.configFlags, + state: "Ready", + reused: "true", + claimed: "false", + flags: kubeFlags, + GlobalOptions: &globalFlags, }, errExpected: false, }, @@ -117,7 +125,7 @@ func TestGetAccountCmdComplete(t *testing.T) { for _, tc := range testCases { t.Run(tc.title, func(t *testing.T) { - cmd := newCmdListAccount(streams, flags.configFlags, mockk8s.NewMockClient(mockCtrl)) + cmd := newCmdListAccount(streams, tc.option.flags, mockk8s.NewMockClient(mockCtrl), &globalFlags) err := tc.option.complete(cmd, nil) if tc.errExpected { g.Expect(err).Should(HaveOccurred()) diff --git a/cmd/account/list/cmd.go b/cmd/account/list/cmd.go index d7e5de1e..47187c17 100644 --- a/cmd/account/list/cmd.go +++ b/cmd/account/list/cmd.go @@ -1,13 +1,14 @@ package list import ( + "github.com/openshift/osdctl/internal/utils/globalflags" "github.com/spf13/cobra" "k8s.io/cli-runtime/pkg/genericclioptions" "sigs.k8s.io/controller-runtime/pkg/client" ) // NewCmdGet implements the get command to get AWS Account related resources -func NewCmdList(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client) *cobra.Command { +func NewCmdList(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, client client.Client, globalOpts *globalflags.GlobalOptions) *cobra.Command { listCmd := &cobra.Command{ Use: "list", Short: "List resources", @@ -16,8 +17,8 @@ func NewCmdList(streams genericclioptions.IOStreams, flags *genericclioptions.Co Run: help, } - listCmd.AddCommand(newCmdListAccount(streams, flags, client)) - listCmd.AddCommand(newCmdListAccountClaim(streams, flags, client)) + listCmd.AddCommand(newCmdListAccount(streams, flags, client, globalOpts)) + listCmd.AddCommand(newCmdListAccountClaim(streams, flags, client, globalOpts)) return listCmd } diff --git a/cmd/account/mgmt/account-assign.go b/cmd/account/mgmt/account-assign.go index 0dd72258..8d21f4f7 100644 --- a/cmd/account/mgmt/account-assign.go +++ b/cmd/account/mgmt/account-assign.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/organizations" outputflag "github.com/openshift/osdctl/cmd/getoutput" + "github.com/openshift/osdctl/internal/utils/globalflags" "github.com/openshift/osdctl/pkg/printer" awsprovider "github.com/openshift/osdctl/pkg/provider/aws" @@ -34,6 +35,7 @@ type accountAssignOptions struct { flags *genericclioptions.ConfigFlags printFlags *printer.PrintFlags genericclioptions.IOStreams + GlobalOptions *globalflags.GlobalOptions } type assignResponse struct { @@ -45,17 +47,18 @@ func (f assignResponse) String() string { return fmt.Sprintf(" Username: %s\n Account: %s\n", f.Username, f.Id) } -func newAccountAssignOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags) *accountAssignOptions { +func newAccountAssignOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, globalOpts *globalflags.GlobalOptions) *accountAssignOptions { return &accountAssignOptions{ - flags: flags, - printFlags: printer.NewPrintFlags(), - IOStreams: streams, + flags: flags, + printFlags: printer.NewPrintFlags(), + IOStreams: streams, + GlobalOptions: globalOpts, } } // assignCmd assigns an aws account to user under osd-staging-2 by default unless osd-staging-1 is specified -func newCmdAccountAssign(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags) *cobra.Command { - ops := newAccountAssignOptions(streams, flags) +func newCmdAccountAssign(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, globalOpts *globalflags.GlobalOptions) *cobra.Command { + ops := newAccountAssignOptions(streams, flags, globalOpts) accountAssignCmd := &cobra.Command{ Use: "assign", Short: "Assign account to user", @@ -80,11 +83,9 @@ func (o *accountAssignOptions) complete(cmd *cobra.Command, _ []string) error { if o.payerAccount == "" { return cmdutil.UsageErrorf(cmd, "Payer account was not provided") } - output, err := outputflag.GetOutput(cmd) - if err != nil { - return err - } - o.output = output + + o.output = o.GlobalOptions.Output + return nil } diff --git a/cmd/account/mgmt/account-list.go b/cmd/account/mgmt/account-list.go index 73d574ec..3cd7187c 100644 --- a/cmd/account/mgmt/account-list.go +++ b/cmd/account/mgmt/account-list.go @@ -7,6 +7,7 @@ import ( "github.com/aws/aws-sdk-go/service/organizations" "github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi" outputflag "github.com/openshift/osdctl/cmd/getoutput" + "github.com/openshift/osdctl/internal/utils/globalflags" "github.com/openshift/osdctl/pkg/printer" awsprovider "github.com/openshift/osdctl/pkg/provider/aws" "github.com/spf13/cobra" @@ -26,6 +27,7 @@ type accountListOptions struct { flags *genericclioptions.ConfigFlags printFlags *printer.PrintFlags genericclioptions.IOStreams + GlobalOptions *globalflags.GlobalOptions } type listResponse struct { @@ -39,16 +41,17 @@ func (f listResponse) String() string { } -func newAccountListOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags) *accountListOptions { +func newAccountListOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, globalOpts *globalflags.GlobalOptions) *accountListOptions { return &accountListOptions{ - flags: flags, - printFlags: printer.NewPrintFlags(), - IOStreams: streams, + flags: flags, + printFlags: printer.NewPrintFlags(), + IOStreams: streams, + GlobalOptions: globalOpts, } } -func newCmdAccountList(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags) *cobra.Command { - ops := newAccountListOptions(streams, flags) +func newCmdAccountList(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, globalOpts *globalflags.GlobalOptions) *cobra.Command { + ops := newAccountListOptions(streams, flags, globalOpts) accountListCmd := &cobra.Command{ Use: "list", Short: "List out accounts for username", @@ -73,11 +76,9 @@ func (o *accountListOptions) complete(cmd *cobra.Command, _ []string) error { if o.username != "" && o.accountID != "" { return cmdutil.UsageErrorf(cmd, "Cannot provide both username and account ID") } - output, err := outputflag.GetOutput(cmd) - if err != nil { - return err - } - o.output = output + + o.output = o.GlobalOptions.Output + return nil } diff --git a/cmd/account/mgmt/cmd.go b/cmd/account/mgmt/cmd.go index 861f18ef..03495121 100644 --- a/cmd/account/mgmt/cmd.go +++ b/cmd/account/mgmt/cmd.go @@ -1,12 +1,13 @@ package mgmt import ( + "github.com/openshift/osdctl/internal/utils/globalflags" "github.com/spf13/cobra" "k8s.io/cli-runtime/pkg/genericclioptions" ) // NewCmMgmt implements the mgmt command to get AWS Account resources -func NewCmdMgmt(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags) *cobra.Command { +func NewCmdMgmt(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, globalOpts *globalflags.GlobalOptions) *cobra.Command { mgmtCmd := &cobra.Command{ Use: "mgmt", Short: "AWS Account Management", @@ -15,8 +16,8 @@ func NewCmdMgmt(streams genericclioptions.IOStreams, flags *genericclioptions.Co Run: help, } - mgmtCmd.AddCommand(newCmdAccountList(streams, flags)) - mgmtCmd.AddCommand(newCmdAccountAssign(streams, flags)) + mgmtCmd.AddCommand(newCmdAccountList(streams, flags, globalOpts)) + mgmtCmd.AddCommand(newCmdAccountAssign(streams, flags, globalOpts)) mgmtCmd.AddCommand(newCmdAccountUnassign(streams, flags)) return mgmtCmd diff --git a/cmd/cluster/cmd.go b/cmd/cluster/cmd.go index 54582b86..9d0130fe 100644 --- a/cmd/cluster/cmd.go +++ b/cmd/cluster/cmd.go @@ -1,12 +1,13 @@ package cluster import ( + "github.com/openshift/osdctl/internal/utils/globalflags" "github.com/spf13/cobra" "k8s.io/cli-runtime/pkg/genericclioptions" ) // NewCmdClusterHealth implements the base cluster health command -func NewCmdCluster(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags) *cobra.Command { +func NewCmdCluster(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, globalOpts *globalflags.GlobalOptions) *cobra.Command { clusterCmd := &cobra.Command{ Use: "cluster", Short: "Provides vitals of an AWS cluster", @@ -15,7 +16,7 @@ func NewCmdCluster(streams genericclioptions.IOStreams, flags *genericclioptions Run: help, } - clusterCmd.AddCommand(newCmdHealth(streams, flags)) + clusterCmd.AddCommand(newCmdHealth(streams, flags, globalOpts)) return clusterCmd } diff --git a/cmd/cluster/health.go b/cmd/cluster/health.go index c8db9db6..b87500ee 100644 --- a/cmd/cluster/health.go +++ b/cmd/cluster/health.go @@ -13,6 +13,7 @@ import ( "github.com/aws/aws-sdk-go/service/ec2" sdk "github.com/openshift-online/ocm-sdk-go" v1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1" + "github.com/openshift/osdctl/internal/utils/globalflags" k8spkg "github.com/openshift/osdctl/pkg/k8s" awsprovider "github.com/openshift/osdctl/pkg/provider/aws" "github.com/openshift/osdctl/pkg/utils" @@ -33,11 +34,12 @@ type healthOptions struct { verbose bool genericclioptions.IOStreams + GlobalOptions *globalflags.GlobalOptions } // newCmdHealth implements the health command to describe number of running instances in cluster and the expected number of nodes -func newCmdHealth(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags) *cobra.Command { - ops := newHealthOptions(streams, flags) +func newCmdHealth(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, globalOpts *globalflags.GlobalOptions) *cobra.Command { + ops := newHealthOptions(streams, flags, globalOpts) healthCmd := &cobra.Command{ Use: "health", Short: "Describes health of cluster nodes and provides other cluster vitals.", @@ -49,18 +51,18 @@ func newCmdHealth(streams genericclioptions.IOStreams, flags *genericclioptions. }, } ops.k8sclusterresourcefactory.AttachCobraCliFlags(healthCmd) - healthCmd.Flags().StringVarP(&ops.output, "out", "o", "default", "Output format [default | json | env]") healthCmd.Flags().BoolVarP(&ops.verbose, "verbose", "", false, "Verbose output") return healthCmd } -func newHealthOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags) *healthOptions { +func newHealthOptions(streams genericclioptions.IOStreams, flags *genericclioptions.ConfigFlags, globalOpts *globalflags.GlobalOptions) *healthOptions { return &healthOptions{ k8sclusterresourcefactory: k8spkg.ClusterResourceFactoryOptions{ Flags: flags, }, - IOStreams: streams, + IOStreams: streams, + GlobalOptions: globalOpts, } } @@ -83,6 +85,8 @@ func (o *healthOptions) complete(cmd *cobra.Command, _ []string) error { } } + o.output = o.GlobalOptions.Output + return nil } diff --git a/cmd/cost/cost.go b/cmd/cost/cost.go index ddc6802a..eba71612 100644 --- a/cmd/cost/cost.go +++ b/cmd/cost/cost.go @@ -1,17 +1,19 @@ package cost import ( + "log" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/organizations" "github.com/openshift/osdctl/cmd/common" + "github.com/openshift/osdctl/internal/utils/globalflags" awsprovider "github.com/openshift/osdctl/pkg/provider/aws" "github.com/spf13/cobra" "k8s.io/cli-runtime/pkg/genericclioptions" - "log" ) // costCmd represents the cost command -func NewCmdCost(streams genericclioptions.IOStreams) *cobra.Command { +func NewCmdCost(streams genericclioptions.IOStreams, globalOpts *globalflags.GlobalOptions) *cobra.Command { opsCost = newCostOptions(streams) costCmd := &cobra.Command{ Use: "cost", @@ -28,10 +30,10 @@ platforms may be added in the future)`, costCmd.PersistentFlags().StringVarP(&opsCost.region, "aws-region", "g", common.DefaultRegion, "specify AWS region") //Add commands - costCmd.AddCommand(newCmdGet(streams)) + costCmd.AddCommand(newCmdGet(streams, globalOpts)) costCmd.AddCommand(newCmdReconcile(streams)) costCmd.AddCommand(newCmdCreate(streams)) - costCmd.AddCommand(newCmdList(streams)) + costCmd.AddCommand(newCmdList(streams, globalOpts)) return costCmd } diff --git a/cmd/cost/get.go b/cmd/cost/get.go index e83ce7c5..f71e8be5 100644 --- a/cmd/cost/get.go +++ b/cmd/cost/get.go @@ -7,6 +7,7 @@ import ( "time" outputflag "github.com/openshift/osdctl/cmd/getoutput" + "github.com/openshift/osdctl/internal/utils/globalflags" awsprovider "github.com/openshift/osdctl/pkg/provider/aws" "github.com/spf13/cobra" @@ -19,8 +20,8 @@ import ( ) // getCmd represents the get command -func newCmdGet(streams genericclioptions.IOStreams) *cobra.Command { - ops := newGetOptions(streams) +func newCmdGet(streams genericclioptions.IOStreams, globalOpts *globalflags.GlobalOptions) *cobra.Command { + ops := newGetOptions(streams, globalOpts) getCmd := &cobra.Command{ Use: "get", Short: "Get total cost of a given OU", @@ -59,11 +60,9 @@ func (o *getOptions) checkArgs(cmd *cobra.Command, _ []string) error { if o.ou == "" { return cmdutil.UsageErrorf(cmd, "Please provide OU") } - output, err := outputflag.GetOutput(cmd) - if err != nil { - return err - } - o.output = output + + o.output = o.GlobalOptions.Output + return nil } @@ -78,6 +77,7 @@ type getOptions struct { output string genericclioptions.IOStreams + GlobalOptions *globalflags.GlobalOptions } type getCostResponse struct { @@ -92,9 +92,10 @@ func (f getCostResponse) String() string { } -func newGetOptions(streams genericclioptions.IOStreams) *getOptions { +func newGetOptions(streams genericclioptions.IOStreams, globalOpts *globalflags.GlobalOptions) *getOptions { return &getOptions{ - IOStreams: streams, + IOStreams: streams, + GlobalOptions: globalOpts, } } diff --git a/cmd/cost/list.go b/cmd/cost/list.go index 01279b0f..8a5147fc 100644 --- a/cmd/cost/list.go +++ b/cmd/cost/list.go @@ -5,6 +5,7 @@ import ( "log" outputflag "github.com/openshift/osdctl/cmd/getoutput" + "github.com/openshift/osdctl/internal/utils/globalflags" awsprovider "github.com/openshift/osdctl/pkg/provider/aws" "k8s.io/cli-runtime/pkg/genericclioptions" cmdutil "k8s.io/kubectl/pkg/cmd/util" @@ -14,8 +15,8 @@ import ( ) // listCmd represents the list command -func newCmdList(streams genericclioptions.IOStreams) *cobra.Command { - ops := newListOptions(streams) +func newCmdList(streams genericclioptions.IOStreams, globalOpts *globalflags.GlobalOptions) *cobra.Command { + ops := newListOptions(streams, globalOpts) listCmd := &cobra.Command{ Use: "list", Short: "List the cost of each OU under given OU", @@ -65,11 +66,9 @@ func (o *listOptions) checkArgs(cmd *cobra.Command, _ []string) error { if o.ou == "" { return cmdutil.UsageErrorf(cmd, "Please provide OU") } - output, err := outputflag.GetOutput(cmd) - if err != nil { - return err - } - o.output = output + + o.output = o.GlobalOptions.Output + return nil } @@ -83,6 +82,7 @@ type listOptions struct { output string genericclioptions.IOStreams + GlobalOptions *globalflags.GlobalOptions } type listCostResponse struct { @@ -97,9 +97,10 @@ func (f listCostResponse) String() string { } -func newListOptions(streams genericclioptions.IOStreams) *listOptions { +func newListOptions(streams genericclioptions.IOStreams, globalOpts *globalflags.GlobalOptions) *listOptions { return &listOptions{ - IOStreams: streams, + IOStreams: streams, + GlobalOptions: globalOpts, } } diff --git a/cmd/getoutput/getoutput.go b/cmd/getoutput/getoutput.go index 8c7b1337..00546e43 100644 --- a/cmd/getoutput/getoutput.go +++ b/cmd/getoutput/getoutput.go @@ -4,23 +4,9 @@ import ( "encoding/json" "fmt" - "github.com/spf13/cobra" "gopkg.in/yaml.v2" - cmdutil "k8s.io/kubectl/pkg/cmd/util" ) -func GetOutput(cmd *cobra.Command) (string, error) { - - out, err := cmd.Flags().GetString("output") - if err != nil { - return "", err - } - if out != "" && out != "json" && out != "yaml" { - return "", cmdutil.UsageErrorf(cmd, "Invalid output format: Valid formats are ['', 'json', 'yaml']") - } - return out, nil -} - type CmdResponse interface { String() string } diff --git a/cmd/root.go b/cmd/root.go index 8edee6df..3ebfffe0 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,7 +1,6 @@ package cmd import ( - "flag" "fmt" routev1 "github.com/openshift/api/route/v1" @@ -13,7 +12,6 @@ import ( "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/client-go/kubernetes/scheme" "k8s.io/kubectl/pkg/util/templates" - "k8s.io/utils/pointer" "github.com/openshift/osdctl/cmd/aao" "github.com/openshift/osdctl/cmd/account" @@ -24,6 +22,7 @@ import ( "github.com/openshift/osdctl/cmd/network" "github.com/openshift/osdctl/cmd/servicelog" "github.com/openshift/osdctl/cmd/sts" + "github.com/openshift/osdctl/internal/utils/globalflags" "github.com/openshift/osdctl/pkg/k8s" ) @@ -33,8 +32,6 @@ var GitCommit string // Version is the tag version from the environment var Version string -var Output string - func init() { _ = awsv1alpha1.AddToScheme(scheme.Scheme) _ = routev1.AddToScheme(scheme.Scheme) @@ -44,6 +41,7 @@ func init() { // NewCmdRoot represents the base command when called without any subcommands func NewCmdRoot(streams genericclioptions.IOStreams) *cobra.Command { + globalOpts := &globalflags.GlobalOptions{} rootCmd := &cobra.Command{ Use: "osdctl", Version: fmt.Sprintf("%s, GitCommit: %s", Version, GitCommit), @@ -53,34 +51,21 @@ func NewCmdRoot(streams genericclioptions.IOStreams) *cobra.Command { Run: help, } - rootCmd.PersistentFlags().AddGoFlagSet(flag.CommandLine) - rootCmd.PersistentFlags().StringVarP(&Output, "output", "o", "", "Invalid output format: Valid formats are ['', 'json', 'yaml']") - - // Reuse kubectl global flags to provide namespace, context and credential options. - // We are not using NewConfigFlags here to avoid adding too many flags - kubeFlags := &genericclioptions.ConfigFlags{ - KubeConfig: pointer.StringPtr(""), - ClusterName: pointer.StringPtr(""), - Context: pointer.StringPtr(""), - APIServer: pointer.StringPtr(""), - Timeout: pointer.StringPtr("0"), - Insecure: pointer.BoolPtr(false), - Impersonate: pointer.StringPtr(""), - } - kubeFlags.AddFlags(rootCmd.PersistentFlags()) + globalflags.AddGlobalFlags(rootCmd, globalOpts) + kubeFlags := globalflags.GetFlags(rootCmd) - client := k8s.NewClient(kubeFlags) + kubeClient := k8s.NewClient(kubeFlags) // add sub commands rootCmd.AddCommand(aao.NewCmdAao(streams, kubeFlags)) - rootCmd.AddCommand(account.NewCmdAccount(streams, kubeFlags, client)) - rootCmd.AddCommand(cluster.NewCmdCluster(streams, kubeFlags)) - rootCmd.AddCommand(clusterdeployment.NewCmdClusterDeployment(streams, kubeFlags, client)) - rootCmd.AddCommand(federatedrole.NewCmdFederatedRole(streams, kubeFlags, client)) - rootCmd.AddCommand(network.NewCmdNetwork(streams, kubeFlags, client)) - rootCmd.AddCommand(newCmdMetrics(streams, kubeFlags, client)) + rootCmd.AddCommand(account.NewCmdAccount(streams, kubeFlags, kubeClient, globalOpts)) + rootCmd.AddCommand(cluster.NewCmdCluster(streams, kubeFlags, globalOpts)) + rootCmd.AddCommand(clusterdeployment.NewCmdClusterDeployment(streams, kubeFlags, kubeClient)) + rootCmd.AddCommand(federatedrole.NewCmdFederatedRole(streams, kubeFlags, kubeClient)) + rootCmd.AddCommand(network.NewCmdNetwork(streams, kubeFlags, kubeClient)) + rootCmd.AddCommand(newCmdMetrics(streams, kubeFlags, kubeClient)) rootCmd.AddCommand(servicelog.NewCmdServiceLog()) - rootCmd.AddCommand(sts.NewCmdSts(streams, kubeFlags, client)) + rootCmd.AddCommand(sts.NewCmdSts(streams, kubeFlags, kubeClient)) // add docs command rootCmd.AddCommand(newCmdDocs(streams)) @@ -93,7 +78,7 @@ func NewCmdRoot(streams genericclioptions.IOStreams) *cobra.Command { rootCmd.AddCommand(newCmdOptions(streams)) //Add cost command to use AWS Cost Manager - rootCmd.AddCommand(cost.NewCmdCost(streams)) + rootCmd.AddCommand(cost.NewCmdCost(streams, globalOpts)) return rootCmd } diff --git a/internal/utils/globalflags/globalflags.go b/internal/utils/globalflags/globalflags.go new file mode 100644 index 00000000..166e0584 --- /dev/null +++ b/internal/utils/globalflags/globalflags.go @@ -0,0 +1,37 @@ +package globalflags + +import ( + "flag" + + "github.com/spf13/cobra" + "k8s.io/cli-runtime/pkg/genericclioptions" + "k8s.io/utils/pointer" +) + +// Defines a set of Global Options available to all commands +type GlobalOptions struct { + Output string +} + +// AddGlobalFlags adds the Global Flags to the root command +func AddGlobalFlags(cmd *cobra.Command, opts *GlobalOptions) { + cmd.PersistentFlags().AddGoFlagSet(flag.CommandLine) + cmd.PersistentFlags().StringVarP(&opts.Output, "output", "o", "", "Invalid output format: Valid formats are ['', 'json', 'yaml']") +} + +// GetFlags adds the kubeFlags we care about and adds the flags from the provided command +func GetFlags(cmd *cobra.Command) *genericclioptions.ConfigFlags { + // Reuse kubectl global flags to provide namespace, context and credential options. + // We are not using NewConfigFlags here to avoid adding too many flags + flags := &genericclioptions.ConfigFlags{ + KubeConfig: pointer.StringPtr(""), + ClusterName: pointer.StringPtr(""), + Context: pointer.StringPtr(""), + APIServer: pointer.StringPtr(""), + Timeout: pointer.StringPtr("0"), + Insecure: pointer.BoolPtr(false), + Impersonate: pointer.StringPtr(""), + } + flags.AddFlags(cmd.PersistentFlags()) + return flags +}