From 98de893412a1e2e3adde79bdc4d24d5df7b7a12e Mon Sep 17 00:00:00 2001 From: Marc Falzon Date: Fri, 29 Oct 2021 09:23:30 +0200 Subject: [PATCH] dbaas: hide type-specific flags in create/update help (#409) This change hides the type-specific CLI flags in the `exo dbaas (create|update)` commands, instead offering to display those in new flags `--help-`. --- cmd/cmd.go | 27 ++++++++++++++ cmd/dbaas_service_create.go | 74 +++++++++++++++++++++++-------------- cmd/dbaas_service_update.go | 60 ++++++++++++++++++++---------- 3 files changed, 114 insertions(+), 47 deletions(-) diff --git a/cmd/cmd.go b/cmd/cmd.go index 1b431b48f..3a2a65ac0 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -1,12 +1,14 @@ package cmd import ( + "bytes" "fmt" "os" "reflect" "strconv" "strings" + "github.com/exoscale/cli/table" "github.com/hashicorp/go-multierror" "github.com/iancoleman/strcase" "github.com/spf13/cobra" @@ -77,6 +79,22 @@ func cmdExitOnUsageError(cmd *cobra.Command, reason string) { os.Exit(1) } +// cmdShowHelpFlags outputs flags matching the specified prefix in the provided flag set. +// This can be used for example to craft specialized usage help messages for hidden flags. +func cmdShowHelpFlags(flags *pflag.FlagSet, prefix string) { + buf := bytes.NewBuffer(nil) + t := table.NewEmbeddedTable(buf) + + flags.VisitAll(func(flag *pflag.Flag) { + if strings.HasPrefix(flag.Name, prefix) { + t.Append([]string{"--" + flag.Name, flag.Usage}) + } + }) + + t.Render() + fmt.Print(buf) +} + // completeVMNames is a Cobra Command.ValidArgsFunction that returns the list of Compute instance names belonging to // the current user for shell auto-completion. func completeVMNames(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { @@ -187,6 +205,7 @@ func mustCLICommandFlagName(c cliCommand, field interface{}) string { // * cli-usage:"": an optional string to use as flag usage // help message. For positional arguments, this field is used as argument // label for the "use" command help. +// * cli-hidden:"": mark the corresponding flag "hidden". func cliCommandFlagSet(c cliCommand) (*pflag.FlagSet, error) { fs := pflag.NewFlagSet("", pflag.ExitOnError) cv := reflect.ValueOf(c) @@ -263,6 +282,14 @@ func cliCommandFlagSet(c cliCommand) (*pflag.FlagSet, error) { default: return nil, cliCommandImplemError{fmt.Sprintf("unsupported type %s", t)} } + + if _, ok := cTypeField.Tag.Lookup("cli-hidden"); ok { + if err := fs.MarkHidden(flagName); err != nil { + return nil, cliCommandImplemError{ + reason: fmt.Sprintf("error marking flag %q hidden: %v", flagName, err), + } + } + } } return fs, nil diff --git a/cmd/dbaas_service_create.go b/cmd/dbaas_service_create.go index 8ddbeb2d8..cdbdf722e 100644 --- a/cmd/dbaas_service_create.go +++ b/cmd/dbaas_service_create.go @@ -2,6 +2,7 @@ package cmd import ( "fmt" + "os" "strings" "github.com/spf13/cobra" @@ -17,6 +18,10 @@ type dbServiceCreateCmd struct { Name string `cli-arg:"#"` ForkFrom string `cli-usage:"name of a Database Service to fork from"` + HelpKafka bool `cli-usage:"show usage for flags specific to the kafka type"` + HelpMysql bool `cli-usage:"show usage for flags specific to the mysql type"` + HelpPg bool `cli-usage:"show usage for flags specific to the pg type"` + HelpRedis bool `cli-usage:"show usage for flags specific to the redis type"` MaintenanceDOW string `cli-flag:"maintenance-dow" cli-usage:"automated Database Service maintenance day-of-week"` MaintenanceTime string `cli-usage:"automated Database Service maintenance time (format HH:MM:SS)"` RecoveryBackupTime string `cli-usage:"the timestamp of the backup to restore when forking from a Database Service"` @@ -24,39 +29,39 @@ type dbServiceCreateCmd struct { Zone string `cli-short:"z" cli-usage:"Database Service zone"` // "kafka" type specific flags - KafkaConnectSettings string `cli-flag:"kafka-connect-settings" cli-usage:"[kafka] Kafka Connect configuration settings (JSON format)"` - KafkaEnableCertAuth bool `cli-flag:"kafka-enable-cert-auth" cli-usage:"[kafka] enable certificate-based authentication method"` - KafkaEnableKafkaConnect bool `cli-flag:"kafka-enable-kafka-connect" cli-usage:"[kafka] enable Kafka Connect"` - KafkaEnableKafkaREST bool `cli-flag:"kafka-enable-kafka-rest" cli-usage:"[kafka] enable Kafka REST"` - KafkaEnableSASLAuth bool `cli-flag:"kafka-enable-sasl-auth" cli-usage:"[kafka] enable SASL-based authentication method"` - KafkaEnableSchemaRegistry bool `cli-flag:"kafka-enable-schema-registry" cli-usage:"[kafka] enable Schema Registry"` - KafkaIPFilter []string `cli-flag:"kafka-ip-filter" cli-usage:"[kafka] allow incoming connections from CIDR address block"` - KafkaRESTSettings string `cli-flag:"kafka-rest-settings" cli-usage:"[kafka] Kafka REST configuration settings (JSON format)"` - KafkaSchemaRegistrySettings string `cli-flag:"kafka-schema-registry-settings" cli-usage:"[kafka] Schema Registry configuration settings (JSON format)"` - KafkaSettings string `cli-flag:"kafka-settings" cli-usage:"[kafka] Kafka configuration settings (JSON format)"` - KafkaVersion string `cli-flag:"kafka-version" cli-usage:"[kafka] Kafka major version"` + KafkaConnectSettings string `cli-flag:"kafka-connect-settings" cli-usage:"Kafka Connect configuration settings (JSON format)" cli-hidden:""` + KafkaEnableCertAuth bool `cli-flag:"kafka-enable-cert-auth" cli-usage:"enable certificate-based authentication method" cli-hidden:""` + KafkaEnableKafkaConnect bool `cli-flag:"kafka-enable-kafka-connect" cli-usage:"enable Kafka Connect" cli-hidden:""` + KafkaEnableKafkaREST bool `cli-flag:"kafka-enable-kafka-rest" cli-usage:"enable Kafka REST" cli-hidden:""` + KafkaEnableSASLAuth bool `cli-flag:"kafka-enable-sasl-auth" cli-usage:"enable SASL-based authentication method" cli-hidden:""` + KafkaEnableSchemaRegistry bool `cli-flag:"kafka-enable-schema-registry" cli-usage:"enable Schema Registry" cli-hidden:""` + KafkaIPFilter []string `cli-flag:"kafka-ip-filter" cli-usage:"allow incoming connections from CIDR address block" cli-hidden:""` + KafkaRESTSettings string `cli-flag:"kafka-rest-settings" cli-usage:"Kafka REST configuration settings (JSON format)" cli-hidden:""` + KafkaSchemaRegistrySettings string `cli-flag:"kafka-schema-registry-settings" cli-usage:"Schema Registry configuration settings (JSON format)" cli-hidden:""` + KafkaSettings string `cli-flag:"kafka-settings" cli-usage:"Kafka configuration settings (JSON format)" cli-hidden:""` + KafkaVersion string `cli-flag:"kafka-version" cli-usage:"Kafka major version" cli-hidden:""` // "mysql" type specific flags - MysqlAdminPassword string `cli-flag:"mysql-admin-password" cli-usage:"[mysql] custom password for admin user"` - MysqlAdminUsername string `cli-flag:"mysql-admin-username" cli-usage:"[mysql] custom username for admin user"` - MysqlBackupSchedule string `cli-flag:"mysql-backup-schedule" cli-usage:"[mysql] automated backup schedule (format: HH:MM)"` - MysqlIPFilter []string `cli-flag:"mysql-ip-filter" cli-usage:"[mysql] allow incoming connections from CIDR address block"` - MysqlSettings string `cli-flag:"mysql-settings" cli-usage:"[mysql] MySQL configuration settings (JSON format)"` - MysqlVersion string `cli-flag:"mysql-version" cli-usage:"[mysql] MySQL major version"` + MysqlAdminPassword string `cli-flag:"mysql-admin-password" cli-usage:"custom password for admin user" cli-hidden:""` + MysqlAdminUsername string `cli-flag:"mysql-admin-username" cli-usage:"custom username for admin user" cli-hidden:""` + MysqlBackupSchedule string `cli-flag:"mysql-backup-schedule" cli-usage:"automated backup schedule (format: HH:MM)" cli-hidden:""` + MysqlIPFilter []string `cli-flag:"mysql-ip-filter" cli-usage:"allow incoming connections from CIDR address block" cli-hidden:""` + MysqlSettings string `cli-flag:"mysql-settings" cli-usage:"MySQL configuration settings (JSON format)" cli-hidden:""` + MysqlVersion string `cli-flag:"mysql-version" cli-usage:"MySQL major version" cli-hidden:""` // "pg" type specific flags - PGAdminPassword string `cli-flag:"pg-admin-password" cli-usage:"[pg] custom password for admin user"` - PGAdminUsername string `cli-flag:"pg-admin-username" cli-usage:"[pg] custom username for admin user"` - PGBackupSchedule string `cli-flag:"pg-backup-schedule" cli-usage:"[pg] automated backup schedule (format: HH:MM)"` - PGBouncerSettings string `cli-flag:"pg-bouncer-settings" cli-usage:"[pg] PgBouncer configuration settings (JSON format)"` - PGIPFilter []string `cli-flag:"pg-ip-filter" cli-usage:"[pg] allow incoming connections from CIDR address block"` - PGLookoutSettings string `cli-flag:"pg-lookout-settings" cli-usage:"[pg] pglookout configuration settings (JSON format)"` - PGSettings string `cli-flag:"pg-settings" cli-usage:"[pg] PostgreSQL configuration settings (JSON format)"` - PGVersion string `cli-flag:"pg-version" cli-usage:"[pg] PostgreSQL major version"` + PGAdminPassword string `cli-flag:"pg-admin-password" cli-usage:"custom password for admin user" cli-hidden:""` + PGAdminUsername string `cli-flag:"pg-admin-username" cli-usage:"custom username for admin user" cli-hidden:""` + PGBackupSchedule string `cli-flag:"pg-backup-schedule" cli-usage:"automated backup schedule (format: HH:MM)" cli-hidden:""` + PGBouncerSettings string `cli-flag:"pg-bouncer-settings" cli-usage:"PgBouncer configuration settings (JSON format)" cli-hidden:""` + PGIPFilter []string `cli-flag:"pg-ip-filter" cli-usage:"allow incoming connections from CIDR address block" cli-hidden:""` + PGLookoutSettings string `cli-flag:"pg-lookout-settings" cli-usage:"pglookout configuration settings (JSON format)" cli-hidden:""` + PGSettings string `cli-flag:"pg-settings" cli-usage:"PostgreSQL configuration settings (JSON format)" cli-hidden:""` + PGVersion string `cli-flag:"pg-version" cli-usage:"PostgreSQL major version" cli-hidden:""` // "redis" type specific flags - RedisIPFilter []string `cli-flag:"redis-ip-filter" cli-usage:"[redis] allow incoming connections from CIDR address block"` - RedisSettings string `cli-flag:"redis-settings" cli-usage:"[redis] PostgreSQL configuration settings (JSON format)"` + RedisIPFilter []string `cli-flag:"redis-ip-filter" cli-usage:"allow incoming connections from CIDR address block" cli-hidden:""` + RedisSettings string `cli-flag:"redis-settings" cli-usage:"Redis configuration settings (JSON format)" cli-hidden:""` } func (c *dbServiceCreateCmd) cmdAliases() []string { return gCreateAlias } @@ -74,6 +79,21 @@ Supported output template annotations: %s`, } func (c *dbServiceCreateCmd) cmdPreRun(cmd *cobra.Command, args []string) error { + switch { + case cmd.Flags().Changed("help-kafka"): + cmdShowHelpFlags(cmd.Flags(), "kafka-") + os.Exit(0) + case cmd.Flags().Changed("help-mysql"): + cmdShowHelpFlags(cmd.Flags(), "mysql-") + os.Exit(0) + case cmd.Flags().Changed("help-pg"): + cmdShowHelpFlags(cmd.Flags(), "pg-") + os.Exit(0) + case cmd.Flags().Changed("help-redis"): + cmdShowHelpFlags(cmd.Flags(), "redis-") + os.Exit(0) + } + cmdSetZoneFlagFromDefault(cmd) return cliCommandDefaultPreRun(c, cmd, args) } diff --git a/cmd/dbaas_service_update.go b/cmd/dbaas_service_update.go index da5eee3f8..0e59f9889 100644 --- a/cmd/dbaas_service_update.go +++ b/cmd/dbaas_service_update.go @@ -2,6 +2,7 @@ package cmd import ( "fmt" + "os" "strings" egoscale "github.com/exoscale/egoscale/v2" @@ -16,6 +17,10 @@ type dbServiceUpdateCmd struct { Name string `cli-arg:"#"` + HelpKafka bool `cli-usage:"show usage for flags specific to the kafka type"` + HelpMysql bool `cli-usage:"show usage for flags specific to the mysql type"` + HelpPg bool `cli-usage:"show usage for flags specific to the pg type"` + HelpRedis bool `cli-usage:"show usage for flags specific to the redis type"` MaintenanceDOW string `cli-flag:"maintenance-dow" cli-usage:"automated Database Service maintenance day-of-week"` MaintenanceTime string `cli-usage:"automated Database Service maintenance time (format HH:MM:SS)"` Plan string `cli-usage:"Database Service plan"` @@ -23,32 +28,32 @@ type dbServiceUpdateCmd struct { Zone string `cli-short:"z" cli-usage:"Database Service zone"` // "kafka" type specific flags - KafkaConnectSettings string `cli-flag:"kafka-connect-settings" cli-usage:"[kafka] Kafka Connect configuration settings (JSON format)"` - KafkaEnableCertAuth bool `cli-flag:"kafka-enable-cert-auth" cli-usage:"[kafka] enable certificate-based authentication method"` - KafkaEnableKafkaConnect bool `cli-flag:"kafka-enable-kafka-connect" cli-usage:"[kafka] enable Kafka Connect"` - KafkaEnableKafkaREST bool `cli-flag:"kafka-enable-kafka-rest" cli-usage:"[kafka] enable Kafka REST"` - KafkaEnableSASLAuth bool `cli-flag:"kafka-enable-sasl-auth" cli-usage:"[kafka] enable SASL-based authentication method"` - KafkaEnableSchemaRegistry bool `cli-flag:"kafka-enable-schema-registry" cli-usage:"[kafka] enable Schema Registry"` - KafkaIPFilter []string `cli-flag:"kafka-ip-filter" cli-usage:"[kafka] allow incoming connections from CIDR address block"` - KafkaRESTSettings string `cli-flag:"kafka-rest-settings" cli-usage:"[kafka] Kafka REST configuration settings (JSON format)"` - KafkaSchemaRegistrySettings string `cli-flag:"kafka-schema-registry-settings" cli-usage:"[kafka] Schema Registry configuration settings (JSON format)"` - KafkaSettings string `cli-flag:"kafka-settings" cli-usage:"[kafka] Kafka configuration settings (JSON format)"` + KafkaConnectSettings string `cli-flag:"kafka-connect-settings" cli-usage:"Kafka Connect configuration settings (JSON format)" cli-hidden:""` + KafkaEnableCertAuth bool `cli-flag:"kafka-enable-cert-auth" cli-usage:"enable certificate-based authentication method" cli-hidden:""` + KafkaEnableKafkaConnect bool `cli-flag:"kafka-enable-kafka-connect" cli-usage:"enable Kafka Connect" cli-hidden:""` + KafkaEnableKafkaREST bool `cli-flag:"kafka-enable-kafka-rest" cli-usage:"enable Kafka REST" cli-hidden:""` + KafkaEnableSASLAuth bool `cli-flag:"kafka-enable-sasl-auth" cli-usage:"enable SASL-based authentication method" cli-hidden:""` + KafkaEnableSchemaRegistry bool `cli-flag:"kafka-enable-schema-registry" cli-usage:"enable Schema Registry" cli-hidden:""` + KafkaIPFilter []string `cli-flag:"kafka-ip-filter" cli-usage:"allow incoming connections from CIDR address block" cli-hidden:""` + KafkaRESTSettings string `cli-flag:"kafka-rest-settings" cli-usage:"Kafka REST configuration settings (JSON format)" cli-hidden:""` + KafkaSchemaRegistrySettings string `cli-flag:"kafka-schema-registry-settings" cli-usage:"Schema Registry configuration settings (JSON format)" cli-hidden:""` + KafkaSettings string `cli-flag:"kafka-settings" cli-usage:"Kafka configuration settings (JSON format)" cli-hidden:""` // "mysql" type specific flags - MysqlBackupSchedule string `cli-flag:"mysql-backup-schedule" cli-usage:"[mysql] automated backup schedule (format: HH:MM)"` - MysqlIPFilter []string `cli-flag:"mysql-ip-filter" cli-usage:"[mysql] allow incoming connections from CIDR address block"` - MysqlSettings string `cli-flag:"mysql-settings" cli-usage:"[mysql] MySQL configuration settings (JSON format)"` + MysqlBackupSchedule string `cli-flag:"mysql-backup-schedule" cli-usage:"automated backup schedule (format: HH:MM)" cli-hidden:""` + MysqlIPFilter []string `cli-flag:"mysql-ip-filter" cli-usage:"allow incoming connections from CIDR address block" cli-hidden:""` + MysqlSettings string `cli-flag:"mysql-settings" cli-usage:"MySQL configuration settings (JSON format)" cli-hidden:""` // "pg" type specific flags - PGBackupSchedule string `cli-flag:"pg-backup-schedule" cli-usage:"[pg] automated backup schedule (format: HH:MM)"` - PGBouncerSettings string `cli-flag:"pg-bouncer-settings" cli-usage:"[pg] PgBouncer configuration settings (JSON format)"` - PGIPFilter []string `cli-flag:"pg-ip-filter" cli-usage:"[pg] allow incoming connections from CIDR address block"` - PGLookoutSettings string `cli-flag:"pg-lookout-settings" cli-usage:"[pg] pglookout configuration settings (JSON format)"` - PGSettings string `cli-flag:"pg-settings" cli-usage:"[pg] PostgreSQL configuration settings (JSON format)"` + PGBackupSchedule string `cli-flag:"pg-backup-schedule" cli-usage:"automated backup schedule (format: HH:MM)" cli-hidden:""` + PGBouncerSettings string `cli-flag:"pg-bouncer-settings" cli-usage:"PgBouncer configuration settings (JSON format)" cli-hidden:""` + PGIPFilter []string `cli-flag:"pg-ip-filter" cli-usage:"allow incoming connections from CIDR address block" cli-hidden:""` + PGLookoutSettings string `cli-flag:"pg-lookout-settings" cli-usage:"pglookout configuration settings (JSON format)" cli-hidden:""` + PGSettings string `cli-flag:"pg-settings" cli-usage:"PostgreSQL configuration settings (JSON format)" cli-hidden:""` // "redis" type specific flags - RedisIPFilter []string `cli-flag:"redis-ip-filter" cli-usage:"[redis] allow incoming connections from CIDR address block"` - RedisSettings string `cli-flag:"redis-settings" cli-usage:"[redis] Redis configuration settings (JSON format)"` + RedisIPFilter []string `cli-flag:"redis-ip-filter" cli-usage:"allow incoming connections from CIDR address block" cli-hidden:""` + RedisSettings string `cli-flag:"redis-settings" cli-usage:"Redis configuration settings (JSON format)" cli-hidden:""` } func (c *dbServiceUpdateCmd) cmdAliases() []string { return nil } @@ -67,6 +72,21 @@ Supported output template annotations: %s`, } func (c *dbServiceUpdateCmd) cmdPreRun(cmd *cobra.Command, args []string) error { + switch { + case cmd.Flags().Changed("help-kafka"): + cmdShowHelpFlags(cmd.Flags(), "kafka-") + os.Exit(0) + case cmd.Flags().Changed("help-mysql"): + cmdShowHelpFlags(cmd.Flags(), "mysql-") + os.Exit(0) + case cmd.Flags().Changed("help-pg"): + cmdShowHelpFlags(cmd.Flags(), "pg-") + os.Exit(0) + case cmd.Flags().Changed("help-redis"): + cmdShowHelpFlags(cmd.Flags(), "redis-") + os.Exit(0) + } + cmdSetZoneFlagFromDefault(cmd) return cliCommandDefaultPreRun(c, cmd, args) }