diff --git a/.codegen/cmds-account.go.tmpl b/.codegen/cmds-account.go.tmpl index d31959248a..f3da7e2c87 100644 --- a/.codegen/cmds-account.go.tmpl +++ b/.codegen/cmds-account.go.tmpl @@ -11,20 +11,21 @@ import ( {{.SnakeName}} "github.com/databricks/cli/cmd/account/{{(.TrimPrefix "account").KebabName}}"{{end}}{{end}}{{end}} ) -var accountCmd = &cobra.Command{ - Use: "account", - Short: `Databricks Account Commands`, -} - -func init() { - root.RootCmd.AddCommand(accountCmd) +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "account", + Short: `Databricks Account Commands`, + } {{range .Services}}{{if .IsAccounts}}{{if not (in $excludes .KebabName) -}} - accountCmd.AddCommand({{.SnakeName}}.Cmd) + cmd.AddCommand({{.SnakeName}}.New()) {{end}}{{end}}{{end}} - // Register commands with groups - {{range .Services}}{{if .IsAccounts}}{{if not (in $excludes .KebabName) -}} - {{.SnakeName}}.Cmd.GroupID = "{{ .Package.Name }}" - {{end}}{{end}}{{end}} + // Register all groups with the parent command. + groups := Groups() + for i := range groups { + cmd.AddGroup(&groups[i]) + } + + return cmd } diff --git a/.codegen/cmds-workspace.go.tmpl b/.codegen/cmds-workspace.go.tmpl index d3da365546..013c62f887 100644 --- a/.codegen/cmds-workspace.go.tmpl +++ b/.codegen/cmds-workspace.go.tmpl @@ -10,13 +10,12 @@ import ( {{.SnakeName}} "github.com/databricks/cli/cmd/workspace/{{.KebabName}}"{{end}}{{end}}{{end}} ) -func init() { - {{range .Services}}{{if not .IsAccounts}}{{if not (in $excludes .KebabName) -}} - root.RootCmd.AddCommand({{.SnakeName}}.Cmd) - {{end}}{{end}}{{end}} +func All() []*cobra.Command { + var out []*cobra.Command - // Register commands with groups {{range .Services}}{{if not .IsAccounts}}{{if not (in $excludes .KebabName) -}} - {{.SnakeName}}.Cmd.GroupID = "{{ .Package.Name }}" + out = append(out, {{.SnakeName}}.New()) {{end}}{{end}}{{end}} + + return out } diff --git a/.codegen/service.go.tmpl b/.codegen/service.go.tmpl index 76f4a94ee9..91f2e5cf7b 100644 --- a/.codegen/service.go.tmpl +++ b/.codegen/service.go.tmpl @@ -19,20 +19,34 @@ import ( {{end}} {{define "service"}} -var Cmd = &cobra.Command{ - Use: "{{(.TrimPrefix "account").KebabName}}", - {{- if .Description }} - Short: `{{.Summary | without "`"}}`, - Long: `{{.Comment " " 80 | without "`"}}`, - {{- end }} - Annotations: map[string]string{ - "package": "{{ .Package.Name }}", - }, - {{- if .IsPrivatePreview }} +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) - // This service is being previewed; hide from help output. - Hidden: true, - {{- end }} +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "{{(.TrimPrefix "account").KebabName}}", + {{- if .Description }} + Short: `{{.Summary | without "`"}}`, + Long: `{{.Comment " " 80 | without "`"}}`, + {{- end }} + GroupID: "{{ .Package.Name }}", + Annotations: map[string]string{ + "package": "{{ .Package.Name }}", + }, + {{- if .IsPrivatePreview }} + + // This service is being previewed; hide from help output. + Hidden: true, + {{- end }} + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } {{- $serviceName := .KebabName -}} @@ -44,26 +58,39 @@ var Cmd = &cobra.Command{ {{end}} // start {{.KebabName}} command -{{- $useJsonForAllFields := or .IsJsonOnly (and .Request (or (not .Request.IsAllRequiredFieldsPrimitive) .Request.HasRequiredNonBodyField)) -}} -{{- $needJsonFlag := or $useJsonForAllFields (and .Request (not .Request.IsOnlyPrimitiveFields)) -}} -{{- if .Request}} -var {{.CamelName}}Req {{.Service.Package.Name}}.{{.Request.PascalName}} -{{- if $needJsonFlag}} -var {{.CamelName}}Json flags.JsonFlag -{{- end}} -{{end}} -{{if .Wait}}var {{.CamelName}}SkipWait bool -var {{.CamelName}}Timeout time.Duration{{end}} +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var {{.CamelName}}Overrides []func( + *cobra.Command, + {{- if .Request }} + *{{.Service.Package.Name}}.{{.Request.PascalName}}, + {{- end }} +) + +func new{{.PascalName}}() *cobra.Command { + cmd := &cobra.Command{} + + {{- $useJsonForAllFields := or .IsJsonOnly (and .Request (or (not .Request.IsAllRequiredFieldsPrimitive) .Request.HasRequiredNonBodyField)) -}} + {{- $needJsonFlag := or $useJsonForAllFields (and .Request (not .Request.IsOnlyPrimitiveFields)) -}} + + {{- if .Request}} + + var {{.CamelName}}Req {{.Service.Package.Name}}.{{.Request.PascalName}} + {{- if $needJsonFlag}} + var {{.CamelName}}Json flags.JsonFlag + {{- end}} + {{- end}} + + {{if .Wait}}var {{.CamelName}}SkipWait bool + var {{.CamelName}}Timeout time.Duration{{end}} -func init() { - Cmd.AddCommand({{.CamelName}}Cmd) {{if .Wait}} - {{.CamelName}}Cmd.Flags().BoolVar(&{{.CamelName}}SkipWait, "no-wait", {{.CamelName}}SkipWait, `do not wait to reach {{range $i, $e := .Wait.Success}}{{if $i}} or {{end}}{{.Content}}{{end}} state`) - {{.CamelName}}Cmd.Flags().DurationVar(&{{.CamelName}}Timeout, "timeout", {{.Wait.Timeout}}*time.Minute, `maximum amount of time to reach {{range $i, $e := .Wait.Success}}{{if $i}} or {{end}}{{.Content}}{{end}} state`) + cmd.Flags().BoolVar(&{{.CamelName}}SkipWait, "no-wait", {{.CamelName}}SkipWait, `do not wait to reach {{range $i, $e := .Wait.Success}}{{if $i}} or {{end}}{{.Content}}{{end}} state`) + cmd.Flags().DurationVar(&{{.CamelName}}Timeout, "timeout", {{.Wait.Timeout}}*time.Minute, `maximum amount of time to reach {{range $i, $e := .Wait.Success}}{{if $i}} or {{end}}{{.Content}}{{end}} state`) {{end -}} {{if .Request}}// TODO: short flags {{- if $needJsonFlag}} - {{.CamelName}}Cmd.Flags().Var(&{{.CamelName}}Json, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&{{.CamelName}}Json, "json", `either inline JSON string or @path/to/file.json with request body`) {{- end}} {{$method := .}} {{ if not .IsJsonOnly }} @@ -74,38 +101,39 @@ func init() { {{else if .Entity.ArrayValue }}// TODO: array: {{.Name}} {{else if .Entity.MapValue }}// TODO: map via StringToStringVar: {{.Name}} {{else if .Entity.IsEmpty }}// TODO: output-only field - {{else if .Entity.Enum }}{{$method.CamelName}}Cmd.Flags().Var(&{{$method.CamelName}}Req.{{.PascalName}}, "{{.KebabName}}", `{{.Summary | without "`"}}`) - {{else}}{{$method.CamelName}}Cmd.Flags().{{template "arg-type" .Entity}}(&{{$method.CamelName}}Req.{{.PascalName}}, "{{.KebabName}}", {{$method.CamelName}}Req.{{.PascalName}}, `{{.Summary | without "`"}}`) + {{else if .Entity.Enum }}cmd.Flags().Var(&{{$method.CamelName}}Req.{{.PascalName}}, "{{.KebabName}}", `{{.Summary | without "`"}}`) + {{else}}cmd.Flags().{{template "arg-type" .Entity}}(&{{$method.CamelName}}Req.{{.PascalName}}, "{{.KebabName}}", {{$method.CamelName}}Req.{{.PascalName}}, `{{.Summary | without "`"}}`) {{end}} {{- end -}} {{- end}} {{- end}} {{end}} -} -{{- $excludeFromPrompts := list "workspace get-status" -}} -{{- $fullCommandName := (print $serviceName " " .KebabName) -}} -{{- $noPrompt := or .IsCrudCreate (in $excludeFromPrompts $fullCommandName) }} - -{{ $hasPosArgs := and .Request (or .Request.IsAllRequiredFieldsPrimitive (eq .PascalName "RunNow")) -}} -{{- $hasSinglePosArg := and $hasPosArgs (eq 1 (len .Request.RequiredFields)) -}} -{{- $serviceHasNamedIdMap := and (and .Service.List .Service.List.NamedIdMap) (not (eq .PascalName "List")) -}} -{{- $hasIdPrompt := and (not $noPrompt) (and $hasSinglePosArg $serviceHasNamedIdMap) -}} -{{- $wait := and .Wait (and (not .IsCrudRead) (not (eq .SnakeName "get_run"))) -}} -{{- $hasRequiredArgs := and (not $hasIdPrompt) $hasPosArgs -}} -var {{.CamelName}}Cmd = &cobra.Command{ - Use: "{{.KebabName}}{{if $hasPosArgs}}{{range .Request.RequiredFields}} {{.ConstantName}}{{end}}{{end}}", + + {{- $excludeFromPrompts := list "workspace get-status" -}} + {{- $fullCommandName := (print $serviceName " " .KebabName) -}} + {{- $noPrompt := or .IsCrudCreate (in $excludeFromPrompts $fullCommandName) }} + + {{- $hasPosArgs := and .Request (or .Request.IsAllRequiredFieldsPrimitive (eq .PascalName "RunNow")) -}} + {{- $hasSinglePosArg := and $hasPosArgs (eq 1 (len .Request.RequiredFields)) -}} + {{- $serviceHasNamedIdMap := and (and .Service.List .Service.List.NamedIdMap) (not (eq .PascalName "List")) -}} + {{- $hasIdPrompt := and (not $noPrompt) (and $hasSinglePosArg $serviceHasNamedIdMap) -}} + {{- $wait := and .Wait (and (not .IsCrudRead) (not (eq .SnakeName "get_run"))) -}} + {{- $hasRequiredArgs := and (not $hasIdPrompt) $hasPosArgs -}} + + cmd.Use = "{{.KebabName}}{{if $hasPosArgs}}{{range .Request.RequiredFields}} {{.ConstantName}}{{end}}{{end}}" {{- if .Description }} - Short: `{{.Summary | without "`"}}`, - Long: `{{.Comment " " 80 | without "`"}}`, + cmd.Short = `{{.Summary | without "`"}}` + cmd.Long = `{{.Comment " " 80 | without "`"}}` {{- end }} {{- if .IsPrivatePreview }} // This command is being previewed; hide from help output. - Hidden: true, + cmd.Hidden = true {{- end }} - Annotations: map[string]string{},{{if $hasRequiredArgs }} - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + {{if $hasRequiredArgs }} + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs({{len .Request.RequiredFields}}) {{- if $useJsonForAllFields }} if cmd.Flags().Changed("json") { @@ -113,9 +141,10 @@ var {{.CamelName}}Cmd = &cobra.Command{ } {{- end }} return check(cmd, args) - },{{end}} - PreRunE: root.Must{{if .Service.IsAccounts}}Account{{else}}Workspace{{end}}Client, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + {{end}} + cmd.PreRunE = root.Must{{if .Service.IsAccounts}}Account{{else}}Workspace{{end}}Client + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() {{if .Service.IsAccounts}}a := root.AccountClient(ctx){{else}}w := root.WorkspaceClient(ctx){{end}} {{- if .Request }} @@ -204,10 +233,24 @@ var {{.CamelName}}Cmd = &cobra.Command{ {{- else -}} {{template "method-call" .}} {{end -}} - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range {{.CamelName}}Overrides { + fn(cmd{{if .Request}}, &{{.CamelName}}Req{{end}}) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(new{{.PascalName}}()) + }) } {{end}} // end service {{.Name}}{{end}} diff --git a/cmd/account/access-control/access-control.go b/cmd/account/access-control/access-control.go index 5cec69a312..01c076fbd0 100755 --- a/cmd/account/access-control/access-control.go +++ b/cmd/account/access-control/access-control.go @@ -12,42 +12,64 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "access-control", - Short: `These APIs manage access rules on resources in an account.`, - Long: `These APIs manage access rules on resources in an account. Currently, only +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "access-control", + Short: `These APIs manage access rules on resources in an account.`, + Long: `These APIs manage access rules on resources in an account. Currently, only grant rules are supported. A grant rule specifies a role assigned to a set of principals. A list of rules attached to a resource is called a rule set.`, - Annotations: map[string]string{ - "package": "iam", - }, + GroupID: "iam", + Annotations: map[string]string{ + "package": "iam", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start get-assignable-roles-for-resource command -var getAssignableRolesForResourceReq iam.GetAssignableRolesForResourceRequest -func init() { - Cmd.AddCommand(getAssignableRolesForResourceCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getAssignableRolesForResourceOverrides []func( + *cobra.Command, + *iam.GetAssignableRolesForResourceRequest, +) -} +func newGetAssignableRolesForResource() *cobra.Command { + cmd := &cobra.Command{} + + var getAssignableRolesForResourceReq iam.GetAssignableRolesForResourceRequest -var getAssignableRolesForResourceCmd = &cobra.Command{ - Use: "get-assignable-roles-for-resource RESOURCE", - Short: `Get assignable roles for a resource.`, - Long: `Get assignable roles for a resource. + // TODO: short flags + + cmd.Use = "get-assignable-roles-for-resource RESOURCE" + cmd.Short = `Get assignable roles for a resource.` + cmd.Long = `Get assignable roles for a resource. Gets all the roles that can be granted on an account level resource. A role is grantable if the rule set on the resource can contain an access rule of the - role.`, + role.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -58,37 +80,59 @@ var getAssignableRolesForResourceCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getAssignableRolesForResourceOverrides { + fn(cmd, &getAssignableRolesForResourceReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetAssignableRolesForResource()) + }) } // start get-rule-set command -var getRuleSetReq iam.GetRuleSetRequest -func init() { - Cmd.AddCommand(getRuleSetCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getRuleSetOverrides []func( + *cobra.Command, + *iam.GetRuleSetRequest, +) -} +func newGetRuleSet() *cobra.Command { + cmd := &cobra.Command{} + + var getRuleSetReq iam.GetRuleSetRequest + + // TODO: short flags -var getRuleSetCmd = &cobra.Command{ - Use: "get-rule-set NAME ETAG", - Short: `Get a rule set.`, - Long: `Get a rule set. + cmd.Use = "get-rule-set NAME ETAG" + cmd.Short = `Get a rule set.` + cmd.Long = `Get a rule set. Get a rule set by its name. A rule set is always attached to a resource and contains a list of access rules on the said resource. Currently only a default - rule set for each resource is supported.`, + rule set for each resource is supported.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -100,35 +144,56 @@ var getRuleSetCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getRuleSetOverrides { + fn(cmd, &getRuleSetReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetRuleSet()) + }) } // start update-rule-set command -var updateRuleSetReq iam.UpdateRuleSetRequest -var updateRuleSetJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateRuleSetCmd) - // TODO: short flags - updateRuleSetCmd.Flags().Var(&updateRuleSetJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateRuleSetOverrides []func( + *cobra.Command, + *iam.UpdateRuleSetRequest, +) -} +func newUpdateRuleSet() *cobra.Command { + cmd := &cobra.Command{} + + var updateRuleSetReq iam.UpdateRuleSetRequest + var updateRuleSetJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&updateRuleSetJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var updateRuleSetCmd = &cobra.Command{ - Use: "update-rule-set", - Short: `Update a rule set.`, - Long: `Update a rule set. + cmd.Use = "update-rule-set" + cmd.Short = `Update a rule set.` + cmd.Long = `Update a rule set. Replace the rules of a rule set. First, use get to read the current version of the rule set before modifying it. This pattern helps prevent conflicts between - concurrent updates.`, + concurrent updates.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -146,10 +211,24 @@ var updateRuleSetCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateRuleSetOverrides { + fn(cmd, &updateRuleSetReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdateRuleSet()) + }) } // end service AccountAccessControl diff --git a/cmd/account/billable-usage/billable-usage.go b/cmd/account/billable-usage/billable-usage.go index babc7bc2ca..b5b9749dca 100755 --- a/cmd/account/billable-usage/billable-usage.go +++ b/cmd/account/billable-usage/billable-usage.go @@ -8,31 +8,51 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "billable-usage", - Short: `This API allows you to download billable usage logs for the specified account and date range.`, - Long: `This API allows you to download billable usage logs for the specified account +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "billable-usage", + Short: `This API allows you to download billable usage logs for the specified account and date range.`, + Long: `This API allows you to download billable usage logs for the specified account and date range. This feature works with all account types.`, - Annotations: map[string]string{ - "package": "billing", - }, + GroupID: "billing", + Annotations: map[string]string{ + "package": "billing", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start download command -var downloadReq billing.DownloadRequest -func init() { - Cmd.AddCommand(downloadCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var downloadOverrides []func( + *cobra.Command, + *billing.DownloadRequest, +) - downloadCmd.Flags().BoolVar(&downloadReq.PersonalData, "personal-data", downloadReq.PersonalData, `Specify whether to include personally identifiable information in the billable usage logs, for example the email addresses of cluster creators.`) +func newDownload() *cobra.Command { + cmd := &cobra.Command{} -} + var downloadReq billing.DownloadRequest + + // TODO: short flags -var downloadCmd = &cobra.Command{ - Use: "download START_MONTH END_MONTH", - Short: `Return billable usage logs.`, - Long: `Return billable usage logs. + cmd.Flags().BoolVar(&downloadReq.PersonalData, "personal-data", downloadReq.PersonalData, `Specify whether to include personally identifiable information in the billable usage logs, for example the email addresses of cluster creators.`) + + cmd.Use = "download START_MONTH END_MONTH" + cmd.Short = `Return billable usage logs.` + cmd.Long = `Return billable usage logs. Returns billable usage logs in CSV format for the specified account and date range. For the data schema, see [CSV file schema]. Note that this method might @@ -43,15 +63,17 @@ var downloadCmd = &cobra.Command{ this API may hit a timeout after a few minutes. If you experience this, try to mitigate by calling the API with narrower date ranges. - [CSV file schema]: https://docs.databricks.com/administration-guide/account-settings/usage-analysis.html#schema`, + [CSV file schema]: https://docs.databricks.com/administration-guide/account-settings/usage-analysis.html#schema` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -63,10 +85,24 @@ var downloadCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range downloadOverrides { + fn(cmd, &downloadReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDownload()) + }) } // end service BillableUsage diff --git a/cmd/account/budgets/budgets.go b/cmd/account/budgets/budgets.go index 3e26b181a8..ed8b4591a4 100755 --- a/cmd/account/budgets/budgets.go +++ b/cmd/account/budgets/budgets.go @@ -12,40 +12,61 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "budgets", - Short: `These APIs manage budget configuration including notifications for exceeding a budget for a period.`, - Long: `These APIs manage budget configuration including notifications for exceeding a +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "budgets", + Short: `These APIs manage budget configuration including notifications for exceeding a budget for a period.`, + Long: `These APIs manage budget configuration including notifications for exceeding a budget for a period. They can also retrieve the status of each budget.`, - Annotations: map[string]string{ - "package": "billing", - }, + GroupID: "billing", + Annotations: map[string]string{ + "package": "billing", + }, - // This service is being previewed; hide from help output. - Hidden: true, + // This service is being previewed; hide from help output. + Hidden: true, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq billing.WrappedBudget -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *billing.WrappedBudget, +) -} +func newCreate() *cobra.Command { + cmd := &cobra.Command{} -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a new budget.`, - Long: `Create a new budget. + var createReq billing.WrappedBudget + var createJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "create" + cmd.Short = `Create a new budget.` + cmd.Long = `Create a new budget. - Creates a new budget in the specified account.`, + Creates a new budget in the specified account.` - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -63,51 +84,60 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq billing.DeleteBudgetRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *billing.DeleteBudgetRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq billing.DeleteBudgetRequest -var deleteCmd = &cobra.Command{ - Use: "delete BUDGET_ID", - Short: `Delete budget.`, - Long: `Delete budget. + // TODO: short flags + + cmd.Use = "delete BUDGET_ID" + cmd.Short = `Delete budget.` + cmd.Long = `Delete budget. - Deletes the budget specified by its UUID.`, + Deletes the budget specified by its UUID.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No BUDGET_ID argument specified. Loading names for Budgets drop-down." - names, err := a.Budgets.BudgetWithStatusNameToBudgetIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Budgets drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Budget ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have budget id") - } deleteReq.BudgetId = args[0] err = a.Budgets.Delete(ctx, deleteReq) @@ -115,52 +145,61 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq billing.GetBudgetRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *billing.GetBudgetRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} -var getCmd = &cobra.Command{ - Use: "get BUDGET_ID", - Short: `Get budget and its status.`, - Long: `Get budget and its status. + var getReq billing.GetBudgetRequest + + // TODO: short flags + + cmd.Use = "get BUDGET_ID" + cmd.Short = `Get budget and its status.` + cmd.Long = `Get budget and its status. Gets the budget specified by its UUID, including noncumulative status for each - day that the budget is configured to include.`, + day that the budget is configured to include.` - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No BUDGET_ID argument specified. Loading names for Budgets drop-down." - names, err := a.Budgets.BudgetWithStatusNameToBudgetIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Budgets drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Budget ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have budget id") - } getReq.BudgetId = args[0] response, err := a.Budgets.Get(ctx, getReq) @@ -168,30 +207,48 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get all budgets.`, - Long: `Get all budgets. + cmd.Use = "list" + cmd.Short = `Get all budgets.` + cmd.Long = `Get all budgets. Gets all budgets associated with this account, including noncumulative status - for each day that the budget is configured to include.`, + for each day that the budget is configured to include.` - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) response, err := a.Budgets.ListAll(ctx) @@ -199,34 +256,55 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq billing.WrappedBudget -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) - // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *billing.WrappedBudget, +) -} +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} -var updateCmd = &cobra.Command{ - Use: "update", - Short: `Modify budget.`, - Long: `Modify budget. + var updateReq billing.WrappedBudget + var updateJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "update" + cmd.Short = `Modify budget.` + cmd.Long = `Modify budget. Modifies a budget in this account. Budget properties are completely - overwritten.`, + overwritten.` - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -244,10 +322,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Budgets diff --git a/cmd/account/cmd.go b/cmd/account/cmd.go index 923948b6b0..294801a686 100644 --- a/cmd/account/cmd.go +++ b/cmd/account/cmd.go @@ -3,7 +3,6 @@ package account import ( - "github.com/databricks/cli/cmd/root" "github.com/spf13/cobra" account_access_control "github.com/databricks/cli/cmd/account/access-control" @@ -32,63 +31,42 @@ import ( workspaces "github.com/databricks/cli/cmd/account/workspaces" ) -var accountCmd = &cobra.Command{ - Use: "account", - Short: `Databricks Account Commands`, -} - -func init() { - root.RootCmd.AddCommand(accountCmd) +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "account", + Short: `Databricks Account Commands`, + } - accountCmd.AddCommand(account_access_control.Cmd) - accountCmd.AddCommand(billable_usage.Cmd) - accountCmd.AddCommand(budgets.Cmd) - accountCmd.AddCommand(credentials.Cmd) - accountCmd.AddCommand(custom_app_integration.Cmd) - accountCmd.AddCommand(encryption_keys.Cmd) - accountCmd.AddCommand(account_groups.Cmd) - accountCmd.AddCommand(account_ip_access_lists.Cmd) - accountCmd.AddCommand(log_delivery.Cmd) - accountCmd.AddCommand(account_metastore_assignments.Cmd) - accountCmd.AddCommand(account_metastores.Cmd) - accountCmd.AddCommand(networks.Cmd) - accountCmd.AddCommand(o_auth_enrollment.Cmd) - accountCmd.AddCommand(private_access.Cmd) - accountCmd.AddCommand(published_app_integration.Cmd) - accountCmd.AddCommand(service_principal_secrets.Cmd) - accountCmd.AddCommand(account_service_principals.Cmd) - accountCmd.AddCommand(account_settings.Cmd) - accountCmd.AddCommand(storage.Cmd) - accountCmd.AddCommand(account_storage_credentials.Cmd) - accountCmd.AddCommand(account_users.Cmd) - accountCmd.AddCommand(vpc_endpoints.Cmd) - accountCmd.AddCommand(workspace_assignment.Cmd) - accountCmd.AddCommand(workspaces.Cmd) + cmd.AddCommand(account_access_control.New()) + cmd.AddCommand(billable_usage.New()) + cmd.AddCommand(budgets.New()) + cmd.AddCommand(credentials.New()) + cmd.AddCommand(custom_app_integration.New()) + cmd.AddCommand(encryption_keys.New()) + cmd.AddCommand(account_groups.New()) + cmd.AddCommand(account_ip_access_lists.New()) + cmd.AddCommand(log_delivery.New()) + cmd.AddCommand(account_metastore_assignments.New()) + cmd.AddCommand(account_metastores.New()) + cmd.AddCommand(networks.New()) + cmd.AddCommand(o_auth_enrollment.New()) + cmd.AddCommand(private_access.New()) + cmd.AddCommand(published_app_integration.New()) + cmd.AddCommand(service_principal_secrets.New()) + cmd.AddCommand(account_service_principals.New()) + cmd.AddCommand(account_settings.New()) + cmd.AddCommand(storage.New()) + cmd.AddCommand(account_storage_credentials.New()) + cmd.AddCommand(account_users.New()) + cmd.AddCommand(vpc_endpoints.New()) + cmd.AddCommand(workspace_assignment.New()) + cmd.AddCommand(workspaces.New()) - // Register commands with groups - account_access_control.Cmd.GroupID = "iam" - billable_usage.Cmd.GroupID = "billing" - budgets.Cmd.GroupID = "billing" - credentials.Cmd.GroupID = "provisioning" - custom_app_integration.Cmd.GroupID = "oauth2" - encryption_keys.Cmd.GroupID = "provisioning" - account_groups.Cmd.GroupID = "iam" - account_ip_access_lists.Cmd.GroupID = "settings" - log_delivery.Cmd.GroupID = "billing" - account_metastore_assignments.Cmd.GroupID = "catalog" - account_metastores.Cmd.GroupID = "catalog" - networks.Cmd.GroupID = "provisioning" - o_auth_enrollment.Cmd.GroupID = "oauth2" - private_access.Cmd.GroupID = "provisioning" - published_app_integration.Cmd.GroupID = "oauth2" - service_principal_secrets.Cmd.GroupID = "oauth2" - account_service_principals.Cmd.GroupID = "iam" - account_settings.Cmd.GroupID = "settings" - storage.Cmd.GroupID = "provisioning" - account_storage_credentials.Cmd.GroupID = "catalog" - account_users.Cmd.GroupID = "iam" - vpc_endpoints.Cmd.GroupID = "provisioning" - workspace_assignment.Cmd.GroupID = "iam" - workspaces.Cmd.GroupID = "provisioning" + // Register all groups with the parent command. + groups := Groups() + for i := range groups { + cmd.AddGroup(&groups[i]) + } + return cmd } diff --git a/cmd/account/credentials/credentials.go b/cmd/account/credentials/credentials.go index 5a1362d15c..35c8869a80 100755 --- a/cmd/account/credentials/credentials.go +++ b/cmd/account/credentials/credentials.go @@ -12,34 +12,54 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "credentials", - Short: `These APIs manage credential configurations for this workspace.`, - Long: `These APIs manage credential configurations for this workspace. Databricks +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "credentials", + Short: `These APIs manage credential configurations for this workspace.`, + Long: `These APIs manage credential configurations for this workspace. Databricks needs access to a cross-account service IAM role in your AWS account so that Databricks can deploy clusters in the appropriate VPC for the new workspace. A credential configuration encapsulates this role information, and its ID is used when creating a new workspace.`, - Annotations: map[string]string{ - "package": "provisioning", - }, + GroupID: "provisioning", + Annotations: map[string]string{ + "package": "provisioning", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq provisioning.CreateCredentialRequest -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *provisioning.CreateCredentialRequest, +) -} +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq provisioning.CreateCredentialRequest + var createJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create credential configuration.`, - Long: `Create credential configuration. + cmd.Use = "create" + cmd.Short = `Create credential configuration.` + cmd.Long = `Create credential configuration. Creates a Databricks credential configuration that represents cloud cross-account credentials for a specified account. Databricks uses this to set @@ -54,11 +74,12 @@ var createCmd = &cobra.Command{ For information about how to create a new workspace with this API, see [Create a new workspace using the Account API] - [Create a new workspace using the Account API]: http://docs.databricks.com/administration-guide/account-api/new-workspace.html`, + [Create a new workspace using the Account API]: http://docs.databricks.com/administration-guide/account-api/new-workspace.html` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -76,53 +97,62 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq provisioning.DeleteCredentialRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *provisioning.DeleteCredentialRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete CREDENTIALS_ID", - Short: `Delete credential configuration.`, - Long: `Delete credential configuration. + var deleteReq provisioning.DeleteCredentialRequest + + // TODO: short flags + + cmd.Use = "delete CREDENTIALS_ID" + cmd.Short = `Delete credential configuration.` + cmd.Long = `Delete credential configuration. Deletes a Databricks credential configuration object for an account, both specified by ID. You cannot delete a credential that is associated with any - workspace.`, + workspace.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No CREDENTIALS_ID argument specified. Loading names for Credentials drop-down." - names, err := a.Credentials.CredentialCredentialsNameToCredentialsIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Credentials drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Databricks Account API credential configuration ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have databricks account api credential configuration id") - } deleteReq.CredentialsId = args[0] err = a.Credentials.Delete(ctx, deleteReq) @@ -130,52 +160,61 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq provisioning.GetCredentialRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *provisioning.GetCredentialRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq provisioning.GetCredentialRequest + + // TODO: short flags -var getCmd = &cobra.Command{ - Use: "get CREDENTIALS_ID", - Short: `Get credential configuration.`, - Long: `Get credential configuration. + cmd.Use = "get CREDENTIALS_ID" + cmd.Short = `Get credential configuration.` + cmd.Long = `Get credential configuration. Gets a Databricks credential configuration object for an account, both - specified by ID.`, + specified by ID.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No CREDENTIALS_ID argument specified. Loading names for Credentials drop-down." - names, err := a.Credentials.CredentialCredentialsNameToCredentialsIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Credentials drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Databricks Account API credential configuration ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have databricks account api credential configuration id") - } getReq.CredentialsId = args[0] response, err := a.Credentials.Get(ctx, getReq) @@ -183,30 +222,48 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get all credential configurations.`, - Long: `Get all credential configurations. + cmd.Use = "list" + cmd.Short = `Get all credential configurations.` + cmd.Long = `Get all credential configurations. Gets all Databricks credential configurations associated with an account - specified by ID.`, + specified by ID.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) response, err := a.Credentials.List(ctx) @@ -214,10 +271,24 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // end service Credentials diff --git a/cmd/account/credentials/overrides.go b/cmd/account/credentials/overrides.go index 5052150552..9f1e6cb665 100644 --- a/cmd/account/credentials/overrides.go +++ b/cmd/account/credentials/overrides.go @@ -1,9 +1,16 @@ package credentials -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{range .}}{{.CredentialsId | green}} {{.CredentialsName}} {{.AwsCredentials.StsRole.RoleArn}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/account/custom-app-integration/custom-app-integration.go b/cmd/account/custom-app-integration/custom-app-integration.go index 837ac5188a..d7269bf47c 100755 --- a/cmd/account/custom-app-integration/custom-app-integration.go +++ b/cmd/account/custom-app-integration/custom-app-integration.go @@ -12,48 +12,69 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "custom-app-integration", - Short: `These APIs enable administrators to manage custom oauth app integrations, which is required for adding/using Custom OAuth App Integration like Tableau Cloud for Databricks in AWS cloud.`, - Long: `These APIs enable administrators to manage custom oauth app integrations, +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "custom-app-integration", + Short: `These APIs enable administrators to manage custom oauth app integrations, which is required for adding/using Custom OAuth App Integration like Tableau Cloud for Databricks in AWS cloud.`, + Long: `These APIs enable administrators to manage custom oauth app integrations, which is required for adding/using Custom OAuth App Integration like Tableau Cloud for Databricks in AWS cloud. **Note:** You can only add/use the OAuth custom application integrations when OAuth enrollment status is enabled. For more details see :method:OAuthEnrollment/create`, - Annotations: map[string]string{ - "package": "oauth2", - }, + GroupID: "oauth2", + Annotations: map[string]string{ + "package": "oauth2", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq oauth2.CreateCustomAppIntegration -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *oauth2.CreateCustomAppIntegration, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq oauth2.CreateCustomAppIntegration + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createCmd.Flags().BoolVar(&createReq.Confidential, "confidential", createReq.Confidential, `indicates if an oauth client-secret should be generated.`) + cmd.Flags().BoolVar(&createReq.Confidential, "confidential", createReq.Confidential, `indicates if an oauth client-secret should be generated.`) // TODO: complex arg: token_access_policy -} - -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create Custom OAuth App Integration.`, - Long: `Create Custom OAuth App Integration. + cmd.Use = "create" + cmd.Short = `Create Custom OAuth App Integration.` + cmd.Long = `Create Custom OAuth App Integration. Create Custom OAuth App Integration. You can retrieve the custom oauth app integration via - :method:CustomAppIntegration/get.`, + :method:CustomAppIntegration/get.` - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -71,36 +92,58 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq oauth2.DeleteCustomAppIntegrationRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *oauth2.DeleteCustomAppIntegrationRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete INTEGRATION_ID", - Short: `Delete Custom OAuth App Integration.`, - Long: `Delete Custom OAuth App Integration. + var deleteReq oauth2.DeleteCustomAppIntegrationRequest + + // TODO: short flags + + cmd.Use = "delete INTEGRATION_ID" + cmd.Short = `Delete Custom OAuth App Integration.` + cmd.Long = `Delete Custom OAuth App Integration. Delete an existing Custom OAuth App Integration. You can retrieve the custom - oauth app integration via :method:CustomAppIntegration/get.`, + oauth app integration via :method:CustomAppIntegration/get.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -111,35 +154,57 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq oauth2.GetCustomAppIntegrationRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *oauth2.GetCustomAppIntegrationRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} -var getCmd = &cobra.Command{ - Use: "get INTEGRATION_ID", - Short: `Get OAuth Custom App Integration.`, - Long: `Get OAuth Custom App Integration. + var getReq oauth2.GetCustomAppIntegrationRequest + + // TODO: short flags + + cmd.Use = "get INTEGRATION_ID" + cmd.Short = `Get OAuth Custom App Integration.` + cmd.Long = `Get OAuth Custom App Integration. - Gets the Custom OAuth App Integration for the given integration id.`, + Gets the Custom OAuth App Integration for the given integration id.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -150,30 +215,48 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get custom oauth app integrations.`, - Long: `Get custom oauth app integrations. + cmd.Use = "list" + cmd.Short = `Get custom oauth app integrations.` + cmd.Long = `Get custom oauth app integrations. Get the list of custom oauth app integrations for the specified Databricks - account`, + account` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) response, err := a.CustomAppIntegration.ListAll(ctx) @@ -181,41 +264,63 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq oauth2.UpdateCustomAppIntegration -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *oauth2.UpdateCustomAppIntegration, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq oauth2.UpdateCustomAppIntegration + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: redirect_urls // TODO: complex arg: token_access_policy -} - -var updateCmd = &cobra.Command{ - Use: "update INTEGRATION_ID", - Short: `Updates Custom OAuth App Integration.`, - Long: `Updates Custom OAuth App Integration. + cmd.Use = "update INTEGRATION_ID" + cmd.Short = `Updates Custom OAuth App Integration.` + cmd.Long = `Updates Custom OAuth App Integration. Updates an existing custom OAuth App Integration. You can retrieve the custom - oauth app integration via :method:CustomAppIntegration/get.`, + oauth app integration via :method:CustomAppIntegration/get.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -232,10 +337,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service CustomAppIntegration diff --git a/cmd/account/encryption-keys/encryption-keys.go b/cmd/account/encryption-keys/encryption-keys.go index 0db4af80e8..2172c49fc0 100755 --- a/cmd/account/encryption-keys/encryption-keys.go +++ b/cmd/account/encryption-keys/encryption-keys.go @@ -12,10 +12,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "encryption-keys", - Short: `These APIs manage encryption key configurations for this workspace (optional).`, - Long: `These APIs manage encryption key configurations for this workspace (optional). +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "encryption-keys", + Short: `These APIs manage encryption key configurations for this workspace (optional).`, + Long: `These APIs manage encryption key configurations for this workspace (optional). A key configuration encapsulates the AWS KMS key information and some information about how the key configuration can be used. There are two possible uses for key configurations: @@ -31,29 +36,44 @@ var Cmd = &cobra.Command{ encryption requires that the workspace is on the E2 version of the platform. If you have an older workspace, it might not be on the E2 version of the platform. If you are not sure, contact your Databricks representative.`, - Annotations: map[string]string{ - "package": "provisioning", - }, + GroupID: "provisioning", + Annotations: map[string]string{ + "package": "provisioning", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq provisioning.CreateCustomerManagedKeyRequest -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *provisioning.CreateCustomerManagedKeyRequest, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq provisioning.CreateCustomerManagedKeyRequest + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: aws_key_info // TODO: complex arg: gcp_key_info -} - -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create encryption key configuration.`, - Long: `Create encryption key configuration. + cmd.Use = "create" + cmd.Short = `Create encryption key configuration.` + cmd.Long = `Create encryption key configuration. Creates a customer-managed key configuration object for an account, specified by ID. This operation uploads a reference to a customer-managed key to @@ -71,11 +91,12 @@ var createCmd = &cobra.Command{ This operation is available only if your account is on the E2 version of the platform or on a select custom plan that allows multiple workspaces per - account.`, + account.` - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -93,36 +114,58 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq provisioning.DeleteEncryptionKeyRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *provisioning.DeleteEncryptionKeyRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq provisioning.DeleteEncryptionKeyRequest + + // TODO: short flags -var deleteCmd = &cobra.Command{ - Use: "delete CUSTOMER_MANAGED_KEY_ID", - Short: `Delete encryption key configuration.`, - Long: `Delete encryption key configuration. + cmd.Use = "delete CUSTOMER_MANAGED_KEY_ID" + cmd.Short = `Delete encryption key configuration.` + cmd.Long = `Delete encryption key configuration. Deletes a customer-managed key configuration object for an account. You cannot - delete a configuration that is associated with a running workspace.`, + delete a configuration that is associated with a running workspace.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -133,25 +176,45 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq provisioning.GetEncryptionKeyRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *provisioning.GetEncryptionKeyRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq provisioning.GetEncryptionKeyRequest -var getCmd = &cobra.Command{ - Use: "get CUSTOMER_MANAGED_KEY_ID", - Short: `Get encryption key configuration.`, - Long: `Get encryption key configuration. + // TODO: short flags + + cmd.Use = "get CUSTOMER_MANAGED_KEY_ID" + cmd.Short = `Get encryption key configuration.` + cmd.Long = `Get encryption key configuration. Gets a customer-managed key configuration object for an account, specified by ID. This operation uploads a reference to a customer-managed key to @@ -167,15 +230,17 @@ var getCmd = &cobra.Command{ types, subscription types, and AWS regions. This operation is available only if your account is on the E2 version of the - platform.",`, + platform.",` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -186,23 +251,40 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get all encryption key configurations.`, - Long: `Get all encryption key configurations. + cmd.Use = "list" + cmd.Short = `Get all encryption key configurations.` + cmd.Long = `Get all encryption key configurations. Gets all customer-managed key configuration objects for an account. If the key is specified as a workspace's managed services customer-managed key, @@ -216,11 +298,12 @@ var listCmd = &cobra.Command{ types, subscription types, and AWS regions. This operation is available only if your account is on the E2 version of the - platform.`, + platform.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) response, err := a.EncryptionKeys.List(ctx) @@ -228,10 +311,24 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // end service EncryptionKeys diff --git a/cmd/account/encryption-keys/overrides.go b/cmd/account/encryption-keys/overrides.go index 9a27ac00dc..906211750c 100644 --- a/cmd/account/encryption-keys/overrides.go +++ b/cmd/account/encryption-keys/overrides.go @@ -1,9 +1,16 @@ package encryption_keys -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{range .}}{{.CustomerManagedKeyId | green}} {{range .UseCases}}{{.}} {{end}} {{.AwsKeyInfo.KeyArn}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/account/groups.go b/cmd/account/groups.go index 7c9d70e3d1..10a795b037 100644 --- a/cmd/account/groups.go +++ b/cmd/account/groups.go @@ -32,11 +32,3 @@ func Groups() []cobra.Group { }, } } - -func init() { - // Register groups with parent command - groups := Groups() - for i := range groups { - accountCmd.AddGroup(&groups[i]) - } -} diff --git a/cmd/account/groups/groups.go b/cmd/account/groups/groups.go index 55d0c7810b..09594fa3ac 100755 --- a/cmd/account/groups/groups.go +++ b/cmd/account/groups/groups.go @@ -3,8 +3,6 @@ package groups import ( - "fmt" - "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/flags" @@ -12,59 +10,81 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "groups", - Short: `Groups simplify identity management, making it easier to assign access to Databricks account, data, and other securable objects.`, - Long: `Groups simplify identity management, making it easier to assign access to +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "groups", + Short: `Groups simplify identity management, making it easier to assign access to Databricks account, data, and other securable objects.`, + Long: `Groups simplify identity management, making it easier to assign access to Databricks account, data, and other securable objects. It is best practice to assign access to workspaces and access-control policies in Unity Catalog to groups, instead of to users individually. All Databricks account identities can be assigned as members of groups, and members inherit permissions that are assigned to their group.`, - Annotations: map[string]string{ - "package": "iam", - }, + GroupID: "iam", + Annotations: map[string]string{ + "package": "iam", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq iam.Group -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *iam.Group, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq iam.Group + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createCmd.Flags().StringVar(&createReq.DisplayName, "display-name", createReq.DisplayName, `String that represents a human-readable group name.`) + cmd.Flags().StringVar(&createReq.DisplayName, "display-name", createReq.DisplayName, `String that represents a human-readable group name.`) // TODO: array: entitlements - createCmd.Flags().StringVar(&createReq.ExternalId, "external-id", createReq.ExternalId, ``) + cmd.Flags().StringVar(&createReq.ExternalId, "external-id", createReq.ExternalId, ``) // TODO: array: groups - createCmd.Flags().StringVar(&createReq.Id, "id", createReq.Id, `Databricks group ID.`) + cmd.Flags().StringVar(&createReq.Id, "id", createReq.Id, `Databricks group ID.`) // TODO: array: members // TODO: complex arg: meta // TODO: array: roles -} - -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a new group.`, - Long: `Create a new group. + cmd.Use = "create" + cmd.Short = `Create a new group.` + cmd.Long = `Create a new group. Creates a group in the Databricks account with a unique name, using the - supplied group details.`, + supplied group details.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -81,51 +101,60 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq iam.DeleteAccountGroupRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *iam.DeleteAccountGroupRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete ID", - Short: `Delete a group.`, - Long: `Delete a group. + var deleteReq iam.DeleteAccountGroupRequest + + // TODO: short flags + + cmd.Use = "delete ID" + cmd.Short = `Delete a group.` + cmd.Long = `Delete a group. - Deletes a group from the Databricks account.`, + Deletes a group from the Databricks account.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Account Groups drop-down." - names, err := a.Groups.GroupDisplayNameToIdMap(ctx, iam.ListAccountGroupsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Account Groups drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID for a group in the Databricks account") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id for a group in the databricks account") - } deleteReq.Id = args[0] err = a.Groups.Delete(ctx, deleteReq) @@ -133,51 +162,60 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq iam.GetAccountGroupRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *iam.GetAccountGroupRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq iam.GetAccountGroupRequest -var getCmd = &cobra.Command{ - Use: "get ID", - Short: `Get group details.`, - Long: `Get group details. + // TODO: short flags + + cmd.Use = "get ID" + cmd.Short = `Get group details.` + cmd.Long = `Get group details. - Gets the information for a specific group in the Databricks account.`, + Gets the information for a specific group in the Databricks account.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Account Groups drop-down." - names, err := a.Groups.GroupDisplayNameToIdMap(ctx, iam.ListAccountGroupsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Account Groups drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID for a group in the Databricks account") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id for a group in the databricks account") - } getReq.Id = args[0] response, err := a.Groups.Get(ctx, getReq) @@ -185,48 +223,70 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq iam.ListAccountGroupsRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *iam.ListAccountGroupsRequest, +) - listCmd.Flags().StringVar(&listReq.Attributes, "attributes", listReq.Attributes, `Comma-separated list of attributes to return in response.`) - listCmd.Flags().IntVar(&listReq.Count, "count", listReq.Count, `Desired number of results per page.`) - listCmd.Flags().StringVar(&listReq.ExcludedAttributes, "excluded-attributes", listReq.ExcludedAttributes, `Comma-separated list of attributes to exclude in response.`) - listCmd.Flags().StringVar(&listReq.Filter, "filter", listReq.Filter, `Query by which the results have to be filtered.`) - listCmd.Flags().StringVar(&listReq.SortBy, "sort-by", listReq.SortBy, `Attribute to sort the results.`) - listCmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order to sort the results.`) - listCmd.Flags().IntVar(&listReq.StartIndex, "start-index", listReq.StartIndex, `Specifies the index of the first result.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq iam.ListAccountGroupsRequest + var listJson flags.JsonFlag -var listCmd = &cobra.Command{ - Use: "list", - Short: `List group details.`, - Long: `List group details. + // TODO: short flags + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&listReq.Attributes, "attributes", listReq.Attributes, `Comma-separated list of attributes to return in response.`) + cmd.Flags().IntVar(&listReq.Count, "count", listReq.Count, `Desired number of results per page.`) + cmd.Flags().StringVar(&listReq.ExcludedAttributes, "excluded-attributes", listReq.ExcludedAttributes, `Comma-separated list of attributes to exclude in response.`) + cmd.Flags().StringVar(&listReq.Filter, "filter", listReq.Filter, `Query by which the results have to be filtered.`) + cmd.Flags().StringVar(&listReq.SortBy, "sort-by", listReq.SortBy, `Attribute to sort the results.`) + cmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order to sort the results.`) + cmd.Flags().IntVar(&listReq.StartIndex, "start-index", listReq.StartIndex, `Specifies the index of the first result.`) + + cmd.Use = "list" + cmd.Short = `List group details.` + cmd.Long = `List group details. - Gets all details of the groups associated with the Databricks account.`, + Gets all details of the groups associated with the Databricks account.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -243,36 +303,62 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start patch command -var patchReq iam.PartialUpdate -var patchJson flags.JsonFlag -func init() { - Cmd.AddCommand(patchCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var patchOverrides []func( + *cobra.Command, + *iam.PartialUpdate, +) + +func newPatch() *cobra.Command { + cmd := &cobra.Command{} + + var patchReq iam.PartialUpdate + var patchJson flags.JsonFlag + // TODO: short flags - patchCmd.Flags().Var(&patchJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&patchJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: Operations // TODO: array: schema -} - -var patchCmd = &cobra.Command{ - Use: "patch ID", - Short: `Update group details.`, - Long: `Update group details. + cmd.Use = "patch ID" + cmd.Short = `Update group details.` + cmd.Long = `Update group details. - Partially updates the details of a group.`, + Partially updates the details of a group.` - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -282,23 +368,6 @@ var patchCmd = &cobra.Command{ return err } } - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Account Groups drop-down." - names, err := a.Groups.GroupDisplayNameToIdMap(ctx, iam.ListAccountGroupsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Account Groups drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID for a group in the Databricks account") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id for a group in the databricks account") - } patchReq.Id = args[0] err = a.Groups.Patch(ctx, patchReq) @@ -306,42 +375,71 @@ var patchCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range patchOverrides { + fn(cmd, &patchReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newPatch()) + }) } // start update command -var updateReq iam.Group -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *iam.Group, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq iam.Group + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) - updateCmd.Flags().StringVar(&updateReq.DisplayName, "display-name", updateReq.DisplayName, `String that represents a human-readable group name.`) + cmd.Flags().StringVar(&updateReq.DisplayName, "display-name", updateReq.DisplayName, `String that represents a human-readable group name.`) // TODO: array: entitlements - updateCmd.Flags().StringVar(&updateReq.ExternalId, "external-id", updateReq.ExternalId, ``) + cmd.Flags().StringVar(&updateReq.ExternalId, "external-id", updateReq.ExternalId, ``) // TODO: array: groups - updateCmd.Flags().StringVar(&updateReq.Id, "id", updateReq.Id, `Databricks group ID.`) + cmd.Flags().StringVar(&updateReq.Id, "id", updateReq.Id, `Databricks group ID.`) // TODO: array: members // TODO: complex arg: meta // TODO: array: roles -} - -var updateCmd = &cobra.Command{ - Use: "update ID", - Short: `Replace a group.`, - Long: `Replace a group. + cmd.Use = "update ID" + cmd.Short = `Replace a group.` + cmd.Long = `Replace a group. - Updates the details of a group by replacing the entire group entity.`, + Updates the details of a group by replacing the entire group entity.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -351,23 +449,6 @@ var updateCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Account Groups drop-down." - names, err := a.Groups.GroupDisplayNameToIdMap(ctx, iam.ListAccountGroupsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Account Groups drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Databricks group ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have databricks group id") - } updateReq.Id = args[0] } @@ -376,10 +457,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service AccountGroups diff --git a/cmd/account/groups/overrides.go b/cmd/account/groups/overrides.go index 28c91c4d20..37d05c64f9 100644 --- a/cmd/account/groups/overrides.go +++ b/cmd/account/groups/overrides.go @@ -1,10 +1,18 @@ package groups -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/databricks-sdk-go/service/iam" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command, listReq *iam.ListAccountGroupsRequest) { listReq.Attributes = "id,displayName" listCmd.Annotations["template"] = cmdio.Heredoc(` {{range .}}{{.Id|green}} {{.DisplayName}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/account/ip-access-lists/ip-access-lists.go b/cmd/account/ip-access-lists/ip-access-lists.go index 7f43ff2a71..980dc77768 100755 --- a/cmd/account/ip-access-lists/ip-access-lists.go +++ b/cmd/account/ip-access-lists/ip-access-lists.go @@ -12,10 +12,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "ip-access-lists", - Short: `The Accounts IP Access List API enables account admins to configure IP access lists for access to the account console.`, - Long: `The Accounts IP Access List API enables account admins to configure IP access +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "ip-access-lists", + Short: `The Accounts IP Access List API enables account admins to configure IP access lists for access to the account console.`, + Long: `The Accounts IP Access List API enables account admins to configure IP access lists for access to the account console. Account IP Access Lists affect web application access and REST API access to @@ -37,26 +42,41 @@ var Cmd = &cobra.Command{ After changes to the account-level IP access lists, it can take a few minutes for changes to take effect.`, - Annotations: map[string]string{ - "package": "settings", - }, + GroupID: "settings", + Annotations: map[string]string{ + "package": "settings", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq settings.CreateIpAccessList -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *settings.CreateIpAccessList, +) -} +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq settings.CreateIpAccessList + var createJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create access list.`, - Long: `Create access list. + cmd.Use = "create" + cmd.Short = `Create access list.` + cmd.Long = `Create access list. Creates an IP access list for the account. @@ -71,11 +91,12 @@ var createCmd = &cobra.Command{ * If the new list would block the calling user's current IP, error 400 is returned with error_code value INVALID_STATE. - It can take a few minutes for the changes to take effect.`, + It can take a few minutes for the changes to take effect.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -93,51 +114,60 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq settings.DeleteAccountIpAccessListRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *settings.DeleteAccountIpAccessListRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete IP_ACCESS_LIST_ID", - Short: `Delete access list.`, - Long: `Delete access list. + var deleteReq settings.DeleteAccountIpAccessListRequest + + // TODO: short flags + + cmd.Use = "delete IP_ACCESS_LIST_ID" + cmd.Short = `Delete access list.` + cmd.Long = `Delete access list. - Deletes an IP access list, specified by its list ID.`, + Deletes an IP access list, specified by its list ID.` - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No IP_ACCESS_LIST_ID argument specified. Loading names for Account Ip Access Lists drop-down." - names, err := a.IpAccessLists.IpAccessListInfoLabelToListIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Account Ip Access Lists drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The ID for the corresponding IP access list") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the id for the corresponding ip access list") - } deleteReq.IpAccessListId = args[0] err = a.IpAccessLists.Delete(ctx, deleteReq) @@ -145,51 +175,60 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq settings.GetAccountIpAccessListRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *settings.GetAccountIpAccessListRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq settings.GetAccountIpAccessListRequest + + // TODO: short flags -var getCmd = &cobra.Command{ - Use: "get IP_ACCESS_LIST_ID", - Short: `Get IP access list.`, - Long: `Get IP access list. + cmd.Use = "get IP_ACCESS_LIST_ID" + cmd.Short = `Get IP access list.` + cmd.Long = `Get IP access list. - Gets an IP access list, specified by its list ID.`, + Gets an IP access list, specified by its list ID.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No IP_ACCESS_LIST_ID argument specified. Loading names for Account Ip Access Lists drop-down." - names, err := a.IpAccessLists.IpAccessListInfoLabelToListIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Account Ip Access Lists drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The ID for the corresponding IP access list") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the id for the corresponding ip access list") - } getReq.IpAccessListId = args[0] response, err := a.IpAccessLists.Get(ctx, getReq) @@ -197,29 +236,47 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get access lists.`, - Long: `Get access lists. + cmd.Use = "list" + cmd.Short = `Get access lists.` + cmd.Long = `Get access lists. - Gets all IP access lists for the specified account.`, + Gets all IP access lists for the specified account.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) response, err := a.IpAccessLists.ListAll(ctx) @@ -227,29 +284,49 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start replace command -var replaceReq settings.ReplaceIpAccessList -var replaceJson flags.JsonFlag -func init() { - Cmd.AddCommand(replaceCmd) - // TODO: short flags - replaceCmd.Flags().Var(&replaceJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var replaceOverrides []func( + *cobra.Command, + *settings.ReplaceIpAccessList, +) - replaceCmd.Flags().StringVar(&replaceReq.ListId, "list-id", replaceReq.ListId, `Universally unique identifier (UUID) of the IP access list.`) +func newReplace() *cobra.Command { + cmd := &cobra.Command{} -} + var replaceReq settings.ReplaceIpAccessList + var replaceJson flags.JsonFlag -var replaceCmd = &cobra.Command{ - Use: "replace", - Short: `Replace access list.`, - Long: `Replace access list. + // TODO: short flags + cmd.Flags().Var(&replaceJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&replaceReq.ListId, "list-id", replaceReq.ListId, `Universally unique identifier (UUID) of the IP access list.`) + + cmd.Use = "replace" + cmd.Short = `Replace access list.` + cmd.Long = `Replace access list. Replaces an IP access list, specified by its ID. @@ -260,11 +337,12 @@ var replaceCmd = &cobra.Command{ counts as a single value. Attempts to exceed that number return error 400 with error_code value QUOTA_EXCEEDED. * If the resulting list would block the calling user's current IP, error 400 is returned with error_code value - INVALID_STATE. It can take a few minutes for the changes to take effect.`, + INVALID_STATE. It can take a few minutes for the changes to take effect.` - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -282,29 +360,49 @@ var replaceCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range replaceOverrides { + fn(cmd, &replaceReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newReplace()) + }) } // start update command -var updateReq settings.UpdateIpAccessList -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) - // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *settings.UpdateIpAccessList, +) - updateCmd.Flags().StringVar(&updateReq.ListId, "list-id", updateReq.ListId, `Universally unique identifier (UUID) of the IP access list.`) +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} -} + var updateReq settings.UpdateIpAccessList + var updateJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&updateReq.ListId, "list-id", updateReq.ListId, `Universally unique identifier (UUID) of the IP access list.`) -var updateCmd = &cobra.Command{ - Use: "update", - Short: `Update access list.`, - Long: `Update access list. + cmd.Use = "update" + cmd.Short = `Update access list.` + cmd.Long = `Update access list. Updates an existing IP access list, specified by its ID. @@ -319,11 +417,12 @@ var updateCmd = &cobra.Command{ * If the updated list would block the calling user's current IP, error 400 is returned with error_code value INVALID_STATE. - It can take a few minutes for the changes to take effect.`, + It can take a few minutes for the changes to take effect.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -341,10 +440,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service AccountIpAccessLists diff --git a/cmd/account/log-delivery/log-delivery.go b/cmd/account/log-delivery/log-delivery.go index d5ae87b1b8..2018932eeb 100755 --- a/cmd/account/log-delivery/log-delivery.go +++ b/cmd/account/log-delivery/log-delivery.go @@ -12,10 +12,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "log-delivery", - Short: `These APIs manage log delivery configurations for this account.`, - Long: `These APIs manage log delivery configurations for this account. The two +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "log-delivery", + Short: `These APIs manage log delivery configurations for this account.`, + Long: `These APIs manage log delivery configurations for this account. The two supported log types for this API are _billable usage logs_ and _audit logs_. This feature is in Public Preview. This feature works with all account ID types. @@ -75,28 +80,43 @@ var Cmd = &cobra.Command{ [Billable usage log delivery]: https://docs.databricks.com/administration-guide/account-settings/billable-usage-delivery.html [Usage page]: https://docs.databricks.com/administration-guide/account-settings/usage.html [create a new AWS S3 bucket]: https://docs.databricks.com/administration-guide/account-api/aws-storage.html`, - Annotations: map[string]string{ - "package": "billing", - }, + GroupID: "billing", + Annotations: map[string]string{ + "package": "billing", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq billing.WrappedCreateLogDeliveryConfiguration -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *billing.WrappedCreateLogDeliveryConfiguration, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq billing.WrappedCreateLogDeliveryConfiguration + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: log_delivery_configuration -} - -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a new log delivery configuration.`, - Long: `Create a new log delivery configuration. + cmd.Use = "create" + cmd.Short = `Create a new log delivery configuration.` + cmd.Long = `Create a new log delivery configuration. Creates a new Databricks log delivery configuration to enable delivery of the specified type of logs to your storage location. This requires that you @@ -123,18 +143,20 @@ var createCmd = &cobra.Command{ configuration](#operation/patch-log-delivery-config-status)). [Configure audit logging]: https://docs.databricks.com/administration-guide/account-settings/audit-logs.html - [Deliver and access billable usage logs]: https://docs.databricks.com/administration-guide/account-settings/billable-usage-delivery.html`, + [Deliver and access billable usage logs]: https://docs.databricks.com/administration-guide/account-settings/billable-usage-delivery.html` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -151,52 +173,61 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start get command -var getReq billing.GetLogDeliveryRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *billing.GetLogDeliveryRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq billing.GetLogDeliveryRequest + + // TODO: short flags -var getCmd = &cobra.Command{ - Use: "get LOG_DELIVERY_CONFIGURATION_ID", - Short: `Get log delivery configuration.`, - Long: `Get log delivery configuration. + cmd.Use = "get LOG_DELIVERY_CONFIGURATION_ID" + cmd.Short = `Get log delivery configuration.` + cmd.Long = `Get log delivery configuration. Gets a Databricks log delivery configuration object for an account, both - specified by ID.`, + specified by ID.` - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No LOG_DELIVERY_CONFIGURATION_ID argument specified. Loading names for Log Delivery drop-down." - names, err := a.LogDelivery.LogDeliveryConfigurationConfigNameToConfigIdMap(ctx, billing.ListLogDeliveryRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Log Delivery drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Databricks log delivery configuration ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have databricks log delivery configuration id") - } getReq.LogDeliveryConfigurationId = args[0] response, err := a.LogDelivery.Get(ctx, getReq) @@ -204,45 +235,67 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq billing.ListLogDeliveryRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *billing.ListLogDeliveryRequest, +) - listCmd.Flags().StringVar(&listReq.CredentialsId, "credentials-id", listReq.CredentialsId, `Filter by credential configuration ID.`) - listCmd.Flags().Var(&listReq.Status, "status", `Filter by status ENABLED or DISABLED.`) - listCmd.Flags().StringVar(&listReq.StorageConfigurationId, "storage-configuration-id", listReq.StorageConfigurationId, `Filter by storage configuration ID.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq billing.ListLogDeliveryRequest + var listJson flags.JsonFlag -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get all log delivery configurations.`, - Long: `Get all log delivery configurations. + // TODO: short flags + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&listReq.CredentialsId, "credentials-id", listReq.CredentialsId, `Filter by credential configuration ID.`) + cmd.Flags().Var(&listReq.Status, "status", `Filter by status ENABLED or DISABLED.`) + cmd.Flags().StringVar(&listReq.StorageConfigurationId, "storage-configuration-id", listReq.StorageConfigurationId, `Filter by storage configuration ID.`) + + cmd.Use = "list" + cmd.Short = `Get all log delivery configurations.` + cmd.Long = `Get all log delivery configurations. Gets all Databricks log delivery configurations associated with an account - specified by ID.`, + specified by ID.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -259,39 +312,61 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start patch-status command -var patchStatusReq billing.UpdateLogDeliveryConfigurationStatusRequest -func init() { - Cmd.AddCommand(patchStatusCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var patchStatusOverrides []func( + *cobra.Command, + *billing.UpdateLogDeliveryConfigurationStatusRequest, +) -} +func newPatchStatus() *cobra.Command { + cmd := &cobra.Command{} + + var patchStatusReq billing.UpdateLogDeliveryConfigurationStatusRequest + + // TODO: short flags -var patchStatusCmd = &cobra.Command{ - Use: "patch-status STATUS LOG_DELIVERY_CONFIGURATION_ID", - Short: `Enable or disable log delivery configuration.`, - Long: `Enable or disable log delivery configuration. + cmd.Use = "patch-status STATUS LOG_DELIVERY_CONFIGURATION_ID" + cmd.Short = `Enable or disable log delivery configuration.` + cmd.Long = `Enable or disable log delivery configuration. Enables or disables a log delivery configuration. Deletion of delivery configurations is not supported, so disable log delivery configurations that are no longer needed. Note that you can't re-enable a delivery configuration if this would violate the delivery configuration limits described under - [Create log delivery](#operation/create-log-delivery-config).`, + [Create log delivery](#operation/create-log-delivery-config).` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -306,10 +381,24 @@ var patchStatusCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range patchStatusOverrides { + fn(cmd, &patchStatusReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newPatchStatus()) + }) } // end service LogDelivery diff --git a/cmd/account/metastore-assignments/metastore-assignments.go b/cmd/account/metastore-assignments/metastore-assignments.go index 673bb8f4cf..8b571f1e57 100755 --- a/cmd/account/metastore-assignments/metastore-assignments.go +++ b/cmd/account/metastore-assignments/metastore-assignments.go @@ -12,43 +12,65 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "metastore-assignments", - Short: `These APIs manage metastore assignments to a workspace.`, - Long: `These APIs manage metastore assignments to a workspace.`, - Annotations: map[string]string{ - "package": "catalog", - }, +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "metastore-assignments", + Short: `These APIs manage metastore assignments to a workspace.`, + Long: `These APIs manage metastore assignments to a workspace.`, + GroupID: "catalog", + Annotations: map[string]string{ + "package": "catalog", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq catalog.AccountsCreateMetastoreAssignment -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *catalog.AccountsCreateMetastoreAssignment, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq catalog.AccountsCreateMetastoreAssignment + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: metastore_assignment -} - -var createCmd = &cobra.Command{ - Use: "create WORKSPACE_ID METASTORE_ID", - Short: `Assigns a workspace to a metastore.`, - Long: `Assigns a workspace to a metastore. + cmd.Use = "create WORKSPACE_ID METASTORE_ID" + cmd.Short = `Assigns a workspace to a metastore.` + cmd.Long = `Assigns a workspace to a metastore. Creates an assignment to a metastore for a workspace Please add a header - X-Databricks-Account-Console-API-Version: 2.0 to access this API.`, + X-Databricks-Account-Console-API-Version: 2.0 to access this API.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -69,37 +91,59 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq catalog.DeleteAccountMetastoreAssignmentRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *catalog.DeleteAccountMetastoreAssignmentRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete WORKSPACE_ID METASTORE_ID", - Short: `Delete a metastore assignment.`, - Long: `Delete a metastore assignment. + var deleteReq catalog.DeleteAccountMetastoreAssignmentRequest + + // TODO: short flags + + cmd.Use = "delete WORKSPACE_ID METASTORE_ID" + cmd.Short = `Delete a metastore assignment.` + cmd.Long = `Delete a metastore assignment. Deletes a metastore assignment to a workspace, leaving the workspace with no metastore. Please add a header X-Databricks-Account-Console-API-Version: 2.0 - to access this API.`, + to access this API.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -114,39 +158,61 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq catalog.GetAccountMetastoreAssignmentRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *catalog.GetAccountMetastoreAssignmentRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} -var getCmd = &cobra.Command{ - Use: "get WORKSPACE_ID", - Short: `Gets the metastore assignment for a workspace.`, - Long: `Gets the metastore assignment for a workspace. + var getReq catalog.GetAccountMetastoreAssignmentRequest + + // TODO: short flags + + cmd.Use = "get WORKSPACE_ID" + cmd.Short = `Gets the metastore assignment for a workspace.` + cmd.Long = `Gets the metastore assignment for a workspace. Gets the metastore assignment, if any, for the workspace specified by ID. If the workspace is assigned a metastore, the mappig will be returned. If no metastore is assigned to the workspace, the assignment will not be found and a 404 returned. Please add a header X-Databricks-Account-Console-API-Version: - 2.0 to access this API.`, + 2.0 to access this API.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -160,37 +226,59 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq catalog.ListAccountMetastoreAssignmentsRequest -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *catalog.ListAccountMetastoreAssignmentsRequest, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} + + var listReq catalog.ListAccountMetastoreAssignmentsRequest -var listCmd = &cobra.Command{ - Use: "list METASTORE_ID", - Short: `Get all workspaces assigned to a metastore.`, - Long: `Get all workspaces assigned to a metastore. + // TODO: short flags + + cmd.Use = "list METASTORE_ID" + cmd.Short = `Get all workspaces assigned to a metastore.` + cmd.Long = `Get all workspaces assigned to a metastore. Gets a list of all Databricks workspace IDs that have been assigned to given metastore. Please add a header X-Databricks-Account-Console-API-Version: 2.0 - to access this API`, + to access this API` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -201,41 +289,63 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq catalog.AccountsUpdateMetastoreAssignment -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *catalog.AccountsUpdateMetastoreAssignment, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq catalog.AccountsUpdateMetastoreAssignment + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: metastore_assignment -} - -var updateCmd = &cobra.Command{ - Use: "update WORKSPACE_ID METASTORE_ID", - Short: `Updates a metastore assignment to a workspaces.`, - Long: `Updates a metastore assignment to a workspaces. + cmd.Use = "update WORKSPACE_ID METASTORE_ID" + cmd.Short = `Updates a metastore assignment to a workspaces.` + cmd.Long = `Updates a metastore assignment to a workspaces. Updates an assignment to a metastore for a workspace. Currently, only the default catalog may be updated. Please add a header - X-Databricks-Account-Console-API-Version: 2.0 to access this API.`, + X-Databricks-Account-Console-API-Version: 2.0 to access this API.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -256,10 +366,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service AccountMetastoreAssignments diff --git a/cmd/account/metastores/metastores.go b/cmd/account/metastores/metastores.go index 89e1c8f2ea..48c8a6b030 100755 --- a/cmd/account/metastores/metastores.go +++ b/cmd/account/metastores/metastores.go @@ -10,47 +10,69 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "metastores", - Short: `These APIs manage Unity Catalog metastores for an account.`, - Long: `These APIs manage Unity Catalog metastores for an account. A metastore +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "metastores", + Short: `These APIs manage Unity Catalog metastores for an account.`, + Long: `These APIs manage Unity Catalog metastores for an account. A metastore contains catalogs that can be associated with workspaces`, - Annotations: map[string]string{ - "package": "catalog", - }, + GroupID: "catalog", + Annotations: map[string]string{ + "package": "catalog", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq catalog.AccountsCreateMetastore -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *catalog.AccountsCreateMetastore, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq catalog.AccountsCreateMetastore + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: metastore_info -} - -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create metastore.`, - Long: `Create metastore. + cmd.Use = "create" + cmd.Short = `Create metastore.` + cmd.Long = `Create metastore. Creates a Unity Catalog metastore. Please add a header - X-Databricks-Account-Console-API-Version: 2.0 to access this API.`, + X-Databricks-Account-Console-API-Version: 2.0 to access this API.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -67,38 +89,60 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq catalog.DeleteAccountMetastoreRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *catalog.DeleteAccountMetastoreRequest, +) - deleteCmd.Flags().BoolVar(&deleteReq.Force, "force", deleteReq.Force, `Force deletion even if the metastore is not empty.`) +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -} + var deleteReq catalog.DeleteAccountMetastoreRequest + + // TODO: short flags -var deleteCmd = &cobra.Command{ - Use: "delete METASTORE_ID", - Short: `Delete a metastore.`, - Long: `Delete a metastore. + cmd.Flags().BoolVar(&deleteReq.Force, "force", deleteReq.Force, `Force deletion even if the metastore is not empty.`) + + cmd.Use = "delete METASTORE_ID" + cmd.Short = `Delete a metastore.` + cmd.Long = `Delete a metastore. Deletes a Unity Catalog metastore for an account, both specified by ID. Please - add a header X-Databricks-Account-Console-API-Version: 2.0 to access this API.`, + add a header X-Databricks-Account-Console-API-Version: 2.0 to access this API.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -109,36 +153,58 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq catalog.GetAccountMetastoreRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *catalog.GetAccountMetastoreRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq catalog.GetAccountMetastoreRequest -var getCmd = &cobra.Command{ - Use: "get METASTORE_ID", - Short: `Get a metastore.`, - Long: `Get a metastore. + // TODO: short flags + + cmd.Use = "get METASTORE_ID" + cmd.Short = `Get a metastore.` + cmd.Long = `Get a metastore. Gets a Unity Catalog metastore from an account, both specified by ID. Please - add a header X-Databricks-Account-Console-API-Version: 2.0 to access this API.`, + add a header X-Databricks-Account-Console-API-Version: 2.0 to access this API.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -149,31 +215,49 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get all metastores associated with an account.`, - Long: `Get all metastores associated with an account. + cmd.Use = "list" + cmd.Short = `Get all metastores associated with an account.` + cmd.Long = `Get all metastores associated with an account. Gets all Unity Catalog metastores associated with an account specified by ID. Please add a header X-Databricks-Account-Console-API-Version: 2.0 to access - this API.`, + this API.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) response, err := a.Metastores.List(ctx) @@ -181,40 +265,62 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq catalog.AccountsUpdateMetastore -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *catalog.AccountsUpdateMetastore, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq catalog.AccountsUpdateMetastore + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: metastore_info -} - -var updateCmd = &cobra.Command{ - Use: "update METASTORE_ID", - Short: `Update a metastore.`, - Long: `Update a metastore. + cmd.Use = "update METASTORE_ID" + cmd.Short = `Update a metastore.` + cmd.Long = `Update a metastore. Updates an existing Unity Catalog metastore. Please add a header - X-Databricks-Account-Console-API-Version: 2.0 to access this API.`, + X-Databricks-Account-Console-API-Version: 2.0 to access this API.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -231,10 +337,24 @@ var updateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service AccountMetastores diff --git a/cmd/account/networks/networks.go b/cmd/account/networks/networks.go index 331f0869a4..36867cf252 100755 --- a/cmd/account/networks/networks.go +++ b/cmd/account/networks/networks.go @@ -3,8 +3,6 @@ package networks import ( - "fmt" - "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/flags" @@ -12,52 +10,74 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "networks", - Short: `These APIs manage network configurations for customer-managed VPCs (optional).`, - Long: `These APIs manage network configurations for customer-managed VPCs (optional). +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "networks", + Short: `These APIs manage network configurations for customer-managed VPCs (optional).`, + Long: `These APIs manage network configurations for customer-managed VPCs (optional). Its ID is used when creating a new workspace if you use customer-managed VPCs.`, - Annotations: map[string]string{ - "package": "provisioning", - }, + GroupID: "provisioning", + Annotations: map[string]string{ + "package": "provisioning", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq provisioning.CreateNetworkRequest -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *provisioning.CreateNetworkRequest, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq provisioning.CreateNetworkRequest + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: gcp_network_info // TODO: array: security_group_ids // TODO: array: subnet_ids // TODO: complex arg: vpc_endpoints - createCmd.Flags().StringVar(&createReq.VpcId, "vpc-id", createReq.VpcId, `The ID of the VPC associated with this network.`) + cmd.Flags().StringVar(&createReq.VpcId, "vpc-id", createReq.VpcId, `The ID of the VPC associated with this network.`) -} - -var createCmd = &cobra.Command{ - Use: "create NETWORK_NAME", - Short: `Create network configuration.`, - Long: `Create network configuration. + cmd.Use = "create NETWORK_NAME" + cmd.Short = `Create network configuration.` + cmd.Long = `Create network configuration. Creates a Databricks network configuration that represents an VPC and its resources. The VPC will be used for new Databricks clusters. This requires a - pre-existing VPC and subnets.`, + pre-existing VPC and subnets.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -75,56 +95,65 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq provisioning.DeleteNetworkRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *provisioning.DeleteNetworkRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq provisioning.DeleteNetworkRequest + + // TODO: short flags -var deleteCmd = &cobra.Command{ - Use: "delete NETWORK_ID", - Short: `Delete a network configuration.`, - Long: `Delete a network configuration. + cmd.Use = "delete NETWORK_ID" + cmd.Short = `Delete a network configuration.` + cmd.Long = `Delete a network configuration. Deletes a Databricks network configuration, which represents a cloud VPC and its resources. You cannot delete a network that is associated with a workspace. This operation is available only if your account is on the E2 version of the - platform.`, + platform.` - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No NETWORK_ID argument specified. Loading names for Networks drop-down." - names, err := a.Networks.NetworkNetworkNameToNetworkIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Networks drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Databricks Account API network configuration ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have databricks account api network configuration id") - } deleteReq.NetworkId = args[0] err = a.Networks.Delete(ctx, deleteReq) @@ -132,52 +161,61 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq provisioning.GetNetworkRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *provisioning.GetNetworkRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq provisioning.GetNetworkRequest + + // TODO: short flags -var getCmd = &cobra.Command{ - Use: "get NETWORK_ID", - Short: `Get a network configuration.`, - Long: `Get a network configuration. + cmd.Use = "get NETWORK_ID" + cmd.Short = `Get a network configuration.` + cmd.Long = `Get a network configuration. Gets a Databricks network configuration, which represents a cloud VPC and its - resources.`, + resources.` - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No NETWORK_ID argument specified. Loading names for Networks drop-down." - names, err := a.Networks.NetworkNetworkNameToNetworkIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Networks drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Databricks Account API network configuration ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have databricks account api network configuration id") - } getReq.NetworkId = args[0] response, err := a.Networks.Get(ctx, getReq) @@ -185,33 +223,51 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get all network configurations.`, - Long: `Get all network configurations. + cmd.Use = "list" + cmd.Short = `Get all network configurations.` + cmd.Long = `Get all network configurations. Gets a list of all Databricks network configurations for an account, specified by ID. This operation is available only if your account is on the E2 version of the - platform.`, + platform.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) response, err := a.Networks.List(ctx) @@ -219,10 +275,24 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // end service Networks diff --git a/cmd/account/networks/overrides.go b/cmd/account/networks/overrides.go index d47b9ce386..082ee242d2 100644 --- a/cmd/account/networks/overrides.go +++ b/cmd/account/networks/overrides.go @@ -1,9 +1,16 @@ package networks -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{range .}}{{.NetworkId | green}} {{.NetworkName}} {{.WorkspaceId}} {{.VpcStatus}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/account/o-auth-enrollment/o-auth-enrollment.go b/cmd/account/o-auth-enrollment/o-auth-enrollment.go index a39306a371..91fdfa0a7f 100755 --- a/cmd/account/o-auth-enrollment/o-auth-enrollment.go +++ b/cmd/account/o-auth-enrollment/o-auth-enrollment.go @@ -10,36 +10,56 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "o-auth-enrollment", - Short: `These APIs enable administrators to enroll OAuth for their accounts, which is required for adding/using any OAuth published/custom application integration.`, - Long: `These APIs enable administrators to enroll OAuth for their accounts, which is +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "o-auth-enrollment", + Short: `These APIs enable administrators to enroll OAuth for their accounts, which is required for adding/using any OAuth published/custom application integration.`, + Long: `These APIs enable administrators to enroll OAuth for their accounts, which is required for adding/using any OAuth published/custom application integration. **Note:** Your account must be on the E2 version to use these APIs, this is because OAuth is only supported on the E2 version.`, - Annotations: map[string]string{ - "package": "oauth2", - }, + GroupID: "oauth2", + Annotations: map[string]string{ + "package": "oauth2", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq oauth2.CreateOAuthEnrollment -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *oauth2.CreateOAuthEnrollment, +) - createCmd.Flags().BoolVar(&createReq.EnableAllPublishedApps, "enable-all-published-apps", createReq.EnableAllPublishedApps, `If true, enable OAuth for all the published applications in the account.`) +func newCreate() *cobra.Command { + cmd := &cobra.Command{} -} + var createReq oauth2.CreateOAuthEnrollment + var createJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().BoolVar(&createReq.EnableAllPublishedApps, "enable-all-published-apps", createReq.EnableAllPublishedApps, `If true, enable OAuth for all the published applications in the account.`) -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create OAuth Enrollment request.`, - Long: `Create OAuth Enrollment request. + cmd.Use = "create" + cmd.Short = `Create OAuth Enrollment request.` + cmd.Long = `Create OAuth Enrollment request. Create an OAuth Enrollment request to enroll OAuth for this account and optionally enable the OAuth integration for all the partner applications in @@ -49,18 +69,20 @@ var createCmd = &cobra.Command{ The enrollment is executed asynchronously, so the API will return 204 immediately. The actual enrollment take a few minutes, you can check the - status via API :method:OAuthEnrollment/get.`, + status via API :method:OAuthEnrollment/get.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -77,32 +99,50 @@ var createCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start get command -func init() { - Cmd.AddCommand(getCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} -var getCmd = &cobra.Command{ - Use: "get", - Short: `Get OAuth enrollment status.`, - Long: `Get OAuth enrollment status. + cmd.Use = "get" + cmd.Short = `Get OAuth enrollment status.` + cmd.Long = `Get OAuth enrollment status. Gets the OAuth enrollment status for this Account. You can only add/use the OAuth published/custom application integrations when - OAuth enrollment status is enabled.`, + OAuth enrollment status is enabled.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) response, err := a.OAuthEnrollment.Get(ctx) @@ -110,10 +150,24 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // end service OAuthEnrollment diff --git a/cmd/account/private-access/private-access.go b/cmd/account/private-access/private-access.go index ebb31dd033..419886a802 100755 --- a/cmd/account/private-access/private-access.go +++ b/cmd/account/private-access/private-access.go @@ -3,8 +3,6 @@ package private_access import ( - "fmt" - "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/flags" @@ -12,34 +10,54 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "private-access", - Short: `These APIs manage private access settings for this account.`, - Long: `These APIs manage private access settings for this account.`, - Annotations: map[string]string{ - "package": "provisioning", - }, +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "private-access", + Short: `These APIs manage private access settings for this account.`, + Long: `These APIs manage private access settings for this account.`, + GroupID: "provisioning", + Annotations: map[string]string{ + "package": "provisioning", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq provisioning.UpsertPrivateAccessSettingsRequest -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *provisioning.UpsertPrivateAccessSettingsRequest, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq provisioning.UpsertPrivateAccessSettingsRequest + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: allowed_vpc_endpoint_ids - createCmd.Flags().Var(&createReq.PrivateAccessLevel, "private-access-level", `The private access level controls which VPC endpoints can connect to the UI or API of any workspace that attaches this private access settings object.`) - createCmd.Flags().BoolVar(&createReq.PublicAccessEnabled, "public-access-enabled", createReq.PublicAccessEnabled, `Determines if the workspace can be accessed over public internet.`) + cmd.Flags().Var(&createReq.PrivateAccessLevel, "private-access-level", `The private access level controls which VPC endpoints can connect to the UI or API of any workspace that attaches this private access settings object.`) + cmd.Flags().BoolVar(&createReq.PublicAccessEnabled, "public-access-enabled", createReq.PublicAccessEnabled, `Determines if the workspace can be accessed over public internet.`) -} - -var createCmd = &cobra.Command{ - Use: "create PRIVATE_ACCESS_SETTINGS_NAME REGION", - Short: `Create private access settings.`, - Long: `Create private access settings. + cmd.Use = "create PRIVATE_ACCESS_SETTINGS_NAME REGION" + cmd.Short = `Create private access settings.` + cmd.Long = `Create private access settings. Creates a private access settings object, which specifies how your workspace is accessed over [AWS PrivateLink]. To use AWS PrivateLink, a workspace must @@ -55,18 +73,20 @@ var createCmd = &cobra.Command{ PrivateLink]. [AWS PrivateLink]: https://aws.amazon.com/privatelink - [Databricks article about PrivateLink]: https://docs.databricks.com/administration-guide/cloud-configurations/aws/privatelink.html`, + [Databricks article about PrivateLink]: https://docs.databricks.com/administration-guide/cloud-configurations/aws/privatelink.html` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -85,25 +105,45 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq provisioning.DeletePrivateAccesRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *provisioning.DeletePrivateAccesRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq provisioning.DeletePrivateAccesRequest + + // TODO: short flags -var deleteCmd = &cobra.Command{ - Use: "delete PRIVATE_ACCESS_SETTINGS_ID", - Short: `Delete a private access settings object.`, - Long: `Delete a private access settings object. + cmd.Use = "delete PRIVATE_ACCESS_SETTINGS_ID" + cmd.Short = `Delete a private access settings object.` + cmd.Long = `Delete a private access settings object. Deletes a private access settings object, which determines how your workspace is accessed over [AWS PrivateLink]. @@ -112,31 +152,20 @@ var deleteCmd = &cobra.Command{ PrivateLink]. [AWS PrivateLink]: https://aws.amazon.com/privatelink - [Databricks article about PrivateLink]: https://docs.databricks.com/administration-guide/cloud-configurations/aws/privatelink.html`, + [Databricks article about PrivateLink]: https://docs.databricks.com/administration-guide/cloud-configurations/aws/privatelink.html` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No PRIVATE_ACCESS_SETTINGS_ID argument specified. Loading names for Private Access drop-down." - names, err := a.PrivateAccess.PrivateAccessSettingsPrivateAccessSettingsNameToPrivateAccessSettingsIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Private Access drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Databricks Account API private access settings ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have databricks account api private access settings id") - } deleteReq.PrivateAccessSettingsId = args[0] err = a.PrivateAccess.Delete(ctx, deleteReq) @@ -144,25 +173,45 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq provisioning.GetPrivateAccesRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *provisioning.GetPrivateAccesRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq provisioning.GetPrivateAccesRequest -var getCmd = &cobra.Command{ - Use: "get PRIVATE_ACCESS_SETTINGS_ID", - Short: `Get a private access settings object.`, - Long: `Get a private access settings object. + // TODO: short flags + + cmd.Use = "get PRIVATE_ACCESS_SETTINGS_ID" + cmd.Short = `Get a private access settings object.` + cmd.Long = `Get a private access settings object. Gets a private access settings object, which specifies how your workspace is accessed over [AWS PrivateLink]. @@ -171,31 +220,20 @@ var getCmd = &cobra.Command{ PrivateLink]. [AWS PrivateLink]: https://aws.amazon.com/privatelink - [Databricks article about PrivateLink]: https://docs.databricks.com/administration-guide/cloud-configurations/aws/privatelink.html`, + [Databricks article about PrivateLink]: https://docs.databricks.com/administration-guide/cloud-configurations/aws/privatelink.html` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No PRIVATE_ACCESS_SETTINGS_ID argument specified. Loading names for Private Access drop-down." - names, err := a.PrivateAccess.PrivateAccessSettingsPrivateAccessSettingsNameToPrivateAccessSettingsIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Private Access drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Databricks Account API private access settings ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have databricks account api private access settings id") - } getReq.PrivateAccessSettingsId = args[0] response, err := a.PrivateAccess.Get(ctx, getReq) @@ -203,30 +241,48 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get all private access settings objects.`, - Long: `Get all private access settings objects. + cmd.Use = "list" + cmd.Short = `Get all private access settings objects.` + cmd.Long = `Get all private access settings objects. Gets a list of all private access settings objects for an account, specified - by ID.`, + by ID.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) response, err := a.PrivateAccess.List(ctx) @@ -234,31 +290,51 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start replace command -var replaceReq provisioning.UpsertPrivateAccessSettingsRequest -var replaceJson flags.JsonFlag -func init() { - Cmd.AddCommand(replaceCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var replaceOverrides []func( + *cobra.Command, + *provisioning.UpsertPrivateAccessSettingsRequest, +) + +func newReplace() *cobra.Command { + cmd := &cobra.Command{} + + var replaceReq provisioning.UpsertPrivateAccessSettingsRequest + var replaceJson flags.JsonFlag + // TODO: short flags - replaceCmd.Flags().Var(&replaceJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&replaceJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: allowed_vpc_endpoint_ids - replaceCmd.Flags().Var(&replaceReq.PrivateAccessLevel, "private-access-level", `The private access level controls which VPC endpoints can connect to the UI or API of any workspace that attaches this private access settings object.`) - replaceCmd.Flags().BoolVar(&replaceReq.PublicAccessEnabled, "public-access-enabled", replaceReq.PublicAccessEnabled, `Determines if the workspace can be accessed over public internet.`) + cmd.Flags().Var(&replaceReq.PrivateAccessLevel, "private-access-level", `The private access level controls which VPC endpoints can connect to the UI or API of any workspace that attaches this private access settings object.`) + cmd.Flags().BoolVar(&replaceReq.PublicAccessEnabled, "public-access-enabled", replaceReq.PublicAccessEnabled, `Determines if the workspace can be accessed over public internet.`) -} - -var replaceCmd = &cobra.Command{ - Use: "replace PRIVATE_ACCESS_SETTINGS_NAME REGION PRIVATE_ACCESS_SETTINGS_ID", - Short: `Replace private access settings.`, - Long: `Replace private access settings. + cmd.Use = "replace PRIVATE_ACCESS_SETTINGS_NAME REGION PRIVATE_ACCESS_SETTINGS_ID" + cmd.Short = `Replace private access settings.` + cmd.Long = `Replace private access settings. Updates an existing private access settings object, which specifies how your workspace is accessed over [AWS PrivateLink]. To use AWS PrivateLink, a @@ -280,15 +356,17 @@ var replaceCmd = &cobra.Command{ PrivateLink]. [AWS PrivateLink]: https://aws.amazon.com/privatelink - [Databricks article about PrivateLink]: https://docs.databricks.com/administration-guide/cloud-configurations/aws/privatelink.html`, + [Databricks article about PrivateLink]: https://docs.databricks.com/administration-guide/cloud-configurations/aws/privatelink.html` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(3) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -307,10 +385,24 @@ var replaceCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range replaceOverrides { + fn(cmd, &replaceReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newReplace()) + }) } // end service PrivateAccess diff --git a/cmd/account/published-app-integration/published-app-integration.go b/cmd/account/published-app-integration/published-app-integration.go index 7eb6d4c9ee..b367ad71a9 100755 --- a/cmd/account/published-app-integration/published-app-integration.go +++ b/cmd/account/published-app-integration/published-app-integration.go @@ -10,55 +10,77 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "published-app-integration", - Short: `These APIs enable administrators to manage published oauth app integrations, which is required for adding/using Published OAuth App Integration like Tableau Cloud for Databricks in AWS cloud.`, - Long: `These APIs enable administrators to manage published oauth app integrations, +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "published-app-integration", + Short: `These APIs enable administrators to manage published oauth app integrations, which is required for adding/using Published OAuth App Integration like Tableau Cloud for Databricks in AWS cloud.`, + Long: `These APIs enable administrators to manage published oauth app integrations, which is required for adding/using Published OAuth App Integration like Tableau Cloud for Databricks in AWS cloud. **Note:** You can only add/use the OAuth published application integrations when OAuth enrollment status is enabled. For more details see :method:OAuthEnrollment/create`, - Annotations: map[string]string{ - "package": "oauth2", - }, + GroupID: "oauth2", + Annotations: map[string]string{ + "package": "oauth2", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq oauth2.CreatePublishedAppIntegration -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *oauth2.CreatePublishedAppIntegration, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq oauth2.CreatePublishedAppIntegration + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createCmd.Flags().StringVar(&createReq.AppId, "app-id", createReq.AppId, `app_id of the oauth published app integration.`) + cmd.Flags().StringVar(&createReq.AppId, "app-id", createReq.AppId, `app_id of the oauth published app integration.`) // TODO: complex arg: token_access_policy -} - -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create Published OAuth App Integration.`, - Long: `Create Published OAuth App Integration. + cmd.Use = "create" + cmd.Short = `Create Published OAuth App Integration.` + cmd.Long = `Create Published OAuth App Integration. Create Published OAuth App Integration. You can retrieve the published oauth app integration via - :method:PublishedAppIntegration/get.`, + :method:PublishedAppIntegration/get.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -75,36 +97,58 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq oauth2.DeletePublishedAppIntegrationRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *oauth2.DeletePublishedAppIntegrationRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq oauth2.DeletePublishedAppIntegrationRequest -var deleteCmd = &cobra.Command{ - Use: "delete INTEGRATION_ID", - Short: `Delete Published OAuth App Integration.`, - Long: `Delete Published OAuth App Integration. + // TODO: short flags + + cmd.Use = "delete INTEGRATION_ID" + cmd.Short = `Delete Published OAuth App Integration.` + cmd.Long = `Delete Published OAuth App Integration. Delete an existing Published OAuth App Integration. You can retrieve the - published oauth app integration via :method:PublishedAppIntegration/get.`, + published oauth app integration via :method:PublishedAppIntegration/get.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -115,35 +159,57 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq oauth2.GetPublishedAppIntegrationRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *oauth2.GetPublishedAppIntegrationRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq oauth2.GetPublishedAppIntegrationRequest -var getCmd = &cobra.Command{ - Use: "get INTEGRATION_ID", - Short: `Get OAuth Published App Integration.`, - Long: `Get OAuth Published App Integration. + // TODO: short flags + + cmd.Use = "get INTEGRATION_ID" + cmd.Short = `Get OAuth Published App Integration.` + cmd.Long = `Get OAuth Published App Integration. - Gets the Published OAuth App Integration for the given integration id.`, + Gets the Published OAuth App Integration for the given integration id.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -154,30 +220,48 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get published oauth app integrations.`, - Long: `Get published oauth app integrations. + cmd.Use = "list" + cmd.Short = `Get published oauth app integrations.` + cmd.Long = `Get published oauth app integrations. Get the list of published oauth app integrations for the specified Databricks - account`, + account` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) response, err := a.PublishedAppIntegration.ListAll(ctx) @@ -185,40 +269,62 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq oauth2.UpdatePublishedAppIntegration -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *oauth2.UpdatePublishedAppIntegration, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq oauth2.UpdatePublishedAppIntegration + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: token_access_policy -} - -var updateCmd = &cobra.Command{ - Use: "update INTEGRATION_ID", - Short: `Updates Published OAuth App Integration.`, - Long: `Updates Published OAuth App Integration. + cmd.Use = "update INTEGRATION_ID" + cmd.Short = `Updates Published OAuth App Integration.` + cmd.Long = `Updates Published OAuth App Integration. Updates an existing published OAuth App Integration. You can retrieve the - published oauth app integration via :method:PublishedAppIntegration/get.`, + published oauth app integration via :method:PublishedAppIntegration/get.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -235,10 +341,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service PublishedAppIntegration diff --git a/cmd/account/service-principal-secrets/service-principal-secrets.go b/cmd/account/service-principal-secrets/service-principal-secrets.go index 8c4c1fb95a..a28f75faa2 100755 --- a/cmd/account/service-principal-secrets/service-principal-secrets.go +++ b/cmd/account/service-principal-secrets/service-principal-secrets.go @@ -11,10 +11,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "service-principal-secrets", - Short: `These APIs enable administrators to manage service principal secrets.`, - Long: `These APIs enable administrators to manage service principal secrets. +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "service-principal-secrets", + Short: `These APIs enable administrators to manage service principal secrets.`, + Long: `These APIs enable administrators to manage service principal secrets. You can use the generated secrets to obtain OAuth access tokens for a service principal, which can then be used to access Databricks Accounts and Workspace @@ -27,34 +32,51 @@ var Cmd = &cobra.Command{ [Authentication using OAuth tokens for service principals]: https://docs.databricks.com/dev-tools/authentication-oauth.html [Databricks Terraform Provider]: https://github.com/databricks/terraform-provider-databricks/blob/master/docs/index.md#authenticating-with-service-principal`, - Annotations: map[string]string{ - "package": "oauth2", - }, + GroupID: "oauth2", + Annotations: map[string]string{ + "package": "oauth2", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq oauth2.CreateServicePrincipalSecretRequest -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *oauth2.CreateServicePrincipalSecretRequest, +) -} +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq oauth2.CreateServicePrincipalSecretRequest + + // TODO: short flags -var createCmd = &cobra.Command{ - Use: "create SERVICE_PRINCIPAL_ID", - Short: `Create service principal secret.`, - Long: `Create service principal secret. + cmd.Use = "create SERVICE_PRINCIPAL_ID" + cmd.Short = `Create service principal secret.` + cmd.Long = `Create service principal secret. - Create a secret for the given service principal.`, + Create a secret for the given service principal.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -68,35 +90,57 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq oauth2.DeleteServicePrincipalSecretRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *oauth2.DeleteServicePrincipalSecretRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq oauth2.DeleteServicePrincipalSecretRequest -var deleteCmd = &cobra.Command{ - Use: "delete SERVICE_PRINCIPAL_ID SECRET_ID", - Short: `Delete service principal secret.`, - Long: `Delete service principal secret. + // TODO: short flags + + cmd.Use = "delete SERVICE_PRINCIPAL_ID SECRET_ID" + cmd.Short = `Delete service principal secret.` + cmd.Long = `Delete service principal secret. - Delete a secret from the given service principal.`, + Delete a secret from the given service principal.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -111,37 +155,59 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start list command -var listReq oauth2.ListServicePrincipalSecretsRequest -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *oauth2.ListServicePrincipalSecretsRequest, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list SERVICE_PRINCIPAL_ID", - Short: `List service principal secrets.`, - Long: `List service principal secrets. + var listReq oauth2.ListServicePrincipalSecretsRequest + + // TODO: short flags + + cmd.Use = "list SERVICE_PRINCIPAL_ID" + cmd.Short = `List service principal secrets.` + cmd.Long = `List service principal secrets. List all secrets associated with the given service principal. This operation only returns information about the secrets themselves and does not include the - secret values.`, + secret values.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -155,10 +221,24 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // end service ServicePrincipalSecrets diff --git a/cmd/account/service-principals/overrides.go b/cmd/account/service-principals/overrides.go index c335bead69..d94a4267c8 100644 --- a/cmd/account/service-principals/overrides.go +++ b/cmd/account/service-principals/overrides.go @@ -1,9 +1,17 @@ package service_principals -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/databricks-sdk-go/service/iam" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command, _ *iam.ListAccountServicePrincipalsRequest) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{range .}}{{.Id|green}} {{.ApplicationId}} {{.DisplayName}} {{range .Groups}}{{.Display}} {{end}} {{if .Active}}{{"ACTIVE"|green}}{{else}}DISABLED{{end}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/account/service-principals/service-principals.go b/cmd/account/service-principals/service-principals.go index 55b7492ff2..7ab3543379 100755 --- a/cmd/account/service-principals/service-principals.go +++ b/cmd/account/service-principals/service-principals.go @@ -3,8 +3,6 @@ package service_principals import ( - "fmt" - "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/flags" @@ -12,57 +10,79 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "service-principals", - Short: `Identities for use with jobs, automated tools, and systems such as scripts, apps, and CI/CD platforms.`, - Long: `Identities for use with jobs, automated tools, and systems such as scripts, +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "service-principals", + Short: `Identities for use with jobs, automated tools, and systems such as scripts, apps, and CI/CD platforms.`, + Long: `Identities for use with jobs, automated tools, and systems such as scripts, apps, and CI/CD platforms. Databricks recommends creating service principals to run production jobs or modify production data. If all processes that act on production data run with service principals, interactive users do not need any write, delete, or modify privileges in production. This eliminates the risk of a user overwriting production data by accident.`, - Annotations: map[string]string{ - "package": "iam", - }, + GroupID: "iam", + Annotations: map[string]string{ + "package": "iam", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq iam.ServicePrincipal -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *iam.ServicePrincipal, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq iam.ServicePrincipal + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createCmd.Flags().BoolVar(&createReq.Active, "active", createReq.Active, `If this user is active.`) - createCmd.Flags().StringVar(&createReq.ApplicationId, "application-id", createReq.ApplicationId, `UUID relating to the service principal.`) - createCmd.Flags().StringVar(&createReq.DisplayName, "display-name", createReq.DisplayName, `String that represents a concatenation of given and family names.`) + cmd.Flags().BoolVar(&createReq.Active, "active", createReq.Active, `If this user is active.`) + cmd.Flags().StringVar(&createReq.ApplicationId, "application-id", createReq.ApplicationId, `UUID relating to the service principal.`) + cmd.Flags().StringVar(&createReq.DisplayName, "display-name", createReq.DisplayName, `String that represents a concatenation of given and family names.`) // TODO: array: entitlements - createCmd.Flags().StringVar(&createReq.ExternalId, "external-id", createReq.ExternalId, ``) + cmd.Flags().StringVar(&createReq.ExternalId, "external-id", createReq.ExternalId, ``) // TODO: array: groups - createCmd.Flags().StringVar(&createReq.Id, "id", createReq.Id, `Databricks service principal ID.`) + cmd.Flags().StringVar(&createReq.Id, "id", createReq.Id, `Databricks service principal ID.`) // TODO: array: roles -} - -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a service principal.`, - Long: `Create a service principal. + cmd.Use = "create" + cmd.Short = `Create a service principal.` + cmd.Long = `Create a service principal. - Creates a new service principal in the Databricks account.`, + Creates a new service principal in the Databricks account.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -79,51 +99,60 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq iam.DeleteAccountServicePrincipalRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *iam.DeleteAccountServicePrincipalRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete ID", - Short: `Delete a service principal.`, - Long: `Delete a service principal. + var deleteReq iam.DeleteAccountServicePrincipalRequest + + // TODO: short flags + + cmd.Use = "delete ID" + cmd.Short = `Delete a service principal.` + cmd.Long = `Delete a service principal. - Delete a single service principal in the Databricks account.`, + Delete a single service principal in the Databricks account.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Account Service Principals drop-down." - names, err := a.ServicePrincipals.ServicePrincipalDisplayNameToIdMap(ctx, iam.ListAccountServicePrincipalsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Account Service Principals drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID for a service principal in the Databricks account") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id for a service principal in the databricks account") - } deleteReq.Id = args[0] err = a.ServicePrincipals.Delete(ctx, deleteReq) @@ -131,52 +160,61 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq iam.GetAccountServicePrincipalRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *iam.GetAccountServicePrincipalRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq iam.GetAccountServicePrincipalRequest -var getCmd = &cobra.Command{ - Use: "get ID", - Short: `Get service principal details.`, - Long: `Get service principal details. + // TODO: short flags + + cmd.Use = "get ID" + cmd.Short = `Get service principal details.` + cmd.Long = `Get service principal details. Gets the details for a single service principal define in the Databricks - account.`, + account.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Account Service Principals drop-down." - names, err := a.ServicePrincipals.ServicePrincipalDisplayNameToIdMap(ctx, iam.ListAccountServicePrincipalsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Account Service Principals drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID for a service principal in the Databricks account") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id for a service principal in the databricks account") - } getReq.Id = args[0] response, err := a.ServicePrincipals.Get(ctx, getReq) @@ -184,48 +222,70 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq iam.ListAccountServicePrincipalsRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *iam.ListAccountServicePrincipalsRequest, +) - listCmd.Flags().StringVar(&listReq.Attributes, "attributes", listReq.Attributes, `Comma-separated list of attributes to return in response.`) - listCmd.Flags().IntVar(&listReq.Count, "count", listReq.Count, `Desired number of results per page.`) - listCmd.Flags().StringVar(&listReq.ExcludedAttributes, "excluded-attributes", listReq.ExcludedAttributes, `Comma-separated list of attributes to exclude in response.`) - listCmd.Flags().StringVar(&listReq.Filter, "filter", listReq.Filter, `Query by which the results have to be filtered.`) - listCmd.Flags().StringVar(&listReq.SortBy, "sort-by", listReq.SortBy, `Attribute to sort the results.`) - listCmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order to sort the results.`) - listCmd.Flags().IntVar(&listReq.StartIndex, "start-index", listReq.StartIndex, `Specifies the index of the first result.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq iam.ListAccountServicePrincipalsRequest + var listJson flags.JsonFlag -var listCmd = &cobra.Command{ - Use: "list", - Short: `List service principals.`, - Long: `List service principals. + // TODO: short flags + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&listReq.Attributes, "attributes", listReq.Attributes, `Comma-separated list of attributes to return in response.`) + cmd.Flags().IntVar(&listReq.Count, "count", listReq.Count, `Desired number of results per page.`) + cmd.Flags().StringVar(&listReq.ExcludedAttributes, "excluded-attributes", listReq.ExcludedAttributes, `Comma-separated list of attributes to exclude in response.`) + cmd.Flags().StringVar(&listReq.Filter, "filter", listReq.Filter, `Query by which the results have to be filtered.`) + cmd.Flags().StringVar(&listReq.SortBy, "sort-by", listReq.SortBy, `Attribute to sort the results.`) + cmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order to sort the results.`) + cmd.Flags().IntVar(&listReq.StartIndex, "start-index", listReq.StartIndex, `Specifies the index of the first result.`) + + cmd.Use = "list" + cmd.Short = `List service principals.` + cmd.Long = `List service principals. - Gets the set of service principals associated with a Databricks account.`, + Gets the set of service principals associated with a Databricks account.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -242,37 +302,63 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start patch command -var patchReq iam.PartialUpdate -var patchJson flags.JsonFlag -func init() { - Cmd.AddCommand(patchCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var patchOverrides []func( + *cobra.Command, + *iam.PartialUpdate, +) + +func newPatch() *cobra.Command { + cmd := &cobra.Command{} + + var patchReq iam.PartialUpdate + var patchJson flags.JsonFlag + // TODO: short flags - patchCmd.Flags().Var(&patchJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&patchJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: Operations // TODO: array: schema -} - -var patchCmd = &cobra.Command{ - Use: "patch ID", - Short: `Update service principal details.`, - Long: `Update service principal details. + cmd.Use = "patch ID" + cmd.Short = `Update service principal details.` + cmd.Long = `Update service principal details. Partially updates the details of a single service principal in the Databricks - account.`, + account.` - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -282,23 +368,6 @@ var patchCmd = &cobra.Command{ return err } } - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Account Service Principals drop-down." - names, err := a.ServicePrincipals.ServicePrincipalDisplayNameToIdMap(ctx, iam.ListAccountServicePrincipalsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Account Service Principals drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID for a service principal in the Databricks account") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id for a service principal in the databricks account") - } patchReq.Id = args[0] err = a.ServicePrincipals.Patch(ctx, patchReq) @@ -306,44 +375,73 @@ var patchCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range patchOverrides { + fn(cmd, &patchReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newPatch()) + }) } // start update command -var updateReq iam.ServicePrincipal -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *iam.ServicePrincipal, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq iam.ServicePrincipal + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) - updateCmd.Flags().BoolVar(&updateReq.Active, "active", updateReq.Active, `If this user is active.`) - updateCmd.Flags().StringVar(&updateReq.ApplicationId, "application-id", updateReq.ApplicationId, `UUID relating to the service principal.`) - updateCmd.Flags().StringVar(&updateReq.DisplayName, "display-name", updateReq.DisplayName, `String that represents a concatenation of given and family names.`) + cmd.Flags().BoolVar(&updateReq.Active, "active", updateReq.Active, `If this user is active.`) + cmd.Flags().StringVar(&updateReq.ApplicationId, "application-id", updateReq.ApplicationId, `UUID relating to the service principal.`) + cmd.Flags().StringVar(&updateReq.DisplayName, "display-name", updateReq.DisplayName, `String that represents a concatenation of given and family names.`) // TODO: array: entitlements - updateCmd.Flags().StringVar(&updateReq.ExternalId, "external-id", updateReq.ExternalId, ``) + cmd.Flags().StringVar(&updateReq.ExternalId, "external-id", updateReq.ExternalId, ``) // TODO: array: groups - updateCmd.Flags().StringVar(&updateReq.Id, "id", updateReq.Id, `Databricks service principal ID.`) + cmd.Flags().StringVar(&updateReq.Id, "id", updateReq.Id, `Databricks service principal ID.`) // TODO: array: roles -} - -var updateCmd = &cobra.Command{ - Use: "update ID", - Short: `Replace service principal.`, - Long: `Replace service principal. + cmd.Use = "update ID" + cmd.Short = `Replace service principal.` + cmd.Long = `Replace service principal. Updates the details of a single service principal. - This action replaces the existing service principal with the same name.`, + This action replaces the existing service principal with the same name.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -353,23 +451,6 @@ var updateCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Account Service Principals drop-down." - names, err := a.ServicePrincipals.ServicePrincipalDisplayNameToIdMap(ctx, iam.ListAccountServicePrincipalsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Account Service Principals drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Databricks service principal ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have databricks service principal id") - } updateReq.Id = args[0] } @@ -378,10 +459,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service AccountServicePrincipals diff --git a/cmd/account/settings/settings.go b/cmd/account/settings/settings.go index c55c7ad622..4e98119dd9 100755 --- a/cmd/account/settings/settings.go +++ b/cmd/account/settings/settings.go @@ -10,10 +10,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "settings", - Short: `The Personal Compute enablement setting lets you control which users can use the Personal Compute default policy to create compute resources.`, - Long: `The Personal Compute enablement setting lets you control which users can use +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "settings", + Short: `The Personal Compute enablement setting lets you control which users can use the Personal Compute default policy to create compute resources.`, + Long: `The Personal Compute enablement setting lets you control which users can use the Personal Compute default policy to create compute resources. By default all users in all workspaces have access (ON), but you can change the setting to instead let individual workspaces configure access control (DELEGATE). @@ -22,37 +27,54 @@ var Cmd = &cobra.Command{ a default value, this setting is present on all accounts even though it's never set on a given account. Deletion reverts the value of the setting back to the default value.`, - Annotations: map[string]string{ - "package": "settings", - }, + GroupID: "settings", + Annotations: map[string]string{ + "package": "settings", + }, - // This service is being previewed; hide from help output. - Hidden: true, + // This service is being previewed; hide from help output. + Hidden: true, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start delete-personal-compute-setting command -var deletePersonalComputeSettingReq settings.DeletePersonalComputeSettingRequest -func init() { - Cmd.AddCommand(deletePersonalComputeSettingCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deletePersonalComputeSettingOverrides []func( + *cobra.Command, + *settings.DeletePersonalComputeSettingRequest, +) -} +func newDeletePersonalComputeSetting() *cobra.Command { + cmd := &cobra.Command{} -var deletePersonalComputeSettingCmd = &cobra.Command{ - Use: "delete-personal-compute-setting ETAG", - Short: `Delete Personal Compute setting.`, - Long: `Delete Personal Compute setting. + var deletePersonalComputeSettingReq settings.DeletePersonalComputeSettingRequest + + // TODO: short flags + + cmd.Use = "delete-personal-compute-setting ETAG" + cmd.Short = `Delete Personal Compute setting.` + cmd.Long = `Delete Personal Compute setting. - Reverts back the Personal Compute setting value to default (ON)`, + Reverts back the Personal Compute setting value to default (ON)` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -63,35 +85,57 @@ var deletePersonalComputeSettingCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deletePersonalComputeSettingOverrides { + fn(cmd, &deletePersonalComputeSettingReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDeletePersonalComputeSetting()) + }) } // start read-personal-compute-setting command -var readPersonalComputeSettingReq settings.ReadPersonalComputeSettingRequest -func init() { - Cmd.AddCommand(readPersonalComputeSettingCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var readPersonalComputeSettingOverrides []func( + *cobra.Command, + *settings.ReadPersonalComputeSettingRequest, +) -} +func newReadPersonalComputeSetting() *cobra.Command { + cmd := &cobra.Command{} + + var readPersonalComputeSettingReq settings.ReadPersonalComputeSettingRequest + + // TODO: short flags -var readPersonalComputeSettingCmd = &cobra.Command{ - Use: "read-personal-compute-setting ETAG", - Short: `Get Personal Compute setting.`, - Long: `Get Personal Compute setting. + cmd.Use = "read-personal-compute-setting ETAG" + cmd.Short = `Get Personal Compute setting.` + cmd.Long = `Get Personal Compute setting. - Gets the value of the Personal Compute setting.`, + Gets the value of the Personal Compute setting.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -102,43 +146,65 @@ var readPersonalComputeSettingCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range readPersonalComputeSettingOverrides { + fn(cmd, &readPersonalComputeSettingReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newReadPersonalComputeSetting()) + }) } // start update-personal-compute-setting command -var updatePersonalComputeSettingReq settings.UpdatePersonalComputeSettingRequest -var updatePersonalComputeSettingJson flags.JsonFlag -func init() { - Cmd.AddCommand(updatePersonalComputeSettingCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updatePersonalComputeSettingOverrides []func( + *cobra.Command, + *settings.UpdatePersonalComputeSettingRequest, +) + +func newUpdatePersonalComputeSetting() *cobra.Command { + cmd := &cobra.Command{} + + var updatePersonalComputeSettingReq settings.UpdatePersonalComputeSettingRequest + var updatePersonalComputeSettingJson flags.JsonFlag + // TODO: short flags - updatePersonalComputeSettingCmd.Flags().Var(&updatePersonalComputeSettingJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updatePersonalComputeSettingJson, "json", `either inline JSON string or @path/to/file.json with request body`) - updatePersonalComputeSettingCmd.Flags().BoolVar(&updatePersonalComputeSettingReq.AllowMissing, "allow-missing", updatePersonalComputeSettingReq.AllowMissing, `This should always be set to true for Settings RPCs.`) + cmd.Flags().BoolVar(&updatePersonalComputeSettingReq.AllowMissing, "allow-missing", updatePersonalComputeSettingReq.AllowMissing, `This should always be set to true for Settings RPCs.`) // TODO: complex arg: setting -} - -var updatePersonalComputeSettingCmd = &cobra.Command{ - Use: "update-personal-compute-setting", - Short: `Update Personal Compute setting.`, - Long: `Update Personal Compute setting. + cmd.Use = "update-personal-compute-setting" + cmd.Short = `Update Personal Compute setting.` + cmd.Long = `Update Personal Compute setting. - Updates the value of the Personal Compute setting.`, + Updates the value of the Personal Compute setting.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -155,10 +221,24 @@ var updatePersonalComputeSettingCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updatePersonalComputeSettingOverrides { + fn(cmd, &updatePersonalComputeSettingReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdatePersonalComputeSetting()) + }) } // end service AccountSettings diff --git a/cmd/account/storage-credentials/storage-credentials.go b/cmd/account/storage-credentials/storage-credentials.go index f5dd58200a..451b711212 100755 --- a/cmd/account/storage-credentials/storage-credentials.go +++ b/cmd/account/storage-credentials/storage-credentials.go @@ -10,32 +10,52 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "storage-credentials", - Short: `These APIs manage storage credentials for a particular metastore.`, - Long: `These APIs manage storage credentials for a particular metastore.`, - Annotations: map[string]string{ - "package": "catalog", - }, +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "storage-credentials", + Short: `These APIs manage storage credentials for a particular metastore.`, + Long: `These APIs manage storage credentials for a particular metastore.`, + GroupID: "catalog", + Annotations: map[string]string{ + "package": "catalog", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq catalog.AccountsCreateStorageCredential -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *catalog.AccountsCreateStorageCredential, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq catalog.AccountsCreateStorageCredential + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: credential_info -} - -var createCmd = &cobra.Command{ - Use: "create METASTORE_ID", - Short: `Create a storage credential.`, - Long: `Create a storage credential. + cmd.Use = "create METASTORE_ID" + cmd.Short = `Create a storage credential.` + cmd.Long = `Create a storage credential. Creates a new storage credential. The request object is specific to the cloud: @@ -43,15 +63,17 @@ var createCmd = &cobra.Command{ credentials * **GcpServiceAcountKey** for GCP credentials. The caller must be a metastore admin and have the - **CREATE_STORAGE_CREDENTIAL** privilege on the metastore.`, + **CREATE_STORAGE_CREDENTIAL** privilege on the metastore.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -68,38 +90,60 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq catalog.DeleteAccountStorageCredentialRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *catalog.DeleteAccountStorageCredentialRequest, +) - deleteCmd.Flags().BoolVar(&deleteReq.Force, "force", deleteReq.Force, `Force deletion even if the Storage Credential is not empty.`) +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -} + var deleteReq catalog.DeleteAccountStorageCredentialRequest -var deleteCmd = &cobra.Command{ - Use: "delete METASTORE_ID NAME", - Short: `Delete a storage credential.`, - Long: `Delete a storage credential. + // TODO: short flags + + cmd.Flags().BoolVar(&deleteReq.Force, "force", deleteReq.Force, `Force deletion even if the Storage Credential is not empty.`) + + cmd.Use = "delete METASTORE_ID NAME" + cmd.Short = `Delete a storage credential.` + cmd.Long = `Delete a storage credential. Deletes a storage credential from the metastore. The caller must be an owner - of the storage credential.`, + of the storage credential.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -111,37 +155,59 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq catalog.GetAccountStorageCredentialRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *catalog.GetAccountStorageCredentialRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} -var getCmd = &cobra.Command{ - Use: "get METASTORE_ID NAME", - Short: `Gets the named storage credential.`, - Long: `Gets the named storage credential. + var getReq catalog.GetAccountStorageCredentialRequest + + // TODO: short flags + + cmd.Use = "get METASTORE_ID NAME" + cmd.Short = `Gets the named storage credential.` + cmd.Long = `Gets the named storage credential. Gets a storage credential from the metastore. The caller must be a metastore admin, the owner of the storage credential, or have a level of privilege on - the storage credential.`, + the storage credential.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -153,36 +219,58 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq catalog.ListAccountStorageCredentialsRequest -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *catalog.ListAccountStorageCredentialsRequest, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} + + var listReq catalog.ListAccountStorageCredentialsRequest -var listCmd = &cobra.Command{ - Use: "list METASTORE_ID", - Short: `Get all storage credentials assigned to a metastore.`, - Long: `Get all storage credentials assigned to a metastore. + // TODO: short flags + + cmd.Use = "list METASTORE_ID" + cmd.Short = `Get all storage credentials assigned to a metastore.` + cmd.Long = `Get all storage credentials assigned to a metastore. Gets a list of all storage credentials that have been assigned to given - metastore.`, + metastore.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -193,41 +281,63 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq catalog.AccountsUpdateStorageCredential -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *catalog.AccountsUpdateStorageCredential, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq catalog.AccountsUpdateStorageCredential + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: credential_info -} - -var updateCmd = &cobra.Command{ - Use: "update METASTORE_ID NAME", - Short: `Updates a storage credential.`, - Long: `Updates a storage credential. + cmd.Use = "update METASTORE_ID NAME" + cmd.Short = `Updates a storage credential.` + cmd.Long = `Updates a storage credential. Updates a storage credential on the metastore. The caller must be the owner of the storage credential. If the caller is a metastore admin, only the __owner__ - credential can be changed.`, + credential can be changed.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -245,10 +355,24 @@ var updateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service AccountStorageCredentials diff --git a/cmd/account/storage/overrides.go b/cmd/account/storage/overrides.go index 76ca6ee1e9..6ebe4a7a43 100644 --- a/cmd/account/storage/overrides.go +++ b/cmd/account/storage/overrides.go @@ -1,9 +1,16 @@ package storage -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{range .}}{{.StorageConfigurationId | green}} {{.StorageConfigurationName}} {{.RootBucketInfo.BucketName}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/account/storage/storage.go b/cmd/account/storage/storage.go index 54821d4d48..19240ccbaf 100755 --- a/cmd/account/storage/storage.go +++ b/cmd/account/storage/storage.go @@ -12,35 +12,55 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "storage", - Short: `These APIs manage storage configurations for this workspace.`, - Long: `These APIs manage storage configurations for this workspace. A root storage S3 +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "storage", + Short: `These APIs manage storage configurations for this workspace.`, + Long: `These APIs manage storage configurations for this workspace. A root storage S3 bucket in your account is required to store objects like cluster logs, notebook revisions, and job results. You can also use the root storage S3 bucket for storage of non-production DBFS data. A storage configuration encapsulates this bucket information, and its ID is used when creating a new workspace.`, - Annotations: map[string]string{ - "package": "provisioning", - }, + GroupID: "provisioning", + Annotations: map[string]string{ + "package": "provisioning", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq provisioning.CreateStorageConfigurationRequest -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *provisioning.CreateStorageConfigurationRequest, +) -} +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq provisioning.CreateStorageConfigurationRequest + var createJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create new storage configuration.`, - Long: `Create new storage configuration. + cmd.Use = "create" + cmd.Short = `Create new storage configuration.` + cmd.Long = `Create new storage configuration. Creates new storage configuration for an account, specified by ID. Uploads a storage configuration object that represents the root AWS S3 bucket in your @@ -51,11 +71,12 @@ var createCmd = &cobra.Command{ For information about how to create a new workspace with this API, see [Create a new workspace using the Account API] - [Create a new workspace using the Account API]: http://docs.databricks.com/administration-guide/account-api/new-workspace.html`, + [Create a new workspace using the Account API]: http://docs.databricks.com/administration-guide/account-api/new-workspace.html` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -73,52 +94,61 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq provisioning.DeleteStorageRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *provisioning.DeleteStorageRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete STORAGE_CONFIGURATION_ID", - Short: `Delete storage configuration.`, - Long: `Delete storage configuration. + var deleteReq provisioning.DeleteStorageRequest + + // TODO: short flags + + cmd.Use = "delete STORAGE_CONFIGURATION_ID" + cmd.Short = `Delete storage configuration.` + cmd.Long = `Delete storage configuration. Deletes a Databricks storage configuration. You cannot delete a storage - configuration that is associated with any workspace.`, + configuration that is associated with any workspace.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No STORAGE_CONFIGURATION_ID argument specified. Loading names for Storage drop-down." - names, err := a.Storage.StorageConfigurationStorageConfigurationNameToStorageConfigurationIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Storage drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Databricks Account API storage configuration ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have databricks account api storage configuration id") - } deleteReq.StorageConfigurationId = args[0] err = a.Storage.Delete(ctx, deleteReq) @@ -126,51 +156,60 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq provisioning.GetStorageRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *provisioning.GetStorageRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq provisioning.GetStorageRequest + + // TODO: short flags -var getCmd = &cobra.Command{ - Use: "get STORAGE_CONFIGURATION_ID", - Short: `Get storage configuration.`, - Long: `Get storage configuration. + cmd.Use = "get STORAGE_CONFIGURATION_ID" + cmd.Short = `Get storage configuration.` + cmd.Long = `Get storage configuration. - Gets a Databricks storage configuration for an account, both specified by ID.`, + Gets a Databricks storage configuration for an account, both specified by ID.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No STORAGE_CONFIGURATION_ID argument specified. Loading names for Storage drop-down." - names, err := a.Storage.StorageConfigurationStorageConfigurationNameToStorageConfigurationIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Storage drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Databricks Account API storage configuration ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have databricks account api storage configuration id") - } getReq.StorageConfigurationId = args[0] response, err := a.Storage.Get(ctx, getReq) @@ -178,30 +217,48 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get all storage configurations.`, - Long: `Get all storage configurations. + cmd.Use = "list" + cmd.Short = `Get all storage configurations.` + cmd.Long = `Get all storage configurations. Gets a list of all Databricks storage configurations for your account, - specified by ID.`, + specified by ID.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) response, err := a.Storage.List(ctx) @@ -209,10 +266,24 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // end service Storage diff --git a/cmd/account/users/overrides.go b/cmd/account/users/overrides.go index 45447a0ae5..ff97733451 100644 --- a/cmd/account/users/overrides.go +++ b/cmd/account/users/overrides.go @@ -1,10 +1,18 @@ package users -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/databricks-sdk-go/service/iam" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command, listReq *iam.ListAccountUsersRequest) { listReq.Attributes = "id,userName,groups,active" listCmd.Annotations["template"] = cmdio.Heredoc(` {{range .}}{{.Id|green}} {{.UserName}} {{range .Groups}}{{.Display}} {{end}} {{if .Active}}{{"ACTIVE"|green}}{{else}}DISABLED{{end}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/account/users/users.go b/cmd/account/users/users.go index 3c3edd0f56..117fe26cec 100755 --- a/cmd/account/users/users.go +++ b/cmd/account/users/users.go @@ -3,8 +3,6 @@ package users import ( - "fmt" - "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/flags" @@ -12,10 +10,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "users", - Short: `User identities recognized by Databricks and represented by email addresses.`, - Long: `User identities recognized by Databricks and represented by email addresses. +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "users", + Short: `User identities recognized by Databricks and represented by email addresses.`, + Long: `User identities recognized by Databricks and represented by email addresses. Databricks recommends using SCIM provisioning to sync users and groups automatically from your identity provider to your Databricks account. SCIM @@ -26,51 +29,68 @@ var Cmd = &cobra.Command{ provider and that user’s account will also be removed from Databricks account. This ensures a consistent offboarding process and prevents unauthorized users from accessing sensitive data.`, - Annotations: map[string]string{ - "package": "iam", - }, + GroupID: "iam", + Annotations: map[string]string{ + "package": "iam", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq iam.User -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *iam.User, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq iam.User + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createCmd.Flags().BoolVar(&createReq.Active, "active", createReq.Active, `If this user is active.`) - createCmd.Flags().StringVar(&createReq.DisplayName, "display-name", createReq.DisplayName, `String that represents a concatenation of given and family names.`) + cmd.Flags().BoolVar(&createReq.Active, "active", createReq.Active, `If this user is active.`) + cmd.Flags().StringVar(&createReq.DisplayName, "display-name", createReq.DisplayName, `String that represents a concatenation of given and family names.`) // TODO: array: emails // TODO: array: entitlements - createCmd.Flags().StringVar(&createReq.ExternalId, "external-id", createReq.ExternalId, ``) + cmd.Flags().StringVar(&createReq.ExternalId, "external-id", createReq.ExternalId, ``) // TODO: array: groups - createCmd.Flags().StringVar(&createReq.Id, "id", createReq.Id, `Databricks user ID.`) + cmd.Flags().StringVar(&createReq.Id, "id", createReq.Id, `Databricks user ID.`) // TODO: complex arg: name // TODO: array: roles - createCmd.Flags().StringVar(&createReq.UserName, "user-name", createReq.UserName, `Email address of the Databricks user.`) + cmd.Flags().StringVar(&createReq.UserName, "user-name", createReq.UserName, `Email address of the Databricks user.`) -} - -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a new user.`, - Long: `Create a new user. + cmd.Use = "create" + cmd.Short = `Create a new user.` + cmd.Long = `Create a new user. Creates a new user in the Databricks account. This new user will also be added - to the Databricks account.`, + to the Databricks account.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -87,52 +107,61 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq iam.DeleteAccountUserRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *iam.DeleteAccountUserRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete ID", - Short: `Delete a user.`, - Long: `Delete a user. + var deleteReq iam.DeleteAccountUserRequest + + // TODO: short flags + + cmd.Use = "delete ID" + cmd.Short = `Delete a user.` + cmd.Long = `Delete a user. Deletes a user. Deleting a user from a Databricks account also removes objects - associated with the user.`, + associated with the user.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Account Users drop-down." - names, err := a.Users.UserUserNameToIdMap(ctx, iam.ListAccountUsersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Account Users drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID for a user in the Databricks account") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id for a user in the databricks account") - } deleteReq.Id = args[0] err = a.Users.Delete(ctx, deleteReq) @@ -140,51 +169,60 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq iam.GetAccountUserRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *iam.GetAccountUserRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq iam.GetAccountUserRequest -var getCmd = &cobra.Command{ - Use: "get ID", - Short: `Get user details.`, - Long: `Get user details. + // TODO: short flags + + cmd.Use = "get ID" + cmd.Short = `Get user details.` + cmd.Long = `Get user details. - Gets information for a specific user in Databricks account.`, + Gets information for a specific user in Databricks account.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Account Users drop-down." - names, err := a.Users.UserUserNameToIdMap(ctx, iam.ListAccountUsersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Account Users drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID for a user in the Databricks account") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id for a user in the databricks account") - } getReq.Id = args[0] response, err := a.Users.Get(ctx, getReq) @@ -192,48 +230,70 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq iam.ListAccountUsersRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *iam.ListAccountUsersRequest, +) - listCmd.Flags().StringVar(&listReq.Attributes, "attributes", listReq.Attributes, `Comma-separated list of attributes to return in response.`) - listCmd.Flags().IntVar(&listReq.Count, "count", listReq.Count, `Desired number of results per page.`) - listCmd.Flags().StringVar(&listReq.ExcludedAttributes, "excluded-attributes", listReq.ExcludedAttributes, `Comma-separated list of attributes to exclude in response.`) - listCmd.Flags().StringVar(&listReq.Filter, "filter", listReq.Filter, `Query by which the results have to be filtered.`) - listCmd.Flags().StringVar(&listReq.SortBy, "sort-by", listReq.SortBy, `Attribute to sort the results.`) - listCmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order to sort the results.`) - listCmd.Flags().IntVar(&listReq.StartIndex, "start-index", listReq.StartIndex, `Specifies the index of the first result.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq iam.ListAccountUsersRequest + var listJson flags.JsonFlag -var listCmd = &cobra.Command{ - Use: "list", - Short: `List users.`, - Long: `List users. + // TODO: short flags + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&listReq.Attributes, "attributes", listReq.Attributes, `Comma-separated list of attributes to return in response.`) + cmd.Flags().IntVar(&listReq.Count, "count", listReq.Count, `Desired number of results per page.`) + cmd.Flags().StringVar(&listReq.ExcludedAttributes, "excluded-attributes", listReq.ExcludedAttributes, `Comma-separated list of attributes to exclude in response.`) + cmd.Flags().StringVar(&listReq.Filter, "filter", listReq.Filter, `Query by which the results have to be filtered.`) + cmd.Flags().StringVar(&listReq.SortBy, "sort-by", listReq.SortBy, `Attribute to sort the results.`) + cmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order to sort the results.`) + cmd.Flags().IntVar(&listReq.StartIndex, "start-index", listReq.StartIndex, `Specifies the index of the first result.`) + + cmd.Use = "list" + cmd.Short = `List users.` + cmd.Long = `List users. - Gets details for all the users associated with a Databricks account.`, + Gets details for all the users associated with a Databricks account.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -250,37 +310,63 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start patch command -var patchReq iam.PartialUpdate -var patchJson flags.JsonFlag -func init() { - Cmd.AddCommand(patchCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var patchOverrides []func( + *cobra.Command, + *iam.PartialUpdate, +) + +func newPatch() *cobra.Command { + cmd := &cobra.Command{} + + var patchReq iam.PartialUpdate + var patchJson flags.JsonFlag + // TODO: short flags - patchCmd.Flags().Var(&patchJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&patchJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: Operations // TODO: array: schema -} - -var patchCmd = &cobra.Command{ - Use: "patch ID", - Short: `Update user details.`, - Long: `Update user details. + cmd.Use = "patch ID" + cmd.Short = `Update user details.` + cmd.Long = `Update user details. Partially updates a user resource by applying the supplied operations on - specific user attributes.`, + specific user attributes.` - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -290,23 +376,6 @@ var patchCmd = &cobra.Command{ return err } } - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Account Users drop-down." - names, err := a.Users.UserUserNameToIdMap(ctx, iam.ListAccountUsersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Account Users drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID for a user in the Databricks account") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id for a user in the databricks account") - } patchReq.Id = args[0] err = a.Users.Patch(ctx, patchReq) @@ -314,44 +383,73 @@ var patchCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range patchOverrides { + fn(cmd, &patchReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newPatch()) + }) } // start update command -var updateReq iam.User -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *iam.User, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq iam.User + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) - updateCmd.Flags().BoolVar(&updateReq.Active, "active", updateReq.Active, `If this user is active.`) - updateCmd.Flags().StringVar(&updateReq.DisplayName, "display-name", updateReq.DisplayName, `String that represents a concatenation of given and family names.`) + cmd.Flags().BoolVar(&updateReq.Active, "active", updateReq.Active, `If this user is active.`) + cmd.Flags().StringVar(&updateReq.DisplayName, "display-name", updateReq.DisplayName, `String that represents a concatenation of given and family names.`) // TODO: array: emails // TODO: array: entitlements - updateCmd.Flags().StringVar(&updateReq.ExternalId, "external-id", updateReq.ExternalId, ``) + cmd.Flags().StringVar(&updateReq.ExternalId, "external-id", updateReq.ExternalId, ``) // TODO: array: groups - updateCmd.Flags().StringVar(&updateReq.Id, "id", updateReq.Id, `Databricks user ID.`) + cmd.Flags().StringVar(&updateReq.Id, "id", updateReq.Id, `Databricks user ID.`) // TODO: complex arg: name // TODO: array: roles - updateCmd.Flags().StringVar(&updateReq.UserName, "user-name", updateReq.UserName, `Email address of the Databricks user.`) - -} + cmd.Flags().StringVar(&updateReq.UserName, "user-name", updateReq.UserName, `Email address of the Databricks user.`) -var updateCmd = &cobra.Command{ - Use: "update ID", - Short: `Replace a user.`, - Long: `Replace a user. + cmd.Use = "update ID" + cmd.Short = `Replace a user.` + cmd.Long = `Replace a user. - Replaces a user's information with the data supplied in request.`, + Replaces a user's information with the data supplied in request.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -361,23 +459,6 @@ var updateCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Account Users drop-down." - names, err := a.Users.UserUserNameToIdMap(ctx, iam.ListAccountUsersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Account Users drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Databricks user ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have databricks user id") - } updateReq.Id = args[0] } @@ -386,10 +467,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service AccountUsers diff --git a/cmd/account/vpc-endpoints/vpc-endpoints.go b/cmd/account/vpc-endpoints/vpc-endpoints.go index 80ed3831e4..d9c0f66642 100755 --- a/cmd/account/vpc-endpoints/vpc-endpoints.go +++ b/cmd/account/vpc-endpoints/vpc-endpoints.go @@ -3,8 +3,6 @@ package vpc_endpoints import ( - "fmt" - "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/flags" @@ -12,34 +10,54 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "vpc-endpoints", - Short: `These APIs manage VPC endpoint configurations for this account.`, - Long: `These APIs manage VPC endpoint configurations for this account.`, - Annotations: map[string]string{ - "package": "provisioning", - }, +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "vpc-endpoints", + Short: `These APIs manage VPC endpoint configurations for this account.`, + Long: `These APIs manage VPC endpoint configurations for this account.`, + GroupID: "provisioning", + Annotations: map[string]string{ + "package": "provisioning", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq provisioning.CreateVpcEndpointRequest -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *provisioning.CreateVpcEndpointRequest, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq provisioning.CreateVpcEndpointRequest + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createCmd.Flags().StringVar(&createReq.AwsVpcEndpointId, "aws-vpc-endpoint-id", createReq.AwsVpcEndpointId, `The ID of the VPC endpoint object in AWS.`) + cmd.Flags().StringVar(&createReq.AwsVpcEndpointId, "aws-vpc-endpoint-id", createReq.AwsVpcEndpointId, `The ID of the VPC endpoint object in AWS.`) // TODO: complex arg: gcp_vpc_endpoint_info - createCmd.Flags().StringVar(&createReq.Region, "region", createReq.Region, `The AWS region in which this VPC endpoint object exists.`) - -} + cmd.Flags().StringVar(&createReq.Region, "region", createReq.Region, `The AWS region in which this VPC endpoint object exists.`) -var createCmd = &cobra.Command{ - Use: "create VPC_ENDPOINT_NAME", - Short: `Create VPC endpoint configuration.`, - Long: `Create VPC endpoint configuration. + cmd.Use = "create VPC_ENDPOINT_NAME" + cmd.Short = `Create VPC endpoint configuration.` + cmd.Long = `Create VPC endpoint configuration. Creates a VPC endpoint configuration, which represents a [VPC endpoint] object in AWS used to communicate privately with Databricks over [AWS PrivateLink]. @@ -53,18 +71,20 @@ var createCmd = &cobra.Command{ [AWS PrivateLink]: https://aws.amazon.com/privatelink [Databricks article about PrivateLink]: https://docs.databricks.com/administration-guide/cloud-configurations/aws/privatelink.html [VPC endpoint]: https://docs.aws.amazon.com/vpc/latest/privatelink/vpc-endpoints.html - [endpoint service]: https://docs.aws.amazon.com/vpc/latest/privatelink/privatelink-share-your-services.html`, + [endpoint service]: https://docs.aws.amazon.com/vpc/latest/privatelink/privatelink-share-your-services.html` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -82,25 +102,45 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq provisioning.DeleteVpcEndpointRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *provisioning.DeleteVpcEndpointRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq provisioning.DeleteVpcEndpointRequest -var deleteCmd = &cobra.Command{ - Use: "delete VPC_ENDPOINT_ID", - Short: `Delete VPC endpoint configuration.`, - Long: `Delete VPC endpoint configuration. + // TODO: short flags + + cmd.Use = "delete VPC_ENDPOINT_ID" + cmd.Short = `Delete VPC endpoint configuration.` + cmd.Long = `Delete VPC endpoint configuration. Deletes a VPC endpoint configuration, which represents an [AWS VPC endpoint] that can communicate privately with Databricks over [AWS PrivateLink]. @@ -110,31 +150,20 @@ var deleteCmd = &cobra.Command{ [AWS PrivateLink]: https://aws.amazon.com/privatelink [AWS VPC endpoint]: https://docs.aws.amazon.com/vpc/latest/privatelink/concepts.html - [Databricks article about PrivateLink]: https://docs.databricks.com/administration-guide/cloud-configurations/aws/privatelink.html`, + [Databricks article about PrivateLink]: https://docs.databricks.com/administration-guide/cloud-configurations/aws/privatelink.html` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No VPC_ENDPOINT_ID argument specified. Loading names for Vpc Endpoints drop-down." - names, err := a.VpcEndpoints.VpcEndpointVpcEndpointNameToVpcEndpointIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Vpc Endpoints drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Databricks VPC endpoint ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have databricks vpc endpoint id") - } deleteReq.VpcEndpointId = args[0] err = a.VpcEndpoints.Delete(ctx, deleteReq) @@ -142,55 +171,64 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq provisioning.GetVpcEndpointRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *provisioning.GetVpcEndpointRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq provisioning.GetVpcEndpointRequest + + // TODO: short flags -var getCmd = &cobra.Command{ - Use: "get VPC_ENDPOINT_ID", - Short: `Get a VPC endpoint configuration.`, - Long: `Get a VPC endpoint configuration. + cmd.Use = "get VPC_ENDPOINT_ID" + cmd.Short = `Get a VPC endpoint configuration.` + cmd.Long = `Get a VPC endpoint configuration. Gets a VPC endpoint configuration, which represents a [VPC endpoint] object in AWS used to communicate privately with Databricks over [AWS PrivateLink]. [AWS PrivateLink]: https://aws.amazon.com/privatelink - [VPC endpoint]: https://docs.aws.amazon.com/vpc/latest/privatelink/concepts.html`, + [VPC endpoint]: https://docs.aws.amazon.com/vpc/latest/privatelink/concepts.html` - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No VPC_ENDPOINT_ID argument specified. Loading names for Vpc Endpoints drop-down." - names, err := a.VpcEndpoints.VpcEndpointVpcEndpointNameToVpcEndpointIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Vpc Endpoints drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Databricks VPC endpoint ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have databricks vpc endpoint id") - } getReq.VpcEndpointId = args[0] response, err := a.VpcEndpoints.Get(ctx, getReq) @@ -198,34 +236,52 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get all VPC endpoint configurations.`, - Long: `Get all VPC endpoint configurations. + cmd.Use = "list" + cmd.Short = `Get all VPC endpoint configurations.` + cmd.Long = `Get all VPC endpoint configurations. Gets a list of all VPC endpoints for an account, specified by ID. Before configuring PrivateLink, read the [Databricks article about PrivateLink]. - [Databricks article about PrivateLink]: https://docs.databricks.com/administration-guide/cloud-configurations/aws/privatelink.html`, + [Databricks article about PrivateLink]: https://docs.databricks.com/administration-guide/cloud-configurations/aws/privatelink.html` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) response, err := a.VpcEndpoints.List(ctx) @@ -233,10 +289,24 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // end service VpcEndpoints diff --git a/cmd/account/workspace-assignment/workspace-assignment.go b/cmd/account/workspace-assignment/workspace-assignment.go index dab3571223..9e8c140457 100755 --- a/cmd/account/workspace-assignment/workspace-assignment.go +++ b/cmd/account/workspace-assignment/workspace-assignment.go @@ -12,40 +12,62 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "workspace-assignment", - Short: `The Workspace Permission Assignment API allows you to manage workspace permissions for principals in your account.`, - Long: `The Workspace Permission Assignment API allows you to manage workspace +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "workspace-assignment", + Short: `The Workspace Permission Assignment API allows you to manage workspace permissions for principals in your account.`, + Long: `The Workspace Permission Assignment API allows you to manage workspace permissions for principals in your account.`, - Annotations: map[string]string{ - "package": "iam", - }, + GroupID: "iam", + Annotations: map[string]string{ + "package": "iam", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start delete command -var deleteReq iam.DeleteWorkspaceAssignmentRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *iam.DeleteWorkspaceAssignmentRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete WORKSPACE_ID PRINCIPAL_ID", - Short: `Delete permissions assignment.`, - Long: `Delete permissions assignment. + var deleteReq iam.DeleteWorkspaceAssignmentRequest + + // TODO: short flags + + cmd.Use = "delete WORKSPACE_ID PRINCIPAL_ID" + cmd.Short = `Delete permissions assignment.` + cmd.Long = `Delete permissions assignment. Deletes the workspace permissions assignment in a given account and workspace - for the specified principal.`, + for the specified principal.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -63,35 +85,57 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq iam.GetWorkspaceAssignmentRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *iam.GetWorkspaceAssignmentRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} -var getCmd = &cobra.Command{ - Use: "get WORKSPACE_ID", - Short: `List workspace permissions.`, - Long: `List workspace permissions. + var getReq iam.GetWorkspaceAssignmentRequest + + // TODO: short flags + + cmd.Use = "get WORKSPACE_ID" + cmd.Short = `List workspace permissions.` + cmd.Long = `List workspace permissions. - Get an array of workspace permissions for the specified account and workspace.`, + Get an array of workspace permissions for the specified account and workspace.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -105,36 +149,58 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq iam.ListWorkspaceAssignmentRequest -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *iam.ListWorkspaceAssignmentRequest, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list WORKSPACE_ID", - Short: `Get permission assignments.`, - Long: `Get permission assignments. + var listReq iam.ListWorkspaceAssignmentRequest + + // TODO: short flags + + cmd.Use = "list WORKSPACE_ID" + cmd.Short = `Get permission assignments.` + cmd.Long = `Get permission assignments. Get the permission assignments for the specified Databricks account and - Databricks workspace.`, + Databricks workspace.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -148,34 +214,55 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq iam.UpdateWorkspaceAssignments -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) - // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *iam.UpdateWorkspaceAssignments, +) -} +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq iam.UpdateWorkspaceAssignments + var updateJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var updateCmd = &cobra.Command{ - Use: "update", - Short: `Create or update permissions assignment.`, - Long: `Create or update permissions assignment. + cmd.Use = "update" + cmd.Short = `Create or update permissions assignment.` + cmd.Long = `Create or update permissions assignment. Creates or updates the workspace permissions assignment in a given account and - workspace for the specified principal.`, + workspace for the specified principal.` - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -193,10 +280,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service WorkspaceAssignment diff --git a/cmd/account/workspaces/overrides.go b/cmd/account/workspaces/overrides.go index 458950242d..283675c61a 100644 --- a/cmd/account/workspaces/overrides.go +++ b/cmd/account/workspaces/overrides.go @@ -1,9 +1,16 @@ package workspaces -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{range .}}{{green "%d" .WorkspaceId}} {{.WorkspaceName}} {{.WorkspaceStatus}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/account/workspaces/workspaces.go b/cmd/account/workspaces/workspaces.go index 833d3cc003..9edf179940 100755 --- a/cmd/account/workspaces/workspaces.go +++ b/cmd/account/workspaces/workspaces.go @@ -13,10 +13,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "workspaces", - Short: `These APIs manage workspaces for this account.`, - Long: `These APIs manage workspaces for this account. A Databricks workspace is an +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "workspaces", + Short: `These APIs manage workspaces for this account.`, + Long: `These APIs manage workspaces for this account. A Databricks workspace is an environment for accessing all of your Databricks assets. The workspace organizes objects (notebooks, libraries, and experiments) into folders, and provides access to data and computational resources such as clusters and jobs. @@ -24,45 +29,59 @@ var Cmd = &cobra.Command{ These endpoints are available if your account is on the E2 version of the platform or on a select custom plan that allows multiple workspaces per account.`, - Annotations: map[string]string{ - "package": "provisioning", - }, + GroupID: "provisioning", + Annotations: map[string]string{ + "package": "provisioning", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq provisioning.CreateWorkspaceRequest -var createJson flags.JsonFlag -var createSkipWait bool -var createTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *provisioning.CreateWorkspaceRequest, +) -func init() { - Cmd.AddCommand(createCmd) +func newCreate() *cobra.Command { + cmd := &cobra.Command{} - createCmd.Flags().BoolVar(&createSkipWait, "no-wait", createSkipWait, `do not wait to reach RUNNING state`) - createCmd.Flags().DurationVar(&createTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + var createReq provisioning.CreateWorkspaceRequest + var createJson flags.JsonFlag - createCmd.Flags().StringVar(&createReq.AwsRegion, "aws-region", createReq.AwsRegion, `The AWS region of the workspace's data plane.`) - createCmd.Flags().StringVar(&createReq.Cloud, "cloud", createReq.Cloud, `The cloud provider which the workspace uses.`) - // TODO: complex arg: cloud_resource_container - createCmd.Flags().StringVar(&createReq.CredentialsId, "credentials-id", createReq.CredentialsId, `ID of the workspace's credential configuration object.`) - createCmd.Flags().StringVar(&createReq.DeploymentName, "deployment-name", createReq.DeploymentName, `The deployment name defines part of the subdomain for the workspace.`) - createCmd.Flags().StringVar(&createReq.Location, "location", createReq.Location, `The Google Cloud region of the workspace data plane in your Google account.`) - createCmd.Flags().StringVar(&createReq.ManagedServicesCustomerManagedKeyId, "managed-services-customer-managed-key-id", createReq.ManagedServicesCustomerManagedKeyId, `The ID of the workspace's managed services encryption key configuration object.`) - createCmd.Flags().StringVar(&createReq.NetworkId, "network-id", createReq.NetworkId, ``) - createCmd.Flags().Var(&createReq.PricingTier, "pricing-tier", `The pricing tier of the workspace.`) - createCmd.Flags().StringVar(&createReq.PrivateAccessSettingsId, "private-access-settings-id", createReq.PrivateAccessSettingsId, `ID of the workspace's private access settings object.`) - createCmd.Flags().StringVar(&createReq.StorageConfigurationId, "storage-configuration-id", createReq.StorageConfigurationId, `The ID of the workspace's storage configuration object.`) - createCmd.Flags().StringVar(&createReq.StorageCustomerManagedKeyId, "storage-customer-managed-key-id", createReq.StorageCustomerManagedKeyId, `The ID of the workspace's storage encryption key configuration object.`) + var createSkipWait bool + var createTimeout time.Duration -} + cmd.Flags().BoolVar(&createSkipWait, "no-wait", createSkipWait, `do not wait to reach RUNNING state`) + cmd.Flags().DurationVar(&createTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var createCmd = &cobra.Command{ - Use: "create WORKSPACE_NAME", - Short: `Create a new workspace.`, - Long: `Create a new workspace. + cmd.Flags().StringVar(&createReq.AwsRegion, "aws-region", createReq.AwsRegion, `The AWS region of the workspace's data plane.`) + cmd.Flags().StringVar(&createReq.Cloud, "cloud", createReq.Cloud, `The cloud provider which the workspace uses.`) + // TODO: complex arg: cloud_resource_container + cmd.Flags().StringVar(&createReq.CredentialsId, "credentials-id", createReq.CredentialsId, `ID of the workspace's credential configuration object.`) + cmd.Flags().StringVar(&createReq.DeploymentName, "deployment-name", createReq.DeploymentName, `The deployment name defines part of the subdomain for the workspace.`) + cmd.Flags().StringVar(&createReq.Location, "location", createReq.Location, `The Google Cloud region of the workspace data plane in your Google account.`) + cmd.Flags().StringVar(&createReq.ManagedServicesCustomerManagedKeyId, "managed-services-customer-managed-key-id", createReq.ManagedServicesCustomerManagedKeyId, `The ID of the workspace's managed services encryption key configuration object.`) + cmd.Flags().StringVar(&createReq.NetworkId, "network-id", createReq.NetworkId, ``) + cmd.Flags().Var(&createReq.PricingTier, "pricing-tier", `The pricing tier of the workspace.`) + cmd.Flags().StringVar(&createReq.PrivateAccessSettingsId, "private-access-settings-id", createReq.PrivateAccessSettingsId, `ID of the workspace's private access settings object.`) + cmd.Flags().StringVar(&createReq.StorageConfigurationId, "storage-configuration-id", createReq.StorageConfigurationId, `The ID of the workspace's storage configuration object.`) + cmd.Flags().StringVar(&createReq.StorageCustomerManagedKeyId, "storage-customer-managed-key-id", createReq.StorageCustomerManagedKeyId, `The ID of the workspace's storage encryption key configuration object.`) + + cmd.Use = "create WORKSPACE_NAME" + cmd.Short = `Create a new workspace.` + cmd.Long = `Create a new workspace. Creates a new workspace. @@ -72,18 +91,20 @@ var createCmd = &cobra.Command{ workspace status is typically PROVISIONING. Use the workspace ID (workspace_id) field in the response to identify the new workspace and make repeated GET requests with the workspace ID and check its status. The - workspace becomes available when the status changes to RUNNING.`, + workspace becomes available when the status changes to RUNNING.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) @@ -113,25 +134,45 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq provisioning.DeleteWorkspaceRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *provisioning.DeleteWorkspaceRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete WORKSPACE_ID", - Short: `Delete a workspace.`, - Long: `Delete a workspace. + var deleteReq provisioning.DeleteWorkspaceRequest + + // TODO: short flags + + cmd.Use = "delete WORKSPACE_ID" + cmd.Short = `Delete a workspace.` + cmd.Long = `Delete a workspace. Terminates and deletes a Databricks workspace. From an API perspective, deletion is immediate. However, it might take a few minutes for all workspaces @@ -140,31 +181,20 @@ var deleteCmd = &cobra.Command{ This operation is available only if your account is on the E2 version of the platform or on a select custom plan that allows multiple workspaces per - account.`, + account.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No WORKSPACE_ID argument specified. Loading names for Workspaces drop-down." - names, err := a.Workspaces.WorkspaceWorkspaceNameToWorkspaceIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Workspaces drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Workspace ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have workspace id") - } _, err = fmt.Sscan(args[0], &deleteReq.WorkspaceId) if err != nil { return fmt.Errorf("invalid WORKSPACE_ID: %s", args[0]) @@ -175,25 +205,45 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq provisioning.GetWorkspaceRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *provisioning.GetWorkspaceRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq provisioning.GetWorkspaceRequest + + // TODO: short flags -var getCmd = &cobra.Command{ - Use: "get WORKSPACE_ID", - Short: `Get a workspace.`, - Long: `Get a workspace. + cmd.Use = "get WORKSPACE_ID" + cmd.Short = `Get a workspace.` + cmd.Long = `Get a workspace. Gets information including status for a Databricks workspace, specified by ID. In the response, the workspace_status field indicates the current status. @@ -208,31 +258,20 @@ var getCmd = &cobra.Command{ platform or on a select custom plan that allows multiple workspaces per account. - [Create a new workspace using the Account API]: http://docs.databricks.com/administration-guide/account-api/new-workspace.html`, + [Create a new workspace using the Account API]: http://docs.databricks.com/administration-guide/account-api/new-workspace.html` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No WORKSPACE_ID argument specified. Loading names for Workspaces drop-down." - names, err := a.Workspaces.WorkspaceWorkspaceNameToWorkspaceIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Workspaces drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Workspace ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have workspace id") - } _, err = fmt.Sscan(args[0], &getReq.WorkspaceId) if err != nil { return fmt.Errorf("invalid WORKSPACE_ID: %s", args[0]) @@ -243,33 +282,51 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get all workspaces.`, - Long: `Get all workspaces. + cmd.Use = "list" + cmd.Short = `Get all workspaces.` + cmd.Long = `Get all workspaces. Gets a list of all workspaces associated with an account, specified by ID. This operation is available only if your account is on the E2 version of the platform or on a select custom plan that allows multiple workspaces per - account.`, + account.` - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) response, err := a.Workspaces.List(ctx) @@ -277,38 +334,57 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq provisioning.UpdateWorkspaceRequest -var updateSkipWait bool -var updateTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *provisioning.UpdateWorkspaceRequest, +) -func init() { - Cmd.AddCommand(updateCmd) +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} - updateCmd.Flags().BoolVar(&updateSkipWait, "no-wait", updateSkipWait, `do not wait to reach RUNNING state`) - updateCmd.Flags().DurationVar(&updateTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) - // TODO: short flags + var updateReq provisioning.UpdateWorkspaceRequest - updateCmd.Flags().StringVar(&updateReq.AwsRegion, "aws-region", updateReq.AwsRegion, `The AWS region of the workspace's data plane (for example, us-west-2).`) - updateCmd.Flags().StringVar(&updateReq.CredentialsId, "credentials-id", updateReq.CredentialsId, `ID of the workspace's credential configuration object.`) - updateCmd.Flags().StringVar(&updateReq.ManagedServicesCustomerManagedKeyId, "managed-services-customer-managed-key-id", updateReq.ManagedServicesCustomerManagedKeyId, `The ID of the workspace's managed services encryption key configuration object.`) - updateCmd.Flags().StringVar(&updateReq.NetworkId, "network-id", updateReq.NetworkId, `The ID of the workspace's network configuration object.`) - updateCmd.Flags().StringVar(&updateReq.StorageConfigurationId, "storage-configuration-id", updateReq.StorageConfigurationId, `The ID of the workspace's storage configuration object.`) - updateCmd.Flags().StringVar(&updateReq.StorageCustomerManagedKeyId, "storage-customer-managed-key-id", updateReq.StorageCustomerManagedKeyId, `The ID of the key configuration object for workspace storage.`) + var updateSkipWait bool + var updateTimeout time.Duration -} + cmd.Flags().BoolVar(&updateSkipWait, "no-wait", updateSkipWait, `do not wait to reach RUNNING state`) + cmd.Flags().DurationVar(&updateTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) + // TODO: short flags -var updateCmd = &cobra.Command{ - Use: "update WORKSPACE_ID", - Short: `Update workspace configuration.`, - Long: `Update workspace configuration. + cmd.Flags().StringVar(&updateReq.AwsRegion, "aws-region", updateReq.AwsRegion, `The AWS region of the workspace's data plane (for example, us-west-2).`) + cmd.Flags().StringVar(&updateReq.CredentialsId, "credentials-id", updateReq.CredentialsId, `ID of the workspace's credential configuration object.`) + cmd.Flags().StringVar(&updateReq.ManagedServicesCustomerManagedKeyId, "managed-services-customer-managed-key-id", updateReq.ManagedServicesCustomerManagedKeyId, `The ID of the workspace's managed services encryption key configuration object.`) + cmd.Flags().StringVar(&updateReq.NetworkId, "network-id", updateReq.NetworkId, `The ID of the workspace's network configuration object.`) + cmd.Flags().StringVar(&updateReq.StorageConfigurationId, "storage-configuration-id", updateReq.StorageConfigurationId, `The ID of the workspace's storage configuration object.`) + cmd.Flags().StringVar(&updateReq.StorageCustomerManagedKeyId, "storage-customer-managed-key-id", updateReq.StorageCustomerManagedKeyId, `The ID of the key configuration object for workspace storage.`) + + cmd.Use = "update WORKSPACE_ID" + cmd.Short = `Update workspace configuration.` + cmd.Long = `Update workspace configuration. Updates a workspace configuration for either a running workspace or a failed workspace. The elements that can be updated varies between these two use @@ -420,31 +496,20 @@ var updateCmd = &cobra.Command{ account. [Account Console]: https://docs.databricks.com/administration-guide/account-settings-e2/account-console-e2.html - [Create a new workspace using the Account API]: http://docs.databricks.com/administration-guide/account-api/new-workspace.html`, + [Create a new workspace using the Account API]: http://docs.databricks.com/administration-guide/account-api/new-workspace.html` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustAccountClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustAccountClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() a := root.AccountClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No WORKSPACE_ID argument specified. Loading names for Workspaces drop-down." - names, err := a.Workspaces.WorkspaceWorkspaceNameToWorkspaceIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Workspaces drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Workspace ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have workspace id") - } _, err = fmt.Sscan(args[0], &updateReq.WorkspaceId) if err != nil { return fmt.Errorf("invalid WORKSPACE_ID: %s", args[0]) @@ -467,10 +532,24 @@ var updateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Workspaces diff --git a/cmd/cmd.go b/cmd/cmd.go new file mode 100644 index 0000000000..69502d5094 --- /dev/null +++ b/cmd/cmd.go @@ -0,0 +1,40 @@ +package cmd + +import ( + "sync" + + "github.com/databricks/cli/cmd/account" + "github.com/databricks/cli/cmd/root" + "github.com/databricks/cli/cmd/workspace" + "github.com/spf13/cobra" +) + +var once sync.Once +var cmd *cobra.Command + +func New() *cobra.Command { + // TODO: this command is still a global. + // Once the non-generated commands are all instantiatable, + // we can remove the global and instantiate this as well. + once.Do(func() { + cli := root.RootCmd + + // Add account subcommand. + cli.AddCommand(account.New()) + + // Add workspace subcommands. + for _, cmd := range workspace.All() { + cli.AddCommand(cmd) + } + + // Add workspace command groups. + groups := workspace.Groups() + for i := range groups { + cli.AddGroup(&groups[i]) + } + + cmd = cli + }) + + return cmd +} diff --git a/cmd/root/root.go b/cmd/root/root.go index 3b940a491c..663dd645fb 100644 --- a/cmd/root/root.go +++ b/cmd/root/root.go @@ -73,12 +73,12 @@ func flagErrorFunc(c *cobra.Command, err error) error { // Execute adds all child commands to the root command and sets flags appropriately. // This is called by main.main(). It only needs to happen once to the rootCmd. -func Execute() { +func Execute(cmd *cobra.Command) { // TODO: deferred panic recovery ctx := context.Background() // Run the command - cmd, err := RootCmd.ExecuteContextC(ctx) + cmd, err := cmd.ExecuteContextC(ctx) if err != nil { // If cmdio logger initialization succeeds, then this function logs with the // initialized cmdio logger, otherwise with the default cmdio logger diff --git a/cmd/workspace/alerts/alerts.go b/cmd/workspace/alerts/alerts.go index e13f728492..b96e240a66 100755 --- a/cmd/workspace/alerts/alerts.go +++ b/cmd/workspace/alerts/alerts.go @@ -12,45 +12,66 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "alerts", - Short: `The alerts API can be used to perform CRUD operations on alerts.`, - Long: `The alerts API can be used to perform CRUD operations on alerts. An alert is a +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "alerts", + Short: `The alerts API can be used to perform CRUD operations on alerts.`, + Long: `The alerts API can be used to perform CRUD operations on alerts. An alert is a Databricks SQL object that periodically runs a query, evaluates a condition of its result, and notifies one or more users and/or notification destinations if the condition was met. Alerts can be scheduled using the sql_task type of the Jobs API, e.g. :method:jobs/create.`, - Annotations: map[string]string{ - "package": "sql", - }, + GroupID: "sql", + Annotations: map[string]string{ + "package": "sql", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq sql.CreateAlert -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *sql.CreateAlert, +) - createCmd.Flags().StringVar(&createReq.Parent, "parent", createReq.Parent, `The identifier of the workspace folder containing the object.`) - createCmd.Flags().IntVar(&createReq.Rearm, "rearm", createReq.Rearm, `Number of seconds after being triggered before the alert rearms itself and can be triggered again.`) +func newCreate() *cobra.Command { + cmd := &cobra.Command{} -} + var createReq sql.CreateAlert + var createJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create an alert.`, - Long: `Create an alert. + cmd.Flags().StringVar(&createReq.Parent, "parent", createReq.Parent, `The identifier of the workspace folder containing the object.`) + cmd.Flags().IntVar(&createReq.Rearm, "rearm", createReq.Rearm, `Number of seconds after being triggered before the alert rearms itself and can be triggered again.`) + + cmd.Use = "create" + cmd.Short = `Create an alert.` + cmd.Long = `Create an alert. Creates an alert. An alert is a Databricks SQL object that periodically runs a query, evaluates a condition of its result, and notifies users or notification - destinations if the condition was met.`, + destinations if the condition was met.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -68,53 +89,62 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq sql.DeleteAlertRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *sql.DeleteAlertRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq sql.DeleteAlertRequest + + // TODO: short flags -var deleteCmd = &cobra.Command{ - Use: "delete ALERT_ID", - Short: `Delete an alert.`, - Long: `Delete an alert. + cmd.Use = "delete ALERT_ID" + cmd.Short = `Delete an alert.` + cmd.Long = `Delete an alert. Deletes an alert. Deleted alerts are no longer accessible and cannot be restored. **Note:** Unlike queries and dashboards, alerts cannot be moved to - the trash.`, + the trash.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ALERT_ID argument specified. Loading names for Alerts drop-down." - names, err := w.Alerts.AlertNameToIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Alerts drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have ") - } deleteReq.AlertId = args[0] err = w.Alerts.Delete(ctx, deleteReq) @@ -122,51 +152,60 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq sql.GetAlertRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *sql.GetAlertRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq sql.GetAlertRequest -var getCmd = &cobra.Command{ - Use: "get ALERT_ID", - Short: `Get an alert.`, - Long: `Get an alert. + // TODO: short flags + + cmd.Use = "get ALERT_ID" + cmd.Short = `Get an alert.` + cmd.Long = `Get an alert. - Gets an alert.`, + Gets an alert.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ALERT_ID argument specified. Loading names for Alerts drop-down." - names, err := w.Alerts.AlertNameToIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Alerts drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have ") - } getReq.AlertId = args[0] response, err := w.Alerts.Get(ctx, getReq) @@ -174,29 +213,47 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get alerts.`, - Long: `Get alerts. + cmd.Use = "list" + cmd.Short = `Get alerts.` + cmd.Long = `Get alerts. - Gets a list of alerts.`, + Gets a list of alerts.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.Alerts.List(ctx) @@ -204,35 +261,56 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq sql.EditAlert -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) - // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *sql.EditAlert, +) - updateCmd.Flags().IntVar(&updateReq.Rearm, "rearm", updateReq.Rearm, `Number of seconds after being triggered before the alert rearms itself and can be triggered again.`) +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} -} + var updateReq sql.EditAlert + var updateJson flags.JsonFlag -var updateCmd = &cobra.Command{ - Use: "update", - Short: `Update an alert.`, - Long: `Update an alert. + // TODO: short flags + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().IntVar(&updateReq.Rearm, "rearm", updateReq.Rearm, `Number of seconds after being triggered before the alert rearms itself and can be triggered again.`) + + cmd.Use = "update" + cmd.Short = `Update an alert.` + cmd.Long = `Update an alert. - Updates an alert.`, + Updates an alert.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -250,10 +328,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Alerts diff --git a/cmd/workspace/catalogs/catalogs.go b/cmd/workspace/catalogs/catalogs.go index 78b8b14996..2c520e4da1 100755 --- a/cmd/workspace/catalogs/catalogs.go +++ b/cmd/workspace/catalogs/catalogs.go @@ -10,10 +10,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "catalogs", - Short: `A catalog is the first layer of Unity Catalog’s three-level namespace.`, - Long: `A catalog is the first layer of Unity Catalog’s three-level namespace. +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "catalogs", + Short: `A catalog is the first layer of Unity Catalog’s three-level namespace.`, + Long: `A catalog is the first layer of Unity Catalog’s three-level namespace. It’s used to organize your data assets. Users can see all catalogs on which they have been assigned the USE_CATALOG data permission. @@ -21,46 +26,63 @@ var Cmd = &cobra.Command{ data centrally across all of the workspaces in a Databricks account. Users in different workspaces can share access to the same data, depending on privileges granted centrally in Unity Catalog.`, - Annotations: map[string]string{ - "package": "catalog", - }, + GroupID: "catalog", + Annotations: map[string]string{ + "package": "catalog", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq catalog.CreateCatalog -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *catalog.CreateCatalog, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq catalog.CreateCatalog + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createCmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `User-provided free-form text description.`) + cmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `User-provided free-form text description.`) // TODO: map via StringToStringVar: properties - createCmd.Flags().StringVar(&createReq.ProviderName, "provider-name", createReq.ProviderName, `The name of delta sharing provider.`) - createCmd.Flags().StringVar(&createReq.ShareName, "share-name", createReq.ShareName, `The name of the share under the share provider.`) - createCmd.Flags().StringVar(&createReq.StorageRoot, "storage-root", createReq.StorageRoot, `Storage root URL for managed tables within catalog.`) + cmd.Flags().StringVar(&createReq.ProviderName, "provider-name", createReq.ProviderName, `The name of delta sharing provider.`) + cmd.Flags().StringVar(&createReq.ShareName, "share-name", createReq.ShareName, `The name of the share under the share provider.`) + cmd.Flags().StringVar(&createReq.StorageRoot, "storage-root", createReq.StorageRoot, `Storage root URL for managed tables within catalog.`) -} - -var createCmd = &cobra.Command{ - Use: "create NAME", - Short: `Create a catalog.`, - Long: `Create a catalog. + cmd.Use = "create NAME" + cmd.Short = `Create a catalog.` + cmd.Long = `Create a catalog. Creates a new catalog instance in the parent metastore if the caller is a - metastore admin or has the **CREATE_CATALOG** privilege.`, + metastore admin or has the **CREATE_CATALOG** privilege.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -78,38 +100,60 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq catalog.DeleteCatalogRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *catalog.DeleteCatalogRequest, +) - deleteCmd.Flags().BoolVar(&deleteReq.Force, "force", deleteReq.Force, `Force deletion even if the catalog is not empty.`) +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -} + var deleteReq catalog.DeleteCatalogRequest + + // TODO: short flags -var deleteCmd = &cobra.Command{ - Use: "delete NAME", - Short: `Delete a catalog.`, - Long: `Delete a catalog. + cmd.Flags().BoolVar(&deleteReq.Force, "force", deleteReq.Force, `Force deletion even if the catalog is not empty.`) + + cmd.Use = "delete NAME" + cmd.Short = `Delete a catalog.` + cmd.Long = `Delete a catalog. Deletes the catalog that matches the supplied name. The caller must be a - metastore admin or the owner of the catalog.`, + metastore admin or the owner of the catalog.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -120,37 +164,59 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq catalog.GetCatalogRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *catalog.GetCatalogRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq catalog.GetCatalogRequest -var getCmd = &cobra.Command{ - Use: "get NAME", - Short: `Get a catalog.`, - Long: `Get a catalog. + // TODO: short flags + + cmd.Use = "get NAME" + cmd.Short = `Get a catalog.` + cmd.Long = `Get a catalog. Gets the specified catalog in a metastore. The caller must be a metastore admin, the owner of the catalog, or a user that has the **USE_CATALOG** - privilege set for their account.`, + privilege set for their account.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -161,33 +227,51 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `List catalogs.`, - Long: `List catalogs. + cmd.Use = "list" + cmd.Short = `List catalogs.` + cmd.Long = `List catalogs. Gets an array of catalogs in the metastore. If the caller is the metastore admin, all catalogs will be retrieved. Otherwise, only catalogs owned by the caller (or for which the caller has the **USE_CATALOG** privilege) will be retrieved. There is no guarantee of a specific ordering of the elements in the - array.`, + array.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.Catalogs.ListAll(ctx) @@ -195,48 +279,70 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq catalog.UpdateCatalog -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *catalog.UpdateCatalog, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq catalog.UpdateCatalog + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) - updateCmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `User-provided free-form text description.`) - updateCmd.Flags().Var(&updateReq.IsolationMode, "isolation-mode", `Whether the current securable is accessible from all workspaces or a specific set of workspaces.`) - updateCmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `Name of catalog.`) - updateCmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `Username of current owner of catalog.`) + cmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `User-provided free-form text description.`) + cmd.Flags().Var(&updateReq.IsolationMode, "isolation-mode", `Whether the current securable is accessible from all workspaces or a specific set of workspaces.`) + cmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `Name of catalog.`) + cmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `Username of current owner of catalog.`) // TODO: map via StringToStringVar: properties -} - -var updateCmd = &cobra.Command{ - Use: "update NAME", - Short: `Update a catalog.`, - Long: `Update a catalog. + cmd.Use = "update NAME" + cmd.Short = `Update a catalog.` + cmd.Long = `Update a catalog. Updates the catalog that matches the supplied name. The caller must be either the owner of the catalog, or a metastore admin (when changing the owner field - of the catalog).`, + of the catalog).` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -254,10 +360,24 @@ var updateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Catalogs diff --git a/cmd/workspace/catalogs/overrides.go b/cmd/workspace/catalogs/overrides.go index 5b8cffea94..6de7a7771b 100644 --- a/cmd/workspace/catalogs/overrides.go +++ b/cmd/workspace/catalogs/overrides.go @@ -1,10 +1,17 @@ package catalogs -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{header "Name"}} {{header "Type"}} {{header "Comment"}} {{range .}}{{.Name|green}} {{blue "%s" .CatalogType}} {{.Comment}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/workspace/clean-rooms/clean-rooms.go b/cmd/workspace/clean-rooms/clean-rooms.go index 328ed3e73f..5aa704fa4a 100755 --- a/cmd/workspace/clean-rooms/clean-rooms.go +++ b/cmd/workspace/clean-rooms/clean-rooms.go @@ -12,47 +12,68 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "clean-rooms", - Short: `A clean room is a secure, privacy-protecting environment where two or more parties can share sensitive enterprise data, including customer data, for measurements, insights, activation and other use cases.`, - Long: `A clean room is a secure, privacy-protecting environment where two or more +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "clean-rooms", + Short: `A clean room is a secure, privacy-protecting environment where two or more parties can share sensitive enterprise data, including customer data, for measurements, insights, activation and other use cases.`, + Long: `A clean room is a secure, privacy-protecting environment where two or more parties can share sensitive enterprise data, including customer data, for measurements, insights, activation and other use cases. To create clean rooms, you must be a metastore admin or a user with the **CREATE_CLEAN_ROOM** privilege.`, - Annotations: map[string]string{ - "package": "sharing", - }, + GroupID: "sharing", + Annotations: map[string]string{ + "package": "sharing", + }, - // This service is being previewed; hide from help output. - Hidden: true, + // This service is being previewed; hide from help output. + Hidden: true, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq sharing.CreateCleanRoom -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *sharing.CreateCleanRoom, +) - createCmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `User-provided free-form text description.`) +func newCreate() *cobra.Command { + cmd := &cobra.Command{} -} + var createReq sharing.CreateCleanRoom + var createJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `User-provided free-form text description.`) -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a clean room.`, - Long: `Create a clean room. + cmd.Use = "create" + cmd.Short = `Create a clean room.` + cmd.Long = `Create a clean room. Creates a new clean room with specified colaborators. The caller must be a - metastore admin or have the **CREATE_CLEAN_ROOM** privilege on the metastore.`, + metastore admin or have the **CREATE_CLEAN_ROOM** privilege on the metastore.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -70,36 +91,58 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq sharing.DeleteCleanRoomRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *sharing.DeleteCleanRoomRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq sharing.DeleteCleanRoomRequest + + // TODO: short flags -var deleteCmd = &cobra.Command{ - Use: "delete NAME_ARG", - Short: `Delete a clean room.`, - Long: `Delete a clean room. + cmd.Use = "delete NAME_ARG" + cmd.Short = `Delete a clean room.` + cmd.Long = `Delete a clean room. Deletes a data object clean room from the metastore. The caller must be an - owner of the clean room.`, + owner of the clean room.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -110,38 +153,60 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq sharing.GetCleanRoomRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *sharing.GetCleanRoomRequest, +) - getCmd.Flags().BoolVar(&getReq.IncludeRemoteDetails, "include-remote-details", getReq.IncludeRemoteDetails, `Whether to include remote details (central) on the clean room.`) +func newGet() *cobra.Command { + cmd := &cobra.Command{} -} + var getReq sharing.GetCleanRoomRequest -var getCmd = &cobra.Command{ - Use: "get NAME_ARG", - Short: `Get a clean room.`, - Long: `Get a clean room. + // TODO: short flags + + cmd.Flags().BoolVar(&getReq.IncludeRemoteDetails, "include-remote-details", getReq.IncludeRemoteDetails, `Whether to include remote details (central) on the clean room.`) + + cmd.Use = "get NAME_ARG" + cmd.Short = `Get a clean room.` + cmd.Long = `Get a clean room. Gets a data object clean room from the metastore. The caller must be a - metastore admin or the owner of the clean room.`, + metastore admin or the owner of the clean room.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -152,31 +217,49 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `List clean rooms.`, - Long: `List clean rooms. + cmd.Use = "list" + cmd.Short = `List clean rooms.` + cmd.Long = `List clean rooms. Gets an array of data object clean rooms from the metastore. The caller must be a metastore admin or the owner of the clean room. There is no guarantee of - a specific ordering of the elements in the array.`, + a specific ordering of the elements in the array.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.CleanRooms.ListAll(ctx) @@ -184,32 +267,52 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq sharing.UpdateCleanRoom -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *sharing.UpdateCleanRoom, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq sharing.UpdateCleanRoom + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: catalog_updates - updateCmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `User-provided free-form text description.`) - updateCmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `Name of the clean room.`) - updateCmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `Username of current owner of clean room.`) - -} + cmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `User-provided free-form text description.`) + cmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `Name of the clean room.`) + cmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `Username of current owner of clean room.`) -var updateCmd = &cobra.Command{ - Use: "update NAME_ARG", - Short: `Update a clean room.`, - Long: `Update a clean room. + cmd.Use = "update NAME_ARG" + cmd.Short = `Update a clean room.` + cmd.Long = `Update a clean room. Updates the clean room with the changes and data objects in the request. The caller must be the owner of the clean room or a metastore admin. @@ -224,15 +327,17 @@ var updateCmd = &cobra.Command{ indefinitely for recipients to be able to access the table. Typically, you should use a group as the clean room owner. - Table removals through **update** do not require additional privileges.`, + Table removals through **update** do not require additional privileges.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -249,10 +354,24 @@ var updateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service CleanRooms diff --git a/cmd/workspace/cluster-policies/cluster-policies.go b/cmd/workspace/cluster-policies/cluster-policies.go index 1f1d36c1db..c4f00e52b2 100755 --- a/cmd/workspace/cluster-policies/cluster-policies.go +++ b/cmd/workspace/cluster-policies/cluster-policies.go @@ -3,8 +3,6 @@ package cluster_policies import ( - "fmt" - "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/flags" @@ -12,10 +10,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "cluster-policies", - Short: `Cluster policy limits the ability to configure clusters based on a set of rules.`, - Long: `Cluster policy limits the ability to configure clusters based on a set of +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "cluster-policies", + Short: `Cluster policy limits the ability to configure clusters based on a set of rules.`, + Long: `Cluster policy limits the ability to configure clusters based on a set of rules. The policy rules limit the attributes or attribute values available for cluster creation. Cluster policies have ACLs that limit their use to specific users and groups. @@ -39,45 +42,62 @@ var Cmd = &cobra.Command{ Only admin users can create, edit, and delete policies. Admin users also have access to all policies.`, - Annotations: map[string]string{ - "package": "compute", - }, + GroupID: "compute", + Annotations: map[string]string{ + "package": "compute", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq compute.CreatePolicy -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *compute.CreatePolicy, +) - createCmd.Flags().StringVar(&createReq.Definition, "definition", createReq.Definition, `Policy definition document expressed in Databricks Cluster Policy Definition Language.`) - createCmd.Flags().StringVar(&createReq.Description, "description", createReq.Description, `Additional human-readable description of the cluster policy.`) - createCmd.Flags().Int64Var(&createReq.MaxClustersPerUser, "max-clusters-per-user", createReq.MaxClustersPerUser, `Max number of clusters per user that can be active using this policy.`) - createCmd.Flags().StringVar(&createReq.PolicyFamilyDefinitionOverrides, "policy-family-definition-overrides", createReq.PolicyFamilyDefinitionOverrides, `Policy definition JSON document expressed in Databricks Policy Definition Language.`) - createCmd.Flags().StringVar(&createReq.PolicyFamilyId, "policy-family-id", createReq.PolicyFamilyId, `ID of the policy family.`) +func newCreate() *cobra.Command { + cmd := &cobra.Command{} -} + var createReq compute.CreatePolicy + var createJson flags.JsonFlag -var createCmd = &cobra.Command{ - Use: "create NAME", - Short: `Create a new policy.`, - Long: `Create a new policy. + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&createReq.Definition, "definition", createReq.Definition, `Policy definition document expressed in Databricks Cluster Policy Definition Language.`) + cmd.Flags().StringVar(&createReq.Description, "description", createReq.Description, `Additional human-readable description of the cluster policy.`) + cmd.Flags().Int64Var(&createReq.MaxClustersPerUser, "max-clusters-per-user", createReq.MaxClustersPerUser, `Max number of clusters per user that can be active using this policy.`) + cmd.Flags().StringVar(&createReq.PolicyFamilyDefinitionOverrides, "policy-family-definition-overrides", createReq.PolicyFamilyDefinitionOverrides, `Policy definition JSON document expressed in Databricks Policy Definition Language.`) + cmd.Flags().StringVar(&createReq.PolicyFamilyId, "policy-family-id", createReq.PolicyFamilyId, `ID of the policy family.`) + + cmd.Use = "create NAME" + cmd.Short = `Create a new policy.` + cmd.Long = `Create a new policy. - Creates a new policy with prescribed settings.`, + Creates a new policy with prescribed settings.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -95,34 +115,63 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq compute.DeletePolicy -var deleteJson flags.JsonFlag -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags - deleteCmd.Flags().Var(&deleteJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *compute.DeletePolicy, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq compute.DeletePolicy + var deleteJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&deleteJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var deleteCmd = &cobra.Command{ - Use: "delete POLICY_ID", - Short: `Delete a cluster policy.`, - Long: `Delete a cluster policy. + cmd.Use = "delete POLICY_ID" + cmd.Short = `Delete a cluster policy.` + cmd.Long = `Delete a cluster policy. Delete a policy for a cluster. Clusters governed by this policy can still run, - but cannot be edited.`, + but cannot be edited.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -132,23 +181,6 @@ var deleteCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No POLICY_ID argument specified. Loading names for Cluster Policies drop-down." - names, err := w.ClusterPolicies.PolicyNameToPolicyIdMap(ctx, compute.ListClusterPoliciesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Cluster Policies drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The ID of the policy to delete") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the id of the policy to delete") - } deleteReq.PolicyId = args[0] } @@ -157,47 +189,69 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start edit command -var editReq compute.EditPolicy -var editJson flags.JsonFlag -func init() { - Cmd.AddCommand(editCmd) - // TODO: short flags - editCmd.Flags().Var(&editJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var editOverrides []func( + *cobra.Command, + *compute.EditPolicy, +) - editCmd.Flags().StringVar(&editReq.Definition, "definition", editReq.Definition, `Policy definition document expressed in Databricks Cluster Policy Definition Language.`) - editCmd.Flags().StringVar(&editReq.Description, "description", editReq.Description, `Additional human-readable description of the cluster policy.`) - editCmd.Flags().Int64Var(&editReq.MaxClustersPerUser, "max-clusters-per-user", editReq.MaxClustersPerUser, `Max number of clusters per user that can be active using this policy.`) - editCmd.Flags().StringVar(&editReq.PolicyFamilyDefinitionOverrides, "policy-family-definition-overrides", editReq.PolicyFamilyDefinitionOverrides, `Policy definition JSON document expressed in Databricks Policy Definition Language.`) - editCmd.Flags().StringVar(&editReq.PolicyFamilyId, "policy-family-id", editReq.PolicyFamilyId, `ID of the policy family.`) +func newEdit() *cobra.Command { + cmd := &cobra.Command{} -} + var editReq compute.EditPolicy + var editJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&editJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var editCmd = &cobra.Command{ - Use: "edit POLICY_ID NAME", - Short: `Update a cluster policy.`, - Long: `Update a cluster policy. + cmd.Flags().StringVar(&editReq.Definition, "definition", editReq.Definition, `Policy definition document expressed in Databricks Cluster Policy Definition Language.`) + cmd.Flags().StringVar(&editReq.Description, "description", editReq.Description, `Additional human-readable description of the cluster policy.`) + cmd.Flags().Int64Var(&editReq.MaxClustersPerUser, "max-clusters-per-user", editReq.MaxClustersPerUser, `Max number of clusters per user that can be active using this policy.`) + cmd.Flags().StringVar(&editReq.PolicyFamilyDefinitionOverrides, "policy-family-definition-overrides", editReq.PolicyFamilyDefinitionOverrides, `Policy definition JSON document expressed in Databricks Policy Definition Language.`) + cmd.Flags().StringVar(&editReq.PolicyFamilyId, "policy-family-id", editReq.PolicyFamilyId, `ID of the policy family.`) + + cmd.Use = "edit POLICY_ID NAME" + cmd.Short = `Update a cluster policy.` + cmd.Long = `Update a cluster policy. Update an existing policy for cluster. This operation may make some clusters - governed by the previous policy invalid.`, + governed by the previous policy invalid.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -216,51 +270,60 @@ var editCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range editOverrides { + fn(cmd, &editReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newEdit()) + }) } // start get command -var getReq compute.GetClusterPolicyRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *compute.GetClusterPolicyRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq compute.GetClusterPolicyRequest -var getCmd = &cobra.Command{ - Use: "get POLICY_ID", - Short: `Get entity.`, - Long: `Get entity. + // TODO: short flags + + cmd.Use = "get POLICY_ID" + cmd.Short = `Get entity.` + cmd.Long = `Get entity. - Get a cluster policy entity. Creation and editing is available to admins only.`, + Get a cluster policy entity. Creation and editing is available to admins only.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No POLICY_ID argument specified. Loading names for Cluster Policies drop-down." - names, err := w.ClusterPolicies.PolicyNameToPolicyIdMap(ctx, compute.ListClusterPoliciesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Cluster Policies drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Canonical unique identifier for the cluster policy") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have canonical unique identifier for the cluster policy") - } getReq.PolicyId = args[0] response, err := w.ClusterPolicies.Get(ctx, getReq) @@ -268,43 +331,65 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq compute.ListClusterPoliciesRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *compute.ListClusterPoliciesRequest, +) - listCmd.Flags().Var(&listReq.SortColumn, "sort-column", `The cluster policy attribute to sort by.`) - listCmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order in which the policies get listed.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq compute.ListClusterPoliciesRequest + var listJson flags.JsonFlag -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get a cluster policy.`, - Long: `Get a cluster policy. + // TODO: short flags + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().Var(&listReq.SortColumn, "sort-column", `The cluster policy attribute to sort by.`) + cmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order in which the policies get listed.`) + + cmd.Use = "list" + cmd.Short = `Get a cluster policy.` + cmd.Long = `Get a cluster policy. - Returns a list of policies accessible by the requesting user.`, + Returns a list of policies accessible by the requesting user.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -321,10 +406,24 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // end service ClusterPolicies diff --git a/cmd/workspace/cluster-policies/overrides.go b/cmd/workspace/cluster-policies/overrides.go index dea5c6bfc7..9278b29c39 100644 --- a/cmd/workspace/cluster-policies/overrides.go +++ b/cmd/workspace/cluster-policies/overrides.go @@ -1,11 +1,22 @@ package cluster_policies -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/databricks-sdk-go/service/compute" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command, _ *compute.ListClusterPoliciesRequest) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{range .}}{{.PolicyId | green}} {{.Name}} {{end}}`) +} +func getOverride(getCmd *cobra.Command, _ *compute.GetClusterPolicyRequest) { getCmd.Annotations["template"] = cmdio.Heredoc(`{{.Definition | pretty_json}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) + getOverrides = append(getOverrides, getOverride) +} diff --git a/cmd/workspace/clusters/clusters.go b/cmd/workspace/clusters/clusters.go index bc891eef79..432fbff4df 100755 --- a/cmd/workspace/clusters/clusters.go +++ b/cmd/workspace/clusters/clusters.go @@ -3,7 +3,6 @@ package clusters import ( - "fmt" "time" "github.com/databricks/cli/cmd/root" @@ -13,10 +12,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "clusters", - Short: `The Clusters API allows you to create, start, edit, list, terminate, and delete clusters.`, - Long: `The Clusters API allows you to create, start, edit, list, terminate, and +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "clusters", + Short: `The Clusters API allows you to create, start, edit, list, terminate, and delete clusters.`, + Long: `The Clusters API allows you to create, start, edit, list, terminate, and delete clusters. Databricks maps cluster node instance types to compute units known as DBUs. @@ -43,40 +47,57 @@ var Cmd = &cobra.Command{ recently terminated by the job scheduler. To keep an all-purpose cluster configuration even after it has been terminated for more than 30 days, an administrator can pin a cluster to the cluster list.`, - Annotations: map[string]string{ - "package": "compute", - }, + GroupID: "compute", + Annotations: map[string]string{ + "package": "compute", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start change-owner command -var changeOwnerReq compute.ChangeClusterOwner -var changeOwnerJson flags.JsonFlag -func init() { - Cmd.AddCommand(changeOwnerCmd) - // TODO: short flags - changeOwnerCmd.Flags().Var(&changeOwnerJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var changeOwnerOverrides []func( + *cobra.Command, + *compute.ChangeClusterOwner, +) -} +func newChangeOwner() *cobra.Command { + cmd := &cobra.Command{} -var changeOwnerCmd = &cobra.Command{ - Use: "change-owner CLUSTER_ID OWNER_USERNAME", - Short: `Change cluster owner.`, - Long: `Change cluster owner. + var changeOwnerReq compute.ChangeClusterOwner + var changeOwnerJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&changeOwnerJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "change-owner CLUSTER_ID OWNER_USERNAME" + cmd.Short = `Change cluster owner.` + cmd.Long = `Change cluster owner. Change the owner of the cluster. You must be an admin to perform this - operation.`, + operation.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -95,58 +116,77 @@ var changeOwnerCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range changeOwnerOverrides { + fn(cmd, &changeOwnerReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newChangeOwner()) + }) } // start create command -var createReq compute.CreateCluster -var createJson flags.JsonFlag -var createSkipWait bool -var createTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *compute.CreateCluster, +) -func init() { - Cmd.AddCommand(createCmd) +func newCreate() *cobra.Command { + cmd := &cobra.Command{} - createCmd.Flags().BoolVar(&createSkipWait, "no-wait", createSkipWait, `do not wait to reach RUNNING state`) - createCmd.Flags().DurationVar(&createTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) + var createReq compute.CreateCluster + var createJson flags.JsonFlag + + var createSkipWait bool + var createTimeout time.Duration + + cmd.Flags().BoolVar(&createSkipWait, "no-wait", createSkipWait, `do not wait to reach RUNNING state`) + cmd.Flags().DurationVar(&createTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createCmd.Flags().BoolVar(&createReq.ApplyPolicyDefaultValues, "apply-policy-default-values", createReq.ApplyPolicyDefaultValues, `Note: This field won't be true for webapp requests.`) + cmd.Flags().BoolVar(&createReq.ApplyPolicyDefaultValues, "apply-policy-default-values", createReq.ApplyPolicyDefaultValues, `Note: This field won't be true for webapp requests.`) // TODO: complex arg: autoscale - createCmd.Flags().IntVar(&createReq.AutoterminationMinutes, "autotermination-minutes", createReq.AutoterminationMinutes, `Automatically terminates the cluster after it is inactive for this time in minutes.`) + cmd.Flags().IntVar(&createReq.AutoterminationMinutes, "autotermination-minutes", createReq.AutoterminationMinutes, `Automatically terminates the cluster after it is inactive for this time in minutes.`) // TODO: complex arg: aws_attributes // TODO: complex arg: azure_attributes // TODO: complex arg: cluster_log_conf - createCmd.Flags().StringVar(&createReq.ClusterName, "cluster-name", createReq.ClusterName, `Cluster name requested by the user.`) - createCmd.Flags().Var(&createReq.ClusterSource, "cluster-source", `Determines whether the cluster was created by a user through the UI, created by the Databricks Jobs Scheduler, or through an API request.`) + cmd.Flags().StringVar(&createReq.ClusterName, "cluster-name", createReq.ClusterName, `Cluster name requested by the user.`) + cmd.Flags().Var(&createReq.ClusterSource, "cluster-source", `Determines whether the cluster was created by a user through the UI, created by the Databricks Jobs Scheduler, or through an API request.`) // TODO: map via StringToStringVar: custom_tags - createCmd.Flags().StringVar(&createReq.DriverInstancePoolId, "driver-instance-pool-id", createReq.DriverInstancePoolId, `The optional ID of the instance pool for the driver of the cluster belongs.`) - createCmd.Flags().StringVar(&createReq.DriverNodeTypeId, "driver-node-type-id", createReq.DriverNodeTypeId, `The node type of the Spark driver.`) - createCmd.Flags().BoolVar(&createReq.EnableElasticDisk, "enable-elastic-disk", createReq.EnableElasticDisk, `Autoscaling Local Storage: when enabled, this cluster will dynamically acquire additional disk space when its Spark workers are running low on disk space.`) - createCmd.Flags().BoolVar(&createReq.EnableLocalDiskEncryption, "enable-local-disk-encryption", createReq.EnableLocalDiskEncryption, `Whether to enable LUKS on cluster VMs' local disks.`) + cmd.Flags().StringVar(&createReq.DriverInstancePoolId, "driver-instance-pool-id", createReq.DriverInstancePoolId, `The optional ID of the instance pool for the driver of the cluster belongs.`) + cmd.Flags().StringVar(&createReq.DriverNodeTypeId, "driver-node-type-id", createReq.DriverNodeTypeId, `The node type of the Spark driver.`) + cmd.Flags().BoolVar(&createReq.EnableElasticDisk, "enable-elastic-disk", createReq.EnableElasticDisk, `Autoscaling Local Storage: when enabled, this cluster will dynamically acquire additional disk space when its Spark workers are running low on disk space.`) + cmd.Flags().BoolVar(&createReq.EnableLocalDiskEncryption, "enable-local-disk-encryption", createReq.EnableLocalDiskEncryption, `Whether to enable LUKS on cluster VMs' local disks.`) // TODO: complex arg: gcp_attributes // TODO: array: init_scripts - createCmd.Flags().StringVar(&createReq.InstancePoolId, "instance-pool-id", createReq.InstancePoolId, `The optional ID of the instance pool to which the cluster belongs.`) - createCmd.Flags().StringVar(&createReq.NodeTypeId, "node-type-id", createReq.NodeTypeId, `This field encodes, through a single value, the resources available to each of the Spark nodes in this cluster.`) - createCmd.Flags().IntVar(&createReq.NumWorkers, "num-workers", createReq.NumWorkers, `Number of worker nodes that this cluster should have.`) - createCmd.Flags().StringVar(&createReq.PolicyId, "policy-id", createReq.PolicyId, `The ID of the cluster policy used to create the cluster if applicable.`) - createCmd.Flags().Var(&createReq.RuntimeEngine, "runtime-engine", `Decides which runtime engine to be use, e.g.`) + cmd.Flags().StringVar(&createReq.InstancePoolId, "instance-pool-id", createReq.InstancePoolId, `The optional ID of the instance pool to which the cluster belongs.`) + cmd.Flags().StringVar(&createReq.NodeTypeId, "node-type-id", createReq.NodeTypeId, `This field encodes, through a single value, the resources available to each of the Spark nodes in this cluster.`) + cmd.Flags().IntVar(&createReq.NumWorkers, "num-workers", createReq.NumWorkers, `Number of worker nodes that this cluster should have.`) + cmd.Flags().StringVar(&createReq.PolicyId, "policy-id", createReq.PolicyId, `The ID of the cluster policy used to create the cluster if applicable.`) + cmd.Flags().Var(&createReq.RuntimeEngine, "runtime-engine", `Decides which runtime engine to be use, e.g.`) // TODO: map via StringToStringVar: spark_conf // TODO: map via StringToStringVar: spark_env_vars // TODO: array: ssh_public_keys // TODO: complex arg: workload_type -} - -var createCmd = &cobra.Command{ - Use: "create SPARK_VERSION", - Short: `Create new cluster.`, - Long: `Create new cluster. + cmd.Use = "create SPARK_VERSION" + cmd.Short = `Create new cluster.` + cmd.Long = `Create new cluster. Creates a new Spark cluster. This method will acquire new instances from the cloud provider if necessary. Note: Databricks may not be able to acquire some @@ -155,18 +195,20 @@ var createCmd = &cobra.Command{ If Databricks acquires at least 85% of the requested on-demand nodes, cluster creation will succeed. Otherwise the cluster will terminate with an - informative error message.`, + informative error message.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -196,42 +238,70 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq compute.DeleteCluster -var deleteJson flags.JsonFlag -var deleteSkipWait bool -var deleteTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *compute.DeleteCluster, +) -func init() { - Cmd.AddCommand(deleteCmd) +func newDelete() *cobra.Command { + cmd := &cobra.Command{} - deleteCmd.Flags().BoolVar(&deleteSkipWait, "no-wait", deleteSkipWait, `do not wait to reach TERMINATED state`) - deleteCmd.Flags().DurationVar(&deleteTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach TERMINATED state`) - // TODO: short flags - deleteCmd.Flags().Var(&deleteJson, "json", `either inline JSON string or @path/to/file.json with request body`) + var deleteReq compute.DeleteCluster + var deleteJson flags.JsonFlag -} + var deleteSkipWait bool + var deleteTimeout time.Duration + + cmd.Flags().BoolVar(&deleteSkipWait, "no-wait", deleteSkipWait, `do not wait to reach TERMINATED state`) + cmd.Flags().DurationVar(&deleteTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach TERMINATED state`) + // TODO: short flags + cmd.Flags().Var(&deleteJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var deleteCmd = &cobra.Command{ - Use: "delete CLUSTER_ID", - Short: `Terminate cluster.`, - Long: `Terminate cluster. + cmd.Use = "delete CLUSTER_ID" + cmd.Short = `Terminate cluster.` + cmd.Long = `Terminate cluster. Terminates the Spark cluster with the specified ID. The cluster is removed asynchronously. Once the termination has completed, the cluster will be in a TERMINATED state. If the cluster is already in a TERMINATING or - TERMINATED state, nothing will happen.`, + TERMINATED state, nothing will happen.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -241,23 +311,6 @@ var deleteCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No CLUSTER_ID argument specified. Loading names for Clusters drop-down." - names, err := w.Clusters.ClusterDetailsClusterNameToClusterIdMap(ctx, compute.ListClustersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Clusters drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The cluster to be terminated") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the cluster to be terminated") - } deleteReq.ClusterId = args[0] } @@ -278,61 +331,80 @@ var deleteCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start edit command -var editReq compute.EditCluster -var editJson flags.JsonFlag -var editSkipWait bool -var editTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var editOverrides []func( + *cobra.Command, + *compute.EditCluster, +) + +func newEdit() *cobra.Command { + cmd := &cobra.Command{} -func init() { - Cmd.AddCommand(editCmd) + var editReq compute.EditCluster + var editJson flags.JsonFlag - editCmd.Flags().BoolVar(&editSkipWait, "no-wait", editSkipWait, `do not wait to reach RUNNING state`) - editCmd.Flags().DurationVar(&editTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) + var editSkipWait bool + var editTimeout time.Duration + + cmd.Flags().BoolVar(&editSkipWait, "no-wait", editSkipWait, `do not wait to reach RUNNING state`) + cmd.Flags().DurationVar(&editTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) // TODO: short flags - editCmd.Flags().Var(&editJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&editJson, "json", `either inline JSON string or @path/to/file.json with request body`) - editCmd.Flags().BoolVar(&editReq.ApplyPolicyDefaultValues, "apply-policy-default-values", editReq.ApplyPolicyDefaultValues, `Note: This field won't be true for webapp requests.`) + cmd.Flags().BoolVar(&editReq.ApplyPolicyDefaultValues, "apply-policy-default-values", editReq.ApplyPolicyDefaultValues, `Note: This field won't be true for webapp requests.`) // TODO: complex arg: autoscale - editCmd.Flags().IntVar(&editReq.AutoterminationMinutes, "autotermination-minutes", editReq.AutoterminationMinutes, `Automatically terminates the cluster after it is inactive for this time in minutes.`) + cmd.Flags().IntVar(&editReq.AutoterminationMinutes, "autotermination-minutes", editReq.AutoterminationMinutes, `Automatically terminates the cluster after it is inactive for this time in minutes.`) // TODO: complex arg: aws_attributes // TODO: complex arg: azure_attributes // TODO: complex arg: cluster_log_conf - editCmd.Flags().StringVar(&editReq.ClusterName, "cluster-name", editReq.ClusterName, `Cluster name requested by the user.`) - editCmd.Flags().Var(&editReq.ClusterSource, "cluster-source", `Determines whether the cluster was created by a user through the UI, created by the Databricks Jobs Scheduler, or through an API request.`) + cmd.Flags().StringVar(&editReq.ClusterName, "cluster-name", editReq.ClusterName, `Cluster name requested by the user.`) + cmd.Flags().Var(&editReq.ClusterSource, "cluster-source", `Determines whether the cluster was created by a user through the UI, created by the Databricks Jobs Scheduler, or through an API request.`) // TODO: map via StringToStringVar: custom_tags - editCmd.Flags().Var(&editReq.DataSecurityMode, "data-security-mode", `This describes an enum.`) + cmd.Flags().Var(&editReq.DataSecurityMode, "data-security-mode", `This describes an enum.`) // TODO: complex arg: docker_image - editCmd.Flags().StringVar(&editReq.DriverInstancePoolId, "driver-instance-pool-id", editReq.DriverInstancePoolId, `The optional ID of the instance pool for the driver of the cluster belongs.`) - editCmd.Flags().StringVar(&editReq.DriverNodeTypeId, "driver-node-type-id", editReq.DriverNodeTypeId, `The node type of the Spark driver.`) - editCmd.Flags().BoolVar(&editReq.EnableElasticDisk, "enable-elastic-disk", editReq.EnableElasticDisk, `Autoscaling Local Storage: when enabled, this cluster will dynamically acquire additional disk space when its Spark workers are running low on disk space.`) - editCmd.Flags().BoolVar(&editReq.EnableLocalDiskEncryption, "enable-local-disk-encryption", editReq.EnableLocalDiskEncryption, `Whether to enable LUKS on cluster VMs' local disks.`) + cmd.Flags().StringVar(&editReq.DriverInstancePoolId, "driver-instance-pool-id", editReq.DriverInstancePoolId, `The optional ID of the instance pool for the driver of the cluster belongs.`) + cmd.Flags().StringVar(&editReq.DriverNodeTypeId, "driver-node-type-id", editReq.DriverNodeTypeId, `The node type of the Spark driver.`) + cmd.Flags().BoolVar(&editReq.EnableElasticDisk, "enable-elastic-disk", editReq.EnableElasticDisk, `Autoscaling Local Storage: when enabled, this cluster will dynamically acquire additional disk space when its Spark workers are running low on disk space.`) + cmd.Flags().BoolVar(&editReq.EnableLocalDiskEncryption, "enable-local-disk-encryption", editReq.EnableLocalDiskEncryption, `Whether to enable LUKS on cluster VMs' local disks.`) // TODO: complex arg: gcp_attributes // TODO: array: init_scripts - editCmd.Flags().StringVar(&editReq.InstancePoolId, "instance-pool-id", editReq.InstancePoolId, `The optional ID of the instance pool to which the cluster belongs.`) - editCmd.Flags().StringVar(&editReq.NodeTypeId, "node-type-id", editReq.NodeTypeId, `This field encodes, through a single value, the resources available to each of the Spark nodes in this cluster.`) - editCmd.Flags().IntVar(&editReq.NumWorkers, "num-workers", editReq.NumWorkers, `Number of worker nodes that this cluster should have.`) - editCmd.Flags().StringVar(&editReq.PolicyId, "policy-id", editReq.PolicyId, `The ID of the cluster policy used to create the cluster if applicable.`) - editCmd.Flags().Var(&editReq.RuntimeEngine, "runtime-engine", `Decides which runtime engine to be use, e.g.`) - editCmd.Flags().StringVar(&editReq.SingleUserName, "single-user-name", editReq.SingleUserName, `Single user name if data_security_mode is SINGLE_USER.`) + cmd.Flags().StringVar(&editReq.InstancePoolId, "instance-pool-id", editReq.InstancePoolId, `The optional ID of the instance pool to which the cluster belongs.`) + cmd.Flags().StringVar(&editReq.NodeTypeId, "node-type-id", editReq.NodeTypeId, `This field encodes, through a single value, the resources available to each of the Spark nodes in this cluster.`) + cmd.Flags().IntVar(&editReq.NumWorkers, "num-workers", editReq.NumWorkers, `Number of worker nodes that this cluster should have.`) + cmd.Flags().StringVar(&editReq.PolicyId, "policy-id", editReq.PolicyId, `The ID of the cluster policy used to create the cluster if applicable.`) + cmd.Flags().Var(&editReq.RuntimeEngine, "runtime-engine", `Decides which runtime engine to be use, e.g.`) + cmd.Flags().StringVar(&editReq.SingleUserName, "single-user-name", editReq.SingleUserName, `Single user name if data_security_mode is SINGLE_USER.`) // TODO: map via StringToStringVar: spark_conf // TODO: map via StringToStringVar: spark_env_vars // TODO: array: ssh_public_keys // TODO: complex arg: workload_type -} - -var editCmd = &cobra.Command{ - Use: "edit CLUSTER_ID SPARK_VERSION", - Short: `Update cluster configuration.`, - Long: `Update cluster configuration. + cmd.Use = "edit CLUSTER_ID SPARK_VERSION" + cmd.Short = `Update cluster configuration.` + cmd.Long = `Update cluster configuration. Updates the configuration of a cluster to match the provided attributes and size. A cluster can be updated if it is in a RUNNING or TERMINATED state. @@ -345,18 +417,20 @@ var editCmd = &cobra.Command{ new attributes will take effect. Any attempt to update a cluster in any other state will be rejected with an INVALID_STATE error code. - Clusters created by the Databricks Jobs service cannot be edited.`, + Clusters created by the Databricks Jobs service cannot be edited.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -387,42 +461,71 @@ var editCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range editOverrides { + fn(cmd, &editReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newEdit()) + }) } // start events command -var eventsReq compute.GetEvents -var eventsJson flags.JsonFlag -func init() { - Cmd.AddCommand(eventsCmd) - // TODO: short flags - eventsCmd.Flags().Var(&eventsJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var eventsOverrides []func( + *cobra.Command, + *compute.GetEvents, +) - eventsCmd.Flags().Int64Var(&eventsReq.EndTime, "end-time", eventsReq.EndTime, `The end time in epoch milliseconds.`) - // TODO: array: event_types - eventsCmd.Flags().Int64Var(&eventsReq.Limit, "limit", eventsReq.Limit, `The maximum number of events to include in a page of events.`) - eventsCmd.Flags().Int64Var(&eventsReq.Offset, "offset", eventsReq.Offset, `The offset in the result set.`) - eventsCmd.Flags().Var(&eventsReq.Order, "order", `The order to list events in; either "ASC" or "DESC".`) - eventsCmd.Flags().Int64Var(&eventsReq.StartTime, "start-time", eventsReq.StartTime, `The start time in epoch milliseconds.`) +func newEvents() *cobra.Command { + cmd := &cobra.Command{} -} + var eventsReq compute.GetEvents + var eventsJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&eventsJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var eventsCmd = &cobra.Command{ - Use: "events CLUSTER_ID", - Short: `List cluster activity events.`, - Long: `List cluster activity events. + cmd.Flags().Int64Var(&eventsReq.EndTime, "end-time", eventsReq.EndTime, `The end time in epoch milliseconds.`) + // TODO: array: event_types + cmd.Flags().Int64Var(&eventsReq.Limit, "limit", eventsReq.Limit, `The maximum number of events to include in a page of events.`) + cmd.Flags().Int64Var(&eventsReq.Offset, "offset", eventsReq.Offset, `The offset in the result set.`) + cmd.Flags().Var(&eventsReq.Order, "order", `The order to list events in; either "ASC" or "DESC".`) + cmd.Flags().Int64Var(&eventsReq.StartTime, "start-time", eventsReq.StartTime, `The start time in epoch milliseconds.`) + + cmd.Use = "events CLUSTER_ID" + cmd.Short = `List cluster activity events.` + cmd.Long = `List cluster activity events. Retrieves a list of events about the activity of a cluster. This API is paginated. If there are more events to read, the response includes all the - nparameters necessary to request the next page of events.`, + nparameters necessary to request the next page of events.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -432,23 +535,6 @@ var eventsCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No CLUSTER_ID argument specified. Loading names for Clusters drop-down." - names, err := w.Clusters.ClusterDetailsClusterNameToClusterIdMap(ctx, compute.ListClustersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Clusters drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The ID of the cluster to retrieve events about") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the id of the cluster to retrieve events about") - } eventsReq.ClusterId = args[0] } @@ -457,58 +543,66 @@ var eventsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range eventsOverrides { + fn(cmd, &eventsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newEvents()) + }) } // start get command -var getReq compute.GetClusterRequest -var getSkipWait bool -var getTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *compute.GetClusterRequest, +) -func init() { - Cmd.AddCommand(getCmd) +func newGet() *cobra.Command { + cmd := &cobra.Command{} - getCmd.Flags().BoolVar(&getSkipWait, "no-wait", getSkipWait, `do not wait to reach RUNNING state`) - getCmd.Flags().DurationVar(&getTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) - // TODO: short flags + var getReq compute.GetClusterRequest -} + var getSkipWait bool + var getTimeout time.Duration -var getCmd = &cobra.Command{ - Use: "get CLUSTER_ID", - Short: `Get cluster info.`, - Long: `Get cluster info. + cmd.Flags().BoolVar(&getSkipWait, "no-wait", getSkipWait, `do not wait to reach RUNNING state`) + cmd.Flags().DurationVar(&getTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) + // TODO: short flags + + cmd.Use = "get CLUSTER_ID" + cmd.Short = `Get cluster info.` + cmd.Long = `Get cluster info. Retrieves the information for a cluster given its identifier. Clusters can be - described while they are running, or up to 60 days after they are terminated.`, + described while they are running, or up to 60 days after they are terminated.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No CLUSTER_ID argument specified. Loading names for Clusters drop-down." - names, err := w.Clusters.ClusterDetailsClusterNameToClusterIdMap(ctx, compute.ListClustersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Clusters drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The cluster about which to retrieve information") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the cluster about which to retrieve information") - } getReq.ClusterId = args[0] response, err := w.Clusters.Get(ctx, getReq) @@ -516,29 +610,49 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq compute.ListClustersRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *compute.ListClustersRequest, +) - listCmd.Flags().StringVar(&listReq.CanUseClient, "can-use-client", listReq.CanUseClient, `Filter clusters based on what type of client it can be used for.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq compute.ListClustersRequest + var listJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var listCmd = &cobra.Command{ - Use: "list", - Short: `List all clusters.`, - Long: `List all clusters. + cmd.Flags().StringVar(&listReq.CanUseClient, "can-use-client", listReq.CanUseClient, `Filter clusters based on what type of client it can be used for.`) + + cmd.Use = "list" + cmd.Short = `List all clusters.` + cmd.Long = `List all clusters. Return information about all pinned clusters, active clusters, up to 200 of the most recently terminated all-purpose clusters in the past 30 days, and up @@ -548,18 +662,20 @@ var listCmd = &cobra.Command{ all-purpose clusters in the past 30 days, and 50 terminated job clusters in the past 30 days, then this API returns the 1 pinned cluster, 4 active clusters, all 45 terminated all-purpose clusters, and the 30 most recently - terminated job clusters.`, + terminated job clusters.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -576,30 +692,48 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start list-node-types command -func init() { - Cmd.AddCommand(listNodeTypesCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listNodeTypesOverrides []func( + *cobra.Command, +) -} +func newListNodeTypes() *cobra.Command { + cmd := &cobra.Command{} -var listNodeTypesCmd = &cobra.Command{ - Use: "list-node-types", - Short: `List node types.`, - Long: `List node types. + cmd.Use = "list-node-types" + cmd.Short = `List node types.` + cmd.Long = `List node types. Returns a list of supported Spark node types. These node types can be used to - launch a cluster.`, + launch a cluster.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.Clusters.ListNodeTypes(ctx) @@ -607,30 +741,48 @@ var listNodeTypesCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listNodeTypesOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newListNodeTypes()) + }) } // start list-zones command -func init() { - Cmd.AddCommand(listZonesCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listZonesOverrides []func( + *cobra.Command, +) -} +func newListZones() *cobra.Command { + cmd := &cobra.Command{} -var listZonesCmd = &cobra.Command{ - Use: "list-zones", - Short: `List availability zones.`, - Long: `List availability zones. + cmd.Use = "list-zones" + cmd.Short = `List availability zones.` + cmd.Long = `List availability zones. Returns a list of availability zones where clusters can be created in (For - example, us-west-2a). These zones can be used to launch a cluster.`, + example, us-west-2a). These zones can be used to launch a cluster.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.Clusters.ListZones(ctx) @@ -638,38 +790,67 @@ var listZonesCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listZonesOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newListZones()) + }) } // start permanent-delete command -var permanentDeleteReq compute.PermanentDeleteCluster -var permanentDeleteJson flags.JsonFlag -func init() { - Cmd.AddCommand(permanentDeleteCmd) - // TODO: short flags - permanentDeleteCmd.Flags().Var(&permanentDeleteJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var permanentDeleteOverrides []func( + *cobra.Command, + *compute.PermanentDeleteCluster, +) -} +func newPermanentDelete() *cobra.Command { + cmd := &cobra.Command{} + + var permanentDeleteReq compute.PermanentDeleteCluster + var permanentDeleteJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&permanentDeleteJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var permanentDeleteCmd = &cobra.Command{ - Use: "permanent-delete CLUSTER_ID", - Short: `Permanently delete cluster.`, - Long: `Permanently delete cluster. + cmd.Use = "permanent-delete CLUSTER_ID" + cmd.Short = `Permanently delete cluster.` + cmd.Long = `Permanently delete cluster. Permanently deletes a Spark cluster. This cluster is terminated and resources are asynchronously removed. In addition, users will no longer see permanently deleted clusters in the cluster list, and API users can no longer perform any action on permanently - deleted clusters.`, + deleted clusters.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -679,23 +860,6 @@ var permanentDeleteCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No CLUSTER_ID argument specified. Loading names for Clusters drop-down." - names, err := w.Clusters.ClusterDetailsClusterNameToClusterIdMap(ctx, compute.ListClustersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Clusters drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The cluster to be deleted") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the cluster to be deleted") - } permanentDeleteReq.ClusterId = args[0] } @@ -704,35 +868,64 @@ var permanentDeleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range permanentDeleteOverrides { + fn(cmd, &permanentDeleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newPermanentDelete()) + }) } // start pin command -var pinReq compute.PinCluster -var pinJson flags.JsonFlag -func init() { - Cmd.AddCommand(pinCmd) - // TODO: short flags - pinCmd.Flags().Var(&pinJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var pinOverrides []func( + *cobra.Command, + *compute.PinCluster, +) -} +func newPin() *cobra.Command { + cmd := &cobra.Command{} + + var pinReq compute.PinCluster + var pinJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&pinJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var pinCmd = &cobra.Command{ - Use: "pin CLUSTER_ID", - Short: `Pin cluster.`, - Long: `Pin cluster. + cmd.Use = "pin CLUSTER_ID" + cmd.Short = `Pin cluster.` + cmd.Long = `Pin cluster. Pinning a cluster ensures that the cluster will always be returned by the ListClusters API. Pinning a cluster that is already pinned will have no - effect. This API can only be called by workspace admins.`, + effect. This API can only be called by workspace admins.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -742,23 +935,6 @@ var pinCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No CLUSTER_ID argument specified. Loading names for Clusters drop-down." - names, err := w.Clusters.ClusterDetailsClusterNameToClusterIdMap(ctx, compute.ListClustersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Clusters drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have ") - } pinReq.ClusterId = args[0] } @@ -767,43 +943,71 @@ var pinCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range pinOverrides { + fn(cmd, &pinReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newPin()) + }) } // start resize command -var resizeReq compute.ResizeCluster -var resizeJson flags.JsonFlag -var resizeSkipWait bool -var resizeTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var resizeOverrides []func( + *cobra.Command, + *compute.ResizeCluster, +) -func init() { - Cmd.AddCommand(resizeCmd) +func newResize() *cobra.Command { + cmd := &cobra.Command{} + + var resizeReq compute.ResizeCluster + var resizeJson flags.JsonFlag - resizeCmd.Flags().BoolVar(&resizeSkipWait, "no-wait", resizeSkipWait, `do not wait to reach RUNNING state`) - resizeCmd.Flags().DurationVar(&resizeTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) + var resizeSkipWait bool + var resizeTimeout time.Duration + + cmd.Flags().BoolVar(&resizeSkipWait, "no-wait", resizeSkipWait, `do not wait to reach RUNNING state`) + cmd.Flags().DurationVar(&resizeTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) // TODO: short flags - resizeCmd.Flags().Var(&resizeJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&resizeJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: autoscale - resizeCmd.Flags().IntVar(&resizeReq.NumWorkers, "num-workers", resizeReq.NumWorkers, `Number of worker nodes that this cluster should have.`) - -} + cmd.Flags().IntVar(&resizeReq.NumWorkers, "num-workers", resizeReq.NumWorkers, `Number of worker nodes that this cluster should have.`) -var resizeCmd = &cobra.Command{ - Use: "resize CLUSTER_ID", - Short: `Resize cluster.`, - Long: `Resize cluster. + cmd.Use = "resize CLUSTER_ID" + cmd.Short = `Resize cluster.` + cmd.Long = `Resize cluster. Resizes a cluster to have a desired number of workers. This will fail unless - the cluster is in a RUNNING state.`, + the cluster is in a RUNNING state.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -813,23 +1017,6 @@ var resizeCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No CLUSTER_ID argument specified. Loading names for Clusters drop-down." - names, err := w.Clusters.ClusterDetailsClusterNameToClusterIdMap(ctx, compute.ListClustersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Clusters drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The cluster to be resized") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the cluster to be resized") - } resizeReq.ClusterId = args[0] } @@ -850,42 +1037,70 @@ var resizeCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range resizeOverrides { + fn(cmd, &resizeReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newResize()) + }) } // start restart command -var restartReq compute.RestartCluster -var restartJson flags.JsonFlag -var restartSkipWait bool -var restartTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var restartOverrides []func( + *cobra.Command, + *compute.RestartCluster, +) -func init() { - Cmd.AddCommand(restartCmd) +func newRestart() *cobra.Command { + cmd := &cobra.Command{} - restartCmd.Flags().BoolVar(&restartSkipWait, "no-wait", restartSkipWait, `do not wait to reach RUNNING state`) - restartCmd.Flags().DurationVar(&restartTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) - // TODO: short flags - restartCmd.Flags().Var(&restartJson, "json", `either inline JSON string or @path/to/file.json with request body`) + var restartReq compute.RestartCluster + var restartJson flags.JsonFlag - restartCmd.Flags().StringVar(&restartReq.RestartUser, "restart-user", restartReq.RestartUser, `.`) + var restartSkipWait bool + var restartTimeout time.Duration -} + cmd.Flags().BoolVar(&restartSkipWait, "no-wait", restartSkipWait, `do not wait to reach RUNNING state`) + cmd.Flags().DurationVar(&restartTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) + // TODO: short flags + cmd.Flags().Var(&restartJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&restartReq.RestartUser, "restart-user", restartReq.RestartUser, `.`) -var restartCmd = &cobra.Command{ - Use: "restart CLUSTER_ID", - Short: `Restart cluster.`, - Long: `Restart cluster. + cmd.Use = "restart CLUSTER_ID" + cmd.Short = `Restart cluster.` + cmd.Long = `Restart cluster. Restarts a Spark cluster with the supplied ID. If the cluster is not currently - in a RUNNING state, nothing will happen.`, + in a RUNNING state, nothing will happen.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -895,23 +1110,6 @@ var restartCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No CLUSTER_ID argument specified. Loading names for Clusters drop-down." - names, err := w.Clusters.ClusterDetailsClusterNameToClusterIdMap(ctx, compute.ListClustersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Clusters drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The cluster to be started") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the cluster to be started") - } restartReq.ClusterId = args[0] } @@ -932,30 +1130,48 @@ var restartCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range restartOverrides { + fn(cmd, &restartReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newRestart()) + }) } // start spark-versions command -func init() { - Cmd.AddCommand(sparkVersionsCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var sparkVersionsOverrides []func( + *cobra.Command, +) -} +func newSparkVersions() *cobra.Command { + cmd := &cobra.Command{} -var sparkVersionsCmd = &cobra.Command{ - Use: "spark-versions", - Short: `List available Spark versions.`, - Long: `List available Spark versions. + cmd.Use = "spark-versions" + cmd.Short = `List available Spark versions.` + cmd.Long = `List available Spark versions. Returns the list of available Spark versions. These versions can be used to - launch a cluster.`, + launch a cluster.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.Clusters.SparkVersions(ctx) @@ -963,33 +1179,52 @@ var sparkVersionsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range sparkVersionsOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newSparkVersions()) + }) } // start start command -var startReq compute.StartCluster -var startJson flags.JsonFlag -var startSkipWait bool -var startTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var startOverrides []func( + *cobra.Command, + *compute.StartCluster, +) -func init() { - Cmd.AddCommand(startCmd) +func newStart() *cobra.Command { + cmd := &cobra.Command{} - startCmd.Flags().BoolVar(&startSkipWait, "no-wait", startSkipWait, `do not wait to reach RUNNING state`) - startCmd.Flags().DurationVar(&startTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) - // TODO: short flags - startCmd.Flags().Var(&startJson, "json", `either inline JSON string or @path/to/file.json with request body`) + var startReq compute.StartCluster + var startJson flags.JsonFlag -} + var startSkipWait bool + var startTimeout time.Duration -var startCmd = &cobra.Command{ - Use: "start CLUSTER_ID", - Short: `Start terminated cluster.`, - Long: `Start terminated cluster. + cmd.Flags().BoolVar(&startSkipWait, "no-wait", startSkipWait, `do not wait to reach RUNNING state`) + cmd.Flags().DurationVar(&startTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) + // TODO: short flags + cmd.Flags().Var(&startJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "start CLUSTER_ID" + cmd.Short = `Start terminated cluster.` + cmd.Long = `Start terminated cluster. Starts a terminated Spark cluster with the supplied ID. This works similar to createCluster except: @@ -998,11 +1233,20 @@ var startCmd = &cobra.Command{ with the last specified cluster size. * If the previous cluster was an autoscaling cluster, the current cluster starts with the minimum number of nodes. * If the cluster is not currently in a TERMINATED state, nothing will - happen. * Clusters launched to run a job cannot be started.`, + happen. * Clusters launched to run a job cannot be started.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1012,23 +1256,6 @@ var startCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No CLUSTER_ID argument specified. Loading names for Clusters drop-down." - names, err := w.Clusters.ClusterDetailsClusterNameToClusterIdMap(ctx, compute.ListClustersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Clusters drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The cluster to be started") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the cluster to be started") - } startReq.ClusterId = args[0] } @@ -1049,35 +1276,64 @@ var startCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range startOverrides { + fn(cmd, &startReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newStart()) + }) } // start unpin command -var unpinReq compute.UnpinCluster -var unpinJson flags.JsonFlag -func init() { - Cmd.AddCommand(unpinCmd) - // TODO: short flags - unpinCmd.Flags().Var(&unpinJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var unpinOverrides []func( + *cobra.Command, + *compute.UnpinCluster, +) -} +func newUnpin() *cobra.Command { + cmd := &cobra.Command{} + + var unpinReq compute.UnpinCluster + var unpinJson flags.JsonFlag -var unpinCmd = &cobra.Command{ - Use: "unpin CLUSTER_ID", - Short: `Unpin cluster.`, - Long: `Unpin cluster. + // TODO: short flags + cmd.Flags().Var(&unpinJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "unpin CLUSTER_ID" + cmd.Short = `Unpin cluster.` + cmd.Long = `Unpin cluster. Unpinning a cluster will allow the cluster to eventually be removed from the ListClusters API. Unpinning a cluster that is not pinned will have no effect. - This API can only be called by workspace admins.`, + This API can only be called by workspace admins.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1087,23 +1343,6 @@ var unpinCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No CLUSTER_ID argument specified. Loading names for Clusters drop-down." - names, err := w.Clusters.ClusterDetailsClusterNameToClusterIdMap(ctx, compute.ListClustersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Clusters drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have ") - } unpinReq.ClusterId = args[0] } @@ -1112,10 +1351,24 @@ var unpinCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range unpinOverrides { + fn(cmd, &unpinReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUnpin()) + }) } // end service Clusters diff --git a/cmd/workspace/clusters/overrides.go b/cmd/workspace/clusters/overrides.go index 1e8818952a..ab32a4cd8a 100644 --- a/cmd/workspace/clusters/overrides.go +++ b/cmd/workspace/clusters/overrides.go @@ -1,19 +1,33 @@ package clusters -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/databricks-sdk-go/service/compute" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command, _ *compute.ListClustersRequest) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{header "ID"}} {{header "Name"}} {{header "State"}} {{range .}}{{.ClusterId | green}} {{.ClusterName | cyan}} {{if eq .State "RUNNING"}}{{green "%s" .State}}{{else if eq .State "TERMINATED"}}{{red "%s" .State}}{{else}}{{blue "%s" .State}}{{end}} {{end}}`) +} +func listNodeTypesOverride(listNodeTypesCmd *cobra.Command) { listNodeTypesCmd.Annotations["template"] = cmdio.Heredoc(` {{range .NodeTypes}}{{.NodeTypeId | green}} {{.NumCores}} {{.MemoryMb}} {{.Category | blue}} {{end}}`) +} +func sparkVersionsOverride(sparkVersionsCmd *cobra.Command) { sparkVersionsCmd.Annotations["template"] = cmdio.Heredoc(` {{range .Versions}}{{.Key | green}} {{.Name}} {{end}} `) } + +func init() { + listOverrides = append(listOverrides, listOverride) + listNodeTypesOverrides = append(listNodeTypesOverrides, listNodeTypesOverride) + sparkVersionsOverrides = append(sparkVersionsOverrides, sparkVersionsOverride) +} diff --git a/cmd/workspace/cmd.go b/cmd/workspace/cmd.go index 596dba8292..74dcc3a58d 100755 --- a/cmd/workspace/cmd.go +++ b/cmd/workspace/cmd.go @@ -3,8 +3,6 @@ package workspace import ( - "github.com/databricks/cli/cmd/root" - alerts "github.com/databricks/cli/cmd/workspace/alerts" catalogs "github.com/databricks/cli/cmd/workspace/catalogs" clean_rooms "github.com/databricks/cli/cmd/workspace/clean-rooms" @@ -54,108 +52,61 @@ import ( workspace "github.com/databricks/cli/cmd/workspace/workspace" workspace_bindings "github.com/databricks/cli/cmd/workspace/workspace-bindings" workspace_conf "github.com/databricks/cli/cmd/workspace/workspace-conf" + "github.com/spf13/cobra" ) -func init() { - root.RootCmd.AddCommand(alerts.Cmd) - root.RootCmd.AddCommand(catalogs.Cmd) - root.RootCmd.AddCommand(clean_rooms.Cmd) - root.RootCmd.AddCommand(cluster_policies.Cmd) - root.RootCmd.AddCommand(clusters.Cmd) - root.RootCmd.AddCommand(connections.Cmd) - root.RootCmd.AddCommand(current_user.Cmd) - root.RootCmd.AddCommand(dashboards.Cmd) - root.RootCmd.AddCommand(data_sources.Cmd) - root.RootCmd.AddCommand(experiments.Cmd) - root.RootCmd.AddCommand(external_locations.Cmd) - root.RootCmd.AddCommand(functions.Cmd) - root.RootCmd.AddCommand(git_credentials.Cmd) - root.RootCmd.AddCommand(global_init_scripts.Cmd) - root.RootCmd.AddCommand(grants.Cmd) - root.RootCmd.AddCommand(groups.Cmd) - root.RootCmd.AddCommand(instance_pools.Cmd) - root.RootCmd.AddCommand(instance_profiles.Cmd) - root.RootCmd.AddCommand(ip_access_lists.Cmd) - root.RootCmd.AddCommand(jobs.Cmd) - root.RootCmd.AddCommand(libraries.Cmd) - root.RootCmd.AddCommand(metastores.Cmd) - root.RootCmd.AddCommand(model_registry.Cmd) - root.RootCmd.AddCommand(permissions.Cmd) - root.RootCmd.AddCommand(pipelines.Cmd) - root.RootCmd.AddCommand(policy_families.Cmd) - root.RootCmd.AddCommand(providers.Cmd) - root.RootCmd.AddCommand(queries.Cmd) - root.RootCmd.AddCommand(query_history.Cmd) - root.RootCmd.AddCommand(recipient_activation.Cmd) - root.RootCmd.AddCommand(recipients.Cmd) - root.RootCmd.AddCommand(repos.Cmd) - root.RootCmd.AddCommand(schemas.Cmd) - root.RootCmd.AddCommand(secrets.Cmd) - root.RootCmd.AddCommand(service_principals.Cmd) - root.RootCmd.AddCommand(serving_endpoints.Cmd) - root.RootCmd.AddCommand(shares.Cmd) - root.RootCmd.AddCommand(storage_credentials.Cmd) - root.RootCmd.AddCommand(system_schemas.Cmd) - root.RootCmd.AddCommand(table_constraints.Cmd) - root.RootCmd.AddCommand(tables.Cmd) - root.RootCmd.AddCommand(token_management.Cmd) - root.RootCmd.AddCommand(tokens.Cmd) - root.RootCmd.AddCommand(users.Cmd) - root.RootCmd.AddCommand(volumes.Cmd) - root.RootCmd.AddCommand(warehouses.Cmd) - root.RootCmd.AddCommand(workspace.Cmd) - root.RootCmd.AddCommand(workspace_bindings.Cmd) - root.RootCmd.AddCommand(workspace_conf.Cmd) +func All() []*cobra.Command { + var out []*cobra.Command - // Register commands with groups - alerts.Cmd.GroupID = "sql" - catalogs.Cmd.GroupID = "catalog" - clean_rooms.Cmd.GroupID = "sharing" - cluster_policies.Cmd.GroupID = "compute" - clusters.Cmd.GroupID = "compute" - connections.Cmd.GroupID = "catalog" - current_user.Cmd.GroupID = "iam" - dashboards.Cmd.GroupID = "sql" - data_sources.Cmd.GroupID = "sql" - experiments.Cmd.GroupID = "ml" - external_locations.Cmd.GroupID = "catalog" - functions.Cmd.GroupID = "catalog" - git_credentials.Cmd.GroupID = "workspace" - global_init_scripts.Cmd.GroupID = "compute" - grants.Cmd.GroupID = "catalog" - groups.Cmd.GroupID = "iam" - instance_pools.Cmd.GroupID = "compute" - instance_profiles.Cmd.GroupID = "compute" - ip_access_lists.Cmd.GroupID = "settings" - jobs.Cmd.GroupID = "jobs" - libraries.Cmd.GroupID = "compute" - metastores.Cmd.GroupID = "catalog" - model_registry.Cmd.GroupID = "ml" - permissions.Cmd.GroupID = "iam" - pipelines.Cmd.GroupID = "pipelines" - policy_families.Cmd.GroupID = "compute" - providers.Cmd.GroupID = "sharing" - queries.Cmd.GroupID = "sql" - query_history.Cmd.GroupID = "sql" - recipient_activation.Cmd.GroupID = "sharing" - recipients.Cmd.GroupID = "sharing" - repos.Cmd.GroupID = "workspace" - schemas.Cmd.GroupID = "catalog" - secrets.Cmd.GroupID = "workspace" - service_principals.Cmd.GroupID = "iam" - serving_endpoints.Cmd.GroupID = "serving" - shares.Cmd.GroupID = "sharing" - storage_credentials.Cmd.GroupID = "catalog" - system_schemas.Cmd.GroupID = "catalog" - table_constraints.Cmd.GroupID = "catalog" - tables.Cmd.GroupID = "catalog" - token_management.Cmd.GroupID = "settings" - tokens.Cmd.GroupID = "settings" - users.Cmd.GroupID = "iam" - volumes.Cmd.GroupID = "catalog" - warehouses.Cmd.GroupID = "sql" - workspace.Cmd.GroupID = "workspace" - workspace_bindings.Cmd.GroupID = "catalog" - workspace_conf.Cmd.GroupID = "settings" + out = append(out, alerts.New()) + out = append(out, catalogs.New()) + out = append(out, clean_rooms.New()) + out = append(out, cluster_policies.New()) + out = append(out, clusters.New()) + out = append(out, connections.New()) + out = append(out, current_user.New()) + out = append(out, dashboards.New()) + out = append(out, data_sources.New()) + out = append(out, experiments.New()) + out = append(out, external_locations.New()) + out = append(out, functions.New()) + out = append(out, git_credentials.New()) + out = append(out, global_init_scripts.New()) + out = append(out, grants.New()) + out = append(out, groups.New()) + out = append(out, instance_pools.New()) + out = append(out, instance_profiles.New()) + out = append(out, ip_access_lists.New()) + out = append(out, jobs.New()) + out = append(out, libraries.New()) + out = append(out, metastores.New()) + out = append(out, model_registry.New()) + out = append(out, permissions.New()) + out = append(out, pipelines.New()) + out = append(out, policy_families.New()) + out = append(out, providers.New()) + out = append(out, queries.New()) + out = append(out, query_history.New()) + out = append(out, recipient_activation.New()) + out = append(out, recipients.New()) + out = append(out, repos.New()) + out = append(out, schemas.New()) + out = append(out, secrets.New()) + out = append(out, service_principals.New()) + out = append(out, serving_endpoints.New()) + out = append(out, shares.New()) + out = append(out, storage_credentials.New()) + out = append(out, system_schemas.New()) + out = append(out, table_constraints.New()) + out = append(out, tables.New()) + out = append(out, token_management.New()) + out = append(out, tokens.New()) + out = append(out, users.New()) + out = append(out, volumes.New()) + out = append(out, warehouses.New()) + out = append(out, workspace.New()) + out = append(out, workspace_bindings.New()) + out = append(out, workspace_conf.New()) + return out } diff --git a/cmd/workspace/connections/connections.go b/cmd/workspace/connections/connections.go index 146fdba9d6..89636b594c 100755 --- a/cmd/workspace/connections/connections.go +++ b/cmd/workspace/connections/connections.go @@ -12,10 +12,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "connections", - Short: `Connections allow for creating a connection to an external data source.`, - Long: `Connections allow for creating a connection to an external data source. +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "connections", + Short: `Connections allow for creating a connection to an external data source.`, + Long: `Connections allow for creating a connection to an external data source. A connection is an abstraction of an external data source that can be connected from Databricks Compute. Creating a connection object is the first @@ -26,44 +31,60 @@ var Cmd = &cobra.Command{ may create different types of connections with each connection having a unique set of configuration options to support credential management and other settings.`, - Annotations: map[string]string{ - "package": "catalog", - }, + GroupID: "catalog", + Annotations: map[string]string{ + "package": "catalog", + }, - // This service is being previewed; hide from help output. - Hidden: true, + // This service is being previewed; hide from help output. + Hidden: true, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq catalog.CreateConnection -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *catalog.CreateConnection, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq catalog.CreateConnection + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createCmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `User-provided free-form text description.`) - createCmd.Flags().StringVar(&createReq.Owner, "owner", createReq.Owner, `Username of current owner of the connection.`) + cmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `User-provided free-form text description.`) + cmd.Flags().StringVar(&createReq.Owner, "owner", createReq.Owner, `Username of current owner of the connection.`) // TODO: map via StringToStringVar: properties_kvpairs - createCmd.Flags().BoolVar(&createReq.ReadOnly, "read-only", createReq.ReadOnly, `If the connection is read only.`) - -} + cmd.Flags().BoolVar(&createReq.ReadOnly, "read-only", createReq.ReadOnly, `If the connection is read only.`) -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a connection.`, - Long: `Create a connection. + cmd.Use = "create" + cmd.Short = `Create a connection.` + cmd.Long = `Create a connection. Creates a new connection Creates a new connection to an external data source. It allows users to specify connection details and configurations for interaction with the - external server.`, + external server.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -81,51 +102,60 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq catalog.DeleteConnectionRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *catalog.DeleteConnectionRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq catalog.DeleteConnectionRequest -var deleteCmd = &cobra.Command{ - Use: "delete NAME_ARG", - Short: `Delete a connection.`, - Long: `Delete a connection. + // TODO: short flags + + cmd.Use = "delete NAME_ARG" + cmd.Short = `Delete a connection.` + cmd.Long = `Delete a connection. - Deletes the connection that matches the supplied name.`, + Deletes the connection that matches the supplied name.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No NAME_ARG argument specified. Loading names for Connections drop-down." - names, err := w.Connections.ConnectionInfoNameToFullNameMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Connections drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The name of the connection to be deleted") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the name of the connection to be deleted") - } deleteReq.NameArg = args[0] err = w.Connections.Delete(ctx, deleteReq) @@ -133,51 +163,60 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq catalog.GetConnectionRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *catalog.GetConnectionRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} -var getCmd = &cobra.Command{ - Use: "get NAME_ARG", - Short: `Get a connection.`, - Long: `Get a connection. + var getReq catalog.GetConnectionRequest + + // TODO: short flags + + cmd.Use = "get NAME_ARG" + cmd.Short = `Get a connection.` + cmd.Long = `Get a connection. - Gets a connection from it's name.`, + Gets a connection from it's name.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No NAME_ARG argument specified. Loading names for Connections drop-down." - names, err := w.Connections.ConnectionInfoNameToFullNameMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Connections drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Name of the connection") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have name of the connection") - } getReq.NameArg = args[0] response, err := w.Connections.Get(ctx, getReq) @@ -185,29 +224,47 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `List connections.`, - Long: `List connections. + cmd.Use = "list" + cmd.Short = `List connections.` + cmd.Long = `List connections. - List all connections.`, + List all connections.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.Connections.ListAll(ctx) @@ -215,33 +272,54 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq catalog.UpdateConnection -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) - // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *catalog.UpdateConnection, +) -} +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} -var updateCmd = &cobra.Command{ - Use: "update", - Short: `Update a connection.`, - Long: `Update a connection. + var updateReq catalog.UpdateConnection + var updateJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "update" + cmd.Short = `Update a connection.` + cmd.Long = `Update a connection. - Updates the connection that matches the supplied name.`, + Updates the connection that matches the supplied name.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -259,10 +337,24 @@ var updateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Connections diff --git a/cmd/workspace/current-user/current-user.go b/cmd/workspace/current-user/current-user.go index 80e539ec98..cb18e71d28 100755 --- a/cmd/workspace/current-user/current-user.go +++ b/cmd/workspace/current-user/current-user.go @@ -8,33 +8,51 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "current-user", - Short: `This API allows retrieving information about currently authenticated user or service principal.`, - Long: `This API allows retrieving information about currently authenticated user or +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "current-user", + Short: `This API allows retrieving information about currently authenticated user or service principal.`, + Long: `This API allows retrieving information about currently authenticated user or service principal.`, - Annotations: map[string]string{ - "package": "iam", - }, + GroupID: "iam", + Annotations: map[string]string{ + "package": "iam", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start me command -func init() { - Cmd.AddCommand(meCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var meOverrides []func( + *cobra.Command, +) -} +func newMe() *cobra.Command { + cmd := &cobra.Command{} -var meCmd = &cobra.Command{ - Use: "me", - Short: `Get current user info.`, - Long: `Get current user info. + cmd.Use = "me" + cmd.Short = `Get current user info.` + cmd.Long = `Get current user info. - Get details about the current method caller's identity.`, + Get details about the current method caller's identity.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.CurrentUser.Me(ctx) @@ -42,10 +60,24 @@ var meCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range meOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newMe()) + }) } // end service CurrentUser diff --git a/cmd/workspace/dashboards/dashboards.go b/cmd/workspace/dashboards/dashboards.go index 014be02f88..03796c2f26 100755 --- a/cmd/workspace/dashboards/dashboards.go +++ b/cmd/workspace/dashboards/dashboards.go @@ -12,46 +12,68 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "dashboards", - Short: `In general, there is little need to modify dashboards using the API.`, - Long: `In general, there is little need to modify dashboards using the API. However, +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "dashboards", + Short: `In general, there is little need to modify dashboards using the API.`, + Long: `In general, there is little need to modify dashboards using the API. However, it can be useful to use dashboard objects to look-up a collection of related query IDs. The API can also be used to duplicate multiple dashboards at once since you can get a dashboard definition with a GET request and then POST it to create a new one. Dashboards can be scheduled using the sql_task type of the Jobs API, e.g. :method:jobs/create.`, - Annotations: map[string]string{ - "package": "sql", - }, + GroupID: "sql", + Annotations: map[string]string{ + "package": "sql", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq sql.CreateDashboardRequest -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *sql.CreateDashboardRequest, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq sql.CreateDashboardRequest + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) -} + cmd.Use = "create" + cmd.Short = `Create a dashboard object.` + cmd.Long = `Create a dashboard object.` -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a dashboard object.`, - Long: `Create a dashboard object.`, + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -69,52 +91,61 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq sql.DeleteDashboardRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *sql.DeleteDashboardRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq sql.DeleteDashboardRequest + + // TODO: short flags -var deleteCmd = &cobra.Command{ - Use: "delete DASHBOARD_ID", - Short: `Remove a dashboard.`, - Long: `Remove a dashboard. + cmd.Use = "delete DASHBOARD_ID" + cmd.Short = `Remove a dashboard.` + cmd.Long = `Remove a dashboard. Moves a dashboard to the trash. Trashed dashboards do not appear in list views - or searches, and cannot be shared.`, + or searches, and cannot be shared.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No DASHBOARD_ID argument specified. Loading names for Dashboards drop-down." - names, err := w.Dashboards.DashboardNameToIdMap(ctx, sql.ListDashboardsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Dashboards drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have ") - } deleteReq.DashboardId = args[0] err = w.Dashboards.Delete(ctx, deleteReq) @@ -122,52 +153,61 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq sql.GetDashboardRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *sql.GetDashboardRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq sql.GetDashboardRequest + + // TODO: short flags -var getCmd = &cobra.Command{ - Use: "get DASHBOARD_ID", - Short: `Retrieve a definition.`, - Long: `Retrieve a definition. + cmd.Use = "get DASHBOARD_ID" + cmd.Short = `Retrieve a definition.` + cmd.Long = `Retrieve a definition. Returns a JSON representation of a dashboard object, including its - visualization and query objects.`, + visualization and query objects.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No DASHBOARD_ID argument specified. Loading names for Dashboards drop-down." - names, err := w.Dashboards.DashboardNameToIdMap(ctx, sql.ListDashboardsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Dashboards drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have ") - } getReq.DashboardId = args[0] response, err := w.Dashboards.Get(ctx, getReq) @@ -175,45 +215,67 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq sql.ListDashboardsRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *sql.ListDashboardsRequest, +) - listCmd.Flags().Var(&listReq.Order, "order", `Name of dashboard attribute to order by.`) - listCmd.Flags().IntVar(&listReq.Page, "page", listReq.Page, `Page number to retrieve.`) - listCmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, `Number of dashboards to return per page.`) - listCmd.Flags().StringVar(&listReq.Q, "q", listReq.Q, `Full text search term.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq sql.ListDashboardsRequest + var listJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().Var(&listReq.Order, "order", `Name of dashboard attribute to order by.`) + cmd.Flags().IntVar(&listReq.Page, "page", listReq.Page, `Page number to retrieve.`) + cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, `Number of dashboards to return per page.`) + cmd.Flags().StringVar(&listReq.Q, "q", listReq.Q, `Full text search term.`) -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get dashboard objects.`, - Long: `Get dashboard objects. + cmd.Use = "list" + cmd.Short = `Get dashboard objects.` + cmd.Long = `Get dashboard objects. - Fetch a paginated list of dashboard objects.`, + Fetch a paginated list of dashboard objects.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -230,51 +292,60 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start restore command -var restoreReq sql.RestoreDashboardRequest -func init() { - Cmd.AddCommand(restoreCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var restoreOverrides []func( + *cobra.Command, + *sql.RestoreDashboardRequest, +) -} +func newRestore() *cobra.Command { + cmd := &cobra.Command{} + + var restoreReq sql.RestoreDashboardRequest -var restoreCmd = &cobra.Command{ - Use: "restore DASHBOARD_ID", - Short: `Restore a dashboard.`, - Long: `Restore a dashboard. + // TODO: short flags + + cmd.Use = "restore DASHBOARD_ID" + cmd.Short = `Restore a dashboard.` + cmd.Long = `Restore a dashboard. - A restored dashboard appears in list views and searches and can be shared.`, + A restored dashboard appears in list views and searches and can be shared.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No DASHBOARD_ID argument specified. Loading names for Dashboards drop-down." - names, err := w.Dashboards.DashboardNameToIdMap(ctx, sql.ListDashboardsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Dashboards drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have ") - } restoreReq.DashboardId = args[0] err = w.Dashboards.Restore(ctx, restoreReq) @@ -282,10 +353,24 @@ var restoreCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range restoreOverrides { + fn(cmd, &restoreReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newRestore()) + }) } // end service Dashboards diff --git a/cmd/workspace/dashboards/overrides.go b/cmd/workspace/dashboards/overrides.go index ba7e42ec76..709e657f85 100644 --- a/cmd/workspace/dashboards/overrides.go +++ b/cmd/workspace/dashboards/overrides.go @@ -1,10 +1,18 @@ package dashboards -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/databricks-sdk-go/service/sql" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command, _ *sql.ListDashboardsRequest) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{header "ID"}} {{header "Name"}} {{range .}}{{.Id|green}} {{.Name}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/workspace/data-sources/data-sources.go b/cmd/workspace/data-sources/data-sources.go index 513ce21448..969399f420 100755 --- a/cmd/workspace/data-sources/data-sources.go +++ b/cmd/workspace/data-sources/data-sources.go @@ -8,10 +8,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "data-sources", - Short: `This API is provided to assist you in making new query objects.`, - Long: `This API is provided to assist you in making new query objects. When creating +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "data-sources", + Short: `This API is provided to assist you in making new query objects.`, + Long: `This API is provided to assist you in making new query objects. When creating a query object, you may optionally specify a data_source_id for the SQL warehouse against which it will run. If you don't already know the data_source_id for your desired SQL warehouse, this API will help you find @@ -21,30 +26,43 @@ var Cmd = &cobra.Command{ in your workspace. We advise you to use any text editor, REST client, or grep to search the response from this API for the name of your SQL warehouse as it appears in Databricks SQL.`, - Annotations: map[string]string{ - "package": "sql", - }, + GroupID: "sql", + Annotations: map[string]string{ + "package": "sql", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get a list of SQL warehouses.`, - Long: `Get a list of SQL warehouses. + cmd.Use = "list" + cmd.Short = `Get a list of SQL warehouses.` + cmd.Long = `Get a list of SQL warehouses. Retrieves a full list of SQL warehouses available in this workspace. All fields that appear in this API response are enumerated for clarity. However, - you need only a SQL warehouse's id to create new queries against it.`, + you need only a SQL warehouse's id to create new queries against it.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.DataSources.List(ctx) @@ -52,10 +70,24 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // end service DataSources diff --git a/cmd/workspace/experiments/experiments.go b/cmd/workspace/experiments/experiments.go index a95da2f5ce..1e2ff9fa1c 100755 --- a/cmd/workspace/experiments/experiments.go +++ b/cmd/workspace/experiments/experiments.go @@ -12,10 +12,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "experiments", - Short: `Experiments are the primary unit of organization in MLflow; all MLflow runs belong to an experiment.`, - Long: `Experiments are the primary unit of organization in MLflow; all MLflow runs +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "experiments", + Short: `Experiments are the primary unit of organization in MLflow; all MLflow runs belong to an experiment.`, + Long: `Experiments are the primary unit of organization in MLflow; all MLflow runs belong to an experiment. Each experiment lets you visualize, search, and compare runs, as well as download run artifacts or metadata for analysis in other tools. Experiments are maintained in a Databricks hosted MLflow tracking @@ -24,47 +29,64 @@ var Cmd = &cobra.Command{ Experiments are located in the workspace file tree. You manage experiments using the same tools you use to manage other workspace objects such as folders, notebooks, and libraries.`, - Annotations: map[string]string{ - "package": "ml", - }, + GroupID: "ml", + Annotations: map[string]string{ + "package": "ml", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create-experiment command -var createExperimentReq ml.CreateExperiment -var createExperimentJson flags.JsonFlag -func init() { - Cmd.AddCommand(createExperimentCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createExperimentOverrides []func( + *cobra.Command, + *ml.CreateExperiment, +) + +func newCreateExperiment() *cobra.Command { + cmd := &cobra.Command{} + + var createExperimentReq ml.CreateExperiment + var createExperimentJson flags.JsonFlag + // TODO: short flags - createExperimentCmd.Flags().Var(&createExperimentJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createExperimentJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createExperimentCmd.Flags().StringVar(&createExperimentReq.ArtifactLocation, "artifact-location", createExperimentReq.ArtifactLocation, `Location where all artifacts for the experiment are stored.`) + cmd.Flags().StringVar(&createExperimentReq.ArtifactLocation, "artifact-location", createExperimentReq.ArtifactLocation, `Location where all artifacts for the experiment are stored.`) // TODO: array: tags -} - -var createExperimentCmd = &cobra.Command{ - Use: "create-experiment NAME", - Short: `Create experiment.`, - Long: `Create experiment. + cmd.Use = "create-experiment NAME" + cmd.Short = `Create experiment.` + cmd.Long = `Create experiment. Creates an experiment with a name. Returns the ID of the newly created experiment. Validates that another experiment with the same name does not already exist and fails if another experiment with the same name already exists. - Throws RESOURCE_ALREADY_EXISTS if a experiment with the given name exists.`, + Throws RESOURCE_ALREADY_EXISTS if a experiment with the given name exists.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -82,48 +104,70 @@ var createExperimentCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createExperimentOverrides { + fn(cmd, &createExperimentReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreateExperiment()) + }) } // start create-run command -var createRunReq ml.CreateRun -var createRunJson flags.JsonFlag -func init() { - Cmd.AddCommand(createRunCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createRunOverrides []func( + *cobra.Command, + *ml.CreateRun, +) + +func newCreateRun() *cobra.Command { + cmd := &cobra.Command{} + + var createRunReq ml.CreateRun + var createRunJson flags.JsonFlag + // TODO: short flags - createRunCmd.Flags().Var(&createRunJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createRunJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createRunCmd.Flags().StringVar(&createRunReq.ExperimentId, "experiment-id", createRunReq.ExperimentId, `ID of the associated experiment.`) - createRunCmd.Flags().Int64Var(&createRunReq.StartTime, "start-time", createRunReq.StartTime, `Unix timestamp in milliseconds of when the run started.`) + cmd.Flags().StringVar(&createRunReq.ExperimentId, "experiment-id", createRunReq.ExperimentId, `ID of the associated experiment.`) + cmd.Flags().Int64Var(&createRunReq.StartTime, "start-time", createRunReq.StartTime, `Unix timestamp in milliseconds of when the run started.`) // TODO: array: tags - createRunCmd.Flags().StringVar(&createRunReq.UserId, "user-id", createRunReq.UserId, `ID of the user executing the run.`) + cmd.Flags().StringVar(&createRunReq.UserId, "user-id", createRunReq.UserId, `ID of the user executing the run.`) -} - -var createRunCmd = &cobra.Command{ - Use: "create-run", - Short: `Create a run.`, - Long: `Create a run. + cmd.Use = "create-run" + cmd.Short = `Create a run.` + cmd.Long = `Create a run. Creates a new run within an experiment. A run is usually a single execution of a machine learning or data ETL pipeline. MLflow uses runs to track the mlflowParam, mlflowMetric and mlflowRunTag associated with a single - execution.`, + execution.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -140,42 +184,64 @@ var createRunCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createRunOverrides { + fn(cmd, &createRunReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreateRun()) + }) } // start delete-experiment command -var deleteExperimentReq ml.DeleteExperiment -var deleteExperimentJson flags.JsonFlag -func init() { - Cmd.AddCommand(deleteExperimentCmd) - // TODO: short flags - deleteExperimentCmd.Flags().Var(&deleteExperimentJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteExperimentOverrides []func( + *cobra.Command, + *ml.DeleteExperiment, +) -} +func newDeleteExperiment() *cobra.Command { + cmd := &cobra.Command{} -var deleteExperimentCmd = &cobra.Command{ - Use: "delete-experiment EXPERIMENT_ID", - Short: `Delete an experiment.`, - Long: `Delete an experiment. + var deleteExperimentReq ml.DeleteExperiment + var deleteExperimentJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&deleteExperimentJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "delete-experiment EXPERIMENT_ID" + cmd.Short = `Delete an experiment.` + cmd.Long = `Delete an experiment. Marks an experiment and associated metadata, runs, metrics, params, and tags for deletion. If the experiment uses FileStore, artifacts associated with - experiment are also deleted.`, + experiment are also deleted.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -193,40 +259,62 @@ var deleteExperimentCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteExperimentOverrides { + fn(cmd, &deleteExperimentReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDeleteExperiment()) + }) } // start delete-run command -var deleteRunReq ml.DeleteRun -var deleteRunJson flags.JsonFlag -func init() { - Cmd.AddCommand(deleteRunCmd) - // TODO: short flags - deleteRunCmd.Flags().Var(&deleteRunJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteRunOverrides []func( + *cobra.Command, + *ml.DeleteRun, +) -} +func newDeleteRun() *cobra.Command { + cmd := &cobra.Command{} + + var deleteRunReq ml.DeleteRun + var deleteRunJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&deleteRunJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var deleteRunCmd = &cobra.Command{ - Use: "delete-run RUN_ID", - Short: `Delete a run.`, - Long: `Delete a run. + cmd.Use = "delete-run RUN_ID" + cmd.Short = `Delete a run.` + cmd.Long = `Delete a run. - Marks a run for deletion.`, + Marks a run for deletion.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -244,41 +332,63 @@ var deleteRunCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteRunOverrides { + fn(cmd, &deleteRunReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDeleteRun()) + }) } // start delete-tag command -var deleteTagReq ml.DeleteTag -var deleteTagJson flags.JsonFlag -func init() { - Cmd.AddCommand(deleteTagCmd) - // TODO: short flags - deleteTagCmd.Flags().Var(&deleteTagJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteTagOverrides []func( + *cobra.Command, + *ml.DeleteTag, +) -} +func newDeleteTag() *cobra.Command { + cmd := &cobra.Command{} + + var deleteTagReq ml.DeleteTag + var deleteTagJson flags.JsonFlag -var deleteTagCmd = &cobra.Command{ - Use: "delete-tag RUN_ID KEY", - Short: `Delete a tag.`, - Long: `Delete a tag. + // TODO: short flags + cmd.Flags().Var(&deleteTagJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "delete-tag RUN_ID KEY" + cmd.Short = `Delete a tag.` + cmd.Long = `Delete a tag. Deletes a tag on a run. Tags are run metadata that can be updated during a run - and after a run completes.`, + and after a run completes.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -297,25 +407,45 @@ var deleteTagCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteTagOverrides { + fn(cmd, &deleteTagReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDeleteTag()) + }) } // start get-by-name command -var getByNameReq ml.GetByNameRequest -func init() { - Cmd.AddCommand(getByNameCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getByNameOverrides []func( + *cobra.Command, + *ml.GetByNameRequest, +) -} +func newGetByName() *cobra.Command { + cmd := &cobra.Command{} -var getByNameCmd = &cobra.Command{ - Use: "get-by-name EXPERIMENT_NAME", - Short: `Get metadata.`, - Long: `Get metadata. + var getByNameReq ml.GetByNameRequest + + // TODO: short flags + + cmd.Use = "get-by-name EXPERIMENT_NAME" + cmd.Short = `Get metadata.` + cmd.Long = `Get metadata. Gets metadata for an experiment. @@ -325,15 +455,17 @@ var getByNameCmd = &cobra.Command{ them. Throws RESOURCE_DOES_NOT_EXIST if no experiment with the specified name - exists.`, + exists.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -344,35 +476,57 @@ var getByNameCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getByNameOverrides { + fn(cmd, &getByNameReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetByName()) + }) } // start get-experiment command -var getExperimentReq ml.GetExperimentRequest -func init() { - Cmd.AddCommand(getExperimentCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getExperimentOverrides []func( + *cobra.Command, + *ml.GetExperimentRequest, +) -} +func newGetExperiment() *cobra.Command { + cmd := &cobra.Command{} + + var getExperimentReq ml.GetExperimentRequest + + // TODO: short flags -var getExperimentCmd = &cobra.Command{ - Use: "get-experiment EXPERIMENT_ID", - Short: `Get an experiment.`, - Long: `Get an experiment. + cmd.Use = "get-experiment EXPERIMENT_ID" + cmd.Short = `Get an experiment.` + cmd.Long = `Get an experiment. - Gets metadata for an experiment. This method works on deleted experiments.`, + Gets metadata for an experiment. This method works on deleted experiments.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -383,40 +537,62 @@ var getExperimentCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getExperimentOverrides { + fn(cmd, &getExperimentReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetExperiment()) + }) } // start get-history command -var getHistoryReq ml.GetHistoryRequest -func init() { - Cmd.AddCommand(getHistoryCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getHistoryOverrides []func( + *cobra.Command, + *ml.GetHistoryRequest, +) - getHistoryCmd.Flags().IntVar(&getHistoryReq.MaxResults, "max-results", getHistoryReq.MaxResults, `Maximum number of Metric records to return per paginated request.`) - getHistoryCmd.Flags().StringVar(&getHistoryReq.PageToken, "page-token", getHistoryReq.PageToken, `Token indicating the page of metric histories to fetch.`) - getHistoryCmd.Flags().StringVar(&getHistoryReq.RunId, "run-id", getHistoryReq.RunId, `ID of the run from which to fetch metric values.`) - getHistoryCmd.Flags().StringVar(&getHistoryReq.RunUuid, "run-uuid", getHistoryReq.RunUuid, `[Deprecated, use run_id instead] ID of the run from which to fetch metric values.`) +func newGetHistory() *cobra.Command { + cmd := &cobra.Command{} -} + var getHistoryReq ml.GetHistoryRequest + + // TODO: short flags -var getHistoryCmd = &cobra.Command{ - Use: "get-history METRIC_KEY", - Short: `Get history of a given metric within a run.`, - Long: `Get history of a given metric within a run. + cmd.Flags().IntVar(&getHistoryReq.MaxResults, "max-results", getHistoryReq.MaxResults, `Maximum number of Metric records to return per paginated request.`) + cmd.Flags().StringVar(&getHistoryReq.PageToken, "page-token", getHistoryReq.PageToken, `Token indicating the page of metric histories to fetch.`) + cmd.Flags().StringVar(&getHistoryReq.RunId, "run-id", getHistoryReq.RunId, `ID of the run from which to fetch metric values.`) + cmd.Flags().StringVar(&getHistoryReq.RunUuid, "run-uuid", getHistoryReq.RunUuid, `[Deprecated, use run_id instead] ID of the run from which to fetch metric values.`) + + cmd.Use = "get-history METRIC_KEY" + cmd.Short = `Get history of a given metric within a run.` + cmd.Long = `Get history of a given metric within a run. - Gets a list of all values for the specified metric for a given run.`, + Gets a list of all values for the specified metric for a given run.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -427,42 +603,64 @@ var getHistoryCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getHistoryOverrides { + fn(cmd, &getHistoryReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetHistory()) + }) } // start get-run command -var getRunReq ml.GetRunRequest -func init() { - Cmd.AddCommand(getRunCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getRunOverrides []func( + *cobra.Command, + *ml.GetRunRequest, +) - getRunCmd.Flags().StringVar(&getRunReq.RunUuid, "run-uuid", getRunReq.RunUuid, `[Deprecated, use run_id instead] ID of the run to fetch.`) +func newGetRun() *cobra.Command { + cmd := &cobra.Command{} -} + var getRunReq ml.GetRunRequest -var getRunCmd = &cobra.Command{ - Use: "get-run RUN_ID", - Short: `Get a run.`, - Long: `Get a run. + // TODO: short flags + + cmd.Flags().StringVar(&getRunReq.RunUuid, "run-uuid", getRunReq.RunUuid, `[Deprecated, use run_id instead] ID of the run to fetch.`) + + cmd.Use = "get-run RUN_ID" + cmd.Short = `Get a run.` + cmd.Long = `Get a run. Gets the metadata, metrics, params, and tags for a run. In the case where multiple metrics with the same key are logged for a run, return only the value with the latest timestamp. If there are multiple values with the latest timestamp, return the maximum of - these values.`, + these values.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -473,46 +671,68 @@ var getRunCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getRunOverrides { + fn(cmd, &getRunReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetRun()) + }) } // start list-artifacts command -var listArtifactsReq ml.ListArtifactsRequest -var listArtifactsJson flags.JsonFlag -func init() { - Cmd.AddCommand(listArtifactsCmd) - // TODO: short flags - listArtifactsCmd.Flags().Var(&listArtifactsJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listArtifactsOverrides []func( + *cobra.Command, + *ml.ListArtifactsRequest, +) - listArtifactsCmd.Flags().StringVar(&listArtifactsReq.PageToken, "page-token", listArtifactsReq.PageToken, `Token indicating the page of artifact results to fetch.`) - listArtifactsCmd.Flags().StringVar(&listArtifactsReq.Path, "path", listArtifactsReq.Path, `Filter artifacts matching this path (a relative path from the root artifact directory).`) - listArtifactsCmd.Flags().StringVar(&listArtifactsReq.RunId, "run-id", listArtifactsReq.RunId, `ID of the run whose artifacts to list.`) - listArtifactsCmd.Flags().StringVar(&listArtifactsReq.RunUuid, "run-uuid", listArtifactsReq.RunUuid, `[Deprecated, use run_id instead] ID of the run whose artifacts to list.`) +func newListArtifacts() *cobra.Command { + cmd := &cobra.Command{} -} + var listArtifactsReq ml.ListArtifactsRequest + var listArtifactsJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&listArtifactsJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var listArtifactsCmd = &cobra.Command{ - Use: "list-artifacts", - Short: `Get all artifacts.`, - Long: `Get all artifacts. + cmd.Flags().StringVar(&listArtifactsReq.PageToken, "page-token", listArtifactsReq.PageToken, `Token indicating the page of artifact results to fetch.`) + cmd.Flags().StringVar(&listArtifactsReq.Path, "path", listArtifactsReq.Path, `Filter artifacts matching this path (a relative path from the root artifact directory).`) + cmd.Flags().StringVar(&listArtifactsReq.RunId, "run-id", listArtifactsReq.RunId, `ID of the run whose artifacts to list.`) + cmd.Flags().StringVar(&listArtifactsReq.RunUuid, "run-uuid", listArtifactsReq.RunUuid, `[Deprecated, use run_id instead] ID of the run whose artifacts to list.`) + + cmd.Use = "list-artifacts" + cmd.Short = `Get all artifacts.` + cmd.Long = `Get all artifacts. List artifacts for a run. Takes an optional artifact_path prefix. If it is - specified, the response contains only artifacts with the specified prefix.",`, + specified, the response contains only artifacts with the specified prefix.",` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -529,44 +749,66 @@ var listArtifactsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listArtifactsOverrides { + fn(cmd, &listArtifactsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newListArtifacts()) + }) } // start list-experiments command -var listExperimentsReq ml.ListExperimentsRequest -var listExperimentsJson flags.JsonFlag -func init() { - Cmd.AddCommand(listExperimentsCmd) - // TODO: short flags - listExperimentsCmd.Flags().Var(&listExperimentsJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listExperimentsOverrides []func( + *cobra.Command, + *ml.ListExperimentsRequest, +) - listExperimentsCmd.Flags().IntVar(&listExperimentsReq.MaxResults, "max-results", listExperimentsReq.MaxResults, `Maximum number of experiments desired.`) - listExperimentsCmd.Flags().StringVar(&listExperimentsReq.PageToken, "page-token", listExperimentsReq.PageToken, `Token indicating the page of experiments to fetch.`) - listExperimentsCmd.Flags().StringVar(&listExperimentsReq.ViewType, "view-type", listExperimentsReq.ViewType, `Qualifier for type of experiments to be returned.`) +func newListExperiments() *cobra.Command { + cmd := &cobra.Command{} -} + var listExperimentsReq ml.ListExperimentsRequest + var listExperimentsJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&listExperimentsJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var listExperimentsCmd = &cobra.Command{ - Use: "list-experiments", - Short: `List experiments.`, - Long: `List experiments. + cmd.Flags().IntVar(&listExperimentsReq.MaxResults, "max-results", listExperimentsReq.MaxResults, `Maximum number of experiments desired.`) + cmd.Flags().StringVar(&listExperimentsReq.PageToken, "page-token", listExperimentsReq.PageToken, `Token indicating the page of experiments to fetch.`) + cmd.Flags().StringVar(&listExperimentsReq.ViewType, "view-type", listExperimentsReq.ViewType, `Qualifier for type of experiments to be returned.`) + + cmd.Use = "list-experiments" + cmd.Short = `List experiments.` + cmd.Long = `List experiments. - Gets a list of all experiments.`, + Gets a list of all experiments.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -583,32 +825,52 @@ var listExperimentsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listExperimentsOverrides { + fn(cmd, &listExperimentsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newListExperiments()) + }) } // start log-batch command -var logBatchReq ml.LogBatch -var logBatchJson flags.JsonFlag -func init() { - Cmd.AddCommand(logBatchCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var logBatchOverrides []func( + *cobra.Command, + *ml.LogBatch, +) + +func newLogBatch() *cobra.Command { + cmd := &cobra.Command{} + + var logBatchReq ml.LogBatch + var logBatchJson flags.JsonFlag + // TODO: short flags - logBatchCmd.Flags().Var(&logBatchJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&logBatchJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: metrics // TODO: array: params - logBatchCmd.Flags().StringVar(&logBatchReq.RunId, "run-id", logBatchReq.RunId, `ID of the run to log under.`) + cmd.Flags().StringVar(&logBatchReq.RunId, "run-id", logBatchReq.RunId, `ID of the run to log under.`) // TODO: array: tags -} - -var logBatchCmd = &cobra.Command{ - Use: "log-batch", - Short: `Log a batch.`, - Long: `Log a batch. + cmd.Use = "log-batch" + cmd.Short = `Log a batch.` + cmd.Long = `Log a batch. Logs a batch of metrics, params, and tags for a run. If any data failed to be persisted, the server will respond with an error (non-200 status code). @@ -646,18 +908,20 @@ var logBatchCmd = &cobra.Command{ The following limits also apply to metric, param, and tag keys and values: * Metric keys, param keys, and tag keys can be up to 250 characters in length - * Parameter and tag values can be up to 250 characters in length`, + * Parameter and tag values can be up to 250 characters in length` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -674,44 +938,66 @@ var logBatchCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range logBatchOverrides { + fn(cmd, &logBatchReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newLogBatch()) + }) } // start log-inputs command -var logInputsReq ml.LogInputs -var logInputsJson flags.JsonFlag -func init() { - Cmd.AddCommand(logInputsCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var logInputsOverrides []func( + *cobra.Command, + *ml.LogInputs, +) + +func newLogInputs() *cobra.Command { + cmd := &cobra.Command{} + + var logInputsReq ml.LogInputs + var logInputsJson flags.JsonFlag + // TODO: short flags - logInputsCmd.Flags().Var(&logInputsJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&logInputsJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: datasets - logInputsCmd.Flags().StringVar(&logInputsReq.RunId, "run-id", logInputsReq.RunId, `ID of the run to log under.`) - -} + cmd.Flags().StringVar(&logInputsReq.RunId, "run-id", logInputsReq.RunId, `ID of the run to log under.`) -var logInputsCmd = &cobra.Command{ - Use: "log-inputs", - Short: `Log inputs to a run.`, - Long: `Log inputs to a run. + cmd.Use = "log-inputs" + cmd.Short = `Log inputs to a run.` + cmd.Long = `Log inputs to a run. **NOTE:** Experimental: This API may change or be removed in a future release - without warning.`, + without warning.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -728,46 +1014,68 @@ var logInputsCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range logInputsOverrides { + fn(cmd, &logInputsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newLogInputs()) + }) } // start log-metric command -var logMetricReq ml.LogMetric -var logMetricJson flags.JsonFlag -func init() { - Cmd.AddCommand(logMetricCmd) - // TODO: short flags - logMetricCmd.Flags().Var(&logMetricJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var logMetricOverrides []func( + *cobra.Command, + *ml.LogMetric, +) - logMetricCmd.Flags().StringVar(&logMetricReq.RunId, "run-id", logMetricReq.RunId, `ID of the run under which to log the metric.`) - logMetricCmd.Flags().StringVar(&logMetricReq.RunUuid, "run-uuid", logMetricReq.RunUuid, `[Deprecated, use run_id instead] ID of the run under which to log the metric.`) - logMetricCmd.Flags().Int64Var(&logMetricReq.Step, "step", logMetricReq.Step, `Step at which to log the metric.`) +func newLogMetric() *cobra.Command { + cmd := &cobra.Command{} -} + var logMetricReq ml.LogMetric + var logMetricJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&logMetricJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var logMetricCmd = &cobra.Command{ - Use: "log-metric KEY VALUE TIMESTAMP", - Short: `Log a metric.`, - Long: `Log a metric. + cmd.Flags().StringVar(&logMetricReq.RunId, "run-id", logMetricReq.RunId, `ID of the run under which to log the metric.`) + cmd.Flags().StringVar(&logMetricReq.RunUuid, "run-uuid", logMetricReq.RunUuid, `[Deprecated, use run_id instead] ID of the run under which to log the metric.`) + cmd.Flags().Int64Var(&logMetricReq.Step, "step", logMetricReq.Step, `Step at which to log the metric.`) + + cmd.Use = "log-metric KEY VALUE TIMESTAMP" + cmd.Short = `Log a metric.` + cmd.Long = `Log a metric. Logs a metric for a run. A metric is a key-value pair (string key, float value) with an associated timestamp. Examples include the various metrics that - represent ML model accuracy. A metric can be logged multiple times.`, + represent ML model accuracy. A metric can be logged multiple times.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(3) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -793,44 +1101,66 @@ var logMetricCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range logMetricOverrides { + fn(cmd, &logMetricReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newLogMetric()) + }) } // start log-model command -var logModelReq ml.LogModel -var logModelJson flags.JsonFlag -func init() { - Cmd.AddCommand(logModelCmd) - // TODO: short flags - logModelCmd.Flags().Var(&logModelJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var logModelOverrides []func( + *cobra.Command, + *ml.LogModel, +) - logModelCmd.Flags().StringVar(&logModelReq.ModelJson, "model-json", logModelReq.ModelJson, `MLmodel file in json format.`) - logModelCmd.Flags().StringVar(&logModelReq.RunId, "run-id", logModelReq.RunId, `ID of the run to log under.`) +func newLogModel() *cobra.Command { + cmd := &cobra.Command{} -} + var logModelReq ml.LogModel + var logModelJson flags.JsonFlag -var logModelCmd = &cobra.Command{ - Use: "log-model", - Short: `Log a model.`, - Long: `Log a model. + // TODO: short flags + cmd.Flags().Var(&logModelJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&logModelReq.ModelJson, "model-json", logModelReq.ModelJson, `MLmodel file in json format.`) + cmd.Flags().StringVar(&logModelReq.RunId, "run-id", logModelReq.RunId, `ID of the run to log under.`) + + cmd.Use = "log-model" + cmd.Short = `Log a model.` + cmd.Long = `Log a model. **NOTE:** Experimental: This API may change or be removed in a future release - without warning.`, + without warning.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -847,46 +1177,68 @@ var logModelCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range logModelOverrides { + fn(cmd, &logModelReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newLogModel()) + }) } // start log-param command -var logParamReq ml.LogParam -var logParamJson flags.JsonFlag -func init() { - Cmd.AddCommand(logParamCmd) - // TODO: short flags - logParamCmd.Flags().Var(&logParamJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var logParamOverrides []func( + *cobra.Command, + *ml.LogParam, +) - logParamCmd.Flags().StringVar(&logParamReq.RunId, "run-id", logParamReq.RunId, `ID of the run under which to log the param.`) - logParamCmd.Flags().StringVar(&logParamReq.RunUuid, "run-uuid", logParamReq.RunUuid, `[Deprecated, use run_id instead] ID of the run under which to log the param.`) +func newLogParam() *cobra.Command { + cmd := &cobra.Command{} -} + var logParamReq ml.LogParam + var logParamJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&logParamJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var logParamCmd = &cobra.Command{ - Use: "log-param KEY VALUE", - Short: `Log a param.`, - Long: `Log a param. + cmd.Flags().StringVar(&logParamReq.RunId, "run-id", logParamReq.RunId, `ID of the run under which to log the param.`) + cmd.Flags().StringVar(&logParamReq.RunUuid, "run-uuid", logParamReq.RunUuid, `[Deprecated, use run_id instead] ID of the run under which to log the param.`) + + cmd.Use = "log-param KEY VALUE" + cmd.Short = `Log a param.` + cmd.Long = `Log a param. Logs a param used for a run. A param is a key-value pair (string key, string value). Examples include hyperparameters used for ML model training and constant dates and values used in an ETL pipeline. A param can be logged only - once for a run.`, + once for a run.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -905,45 +1257,67 @@ var logParamCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range logParamOverrides { + fn(cmd, &logParamReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newLogParam()) + }) } // start restore-experiment command -var restoreExperimentReq ml.RestoreExperiment -var restoreExperimentJson flags.JsonFlag -func init() { - Cmd.AddCommand(restoreExperimentCmd) - // TODO: short flags - restoreExperimentCmd.Flags().Var(&restoreExperimentJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var restoreExperimentOverrides []func( + *cobra.Command, + *ml.RestoreExperiment, +) -} +func newRestoreExperiment() *cobra.Command { + cmd := &cobra.Command{} + + var restoreExperimentReq ml.RestoreExperiment + var restoreExperimentJson flags.JsonFlag -var restoreExperimentCmd = &cobra.Command{ - Use: "restore-experiment EXPERIMENT_ID", - Short: `Restores an experiment.`, - Long: `Restores an experiment. + // TODO: short flags + cmd.Flags().Var(&restoreExperimentJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "restore-experiment EXPERIMENT_ID" + cmd.Short = `Restores an experiment.` + cmd.Long = `Restores an experiment. Restore an experiment marked for deletion. This also restores associated metadata, runs, metrics, params, and tags. If experiment uses FileStore, underlying artifacts associated with experiment are also restored. Throws RESOURCE_DOES_NOT_EXIST if experiment was never created or was - permanently deleted.`, + permanently deleted.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -961,40 +1335,62 @@ var restoreExperimentCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range restoreExperimentOverrides { + fn(cmd, &restoreExperimentReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newRestoreExperiment()) + }) } // start restore-run command -var restoreRunReq ml.RestoreRun -var restoreRunJson flags.JsonFlag -func init() { - Cmd.AddCommand(restoreRunCmd) - // TODO: short flags - restoreRunCmd.Flags().Var(&restoreRunJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var restoreRunOverrides []func( + *cobra.Command, + *ml.RestoreRun, +) -} +func newRestoreRun() *cobra.Command { + cmd := &cobra.Command{} -var restoreRunCmd = &cobra.Command{ - Use: "restore-run RUN_ID", - Short: `Restore a run.`, - Long: `Restore a run. + var restoreRunReq ml.RestoreRun + var restoreRunJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&restoreRunJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "restore-run RUN_ID" + cmd.Short = `Restore a run.` + cmd.Long = `Restore a run. - Restores a deleted run.`, + Restores a deleted run.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1012,46 +1408,68 @@ var restoreRunCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range restoreRunOverrides { + fn(cmd, &restoreRunReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newRestoreRun()) + }) } // start search-experiments command -var searchExperimentsReq ml.SearchExperiments -var searchExperimentsJson flags.JsonFlag -func init() { - Cmd.AddCommand(searchExperimentsCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var searchExperimentsOverrides []func( + *cobra.Command, + *ml.SearchExperiments, +) + +func newSearchExperiments() *cobra.Command { + cmd := &cobra.Command{} + + var searchExperimentsReq ml.SearchExperiments + var searchExperimentsJson flags.JsonFlag + // TODO: short flags - searchExperimentsCmd.Flags().Var(&searchExperimentsJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&searchExperimentsJson, "json", `either inline JSON string or @path/to/file.json with request body`) - searchExperimentsCmd.Flags().StringVar(&searchExperimentsReq.Filter, "filter", searchExperimentsReq.Filter, `String representing a SQL filter condition (e.g.`) - searchExperimentsCmd.Flags().Int64Var(&searchExperimentsReq.MaxResults, "max-results", searchExperimentsReq.MaxResults, `Maximum number of experiments desired.`) + cmd.Flags().StringVar(&searchExperimentsReq.Filter, "filter", searchExperimentsReq.Filter, `String representing a SQL filter condition (e.g.`) + cmd.Flags().Int64Var(&searchExperimentsReq.MaxResults, "max-results", searchExperimentsReq.MaxResults, `Maximum number of experiments desired.`) // TODO: array: order_by - searchExperimentsCmd.Flags().StringVar(&searchExperimentsReq.PageToken, "page-token", searchExperimentsReq.PageToken, `Token indicating the page of experiments to fetch.`) - searchExperimentsCmd.Flags().Var(&searchExperimentsReq.ViewType, "view-type", `Qualifier for type of experiments to be returned.`) - -} + cmd.Flags().StringVar(&searchExperimentsReq.PageToken, "page-token", searchExperimentsReq.PageToken, `Token indicating the page of experiments to fetch.`) + cmd.Flags().Var(&searchExperimentsReq.ViewType, "view-type", `Qualifier for type of experiments to be returned.`) -var searchExperimentsCmd = &cobra.Command{ - Use: "search-experiments", - Short: `Search experiments.`, - Long: `Search experiments. + cmd.Use = "search-experiments" + cmd.Short = `Search experiments.` + cmd.Long = `Search experiments. - Searches for experiments that satisfy specified search criteria.`, + Searches for experiments that satisfy specified search criteria.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1068,49 +1486,71 @@ var searchExperimentsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range searchExperimentsOverrides { + fn(cmd, &searchExperimentsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newSearchExperiments()) + }) } // start search-runs command -var searchRunsReq ml.SearchRuns -var searchRunsJson flags.JsonFlag -func init() { - Cmd.AddCommand(searchRunsCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var searchRunsOverrides []func( + *cobra.Command, + *ml.SearchRuns, +) + +func newSearchRuns() *cobra.Command { + cmd := &cobra.Command{} + + var searchRunsReq ml.SearchRuns + var searchRunsJson flags.JsonFlag + // TODO: short flags - searchRunsCmd.Flags().Var(&searchRunsJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&searchRunsJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: experiment_ids - searchRunsCmd.Flags().StringVar(&searchRunsReq.Filter, "filter", searchRunsReq.Filter, `A filter expression over params, metrics, and tags, that allows returning a subset of runs.`) - searchRunsCmd.Flags().IntVar(&searchRunsReq.MaxResults, "max-results", searchRunsReq.MaxResults, `Maximum number of runs desired.`) + cmd.Flags().StringVar(&searchRunsReq.Filter, "filter", searchRunsReq.Filter, `A filter expression over params, metrics, and tags, that allows returning a subset of runs.`) + cmd.Flags().IntVar(&searchRunsReq.MaxResults, "max-results", searchRunsReq.MaxResults, `Maximum number of runs desired.`) // TODO: array: order_by - searchRunsCmd.Flags().StringVar(&searchRunsReq.PageToken, "page-token", searchRunsReq.PageToken, `Token for the current page of runs.`) - searchRunsCmd.Flags().Var(&searchRunsReq.RunViewType, "run-view-type", `Whether to display only active, only deleted, or all runs.`) + cmd.Flags().StringVar(&searchRunsReq.PageToken, "page-token", searchRunsReq.PageToken, `Token for the current page of runs.`) + cmd.Flags().Var(&searchRunsReq.RunViewType, "run-view-type", `Whether to display only active, only deleted, or all runs.`) -} - -var searchRunsCmd = &cobra.Command{ - Use: "search-runs", - Short: `Search for runs.`, - Long: `Search for runs. + cmd.Use = "search-runs" + cmd.Short = `Search for runs.` + cmd.Long = `Search for runs. Searches for runs that satisfy expressions. - Search expressions can use mlflowMetric and mlflowParam keys.",`, + Search expressions can use mlflowMetric and mlflowParam keys.",` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1127,40 +1567,62 @@ var searchRunsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range searchRunsOverrides { + fn(cmd, &searchRunsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newSearchRuns()) + }) } // start set-experiment-tag command -var setExperimentTagReq ml.SetExperimentTag -var setExperimentTagJson flags.JsonFlag -func init() { - Cmd.AddCommand(setExperimentTagCmd) - // TODO: short flags - setExperimentTagCmd.Flags().Var(&setExperimentTagJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var setExperimentTagOverrides []func( + *cobra.Command, + *ml.SetExperimentTag, +) -} +func newSetExperimentTag() *cobra.Command { + cmd := &cobra.Command{} -var setExperimentTagCmd = &cobra.Command{ - Use: "set-experiment-tag EXPERIMENT_ID KEY VALUE", - Short: `Set a tag.`, - Long: `Set a tag. + var setExperimentTagReq ml.SetExperimentTag + var setExperimentTagJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&setExperimentTagJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "set-experiment-tag EXPERIMENT_ID KEY VALUE" + cmd.Short = `Set a tag.` + cmd.Long = `Set a tag. - Sets a tag on an experiment. Experiment tags are metadata that can be updated.`, + Sets a tag on an experiment. Experiment tags are metadata that can be updated.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(3) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1180,44 +1642,66 @@ var setExperimentTagCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range setExperimentTagOverrides { + fn(cmd, &setExperimentTagReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newSetExperimentTag()) + }) } // start set-tag command -var setTagReq ml.SetTag -var setTagJson flags.JsonFlag -func init() { - Cmd.AddCommand(setTagCmd) - // TODO: short flags - setTagCmd.Flags().Var(&setTagJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var setTagOverrides []func( + *cobra.Command, + *ml.SetTag, +) - setTagCmd.Flags().StringVar(&setTagReq.RunId, "run-id", setTagReq.RunId, `ID of the run under which to log the tag.`) - setTagCmd.Flags().StringVar(&setTagReq.RunUuid, "run-uuid", setTagReq.RunUuid, `[Deprecated, use run_id instead] ID of the run under which to log the tag.`) +func newSetTag() *cobra.Command { + cmd := &cobra.Command{} -} + var setTagReq ml.SetTag + var setTagJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&setTagJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var setTagCmd = &cobra.Command{ - Use: "set-tag KEY VALUE", - Short: `Set a tag.`, - Long: `Set a tag. + cmd.Flags().StringVar(&setTagReq.RunId, "run-id", setTagReq.RunId, `ID of the run under which to log the tag.`) + cmd.Flags().StringVar(&setTagReq.RunUuid, "run-uuid", setTagReq.RunUuid, `[Deprecated, use run_id instead] ID of the run under which to log the tag.`) + + cmd.Use = "set-tag KEY VALUE" + cmd.Short = `Set a tag.` + cmd.Long = `Set a tag. Sets a tag on a run. Tags are run metadata that can be updated during a run - and after a run completes.`, + and after a run completes.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1236,42 +1720,64 @@ var setTagCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range setTagOverrides { + fn(cmd, &setTagReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newSetTag()) + }) } // start update-experiment command -var updateExperimentReq ml.UpdateExperiment -var updateExperimentJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateExperimentCmd) - // TODO: short flags - updateExperimentCmd.Flags().Var(&updateExperimentJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateExperimentOverrides []func( + *cobra.Command, + *ml.UpdateExperiment, +) - updateExperimentCmd.Flags().StringVar(&updateExperimentReq.NewName, "new-name", updateExperimentReq.NewName, `If provided, the experiment's name is changed to the new name.`) +func newUpdateExperiment() *cobra.Command { + cmd := &cobra.Command{} -} + var updateExperimentReq ml.UpdateExperiment + var updateExperimentJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&updateExperimentJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var updateExperimentCmd = &cobra.Command{ - Use: "update-experiment EXPERIMENT_ID", - Short: `Update an experiment.`, - Long: `Update an experiment. + cmd.Flags().StringVar(&updateExperimentReq.NewName, "new-name", updateExperimentReq.NewName, `If provided, the experiment's name is changed to the new name.`) + + cmd.Use = "update-experiment EXPERIMENT_ID" + cmd.Short = `Update an experiment.` + cmd.Long = `Update an experiment. - Updates experiment metadata.`, + Updates experiment metadata.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1289,45 +1795,67 @@ var updateExperimentCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateExperimentOverrides { + fn(cmd, &updateExperimentReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdateExperiment()) + }) } // start update-run command -var updateRunReq ml.UpdateRun -var updateRunJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateRunCmd) - // TODO: short flags - updateRunCmd.Flags().Var(&updateRunJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateRunOverrides []func( + *cobra.Command, + *ml.UpdateRun, +) - updateRunCmd.Flags().Int64Var(&updateRunReq.EndTime, "end-time", updateRunReq.EndTime, `Unix timestamp in milliseconds of when the run ended.`) - updateRunCmd.Flags().StringVar(&updateRunReq.RunId, "run-id", updateRunReq.RunId, `ID of the run to update.`) - updateRunCmd.Flags().StringVar(&updateRunReq.RunUuid, "run-uuid", updateRunReq.RunUuid, `[Deprecated, use run_id instead] ID of the run to update.`) - updateRunCmd.Flags().Var(&updateRunReq.Status, "status", `Updated status of the run.`) +func newUpdateRun() *cobra.Command { + cmd := &cobra.Command{} -} + var updateRunReq ml.UpdateRun + var updateRunJson flags.JsonFlag -var updateRunCmd = &cobra.Command{ - Use: "update-run", - Short: `Update a run.`, - Long: `Update a run. + // TODO: short flags + cmd.Flags().Var(&updateRunJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().Int64Var(&updateRunReq.EndTime, "end-time", updateRunReq.EndTime, `Unix timestamp in milliseconds of when the run ended.`) + cmd.Flags().StringVar(&updateRunReq.RunId, "run-id", updateRunReq.RunId, `ID of the run to update.`) + cmd.Flags().StringVar(&updateRunReq.RunUuid, "run-uuid", updateRunReq.RunUuid, `[Deprecated, use run_id instead] ID of the run to update.`) + cmd.Flags().Var(&updateRunReq.Status, "status", `Updated status of the run.`) + + cmd.Use = "update-run" + cmd.Short = `Update a run.` + cmd.Long = `Update a run. - Updates run metadata.`, + Updates run metadata.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1344,10 +1872,24 @@ var updateRunCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateRunOverrides { + fn(cmd, &updateRunReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdateRun()) + }) } // end service Experiments diff --git a/cmd/workspace/external-locations/external-locations.go b/cmd/workspace/external-locations/external-locations.go index a739c931c8..db6153df08 100755 --- a/cmd/workspace/external-locations/external-locations.go +++ b/cmd/workspace/external-locations/external-locations.go @@ -10,10 +10,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "external-locations", - Short: `An external location is an object that combines a cloud storage path with a storage credential that authorizes access to the cloud storage path.`, - Long: `An external location is an object that combines a cloud storage path with a +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "external-locations", + Short: `An external location is an object that combines a cloud storage path with a storage credential that authorizes access to the cloud storage path.`, + Long: `An external location is an object that combines a cloud storage path with a storage credential that authorizes access to the cloud storage path. Each external location is subject to Unity Catalog access-control policies that control which users and groups can access the credential. If a user does not @@ -26,45 +31,62 @@ var Cmd = &cobra.Command{ To create external locations, you must be a metastore admin or a user with the **CREATE_EXTERNAL_LOCATION** privilege.`, - Annotations: map[string]string{ - "package": "catalog", - }, + GroupID: "catalog", + Annotations: map[string]string{ + "package": "catalog", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq catalog.CreateExternalLocation -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *catalog.CreateExternalLocation, +) - createCmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `User-provided free-form text description.`) - createCmd.Flags().BoolVar(&createReq.ReadOnly, "read-only", createReq.ReadOnly, `Indicates whether the external location is read-only.`) - createCmd.Flags().BoolVar(&createReq.SkipValidation, "skip-validation", createReq.SkipValidation, `Skips validation of the storage credential associated with the external location.`) +func newCreate() *cobra.Command { + cmd := &cobra.Command{} -} + var createReq catalog.CreateExternalLocation + var createJson flags.JsonFlag -var createCmd = &cobra.Command{ - Use: "create NAME URL CREDENTIAL_NAME", - Short: `Create an external location.`, - Long: `Create an external location. + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `User-provided free-form text description.`) + cmd.Flags().BoolVar(&createReq.ReadOnly, "read-only", createReq.ReadOnly, `Indicates whether the external location is read-only.`) + cmd.Flags().BoolVar(&createReq.SkipValidation, "skip-validation", createReq.SkipValidation, `Skips validation of the storage credential associated with the external location.`) + + cmd.Use = "create NAME URL CREDENTIAL_NAME" + cmd.Short = `Create an external location.` + cmd.Long = `Create an external location. Creates a new external location entry in the metastore. The caller must be a metastore admin or have the **CREATE_EXTERNAL_LOCATION** privilege on both the - metastore and the associated storage credential.`, + metastore and the associated storage credential.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(3) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -84,38 +106,60 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq catalog.DeleteExternalLocationRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *catalog.DeleteExternalLocationRequest, +) - deleteCmd.Flags().BoolVar(&deleteReq.Force, "force", deleteReq.Force, `Force deletion even if there are dependent external tables or mounts.`) +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -} + var deleteReq catalog.DeleteExternalLocationRequest + + // TODO: short flags + + cmd.Flags().BoolVar(&deleteReq.Force, "force", deleteReq.Force, `Force deletion even if there are dependent external tables or mounts.`) -var deleteCmd = &cobra.Command{ - Use: "delete NAME", - Short: `Delete an external location.`, - Long: `Delete an external location. + cmd.Use = "delete NAME" + cmd.Short = `Delete an external location.` + cmd.Long = `Delete an external location. Deletes the specified external location from the metastore. The caller must be - the owner of the external location.`, + the owner of the external location.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -126,37 +170,59 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq catalog.GetExternalLocationRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *catalog.GetExternalLocationRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} -var getCmd = &cobra.Command{ - Use: "get NAME", - Short: `Get an external location.`, - Long: `Get an external location. + var getReq catalog.GetExternalLocationRequest + + // TODO: short flags + + cmd.Use = "get NAME" + cmd.Short = `Get an external location.` + cmd.Long = `Get an external location. Gets an external location from the metastore. The caller must be either a metastore admin, the owner of the external location, or a user that has some - privilege on the external location.`, + privilege on the external location.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -167,32 +233,50 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `List external locations.`, - Long: `List external locations. + cmd.Use = "list" + cmd.Short = `List external locations.` + cmd.Long = `List external locations. Gets an array of external locations (__ExternalLocationInfo__ objects) from the metastore. The caller must be a metastore admin, the owner of the external location, or a user that has some privilege on the external location. There is - no guarantee of a specific ordering of the elements in the array.`, + no guarantee of a specific ordering of the elements in the array.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.ExternalLocations.ListAll(ctx) @@ -200,50 +284,72 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq catalog.UpdateExternalLocation -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) - // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *catalog.UpdateExternalLocation, +) - updateCmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `User-provided free-form text description.`) - updateCmd.Flags().StringVar(&updateReq.CredentialName, "credential-name", updateReq.CredentialName, `Name of the storage credential used with this location.`) - updateCmd.Flags().BoolVar(&updateReq.Force, "force", updateReq.Force, `Force update even if changing url invalidates dependent external tables or mounts.`) - updateCmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `Name of the external location.`) - updateCmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `The owner of the external location.`) - updateCmd.Flags().BoolVar(&updateReq.ReadOnly, "read-only", updateReq.ReadOnly, `Indicates whether the external location is read-only.`) - updateCmd.Flags().StringVar(&updateReq.Url, "url", updateReq.Url, `Path URL of the external location.`) +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} -} + var updateReq catalog.UpdateExternalLocation + var updateJson flags.JsonFlag -var updateCmd = &cobra.Command{ - Use: "update NAME", - Short: `Update an external location.`, - Long: `Update an external location. + // TODO: short flags + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `User-provided free-form text description.`) + cmd.Flags().StringVar(&updateReq.CredentialName, "credential-name", updateReq.CredentialName, `Name of the storage credential used with this location.`) + cmd.Flags().BoolVar(&updateReq.Force, "force", updateReq.Force, `Force update even if changing url invalidates dependent external tables or mounts.`) + cmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `Name of the external location.`) + cmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `The owner of the external location.`) + cmd.Flags().BoolVar(&updateReq.ReadOnly, "read-only", updateReq.ReadOnly, `Indicates whether the external location is read-only.`) + cmd.Flags().StringVar(&updateReq.Url, "url", updateReq.Url, `Path URL of the external location.`) + + cmd.Use = "update NAME" + cmd.Short = `Update an external location.` + cmd.Long = `Update an external location. Updates an external location in the metastore. The caller must be the owner of the external location, or be a metastore admin. In the second case, the admin - can only update the name of the external location.`, + can only update the name of the external location.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -261,10 +367,24 @@ var updateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service ExternalLocations diff --git a/cmd/workspace/external-locations/overrides.go b/cmd/workspace/external-locations/overrides.go index 7efd193d93..a271e5f654 100644 --- a/cmd/workspace/external-locations/overrides.go +++ b/cmd/workspace/external-locations/overrides.go @@ -1,10 +1,17 @@ package external_locations -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{header "Name"}} {{header "Credential"}} {{header "URL"}} {{range .}}{{.Name|green}} {{.CredentialName|cyan}} {{.Url}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/workspace/functions/functions.go b/cmd/workspace/functions/functions.go index 9ce3f2faf0..8b4a50ec58 100755 --- a/cmd/workspace/functions/functions.go +++ b/cmd/workspace/functions/functions.go @@ -12,51 +12,72 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "functions", - Short: `Functions implement User-Defined Functions (UDFs) in Unity Catalog.`, - Long: `Functions implement User-Defined Functions (UDFs) in Unity Catalog. +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "functions", + Short: `Functions implement User-Defined Functions (UDFs) in Unity Catalog.`, + Long: `Functions implement User-Defined Functions (UDFs) in Unity Catalog. The function implementation can be any SQL expression or Query, and it can be invoked wherever a table reference is allowed in a query. In Unity Catalog, a function resides at the same level as a table, so it can be referenced with the form __catalog_name__.__schema_name__.__function_name__.`, - Annotations: map[string]string{ - "package": "catalog", - }, + GroupID: "catalog", + Annotations: map[string]string{ + "package": "catalog", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq catalog.CreateFunction -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *catalog.CreateFunction, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq catalog.CreateFunction + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createCmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `User-provided free-form text description.`) - createCmd.Flags().StringVar(&createReq.ExternalLanguage, "external-language", createReq.ExternalLanguage, `External function language.`) - createCmd.Flags().StringVar(&createReq.ExternalName, "external-name", createReq.ExternalName, `External function name.`) + cmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `User-provided free-form text description.`) + cmd.Flags().StringVar(&createReq.ExternalLanguage, "external-language", createReq.ExternalLanguage, `External function language.`) + cmd.Flags().StringVar(&createReq.ExternalName, "external-name", createReq.ExternalName, `External function name.`) // TODO: map via StringToStringVar: properties - createCmd.Flags().StringVar(&createReq.SqlPath, "sql-path", createReq.SqlPath, `List of schemes whose objects can be referenced without qualification.`) - -} + cmd.Flags().StringVar(&createReq.SqlPath, "sql-path", createReq.SqlPath, `List of schemes whose objects can be referenced without qualification.`) -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a function.`, - Long: `Create a function. + cmd.Use = "create" + cmd.Short = `Create a function.` + cmd.Long = `Create a function. Creates a new function The user must have the following permissions in order for the function to be created: - **USE_CATALOG** on the function's parent catalog - **USE_SCHEMA** - and **CREATE_FUNCTION** on the function's parent schema`, + and **CREATE_FUNCTION** on the function's parent schema` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -74,58 +95,67 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq catalog.DeleteFunctionRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *catalog.DeleteFunctionRequest, +) - deleteCmd.Flags().BoolVar(&deleteReq.Force, "force", deleteReq.Force, `Force deletion even if the function is notempty.`) +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -} + var deleteReq catalog.DeleteFunctionRequest + + // TODO: short flags + + cmd.Flags().BoolVar(&deleteReq.Force, "force", deleteReq.Force, `Force deletion even if the function is notempty.`) -var deleteCmd = &cobra.Command{ - Use: "delete NAME", - Short: `Delete a function.`, - Long: `Delete a function. + cmd.Use = "delete NAME" + cmd.Short = `Delete a function.` + cmd.Long = `Delete a function. Deletes the function that matches the supplied name. For the deletion to succeed, the user must satisfy one of the following conditions: - Is the owner of the function's parent catalog - Is the owner of the function's parent schema and have the **USE_CATALOG** privilege on its parent catalog - Is the owner of the function itself and have both the **USE_CATALOG** privilege on - its parent catalog and the **USE_SCHEMA** privilege on its parent schema`, + its parent catalog and the **USE_SCHEMA** privilege on its parent schema` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No NAME argument specified. Loading names for Functions drop-down." - names, err := w.Functions.FunctionInfoNameToFullNameMap(ctx, catalog.ListFunctionsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Functions drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The fully-qualified name of the function (of the form __catalog_name__.__schema_name__.__function__name__)") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the fully-qualified name of the function (of the form __catalog_name__.__schema_name__.__function__name__)") - } deleteReq.Name = args[0] err = w.Functions.Delete(ctx, deleteReq) @@ -133,25 +163,45 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq catalog.GetFunctionRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *catalog.GetFunctionRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq catalog.GetFunctionRequest + + // TODO: short flags -var getCmd = &cobra.Command{ - Use: "get NAME", - Short: `Get a function.`, - Long: `Get a function. + cmd.Use = "get NAME" + cmd.Short = `Get a function.` + cmd.Long = `Get a function. Gets a function from within a parent catalog and schema. For the fetch to succeed, the user must satisfy one of the following requirements: - Is a @@ -159,31 +209,20 @@ var getCmd = &cobra.Command{ **USE_CATALOG** privilege on the function's parent catalog and be the owner of the function - Have the **USE_CATALOG** privilege on the function's parent catalog, the **USE_SCHEMA** privilege on the function's parent schema, and the - **EXECUTE** privilege on the function itself`, + **EXECUTE** privilege on the function itself` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No NAME argument specified. Loading names for Functions drop-down." - names, err := w.Functions.FunctionInfoNameToFullNameMap(ctx, catalog.ListFunctionsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Functions drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The fully-qualified name of the function (of the form __catalog_name__.__schema_name__.__function__name__)") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the fully-qualified name of the function (of the form __catalog_name__.__schema_name__.__function__name__)") - } getReq.Name = args[0] response, err := w.Functions.Get(ctx, getReq) @@ -191,25 +230,45 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq catalog.ListFunctionsRequest -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *catalog.ListFunctionsRequest, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} + + var listReq catalog.ListFunctionsRequest -var listCmd = &cobra.Command{ - Use: "list CATALOG_NAME SCHEMA_NAME", - Short: `List functions.`, - Long: `List functions. + // TODO: short flags + + cmd.Use = "list CATALOG_NAME SCHEMA_NAME" + cmd.Short = `List functions.` + cmd.Long = `List functions. List functions within the specified parent catalog and schema. If the user is a metastore admin, all functions are returned in the output list. Otherwise, @@ -217,15 +276,17 @@ var listCmd = &cobra.Command{ **USE_SCHEMA** privilege on the schema, and the output list contains only functions for which either the user has the **EXECUTE** privilege or the user is the owner. There is no guarantee of a specific ordering of the elements in - the array.`, + the array.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -237,27 +298,47 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq catalog.UpdateFunction -func init() { - Cmd.AddCommand(updateCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *catalog.UpdateFunction, +) - updateCmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `Username of current owner of function.`) +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} -} + var updateReq catalog.UpdateFunction + + // TODO: short flags + + cmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `Username of current owner of function.`) -var updateCmd = &cobra.Command{ - Use: "update NAME", - Short: `Update a function.`, - Long: `Update a function. + cmd.Use = "update NAME" + cmd.Short = `Update a function.` + cmd.Long = `Update a function. Updates the function that matches the supplied name. Only the owner of the function can be updated. If the user is not a metastore admin, the user must @@ -266,31 +347,20 @@ var updateCmd = &cobra.Command{ function's parent schema and has the **USE_CATALOG** privilege on its parent catalog - Is the owner of the function itself and has the **USE_CATALOG** privilege on its parent catalog as well as the **USE_SCHEMA** privilege on the - function's parent schema.`, + function's parent schema.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No NAME argument specified. Loading names for Functions drop-down." - names, err := w.Functions.FunctionInfoNameToFullNameMap(ctx, catalog.ListFunctionsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Functions drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The fully-qualified name of the function (of the form __catalog_name__.__schema_name__.__function__name__)") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the fully-qualified name of the function (of the form __catalog_name__.__schema_name__.__function__name__)") - } updateReq.Name = args[0] response, err := w.Functions.Update(ctx, updateReq) @@ -298,10 +368,24 @@ var updateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Functions diff --git a/cmd/workspace/git-credentials/git-credentials.go b/cmd/workspace/git-credentials/git-credentials.go index f75ed83e03..7e61b4c4f0 100755 --- a/cmd/workspace/git-credentials/git-credentials.go +++ b/cmd/workspace/git-credentials/git-credentials.go @@ -12,54 +12,76 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "git-credentials", - Short: `Registers personal access token for Databricks to do operations on behalf of the user.`, - Long: `Registers personal access token for Databricks to do operations on behalf of +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "git-credentials", + Short: `Registers personal access token for Databricks to do operations on behalf of the user.`, + Long: `Registers personal access token for Databricks to do operations on behalf of the user. See [more info]. [more info]: https://docs.databricks.com/repos/get-access-tokens-from-git-provider.html`, - Annotations: map[string]string{ - "package": "workspace", - }, + GroupID: "workspace", + Annotations: map[string]string{ + "package": "workspace", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq workspace.CreateCredentials -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *workspace.CreateCredentials, +) - createCmd.Flags().StringVar(&createReq.GitUsername, "git-username", createReq.GitUsername, `Git username.`) - createCmd.Flags().StringVar(&createReq.PersonalAccessToken, "personal-access-token", createReq.PersonalAccessToken, `The personal access token used to authenticate to the corresponding Git provider.`) +func newCreate() *cobra.Command { + cmd := &cobra.Command{} -} + var createReq workspace.CreateCredentials + var createJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&createReq.GitUsername, "git-username", createReq.GitUsername, `Git username.`) + cmd.Flags().StringVar(&createReq.PersonalAccessToken, "personal-access-token", createReq.PersonalAccessToken, `The personal access token used to authenticate to the corresponding Git provider.`) -var createCmd = &cobra.Command{ - Use: "create GIT_PROVIDER", - Short: `Create a credential entry.`, - Long: `Create a credential entry. + cmd.Use = "create GIT_PROVIDER" + cmd.Short = `Create a credential entry.` + cmd.Long = `Create a credential entry. Creates a Git credential entry for the user. Only one Git credential per user is supported, so any attempts to create credentials if an entry already exists will fail. Use the PATCH endpoint to update existing credentials, or the - DELETE endpoint to delete existing credentials.`, + DELETE endpoint to delete existing credentials.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -77,51 +99,60 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq workspace.DeleteGitCredentialRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *workspace.DeleteGitCredentialRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete CREDENTIAL_ID", - Short: `Delete a credential.`, - Long: `Delete a credential. + var deleteReq workspace.DeleteGitCredentialRequest + + // TODO: short flags + + cmd.Use = "delete CREDENTIAL_ID" + cmd.Short = `Delete a credential.` + cmd.Long = `Delete a credential. - Deletes the specified Git credential.`, + Deletes the specified Git credential.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No CREDENTIAL_ID argument specified. Loading names for Git Credentials drop-down." - names, err := w.GitCredentials.CredentialInfoGitProviderToCredentialIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Git Credentials drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The ID for the corresponding credential to access") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the id for the corresponding credential to access") - } _, err = fmt.Sscan(args[0], &deleteReq.CredentialId) if err != nil { return fmt.Errorf("invalid CREDENTIAL_ID: %s", args[0]) @@ -132,51 +163,60 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq workspace.GetGitCredentialRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *workspace.GetGitCredentialRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} -var getCmd = &cobra.Command{ - Use: "get CREDENTIAL_ID", - Short: `Get a credential entry.`, - Long: `Get a credential entry. + var getReq workspace.GetGitCredentialRequest + + // TODO: short flags + + cmd.Use = "get CREDENTIAL_ID" + cmd.Short = `Get a credential entry.` + cmd.Long = `Get a credential entry. - Gets the Git credential with the specified credential ID.`, + Gets the Git credential with the specified credential ID.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No CREDENTIAL_ID argument specified. Loading names for Git Credentials drop-down." - names, err := w.GitCredentials.CredentialInfoGitProviderToCredentialIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Git Credentials drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The ID for the corresponding credential to access") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the id for the corresponding credential to access") - } _, err = fmt.Sscan(args[0], &getReq.CredentialId) if err != nil { return fmt.Errorf("invalid CREDENTIAL_ID: %s", args[0]) @@ -187,30 +227,48 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get Git credentials.`, - Long: `Get Git credentials. + cmd.Use = "list" + cmd.Short = `Get Git credentials.` + cmd.Long = `Get Git credentials. Lists the calling user's Git credentials. One credential per user is - supported.`, + supported.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.GitCredentials.ListAll(ctx) @@ -218,55 +276,64 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq workspace.UpdateCredentials -func init() { - Cmd.AddCommand(updateCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *workspace.UpdateCredentials, +) - updateCmd.Flags().StringVar(&updateReq.GitProvider, "git-provider", updateReq.GitProvider, `Git provider.`) - updateCmd.Flags().StringVar(&updateReq.GitUsername, "git-username", updateReq.GitUsername, `Git username.`) - updateCmd.Flags().StringVar(&updateReq.PersonalAccessToken, "personal-access-token", updateReq.PersonalAccessToken, `The personal access token used to authenticate to the corresponding Git provider.`) +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} -} + var updateReq workspace.UpdateCredentials + + // TODO: short flags -var updateCmd = &cobra.Command{ - Use: "update CREDENTIAL_ID", - Short: `Update a credential.`, - Long: `Update a credential. + cmd.Flags().StringVar(&updateReq.GitProvider, "git-provider", updateReq.GitProvider, `Git provider.`) + cmd.Flags().StringVar(&updateReq.GitUsername, "git-username", updateReq.GitUsername, `Git username.`) + cmd.Flags().StringVar(&updateReq.PersonalAccessToken, "personal-access-token", updateReq.PersonalAccessToken, `The personal access token used to authenticate to the corresponding Git provider.`) + + cmd.Use = "update CREDENTIAL_ID" + cmd.Short = `Update a credential.` + cmd.Long = `Update a credential. - Updates the specified Git credential.`, + Updates the specified Git credential.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No CREDENTIAL_ID argument specified. Loading names for Git Credentials drop-down." - names, err := w.GitCredentials.CredentialInfoGitProviderToCredentialIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Git Credentials drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The ID for the corresponding credential to access") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the id for the corresponding credential to access") - } _, err = fmt.Sscan(args[0], &updateReq.CredentialId) if err != nil { return fmt.Errorf("invalid CREDENTIAL_ID: %s", args[0]) @@ -277,10 +344,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service GitCredentials diff --git a/cmd/workspace/global-init-scripts/global-init-scripts.go b/cmd/workspace/global-init-scripts/global-init-scripts.go index b63338f6c3..e7d734f065 100755 --- a/cmd/workspace/global-init-scripts/global-init-scripts.go +++ b/cmd/workspace/global-init-scripts/global-init-scripts.go @@ -3,8 +3,6 @@ package global_init_scripts import ( - "fmt" - "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/flags" @@ -12,10 +10,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "global-init-scripts", - Short: `The Global Init Scripts API enables Workspace administrators to configure global initialization scripts for their workspace.`, - Long: `The Global Init Scripts API enables Workspace administrators to configure +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "global-init-scripts", + Short: `The Global Init Scripts API enables Workspace administrators to configure global initialization scripts for their workspace.`, + Long: `The Global Init Scripts API enables Workspace administrators to configure global initialization scripts for their workspace. These scripts run on every node in every cluster in the workspace. @@ -24,42 +27,59 @@ var Cmd = &cobra.Command{ script returns with a bad exit code, the Apache Spark container fails to launch and init scripts with later position are skipped. If enough containers fail, the entire cluster fails with a GLOBAL_INIT_SCRIPT_FAILURE error code.`, - Annotations: map[string]string{ - "package": "compute", - }, + GroupID: "compute", + Annotations: map[string]string{ + "package": "compute", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq compute.GlobalInitScriptCreateRequest -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *compute.GlobalInitScriptCreateRequest, +) - createCmd.Flags().BoolVar(&createReq.Enabled, "enabled", createReq.Enabled, `Specifies whether the script is enabled.`) - createCmd.Flags().IntVar(&createReq.Position, "position", createReq.Position, `The position of a global init script, where 0 represents the first script to run, 1 is the second script to run, in ascending order.`) +func newCreate() *cobra.Command { + cmd := &cobra.Command{} -} + var createReq compute.GlobalInitScriptCreateRequest + var createJson flags.JsonFlag -var createCmd = &cobra.Command{ - Use: "create NAME SCRIPT", - Short: `Create init script.`, - Long: `Create init script. + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().BoolVar(&createReq.Enabled, "enabled", createReq.Enabled, `Specifies whether the script is enabled.`) + cmd.Flags().IntVar(&createReq.Position, "position", createReq.Position, `The position of a global init script, where 0 represents the first script to run, 1 is the second script to run, in ascending order.`) + + cmd.Use = "create NAME SCRIPT" + cmd.Short = `Create init script.` + cmd.Long = `Create init script. - Creates a new global init script in this workspace.`, + Creates a new global init script in this workspace.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -78,51 +98,60 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq compute.DeleteGlobalInitScriptRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *compute.DeleteGlobalInitScriptRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq compute.DeleteGlobalInitScriptRequest -var deleteCmd = &cobra.Command{ - Use: "delete SCRIPT_ID", - Short: `Delete init script.`, - Long: `Delete init script. + // TODO: short flags + + cmd.Use = "delete SCRIPT_ID" + cmd.Short = `Delete init script.` + cmd.Long = `Delete init script. - Deletes a global init script.`, + Deletes a global init script.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No SCRIPT_ID argument specified. Loading names for Global Init Scripts drop-down." - names, err := w.GlobalInitScripts.GlobalInitScriptDetailsNameToScriptIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Global Init Scripts drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The ID of the global init script") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the id of the global init script") - } deleteReq.ScriptId = args[0] err = w.GlobalInitScripts.Delete(ctx, deleteReq) @@ -130,51 +159,60 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq compute.GetGlobalInitScriptRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *compute.GetGlobalInitScriptRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} -var getCmd = &cobra.Command{ - Use: "get SCRIPT_ID", - Short: `Get an init script.`, - Long: `Get an init script. + var getReq compute.GetGlobalInitScriptRequest + + // TODO: short flags + + cmd.Use = "get SCRIPT_ID" + cmd.Short = `Get an init script.` + cmd.Long = `Get an init script. - Gets all the details of a script, including its Base64-encoded contents.`, + Gets all the details of a script, including its Base64-encoded contents.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No SCRIPT_ID argument specified. Loading names for Global Init Scripts drop-down." - names, err := w.GlobalInitScripts.GlobalInitScriptDetailsNameToScriptIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Global Init Scripts drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The ID of the global init script") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the id of the global init script") - } getReq.ScriptId = args[0] response, err := w.GlobalInitScripts.Get(ctx, getReq) @@ -182,32 +220,50 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get init scripts.`, - Long: `Get init scripts. + cmd.Use = "list" + cmd.Short = `Get init scripts.` + cmd.Long = `Get init scripts. Get a list of all global init scripts for this workspace. This returns all properties for each script but **not** the script contents. To retrieve the contents of a script, use the [get a global init - script](#operation/get-script) operation.`, + script](#operation/get-script) operation.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.GlobalInitScripts.ListAll(ctx) @@ -215,39 +271,61 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq compute.GlobalInitScriptUpdateRequest -func init() { - Cmd.AddCommand(updateCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *compute.GlobalInitScriptUpdateRequest, +) - updateCmd.Flags().BoolVar(&updateReq.Enabled, "enabled", updateReq.Enabled, `Specifies whether the script is enabled.`) - updateCmd.Flags().IntVar(&updateReq.Position, "position", updateReq.Position, `The position of a script, where 0 represents the first script to run, 1 is the second script to run, in ascending order.`) +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} -} + var updateReq compute.GlobalInitScriptUpdateRequest -var updateCmd = &cobra.Command{ - Use: "update NAME SCRIPT SCRIPT_ID", - Short: `Update init script.`, - Long: `Update init script. + // TODO: short flags + + cmd.Flags().BoolVar(&updateReq.Enabled, "enabled", updateReq.Enabled, `Specifies whether the script is enabled.`) + cmd.Flags().IntVar(&updateReq.Position, "position", updateReq.Position, `The position of a script, where 0 represents the first script to run, 1 is the second script to run, in ascending order.`) + + cmd.Use = "update NAME SCRIPT SCRIPT_ID" + cmd.Short = `Update init script.` + cmd.Long = `Update init script. Updates a global init script, specifying only the fields to change. All fields - are optional. Unspecified fields retain their current value.`, + are optional. Unspecified fields retain their current value.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(3) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -260,10 +338,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service GlobalInitScripts diff --git a/cmd/workspace/grants/grants.go b/cmd/workspace/grants/grants.go index 1cc973872d..a5ebd73301 100755 --- a/cmd/workspace/grants/grants.go +++ b/cmd/workspace/grants/grants.go @@ -12,10 +12,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "grants", - Short: `In Unity Catalog, data is secure by default.`, - Long: `In Unity Catalog, data is secure by default. Initially, users have no access +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "grants", + Short: `In Unity Catalog, data is secure by default.`, + Long: `In Unity Catalog, data is secure by default. Initially, users have no access to data in a metastore. Access can be granted by either a metastore admin, the owner of an object, or the owner of the catalog or schema that contains the object. Securable objects in Unity Catalog are hierarchical and privileges are @@ -26,36 +31,53 @@ var Cmd = &cobra.Command{ automatically grants the privilege to all current and future objects within the catalog. Similarly, privileges granted on a schema are inherited by all current and future objects within that schema.`, - Annotations: map[string]string{ - "package": "catalog", - }, + GroupID: "catalog", + Annotations: map[string]string{ + "package": "catalog", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start get command -var getReq catalog.GetGrantRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *catalog.GetGrantRequest, +) - getCmd.Flags().StringVar(&getReq.Principal, "principal", getReq.Principal, `If provided, only the permissions for the specified principal (user or group) are returned.`) +func newGet() *cobra.Command { + cmd := &cobra.Command{} -} + var getReq catalog.GetGrantRequest + + // TODO: short flags -var getCmd = &cobra.Command{ - Use: "get SECURABLE_TYPE FULL_NAME", - Short: `Get permissions.`, - Long: `Get permissions. + cmd.Flags().StringVar(&getReq.Principal, "principal", getReq.Principal, `If provided, only the permissions for the specified principal (user or group) are returned.`) + + cmd.Use = "get SECURABLE_TYPE FULL_NAME" + cmd.Short = `Get permissions.` + cmd.Long = `Get permissions. - Gets the permissions for a securable.`, + Gets the permissions for a securable.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -70,37 +92,59 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start get-effective command -var getEffectiveReq catalog.GetEffectiveRequest -func init() { - Cmd.AddCommand(getEffectiveCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getEffectiveOverrides []func( + *cobra.Command, + *catalog.GetEffectiveRequest, +) - getEffectiveCmd.Flags().StringVar(&getEffectiveReq.Principal, "principal", getEffectiveReq.Principal, `If provided, only the effective permissions for the specified principal (user or group) are returned.`) +func newGetEffective() *cobra.Command { + cmd := &cobra.Command{} -} + var getEffectiveReq catalog.GetEffectiveRequest + + // TODO: short flags -var getEffectiveCmd = &cobra.Command{ - Use: "get-effective SECURABLE_TYPE FULL_NAME", - Short: `Get effective permissions.`, - Long: `Get effective permissions. + cmd.Flags().StringVar(&getEffectiveReq.Principal, "principal", getEffectiveReq.Principal, `If provided, only the effective permissions for the specified principal (user or group) are returned.`) + + cmd.Use = "get-effective SECURABLE_TYPE FULL_NAME" + cmd.Short = `Get effective permissions.` + cmd.Long = `Get effective permissions. - Gets the effective permissions for a securable.`, + Gets the effective permissions for a securable.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -115,39 +159,61 @@ var getEffectiveCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getEffectiveOverrides { + fn(cmd, &getEffectiveReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetEffective()) + }) } // start update command -var updateReq catalog.UpdatePermissions -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *catalog.UpdatePermissions, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq catalog.UpdatePermissions + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: changes -} - -var updateCmd = &cobra.Command{ - Use: "update SECURABLE_TYPE FULL_NAME", - Short: `Update permissions.`, - Long: `Update permissions. + cmd.Use = "update SECURABLE_TYPE FULL_NAME" + cmd.Short = `Update permissions.` + cmd.Long = `Update permissions. - Updates the permissions for a securable.`, + Updates the permissions for a securable.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -168,10 +234,24 @@ var updateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Grants diff --git a/cmd/workspace/groups.go b/cmd/workspace/groups.go index 92b9ae9465..43159d18bc 100644 --- a/cmd/workspace/groups.go +++ b/cmd/workspace/groups.go @@ -1,7 +1,6 @@ package workspace import ( - "github.com/databricks/cli/cmd/root" "github.com/spf13/cobra" ) @@ -55,11 +54,3 @@ func Groups() []cobra.Group { }, } } - -func init() { - // Register groups with parent command - groups := Groups() - for i := range groups { - root.RootCmd.AddGroup(&groups[i]) - } -} diff --git a/cmd/workspace/groups/groups.go b/cmd/workspace/groups/groups.go index 39a95aada0..0ef9a2696b 100755 --- a/cmd/workspace/groups/groups.go +++ b/cmd/workspace/groups/groups.go @@ -3,8 +3,6 @@ package groups import ( - "fmt" - "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/flags" @@ -12,59 +10,81 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "groups", - Short: `Groups simplify identity management, making it easier to assign access to Databricks workspace, data, and other securable objects.`, - Long: `Groups simplify identity management, making it easier to assign access to +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "groups", + Short: `Groups simplify identity management, making it easier to assign access to Databricks workspace, data, and other securable objects.`, + Long: `Groups simplify identity management, making it easier to assign access to Databricks workspace, data, and other securable objects. It is best practice to assign access to workspaces and access-control policies in Unity Catalog to groups, instead of to users individually. All Databricks workspace identities can be assigned as members of groups, and members inherit permissions that are assigned to their group.`, - Annotations: map[string]string{ - "package": "iam", - }, + GroupID: "iam", + Annotations: map[string]string{ + "package": "iam", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq iam.Group -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *iam.Group, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq iam.Group + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createCmd.Flags().StringVar(&createReq.DisplayName, "display-name", createReq.DisplayName, `String that represents a human-readable group name.`) + cmd.Flags().StringVar(&createReq.DisplayName, "display-name", createReq.DisplayName, `String that represents a human-readable group name.`) // TODO: array: entitlements - createCmd.Flags().StringVar(&createReq.ExternalId, "external-id", createReq.ExternalId, ``) + cmd.Flags().StringVar(&createReq.ExternalId, "external-id", createReq.ExternalId, ``) // TODO: array: groups - createCmd.Flags().StringVar(&createReq.Id, "id", createReq.Id, `Databricks group ID.`) + cmd.Flags().StringVar(&createReq.Id, "id", createReq.Id, `Databricks group ID.`) // TODO: array: members // TODO: complex arg: meta // TODO: array: roles -} - -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a new group.`, - Long: `Create a new group. + cmd.Use = "create" + cmd.Short = `Create a new group.` + cmd.Long = `Create a new group. Creates a group in the Databricks workspace with a unique name, using the - supplied group details.`, + supplied group details.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -81,51 +101,60 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq iam.DeleteGroupRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *iam.DeleteGroupRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete ID", - Short: `Delete a group.`, - Long: `Delete a group. + var deleteReq iam.DeleteGroupRequest + + // TODO: short flags + + cmd.Use = "delete ID" + cmd.Short = `Delete a group.` + cmd.Long = `Delete a group. - Deletes a group from the Databricks workspace.`, + Deletes a group from the Databricks workspace.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Groups drop-down." - names, err := w.Groups.GroupDisplayNameToIdMap(ctx, iam.ListGroupsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Groups drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID for a group in the Databricks workspace") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id for a group in the databricks workspace") - } deleteReq.Id = args[0] err = w.Groups.Delete(ctx, deleteReq) @@ -133,51 +162,60 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq iam.GetGroupRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *iam.GetGroupRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq iam.GetGroupRequest -var getCmd = &cobra.Command{ - Use: "get ID", - Short: `Get group details.`, - Long: `Get group details. + // TODO: short flags + + cmd.Use = "get ID" + cmd.Short = `Get group details.` + cmd.Long = `Get group details. - Gets the information for a specific group in the Databricks workspace.`, + Gets the information for a specific group in the Databricks workspace.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Groups drop-down." - names, err := w.Groups.GroupDisplayNameToIdMap(ctx, iam.ListGroupsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Groups drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID for a group in the Databricks workspace") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id for a group in the databricks workspace") - } getReq.Id = args[0] response, err := w.Groups.Get(ctx, getReq) @@ -185,48 +223,70 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq iam.ListGroupsRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *iam.ListGroupsRequest, +) - listCmd.Flags().StringVar(&listReq.Attributes, "attributes", listReq.Attributes, `Comma-separated list of attributes to return in response.`) - listCmd.Flags().IntVar(&listReq.Count, "count", listReq.Count, `Desired number of results per page.`) - listCmd.Flags().StringVar(&listReq.ExcludedAttributes, "excluded-attributes", listReq.ExcludedAttributes, `Comma-separated list of attributes to exclude in response.`) - listCmd.Flags().StringVar(&listReq.Filter, "filter", listReq.Filter, `Query by which the results have to be filtered.`) - listCmd.Flags().StringVar(&listReq.SortBy, "sort-by", listReq.SortBy, `Attribute to sort the results.`) - listCmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order to sort the results.`) - listCmd.Flags().IntVar(&listReq.StartIndex, "start-index", listReq.StartIndex, `Specifies the index of the first result.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq iam.ListGroupsRequest + var listJson flags.JsonFlag -var listCmd = &cobra.Command{ - Use: "list", - Short: `List group details.`, - Long: `List group details. + // TODO: short flags + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&listReq.Attributes, "attributes", listReq.Attributes, `Comma-separated list of attributes to return in response.`) + cmd.Flags().IntVar(&listReq.Count, "count", listReq.Count, `Desired number of results per page.`) + cmd.Flags().StringVar(&listReq.ExcludedAttributes, "excluded-attributes", listReq.ExcludedAttributes, `Comma-separated list of attributes to exclude in response.`) + cmd.Flags().StringVar(&listReq.Filter, "filter", listReq.Filter, `Query by which the results have to be filtered.`) + cmd.Flags().StringVar(&listReq.SortBy, "sort-by", listReq.SortBy, `Attribute to sort the results.`) + cmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order to sort the results.`) + cmd.Flags().IntVar(&listReq.StartIndex, "start-index", listReq.StartIndex, `Specifies the index of the first result.`) + + cmd.Use = "list" + cmd.Short = `List group details.` + cmd.Long = `List group details. - Gets all details of the groups associated with the Databricks workspace.`, + Gets all details of the groups associated with the Databricks workspace.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -243,36 +303,62 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start patch command -var patchReq iam.PartialUpdate -var patchJson flags.JsonFlag -func init() { - Cmd.AddCommand(patchCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var patchOverrides []func( + *cobra.Command, + *iam.PartialUpdate, +) + +func newPatch() *cobra.Command { + cmd := &cobra.Command{} + + var patchReq iam.PartialUpdate + var patchJson flags.JsonFlag + // TODO: short flags - patchCmd.Flags().Var(&patchJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&patchJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: Operations // TODO: array: schema -} - -var patchCmd = &cobra.Command{ - Use: "patch ID", - Short: `Update group details.`, - Long: `Update group details. + cmd.Use = "patch ID" + cmd.Short = `Update group details.` + cmd.Long = `Update group details. - Partially updates the details of a group.`, + Partially updates the details of a group.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -282,23 +368,6 @@ var patchCmd = &cobra.Command{ return err } } - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Groups drop-down." - names, err := w.Groups.GroupDisplayNameToIdMap(ctx, iam.ListGroupsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Groups drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID for a group in the Databricks workspace") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id for a group in the databricks workspace") - } patchReq.Id = args[0] err = w.Groups.Patch(ctx, patchReq) @@ -306,42 +375,71 @@ var patchCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range patchOverrides { + fn(cmd, &patchReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newPatch()) + }) } // start update command -var updateReq iam.Group -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *iam.Group, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq iam.Group + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) - updateCmd.Flags().StringVar(&updateReq.DisplayName, "display-name", updateReq.DisplayName, `String that represents a human-readable group name.`) + cmd.Flags().StringVar(&updateReq.DisplayName, "display-name", updateReq.DisplayName, `String that represents a human-readable group name.`) // TODO: array: entitlements - updateCmd.Flags().StringVar(&updateReq.ExternalId, "external-id", updateReq.ExternalId, ``) + cmd.Flags().StringVar(&updateReq.ExternalId, "external-id", updateReq.ExternalId, ``) // TODO: array: groups - updateCmd.Flags().StringVar(&updateReq.Id, "id", updateReq.Id, `Databricks group ID.`) + cmd.Flags().StringVar(&updateReq.Id, "id", updateReq.Id, `Databricks group ID.`) // TODO: array: members // TODO: complex arg: meta // TODO: array: roles -} - -var updateCmd = &cobra.Command{ - Use: "update ID", - Short: `Replace a group.`, - Long: `Replace a group. + cmd.Use = "update ID" + cmd.Short = `Replace a group.` + cmd.Long = `Replace a group. - Updates the details of a group by replacing the entire group entity.`, + Updates the details of a group by replacing the entire group entity.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -351,23 +449,6 @@ var updateCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Groups drop-down." - names, err := w.Groups.GroupDisplayNameToIdMap(ctx, iam.ListGroupsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Groups drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Databricks group ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have databricks group id") - } updateReq.Id = args[0] } @@ -376,10 +457,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Groups diff --git a/cmd/workspace/groups/overrides.go b/cmd/workspace/groups/overrides.go index 28c91c4d20..db9c7610cc 100644 --- a/cmd/workspace/groups/overrides.go +++ b/cmd/workspace/groups/overrides.go @@ -1,10 +1,18 @@ package groups -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/databricks-sdk-go/service/iam" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command, listReq *iam.ListGroupsRequest) { listReq.Attributes = "id,displayName" listCmd.Annotations["template"] = cmdio.Heredoc(` {{range .}}{{.Id|green}} {{.DisplayName}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/workspace/instance-pools/instance-pools.go b/cmd/workspace/instance-pools/instance-pools.go index 80c091e2af..e1e3cd21dd 100755 --- a/cmd/workspace/instance-pools/instance-pools.go +++ b/cmd/workspace/instance-pools/instance-pools.go @@ -3,8 +3,6 @@ package instance_pools import ( - "fmt" - "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/flags" @@ -12,10 +10,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "instance-pools", - Short: `Instance Pools API are used to create, edit, delete and list instance pools by using ready-to-use cloud instances which reduces a cluster start and auto-scaling times.`, - Long: `Instance Pools API are used to create, edit, delete and list instance pools by +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "instance-pools", + Short: `Instance Pools API are used to create, edit, delete and list instance pools by using ready-to-use cloud instances which reduces a cluster start and auto-scaling times.`, + Long: `Instance Pools API are used to create, edit, delete and list instance pools by using ready-to-use cloud instances which reduces a cluster start and auto-scaling times. @@ -33,52 +36,69 @@ var Cmd = &cobra.Command{ Databricks does not charge DBUs while instances are idle in the pool. Instance provider billing does apply. See pricing.`, - Annotations: map[string]string{ - "package": "compute", - }, + GroupID: "compute", + Annotations: map[string]string{ + "package": "compute", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq compute.CreateInstancePool -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *compute.CreateInstancePool, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq compute.CreateInstancePool + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: aws_attributes // TODO: complex arg: azure_attributes // TODO: map via StringToStringVar: custom_tags // TODO: complex arg: disk_spec - createCmd.Flags().BoolVar(&createReq.EnableElasticDisk, "enable-elastic-disk", createReq.EnableElasticDisk, `Autoscaling Local Storage: when enabled, this instances in this pool will dynamically acquire additional disk space when its Spark workers are running low on disk space.`) + cmd.Flags().BoolVar(&createReq.EnableElasticDisk, "enable-elastic-disk", createReq.EnableElasticDisk, `Autoscaling Local Storage: when enabled, this instances in this pool will dynamically acquire additional disk space when its Spark workers are running low on disk space.`) // TODO: complex arg: gcp_attributes - createCmd.Flags().IntVar(&createReq.IdleInstanceAutoterminationMinutes, "idle-instance-autotermination-minutes", createReq.IdleInstanceAutoterminationMinutes, `Automatically terminates the extra instances in the pool cache after they are inactive for this time in minutes if min_idle_instances requirement is already met.`) + cmd.Flags().IntVar(&createReq.IdleInstanceAutoterminationMinutes, "idle-instance-autotermination-minutes", createReq.IdleInstanceAutoterminationMinutes, `Automatically terminates the extra instances in the pool cache after they are inactive for this time in minutes if min_idle_instances requirement is already met.`) // TODO: complex arg: instance_pool_fleet_attributes - createCmd.Flags().IntVar(&createReq.MaxCapacity, "max-capacity", createReq.MaxCapacity, `Maximum number of outstanding instances to keep in the pool, including both instances used by clusters and idle instances.`) - createCmd.Flags().IntVar(&createReq.MinIdleInstances, "min-idle-instances", createReq.MinIdleInstances, `Minimum number of idle instances to keep in the instance pool.`) + cmd.Flags().IntVar(&createReq.MaxCapacity, "max-capacity", createReq.MaxCapacity, `Maximum number of outstanding instances to keep in the pool, including both instances used by clusters and idle instances.`) + cmd.Flags().IntVar(&createReq.MinIdleInstances, "min-idle-instances", createReq.MinIdleInstances, `Minimum number of idle instances to keep in the instance pool.`) // TODO: array: preloaded_docker_images // TODO: array: preloaded_spark_versions -} - -var createCmd = &cobra.Command{ - Use: "create INSTANCE_POOL_NAME NODE_TYPE_ID", - Short: `Create a new instance pool.`, - Long: `Create a new instance pool. + cmd.Use = "create INSTANCE_POOL_NAME NODE_TYPE_ID" + cmd.Short = `Create a new instance pool.` + cmd.Long = `Create a new instance pool. - Creates a new instance pool using idle and ready-to-use cloud instances.`, + Creates a new instance pool using idle and ready-to-use cloud instances.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -97,34 +117,63 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq compute.DeleteInstancePool -var deleteJson flags.JsonFlag -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags - deleteCmd.Flags().Var(&deleteJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *compute.DeleteInstancePool, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq compute.DeleteInstancePool + var deleteJson flags.JsonFlag -var deleteCmd = &cobra.Command{ - Use: "delete INSTANCE_POOL_ID", - Short: `Delete an instance pool.`, - Long: `Delete an instance pool. + // TODO: short flags + cmd.Flags().Var(&deleteJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "delete INSTANCE_POOL_ID" + cmd.Short = `Delete an instance pool.` + cmd.Long = `Delete an instance pool. Deletes the instance pool permanently. The idle instances in the pool are - terminated asynchronously.`, + terminated asynchronously.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -134,23 +183,6 @@ var deleteCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No INSTANCE_POOL_ID argument specified. Loading names for Instance Pools drop-down." - names, err := w.InstancePools.InstancePoolAndStatsInstancePoolNameToInstancePoolIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Instance Pools drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The instance pool to be terminated") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the instance pool to be terminated") - } deleteReq.InstancePoolId = args[0] } @@ -159,53 +191,75 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start edit command -var editReq compute.EditInstancePool -var editJson flags.JsonFlag -func init() { - Cmd.AddCommand(editCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var editOverrides []func( + *cobra.Command, + *compute.EditInstancePool, +) + +func newEdit() *cobra.Command { + cmd := &cobra.Command{} + + var editReq compute.EditInstancePool + var editJson flags.JsonFlag + // TODO: short flags - editCmd.Flags().Var(&editJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&editJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: aws_attributes // TODO: complex arg: azure_attributes // TODO: map via StringToStringVar: custom_tags // TODO: complex arg: disk_spec - editCmd.Flags().BoolVar(&editReq.EnableElasticDisk, "enable-elastic-disk", editReq.EnableElasticDisk, `Autoscaling Local Storage: when enabled, this instances in this pool will dynamically acquire additional disk space when its Spark workers are running low on disk space.`) + cmd.Flags().BoolVar(&editReq.EnableElasticDisk, "enable-elastic-disk", editReq.EnableElasticDisk, `Autoscaling Local Storage: when enabled, this instances in this pool will dynamically acquire additional disk space when its Spark workers are running low on disk space.`) // TODO: complex arg: gcp_attributes - editCmd.Flags().IntVar(&editReq.IdleInstanceAutoterminationMinutes, "idle-instance-autotermination-minutes", editReq.IdleInstanceAutoterminationMinutes, `Automatically terminates the extra instances in the pool cache after they are inactive for this time in minutes if min_idle_instances requirement is already met.`) + cmd.Flags().IntVar(&editReq.IdleInstanceAutoterminationMinutes, "idle-instance-autotermination-minutes", editReq.IdleInstanceAutoterminationMinutes, `Automatically terminates the extra instances in the pool cache after they are inactive for this time in minutes if min_idle_instances requirement is already met.`) // TODO: complex arg: instance_pool_fleet_attributes - editCmd.Flags().IntVar(&editReq.MaxCapacity, "max-capacity", editReq.MaxCapacity, `Maximum number of outstanding instances to keep in the pool, including both instances used by clusters and idle instances.`) - editCmd.Flags().IntVar(&editReq.MinIdleInstances, "min-idle-instances", editReq.MinIdleInstances, `Minimum number of idle instances to keep in the instance pool.`) + cmd.Flags().IntVar(&editReq.MaxCapacity, "max-capacity", editReq.MaxCapacity, `Maximum number of outstanding instances to keep in the pool, including both instances used by clusters and idle instances.`) + cmd.Flags().IntVar(&editReq.MinIdleInstances, "min-idle-instances", editReq.MinIdleInstances, `Minimum number of idle instances to keep in the instance pool.`) // TODO: array: preloaded_docker_images // TODO: array: preloaded_spark_versions -} - -var editCmd = &cobra.Command{ - Use: "edit INSTANCE_POOL_ID INSTANCE_POOL_NAME NODE_TYPE_ID", - Short: `Edit an existing instance pool.`, - Long: `Edit an existing instance pool. + cmd.Use = "edit INSTANCE_POOL_ID INSTANCE_POOL_NAME NODE_TYPE_ID" + cmd.Short = `Edit an existing instance pool.` + cmd.Long = `Edit an existing instance pool. - Modifies the configuration of an existing instance pool.`, + Modifies the configuration of an existing instance pool.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(3) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -225,51 +279,60 @@ var editCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range editOverrides { + fn(cmd, &editReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newEdit()) + }) } // start get command -var getReq compute.GetInstancePoolRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *compute.GetInstancePoolRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq compute.GetInstancePoolRequest + + // TODO: short flags -var getCmd = &cobra.Command{ - Use: "get INSTANCE_POOL_ID", - Short: `Get instance pool information.`, - Long: `Get instance pool information. + cmd.Use = "get INSTANCE_POOL_ID" + cmd.Short = `Get instance pool information.` + cmd.Long = `Get instance pool information. - Retrieve the information for an instance pool based on its identifier.`, + Retrieve the information for an instance pool based on its identifier.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No INSTANCE_POOL_ID argument specified. Loading names for Instance Pools drop-down." - names, err := w.InstancePools.InstancePoolAndStatsInstancePoolNameToInstancePoolIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Instance Pools drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The canonical unique identifier for the instance pool") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the canonical unique identifier for the instance pool") - } getReq.InstancePoolId = args[0] response, err := w.InstancePools.Get(ctx, getReq) @@ -277,29 +340,47 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `List instance pool info.`, - Long: `List instance pool info. + cmd.Use = "list" + cmd.Short = `List instance pool info.` + cmd.Long = `List instance pool info. - Gets a list of instance pools with their statistics.`, + Gets a list of instance pools with their statistics.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.InstancePools.ListAll(ctx) @@ -307,10 +388,24 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // end service InstancePools diff --git a/cmd/workspace/instance-pools/overrides.go b/cmd/workspace/instance-pools/overrides.go index 11a76bdd52..f62f8c5367 100644 --- a/cmd/workspace/instance-pools/overrides.go +++ b/cmd/workspace/instance-pools/overrides.go @@ -1,9 +1,16 @@ package instance_pools -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{range .}}{{.InstancePoolId|green}} {{.InstancePoolName}} {{.NodeTypeId}} {{.State}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/workspace/instance-profiles/instance-profiles.go b/cmd/workspace/instance-profiles/instance-profiles.go index 17eea267ce..0922a5ae3b 100755 --- a/cmd/workspace/instance-profiles/instance-profiles.go +++ b/cmd/workspace/instance-profiles/instance-profiles.go @@ -10,53 +10,75 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "instance-profiles", - Short: `The Instance Profiles API allows admins to add, list, and remove instance profiles that users can launch clusters with.`, - Long: `The Instance Profiles API allows admins to add, list, and remove instance +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "instance-profiles", + Short: `The Instance Profiles API allows admins to add, list, and remove instance profiles that users can launch clusters with.`, + Long: `The Instance Profiles API allows admins to add, list, and remove instance profiles that users can launch clusters with. Regular users can list the instance profiles available to them. See [Secure access to S3 buckets] using instance profiles for more information. [Secure access to S3 buckets]: https://docs.databricks.com/administration-guide/cloud-configurations/aws/instance-profiles.html`, - Annotations: map[string]string{ - "package": "compute", - }, + GroupID: "compute", + Annotations: map[string]string{ + "package": "compute", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start add command -var addReq compute.AddInstanceProfile -var addJson flags.JsonFlag -func init() { - Cmd.AddCommand(addCmd) - // TODO: short flags - addCmd.Flags().Var(&addJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var addOverrides []func( + *cobra.Command, + *compute.AddInstanceProfile, +) - addCmd.Flags().StringVar(&addReq.IamRoleArn, "iam-role-arn", addReq.IamRoleArn, `The AWS IAM role ARN of the role associated with the instance profile.`) - addCmd.Flags().BoolVar(&addReq.IsMetaInstanceProfile, "is-meta-instance-profile", addReq.IsMetaInstanceProfile, `Boolean flag indicating whether the instance profile should only be used in credential passthrough scenarios.`) - addCmd.Flags().BoolVar(&addReq.SkipValidation, "skip-validation", addReq.SkipValidation, `By default, Databricks validates that it has sufficient permissions to launch instances with the instance profile.`) +func newAdd() *cobra.Command { + cmd := &cobra.Command{} -} + var addReq compute.AddInstanceProfile + var addJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&addJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&addReq.IamRoleArn, "iam-role-arn", addReq.IamRoleArn, `The AWS IAM role ARN of the role associated with the instance profile.`) + cmd.Flags().BoolVar(&addReq.IsMetaInstanceProfile, "is-meta-instance-profile", addReq.IsMetaInstanceProfile, `Boolean flag indicating whether the instance profile should only be used in credential passthrough scenarios.`) + cmd.Flags().BoolVar(&addReq.SkipValidation, "skip-validation", addReq.SkipValidation, `By default, Databricks validates that it has sufficient permissions to launch instances with the instance profile.`) -var addCmd = &cobra.Command{ - Use: "add INSTANCE_PROFILE_ARN", - Short: `Register an instance profile.`, - Long: `Register an instance profile. + cmd.Use = "add INSTANCE_PROFILE_ARN" + cmd.Short = `Register an instance profile.` + cmd.Long = `Register an instance profile. In the UI, you can select the instance profile when launching clusters. This - API is only available to admin users.`, + API is only available to admin users.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -74,30 +96,50 @@ var addCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range addOverrides { + fn(cmd, &addReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newAdd()) + }) } // start edit command -var editReq compute.InstanceProfile -var editJson flags.JsonFlag -func init() { - Cmd.AddCommand(editCmd) - // TODO: short flags - editCmd.Flags().Var(&editJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var editOverrides []func( + *cobra.Command, + *compute.InstanceProfile, +) - editCmd.Flags().StringVar(&editReq.IamRoleArn, "iam-role-arn", editReq.IamRoleArn, `The AWS IAM role ARN of the role associated with the instance profile.`) - editCmd.Flags().BoolVar(&editReq.IsMetaInstanceProfile, "is-meta-instance-profile", editReq.IsMetaInstanceProfile, `Boolean flag indicating whether the instance profile should only be used in credential passthrough scenarios.`) +func newEdit() *cobra.Command { + cmd := &cobra.Command{} -} + var editReq compute.InstanceProfile + var editJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&editJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var editCmd = &cobra.Command{ - Use: "edit INSTANCE_PROFILE_ARN", - Short: `Edit an instance profile.`, - Long: `Edit an instance profile. + cmd.Flags().StringVar(&editReq.IamRoleArn, "iam-role-arn", editReq.IamRoleArn, `The AWS IAM role ARN of the role associated with the instance profile.`) + cmd.Flags().BoolVar(&editReq.IsMetaInstanceProfile, "is-meta-instance-profile", editReq.IsMetaInstanceProfile, `Boolean flag indicating whether the instance profile should only be used in credential passthrough scenarios.`) + + cmd.Use = "edit INSTANCE_PROFILE_ARN" + cmd.Short = `Edit an instance profile.` + cmd.Long = `Edit an instance profile. The only supported field to change is the optional IAM role ARN associated with the instance profile. It is required to specify the IAM role ARN if both @@ -113,18 +155,20 @@ var editCmd = &cobra.Command{ This API is only available to admin users. [Databricks SQL Serverless]: https://docs.databricks.com/sql/admin/serverless.html - [Enable serverless SQL warehouses]: https://docs.databricks.com/sql/admin/serverless.html`, + [Enable serverless SQL warehouses]: https://docs.databricks.com/sql/admin/serverless.html` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -142,31 +186,49 @@ var editCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range editOverrides { + fn(cmd, &editReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newEdit()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `List available instance profiles.`, - Long: `List available instance profiles. + cmd.Use = "list" + cmd.Short = `List available instance profiles.` + cmd.Long = `List available instance profiles. List the instance profiles that the calling user can use to launch a cluster. - This API is available to all users.`, + This API is available to all users.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.InstanceProfiles.ListAll(ctx) @@ -174,43 +236,65 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start remove command -var removeReq compute.RemoveInstanceProfile -var removeJson flags.JsonFlag -func init() { - Cmd.AddCommand(removeCmd) - // TODO: short flags - removeCmd.Flags().Var(&removeJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var removeOverrides []func( + *cobra.Command, + *compute.RemoveInstanceProfile, +) -} +func newRemove() *cobra.Command { + cmd := &cobra.Command{} -var removeCmd = &cobra.Command{ - Use: "remove INSTANCE_PROFILE_ARN", - Short: `Remove the instance profile.`, - Long: `Remove the instance profile. + var removeReq compute.RemoveInstanceProfile + var removeJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&removeJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "remove INSTANCE_PROFILE_ARN" + cmd.Short = `Remove the instance profile.` + cmd.Long = `Remove the instance profile. Remove the instance profile with the provided ARN. Existing clusters with this instance profile will continue to function. - This API is only accessible to admin users.`, + This API is only accessible to admin users.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -228,10 +312,24 @@ var removeCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range removeOverrides { + fn(cmd, &removeReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newRemove()) + }) } // end service InstanceProfiles diff --git a/cmd/workspace/instance-profiles/overrides.go b/cmd/workspace/instance-profiles/overrides.go index 3b5cbd1c6e..adf0605289 100644 --- a/cmd/workspace/instance-profiles/overrides.go +++ b/cmd/workspace/instance-profiles/overrides.go @@ -1,9 +1,16 @@ package instance_profiles -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{range .}}{{.InstanceProfileArn}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/workspace/ip-access-lists/ip-access-lists.go b/cmd/workspace/ip-access-lists/ip-access-lists.go index 94bd110d06..081cb385c4 100755 --- a/cmd/workspace/ip-access-lists/ip-access-lists.go +++ b/cmd/workspace/ip-access-lists/ip-access-lists.go @@ -12,10 +12,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "ip-access-lists", - Short: `IP Access List enables admins to configure IP access lists.`, - Long: `IP Access List enables admins to configure IP access lists. +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "ip-access-lists", + Short: `IP Access List enables admins to configure IP access lists.`, + Long: `IP Access List enables admins to configure IP access lists. IP access lists affect web application access and REST API access to this workspace only. If the feature is disabled for a workspace, all access is @@ -36,26 +41,41 @@ var Cmd = &cobra.Command{ After changes to the IP access list feature, it can take a few minutes for changes to take effect.`, - Annotations: map[string]string{ - "package": "settings", - }, + GroupID: "settings", + Annotations: map[string]string{ + "package": "settings", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq settings.CreateIpAccessList -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *settings.CreateIpAccessList, +) -} +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq settings.CreateIpAccessList + var createJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create access list.`, - Long: `Create access list. + cmd.Use = "create" + cmd.Short = `Create access list.` + cmd.Long = `Create access list. Creates an IP access list for this workspace. @@ -72,11 +92,12 @@ var createCmd = &cobra.Command{ It can take a few minutes for the changes to take effect. **Note**: Your new IP access list has no effect until you enable the feature. See - :method:workspaceconf/setStatus`, + :method:workspaceconf/setStatus` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -94,51 +115,60 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq settings.DeleteIpAccessListRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *settings.DeleteIpAccessListRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete IP_ACCESS_LIST_ID", - Short: `Delete access list.`, - Long: `Delete access list. + var deleteReq settings.DeleteIpAccessListRequest + + // TODO: short flags + + cmd.Use = "delete IP_ACCESS_LIST_ID" + cmd.Short = `Delete access list.` + cmd.Long = `Delete access list. - Deletes an IP access list, specified by its list ID.`, + Deletes an IP access list, specified by its list ID.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No IP_ACCESS_LIST_ID argument specified. Loading names for Ip Access Lists drop-down." - names, err := w.IpAccessLists.IpAccessListInfoLabelToListIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Ip Access Lists drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The ID for the corresponding IP access list to modify") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the id for the corresponding ip access list to modify") - } deleteReq.IpAccessListId = args[0] err = w.IpAccessLists.Delete(ctx, deleteReq) @@ -146,51 +176,60 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq settings.GetIpAccessListRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *settings.GetIpAccessListRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq settings.GetIpAccessListRequest + + // TODO: short flags -var getCmd = &cobra.Command{ - Use: "get IP_ACCESS_LIST_ID", - Short: `Get access list.`, - Long: `Get access list. + cmd.Use = "get IP_ACCESS_LIST_ID" + cmd.Short = `Get access list.` + cmd.Long = `Get access list. - Gets an IP access list, specified by its list ID.`, + Gets an IP access list, specified by its list ID.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No IP_ACCESS_LIST_ID argument specified. Loading names for Ip Access Lists drop-down." - names, err := w.IpAccessLists.IpAccessListInfoLabelToListIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Ip Access Lists drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The ID for the corresponding IP access list to modify") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the id for the corresponding ip access list to modify") - } getReq.IpAccessListId = args[0] response, err := w.IpAccessLists.Get(ctx, getReq) @@ -198,29 +237,47 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get access lists.`, - Long: `Get access lists. + cmd.Use = "list" + cmd.Short = `Get access lists.` + cmd.Long = `Get access lists. - Gets all IP access lists for the specified workspace.`, + Gets all IP access lists for the specified workspace.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.IpAccessLists.ListAll(ctx) @@ -228,29 +285,49 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start replace command -var replaceReq settings.ReplaceIpAccessList -var replaceJson flags.JsonFlag -func init() { - Cmd.AddCommand(replaceCmd) - // TODO: short flags - replaceCmd.Flags().Var(&replaceJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var replaceOverrides []func( + *cobra.Command, + *settings.ReplaceIpAccessList, +) - replaceCmd.Flags().StringVar(&replaceReq.ListId, "list-id", replaceReq.ListId, `Universally unique identifier (UUID) of the IP access list.`) +func newReplace() *cobra.Command { + cmd := &cobra.Command{} -} + var replaceReq settings.ReplaceIpAccessList + var replaceJson flags.JsonFlag -var replaceCmd = &cobra.Command{ - Use: "replace", - Short: `Replace access list.`, - Long: `Replace access list. + // TODO: short flags + cmd.Flags().Var(&replaceJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&replaceReq.ListId, "list-id", replaceReq.ListId, `Universally unique identifier (UUID) of the IP access list.`) + + cmd.Use = "replace" + cmd.Short = `Replace access list.` + cmd.Long = `Replace access list. Replaces an IP access list, specified by its ID. @@ -263,11 +340,12 @@ var replaceCmd = &cobra.Command{ calling user's current IP, error 400 is returned with error_code value INVALID_STATE. It can take a few minutes for the changes to take effect. Note that your resulting IP access list has no effect until you enable the - feature. See :method:workspaceconf/setStatus.`, + feature. See :method:workspaceconf/setStatus.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -285,29 +363,49 @@ var replaceCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range replaceOverrides { + fn(cmd, &replaceReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newReplace()) + }) } // start update command -var updateReq settings.UpdateIpAccessList -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) - // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *settings.UpdateIpAccessList, +) - updateCmd.Flags().StringVar(&updateReq.ListId, "list-id", updateReq.ListId, `Universally unique identifier (UUID) of the IP access list.`) +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} -} + var updateReq settings.UpdateIpAccessList + var updateJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&updateReq.ListId, "list-id", updateReq.ListId, `Universally unique identifier (UUID) of the IP access list.`) -var updateCmd = &cobra.Command{ - Use: "update", - Short: `Update access list.`, - Long: `Update access list. + cmd.Use = "update" + cmd.Short = `Update access list.` + cmd.Long = `Update access list. Updates an existing IP access list, specified by its ID. @@ -324,11 +422,12 @@ var updateCmd = &cobra.Command{ It can take a few minutes for the changes to take effect. Note that your resulting IP access list has no effect until you enable the feature. See - :method:workspaceconf/setStatus.`, + :method:workspaceconf/setStatus.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -346,10 +445,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service IpAccessLists diff --git a/cmd/workspace/ip-access-lists/overrides.go b/cmd/workspace/ip-access-lists/overrides.go index abea3032fd..ab4db1ec6c 100644 --- a/cmd/workspace/ip-access-lists/overrides.go +++ b/cmd/workspace/ip-access-lists/overrides.go @@ -1,10 +1,17 @@ package ip_access_lists -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command) { // this command still has no Web UI listCmd.Annotations["template"] = cmdio.Heredoc(` {{range .}}{{.ListId|green}} {{.Label}} {{join .IpAddresses ","}} {{if eq .ListType "ALLOW"}}{{"ALLOW"|green}}{{else}}{{"BLOCK"|red}}{{end}} {{if .Enabled}}{{"ENABLED"|green}}{{else}}{{"DISABLED"|red}}{{end}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/workspace/jobs/jobs.go b/cmd/workspace/jobs/jobs.go index 41101bdbf3..49d7edbd15 100755 --- a/cmd/workspace/jobs/jobs.go +++ b/cmd/workspace/jobs/jobs.go @@ -13,10 +13,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "jobs", - Short: `The Jobs API allows you to create, edit, and delete jobs.`, - Long: `The Jobs API allows you to create, edit, and delete jobs. +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "jobs", + Short: `The Jobs API allows you to create, edit, and delete jobs.`, + Long: `The Jobs API allows you to create, edit, and delete jobs. You can use a Databricks job to run a data processing or data analysis task in a Databricks cluster with scalable resources. Your job can consist of a single @@ -34,33 +39,57 @@ var Cmd = &cobra.Command{ [Databricks CLI]: https://docs.databricks.com/dev-tools/cli/index.html [Secrets CLI]: https://docs.databricks.com/dev-tools/cli/secrets-cli.html [Secrets utility]: https://docs.databricks.com/dev-tools/databricks-utils.html#dbutils-secrets`, - Annotations: map[string]string{ - "package": "jobs", - }, + GroupID: "jobs", + Annotations: map[string]string{ + "package": "jobs", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start cancel-all-runs command -var cancelAllRunsReq jobs.CancelAllRuns -var cancelAllRunsJson flags.JsonFlag -func init() { - Cmd.AddCommand(cancelAllRunsCmd) - // TODO: short flags - cancelAllRunsCmd.Flags().Var(&cancelAllRunsJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cancelAllRunsOverrides []func( + *cobra.Command, + *jobs.CancelAllRuns, +) -} +func newCancelAllRuns() *cobra.Command { + cmd := &cobra.Command{} + + var cancelAllRunsReq jobs.CancelAllRuns + var cancelAllRunsJson flags.JsonFlag -var cancelAllRunsCmd = &cobra.Command{ - Use: "cancel-all-runs JOB_ID", - Short: `Cancel all runs of a job.`, - Long: `Cancel all runs of a job. + // TODO: short flags + cmd.Flags().Var(&cancelAllRunsJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "cancel-all-runs JOB_ID" + cmd.Short = `Cancel all runs of a job.` + cmd.Long = `Cancel all runs of a job. Cancels all active runs of a job. The runs are canceled asynchronously, so it - doesn't prevent new runs from being started.`, + doesn't prevent new runs from being started.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -70,23 +99,6 @@ var cancelAllRunsCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No JOB_ID argument specified. Loading names for Jobs drop-down." - names, err := w.Jobs.BaseJobSettingsNameToJobIdMap(ctx, jobs.ListJobsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Jobs drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The canonical identifier of the job to cancel all runs of") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the canonical identifier of the job to cancel all runs of") - } _, err = fmt.Sscan(args[0], &cancelAllRunsReq.JobId) if err != nil { return fmt.Errorf("invalid JOB_ID: %s", args[0]) @@ -98,40 +110,68 @@ var cancelAllRunsCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range cancelAllRunsOverrides { + fn(cmd, &cancelAllRunsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCancelAllRuns()) + }) } // start cancel-run command -var cancelRunReq jobs.CancelRun -var cancelRunJson flags.JsonFlag -var cancelRunSkipWait bool -var cancelRunTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cancelRunOverrides []func( + *cobra.Command, + *jobs.CancelRun, +) -func init() { - Cmd.AddCommand(cancelRunCmd) +func newCancelRun() *cobra.Command { + cmd := &cobra.Command{} - cancelRunCmd.Flags().BoolVar(&cancelRunSkipWait, "no-wait", cancelRunSkipWait, `do not wait to reach TERMINATED or SKIPPED state`) - cancelRunCmd.Flags().DurationVar(&cancelRunTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach TERMINATED or SKIPPED state`) - // TODO: short flags - cancelRunCmd.Flags().Var(&cancelRunJson, "json", `either inline JSON string or @path/to/file.json with request body`) + var cancelRunReq jobs.CancelRun + var cancelRunJson flags.JsonFlag -} + var cancelRunSkipWait bool + var cancelRunTimeout time.Duration -var cancelRunCmd = &cobra.Command{ - Use: "cancel-run RUN_ID", - Short: `Cancel a job run.`, - Long: `Cancel a job run. + cmd.Flags().BoolVar(&cancelRunSkipWait, "no-wait", cancelRunSkipWait, `do not wait to reach TERMINATED or SKIPPED state`) + cmd.Flags().DurationVar(&cancelRunTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach TERMINATED or SKIPPED state`) + // TODO: short flags + cmd.Flags().Var(&cancelRunJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "cancel-run RUN_ID" + cmd.Short = `Cancel a job run.` + cmd.Long = `Cancel a job run. Cancels a job run. The run is canceled asynchronously, so it may still be - running when this request completes.`, + running when this request completes.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -141,23 +181,6 @@ var cancelRunCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No RUN_ID argument specified. Loading names for Jobs drop-down." - names, err := w.Jobs.BaseJobSettingsNameToJobIdMap(ctx, jobs.ListJobsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Jobs drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "This field is required") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have this field is required") - } _, err = fmt.Sscan(args[0], &cancelRunReq.RunId) if err != nil { return fmt.Errorf("invalid RUN_ID: %s", args[0]) @@ -188,40 +211,62 @@ var cancelRunCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range cancelRunOverrides { + fn(cmd, &cancelRunReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCancelRun()) + }) } // start create command -var createReq jobs.CreateJob -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *jobs.CreateJob, +) -} +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq jobs.CreateJob + var createJson flags.JsonFlag -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a new job.`, - Long: `Create a new job. + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "create" + cmd.Short = `Create a new job.` + cmd.Long = `Create a new job. - Create a new job.`, + Create a new job.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -239,33 +284,62 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq jobs.DeleteJob -var deleteJson flags.JsonFlag -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags - deleteCmd.Flags().Var(&deleteJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *jobs.DeleteJob, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq jobs.DeleteJob + var deleteJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&deleteJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var deleteCmd = &cobra.Command{ - Use: "delete JOB_ID", - Short: `Delete a job.`, - Long: `Delete a job. + cmd.Use = "delete JOB_ID" + cmd.Short = `Delete a job.` + cmd.Long = `Delete a job. - Deletes a job.`, + Deletes a job.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -275,23 +349,6 @@ var deleteCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No JOB_ID argument specified. Loading names for Jobs drop-down." - names, err := w.Jobs.BaseJobSettingsNameToJobIdMap(ctx, jobs.ListJobsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Jobs drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The canonical identifier of the job to delete") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the canonical identifier of the job to delete") - } _, err = fmt.Sscan(args[0], &deleteReq.JobId) if err != nil { return fmt.Errorf("invalid JOB_ID: %s", args[0]) @@ -303,33 +360,62 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start delete-run command -var deleteRunReq jobs.DeleteRun -var deleteRunJson flags.JsonFlag -func init() { - Cmd.AddCommand(deleteRunCmd) - // TODO: short flags - deleteRunCmd.Flags().Var(&deleteRunJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteRunOverrides []func( + *cobra.Command, + *jobs.DeleteRun, +) -} +func newDeleteRun() *cobra.Command { + cmd := &cobra.Command{} + + var deleteRunReq jobs.DeleteRun + var deleteRunJson flags.JsonFlag -var deleteRunCmd = &cobra.Command{ - Use: "delete-run RUN_ID", - Short: `Delete a job run.`, - Long: `Delete a job run. + // TODO: short flags + cmd.Flags().Var(&deleteRunJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "delete-run RUN_ID" + cmd.Short = `Delete a job run.` + cmd.Long = `Delete a job run. - Deletes a non-active run. Returns an error if the run is active.`, + Deletes a non-active run. Returns an error if the run is active.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -339,23 +425,6 @@ var deleteRunCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No RUN_ID argument specified. Loading names for Jobs drop-down." - names, err := w.Jobs.BaseJobSettingsNameToJobIdMap(ctx, jobs.ListJobsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Jobs drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The canonical identifier of the run for which to retrieve the metadata") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the canonical identifier of the run for which to retrieve the metadata") - } _, err = fmt.Sscan(args[0], &deleteRunReq.RunId) if err != nil { return fmt.Errorf("invalid RUN_ID: %s", args[0]) @@ -367,53 +436,62 @@ var deleteRunCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteRunOverrides { + fn(cmd, &deleteRunReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDeleteRun()) + }) } // start export-run command -var exportRunReq jobs.ExportRunRequest -func init() { - Cmd.AddCommand(exportRunCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var exportRunOverrides []func( + *cobra.Command, + *jobs.ExportRunRequest, +) - exportRunCmd.Flags().Var(&exportRunReq.ViewsToExport, "views-to-export", `Which views to export (CODE, DASHBOARDS, or ALL).`) +func newExportRun() *cobra.Command { + cmd := &cobra.Command{} -} + var exportRunReq jobs.ExportRunRequest -var exportRunCmd = &cobra.Command{ - Use: "export-run RUN_ID", - Short: `Export and retrieve a job run.`, - Long: `Export and retrieve a job run. + // TODO: short flags + + cmd.Flags().Var(&exportRunReq.ViewsToExport, "views-to-export", `Which views to export (CODE, DASHBOARDS, or ALL).`) + + cmd.Use = "export-run RUN_ID" + cmd.Short = `Export and retrieve a job run.` + cmd.Long = `Export and retrieve a job run. - Export and retrieve the job run task.`, + Export and retrieve the job run task.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No RUN_ID argument specified. Loading names for Jobs drop-down." - names, err := w.Jobs.BaseJobSettingsNameToJobIdMap(ctx, jobs.ListJobsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Jobs drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The canonical identifier for the run") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the canonical identifier for the run") - } _, err = fmt.Sscan(args[0], &exportRunReq.RunId) if err != nil { return fmt.Errorf("invalid RUN_ID: %s", args[0]) @@ -424,51 +502,60 @@ var exportRunCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range exportRunOverrides { + fn(cmd, &exportRunReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newExportRun()) + }) } // start get command -var getReq jobs.GetJobRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *jobs.GetJobRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq jobs.GetJobRequest -var getCmd = &cobra.Command{ - Use: "get JOB_ID", - Short: `Get a single job.`, - Long: `Get a single job. + // TODO: short flags + + cmd.Use = "get JOB_ID" + cmd.Short = `Get a single job.` + cmd.Long = `Get a single job. - Retrieves the details for a single job.`, + Retrieves the details for a single job.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No JOB_ID argument specified. Loading names for Jobs drop-down." - names, err := w.Jobs.BaseJobSettingsNameToJobIdMap(ctx, jobs.ListJobsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Jobs drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The canonical identifier of the job to retrieve information about") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the canonical identifier of the job to retrieve information about") - } _, err = fmt.Sscan(args[0], &getReq.JobId) if err != nil { return fmt.Errorf("invalid JOB_ID: %s", args[0]) @@ -479,59 +566,67 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start get-run command -var getRunReq jobs.GetRunRequest -var getRunSkipWait bool -var getRunTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getRunOverrides []func( + *cobra.Command, + *jobs.GetRunRequest, +) -func init() { - Cmd.AddCommand(getRunCmd) +func newGetRun() *cobra.Command { + cmd := &cobra.Command{} - getRunCmd.Flags().BoolVar(&getRunSkipWait, "no-wait", getRunSkipWait, `do not wait to reach TERMINATED or SKIPPED state`) - getRunCmd.Flags().DurationVar(&getRunTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach TERMINATED or SKIPPED state`) - // TODO: short flags + var getRunReq jobs.GetRunRequest - getRunCmd.Flags().BoolVar(&getRunReq.IncludeHistory, "include-history", getRunReq.IncludeHistory, `Whether to include the repair history in the response.`) + var getRunSkipWait bool + var getRunTimeout time.Duration -} + cmd.Flags().BoolVar(&getRunSkipWait, "no-wait", getRunSkipWait, `do not wait to reach TERMINATED or SKIPPED state`) + cmd.Flags().DurationVar(&getRunTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach TERMINATED or SKIPPED state`) + // TODO: short flags + + cmd.Flags().BoolVar(&getRunReq.IncludeHistory, "include-history", getRunReq.IncludeHistory, `Whether to include the repair history in the response.`) -var getRunCmd = &cobra.Command{ - Use: "get-run RUN_ID", - Short: `Get a single job run.`, - Long: `Get a single job run. + cmd.Use = "get-run RUN_ID" + cmd.Short = `Get a single job run.` + cmd.Long = `Get a single job run. - Retrieve the metadata of a run.`, + Retrieve the metadata of a run.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No RUN_ID argument specified. Loading names for Jobs drop-down." - names, err := w.Jobs.BaseJobSettingsNameToJobIdMap(ctx, jobs.ListJobsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Jobs drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The canonical identifier of the run for which to retrieve the metadata") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the canonical identifier of the run for which to retrieve the metadata") - } _, err = fmt.Sscan(args[0], &getRunReq.RunId) if err != nil { return fmt.Errorf("invalid RUN_ID: %s", args[0]) @@ -542,25 +637,45 @@ var getRunCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getRunOverrides { + fn(cmd, &getRunReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetRun()) + }) } // start get-run-output command -var getRunOutputReq jobs.GetRunOutputRequest -func init() { - Cmd.AddCommand(getRunOutputCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getRunOutputOverrides []func( + *cobra.Command, + *jobs.GetRunOutputRequest, +) -} +func newGetRunOutput() *cobra.Command { + cmd := &cobra.Command{} + + var getRunOutputReq jobs.GetRunOutputRequest -var getRunOutputCmd = &cobra.Command{ - Use: "get-run-output RUN_ID", - Short: `Get the output for a single run.`, - Long: `Get the output for a single run. + // TODO: short flags + + cmd.Use = "get-run-output RUN_ID" + cmd.Short = `Get the output for a single run.` + cmd.Long = `Get the output for a single run. Retrieve the output and metadata of a single task run. When a notebook task returns a value through the dbutils.notebook.exit() call, you can use this @@ -571,31 +686,20 @@ var getRunOutputCmd = &cobra.Command{ This endpoint validates that the __run_id__ parameter is valid and returns an HTTP status code 400 if the __run_id__ parameter is invalid. Runs are automatically removed after 60 days. If you to want to reference them beyond - 60 days, you must save old run results before they expire.`, + 60 days, you must save old run results before they expire.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No RUN_ID argument specified. Loading names for Jobs drop-down." - names, err := w.Jobs.BaseJobSettingsNameToJobIdMap(ctx, jobs.ListJobsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Jobs drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The canonical identifier for the run") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the canonical identifier for the run") - } _, err = fmt.Sscan(args[0], &getRunOutputReq.RunId) if err != nil { return fmt.Errorf("invalid RUN_ID: %s", args[0]) @@ -606,46 +710,68 @@ var getRunOutputCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getRunOutputOverrides { + fn(cmd, &getRunOutputReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetRunOutput()) + }) } // start list command -var listReq jobs.ListJobsRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *jobs.ListJobsRequest, +) - listCmd.Flags().BoolVar(&listReq.ExpandTasks, "expand-tasks", listReq.ExpandTasks, `Whether to include task and cluster details in the response.`) - listCmd.Flags().IntVar(&listReq.Limit, "limit", listReq.Limit, `The number of jobs to return.`) - listCmd.Flags().StringVar(&listReq.Name, "name", listReq.Name, `A filter on the list based on the exact (case insensitive) job name.`) - listCmd.Flags().IntVar(&listReq.Offset, "offset", listReq.Offset, `The offset of the first job to return, relative to the most recently created job.`) - listCmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Use next_page_token or prev_page_token returned from the previous request to list the next or previous page of jobs respectively.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq jobs.ListJobsRequest + var listJson flags.JsonFlag -var listCmd = &cobra.Command{ - Use: "list", - Short: `List jobs.`, - Long: `List jobs. + // TODO: short flags + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().BoolVar(&listReq.ExpandTasks, "expand-tasks", listReq.ExpandTasks, `Whether to include task and cluster details in the response.`) + cmd.Flags().IntVar(&listReq.Limit, "limit", listReq.Limit, `The number of jobs to return.`) + cmd.Flags().StringVar(&listReq.Name, "name", listReq.Name, `A filter on the list based on the exact (case insensitive) job name.`) + cmd.Flags().IntVar(&listReq.Offset, "offset", listReq.Offset, `The offset of the first job to return, relative to the most recently created job.`) + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Use next_page_token or prev_page_token returned from the previous request to list the next or previous page of jobs respectively.`) + + cmd.Use = "list" + cmd.Short = `List jobs.` + cmd.Long = `List jobs. - Retrieves a list of jobs.`, + Retrieves a list of jobs.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -662,51 +788,73 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start list-runs command -var listRunsReq jobs.ListRunsRequest -var listRunsJson flags.JsonFlag -func init() { - Cmd.AddCommand(listRunsCmd) - // TODO: short flags - listRunsCmd.Flags().Var(&listRunsJson, "json", `either inline JSON string or @path/to/file.json with request body`) - - listRunsCmd.Flags().BoolVar(&listRunsReq.ActiveOnly, "active-only", listRunsReq.ActiveOnly, `If active_only is true, only active runs are included in the results; otherwise, lists both active and completed runs.`) - listRunsCmd.Flags().BoolVar(&listRunsReq.CompletedOnly, "completed-only", listRunsReq.CompletedOnly, `If completed_only is true, only completed runs are included in the results; otherwise, lists both active and completed runs.`) - listRunsCmd.Flags().BoolVar(&listRunsReq.ExpandTasks, "expand-tasks", listRunsReq.ExpandTasks, `Whether to include task and cluster details in the response.`) - listRunsCmd.Flags().Int64Var(&listRunsReq.JobId, "job-id", listRunsReq.JobId, `The job for which to list runs.`) - listRunsCmd.Flags().IntVar(&listRunsReq.Limit, "limit", listRunsReq.Limit, `The number of runs to return.`) - listRunsCmd.Flags().IntVar(&listRunsReq.Offset, "offset", listRunsReq.Offset, `The offset of the first run to return, relative to the most recent run.`) - listRunsCmd.Flags().StringVar(&listRunsReq.PageToken, "page-token", listRunsReq.PageToken, `Use next_page_token or prev_page_token returned from the previous request to list the next or previous page of runs respectively.`) - listRunsCmd.Flags().Var(&listRunsReq.RunType, "run-type", `The type of runs to return.`) - listRunsCmd.Flags().IntVar(&listRunsReq.StartTimeFrom, "start-time-from", listRunsReq.StartTimeFrom, `Show runs that started _at or after_ this value.`) - listRunsCmd.Flags().IntVar(&listRunsReq.StartTimeTo, "start-time-to", listRunsReq.StartTimeTo, `Show runs that started _at or before_ this value.`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listRunsOverrides []func( + *cobra.Command, + *jobs.ListRunsRequest, +) -} +func newListRuns() *cobra.Command { + cmd := &cobra.Command{} -var listRunsCmd = &cobra.Command{ - Use: "list-runs", - Short: `List job runs.`, - Long: `List job runs. + var listRunsReq jobs.ListRunsRequest + var listRunsJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&listRunsJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().BoolVar(&listRunsReq.ActiveOnly, "active-only", listRunsReq.ActiveOnly, `If active_only is true, only active runs are included in the results; otherwise, lists both active and completed runs.`) + cmd.Flags().BoolVar(&listRunsReq.CompletedOnly, "completed-only", listRunsReq.CompletedOnly, `If completed_only is true, only completed runs are included in the results; otherwise, lists both active and completed runs.`) + cmd.Flags().BoolVar(&listRunsReq.ExpandTasks, "expand-tasks", listRunsReq.ExpandTasks, `Whether to include task and cluster details in the response.`) + cmd.Flags().Int64Var(&listRunsReq.JobId, "job-id", listRunsReq.JobId, `The job for which to list runs.`) + cmd.Flags().IntVar(&listRunsReq.Limit, "limit", listRunsReq.Limit, `The number of runs to return.`) + cmd.Flags().IntVar(&listRunsReq.Offset, "offset", listRunsReq.Offset, `The offset of the first run to return, relative to the most recent run.`) + cmd.Flags().StringVar(&listRunsReq.PageToken, "page-token", listRunsReq.PageToken, `Use next_page_token or prev_page_token returned from the previous request to list the next or previous page of runs respectively.`) + cmd.Flags().Var(&listRunsReq.RunType, "run-type", `The type of runs to return.`) + cmd.Flags().IntVar(&listRunsReq.StartTimeFrom, "start-time-from", listRunsReq.StartTimeFrom, `Show runs that started _at or after_ this value.`) + cmd.Flags().IntVar(&listRunsReq.StartTimeTo, "start-time-to", listRunsReq.StartTimeTo, `Show runs that started _at or before_ this value.`) + + cmd.Use = "list-runs" + cmd.Short = `List job runs.` + cmd.Long = `List job runs. - List runs in descending order by start time.`, + List runs in descending order by start time.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -723,54 +871,82 @@ var listRunsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listRunsOverrides { + fn(cmd, &listRunsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newListRuns()) + }) } // start repair-run command -var repairRunReq jobs.RepairRun -var repairRunJson flags.JsonFlag -var repairRunSkipWait bool -var repairRunTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var repairRunOverrides []func( + *cobra.Command, + *jobs.RepairRun, +) -func init() { - Cmd.AddCommand(repairRunCmd) +func newRepairRun() *cobra.Command { + cmd := &cobra.Command{} + + var repairRunReq jobs.RepairRun + var repairRunJson flags.JsonFlag + + var repairRunSkipWait bool + var repairRunTimeout time.Duration - repairRunCmd.Flags().BoolVar(&repairRunSkipWait, "no-wait", repairRunSkipWait, `do not wait to reach TERMINATED or SKIPPED state`) - repairRunCmd.Flags().DurationVar(&repairRunTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach TERMINATED or SKIPPED state`) + cmd.Flags().BoolVar(&repairRunSkipWait, "no-wait", repairRunSkipWait, `do not wait to reach TERMINATED or SKIPPED state`) + cmd.Flags().DurationVar(&repairRunTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach TERMINATED or SKIPPED state`) // TODO: short flags - repairRunCmd.Flags().Var(&repairRunJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&repairRunJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: dbt_commands // TODO: array: jar_params - repairRunCmd.Flags().Int64Var(&repairRunReq.LatestRepairId, "latest-repair-id", repairRunReq.LatestRepairId, `The ID of the latest repair.`) + cmd.Flags().Int64Var(&repairRunReq.LatestRepairId, "latest-repair-id", repairRunReq.LatestRepairId, `The ID of the latest repair.`) // TODO: map via StringToStringVar: notebook_params // TODO: complex arg: pipeline_params // TODO: map via StringToStringVar: python_named_params // TODO: array: python_params - repairRunCmd.Flags().BoolVar(&repairRunReq.RerunAllFailedTasks, "rerun-all-failed-tasks", repairRunReq.RerunAllFailedTasks, `If true, repair all failed tasks.`) - repairRunCmd.Flags().BoolVar(&repairRunReq.RerunDependentTasks, "rerun-dependent-tasks", repairRunReq.RerunDependentTasks, `If true, repair all tasks that depend on the tasks in rerun_tasks, even if they were previously successful.`) + cmd.Flags().BoolVar(&repairRunReq.RerunAllFailedTasks, "rerun-all-failed-tasks", repairRunReq.RerunAllFailedTasks, `If true, repair all failed tasks.`) + cmd.Flags().BoolVar(&repairRunReq.RerunDependentTasks, "rerun-dependent-tasks", repairRunReq.RerunDependentTasks, `If true, repair all tasks that depend on the tasks in rerun_tasks, even if they were previously successful.`) // TODO: array: rerun_tasks // TODO: array: spark_submit_params // TODO: map via StringToStringVar: sql_params -} - -var repairRunCmd = &cobra.Command{ - Use: "repair-run RUN_ID", - Short: `Repair a job run.`, - Long: `Repair a job run. + cmd.Use = "repair-run RUN_ID" + cmd.Short = `Repair a job run.` + cmd.Long = `Repair a job run. Re-run one or more tasks. Tasks are re-run as part of the original job run. They use the current job and task settings, and can be viewed in the history - for the original job run.`, + for the original job run.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -780,23 +956,6 @@ var repairRunCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No RUN_ID argument specified. Loading names for Jobs drop-down." - names, err := w.Jobs.BaseJobSettingsNameToJobIdMap(ctx, jobs.ListJobsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Jobs drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The job run ID of the run to repair") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the job run id of the run to repair") - } _, err = fmt.Sscan(args[0], &repairRunReq.RunId) if err != nil { return fmt.Errorf("invalid RUN_ID: %s", args[0]) @@ -827,34 +986,55 @@ var repairRunCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range repairRunOverrides { + fn(cmd, &repairRunReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newRepairRun()) + }) } // start reset command -var resetReq jobs.ResetJob -var resetJson flags.JsonFlag -func init() { - Cmd.AddCommand(resetCmd) - // TODO: short flags - resetCmd.Flags().Var(&resetJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var resetOverrides []func( + *cobra.Command, + *jobs.ResetJob, +) -} +func newReset() *cobra.Command { + cmd := &cobra.Command{} + + var resetReq jobs.ResetJob + var resetJson flags.JsonFlag -var resetCmd = &cobra.Command{ - Use: "reset", - Short: `Overwrites all settings for a job.`, - Long: `Overwrites all settings for a job. + // TODO: short flags + cmd.Flags().Var(&resetJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "reset" + cmd.Short = `Overwrites all settings for a job.` + cmd.Long = `Overwrites all settings for a job. Overwrites all the settings for a specific job. Use the Update endpoint to - update job settings partially.`, + update job settings partially.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -872,29 +1052,51 @@ var resetCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range resetOverrides { + fn(cmd, &resetReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newReset()) + }) } // start run-now command -var runNowReq jobs.RunNow -var runNowJson flags.JsonFlag -var runNowSkipWait bool -var runNowTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var runNowOverrides []func( + *cobra.Command, + *jobs.RunNow, +) -func init() { - Cmd.AddCommand(runNowCmd) +func newRunNow() *cobra.Command { + cmd := &cobra.Command{} + + var runNowReq jobs.RunNow + var runNowJson flags.JsonFlag - runNowCmd.Flags().BoolVar(&runNowSkipWait, "no-wait", runNowSkipWait, `do not wait to reach TERMINATED or SKIPPED state`) - runNowCmd.Flags().DurationVar(&runNowTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach TERMINATED or SKIPPED state`) + var runNowSkipWait bool + var runNowTimeout time.Duration + + cmd.Flags().BoolVar(&runNowSkipWait, "no-wait", runNowSkipWait, `do not wait to reach TERMINATED or SKIPPED state`) + cmd.Flags().DurationVar(&runNowTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach TERMINATED or SKIPPED state`) // TODO: short flags - runNowCmd.Flags().Var(&runNowJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&runNowJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: dbt_commands - runNowCmd.Flags().StringVar(&runNowReq.IdempotencyToken, "idempotency-token", runNowReq.IdempotencyToken, `An optional token to guarantee the idempotency of job run requests.`) + cmd.Flags().StringVar(&runNowReq.IdempotencyToken, "idempotency-token", runNowReq.IdempotencyToken, `An optional token to guarantee the idempotency of job run requests.`) // TODO: array: jar_params // TODO: array: job_parameters // TODO: map via StringToStringVar: notebook_params @@ -904,18 +1106,24 @@ func init() { // TODO: array: spark_submit_params // TODO: map via StringToStringVar: sql_params -} - -var runNowCmd = &cobra.Command{ - Use: "run-now JOB_ID", - Short: `Trigger a new job run.`, - Long: `Trigger a new job run. + cmd.Use = "run-now JOB_ID" + cmd.Short = `Trigger a new job run.` + cmd.Long = `Trigger a new job run. - Run a job and return the run_id of the triggered run.`, + Run a job and return the run_id of the triggered run.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -925,23 +1133,6 @@ var runNowCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No JOB_ID argument specified. Loading names for Jobs drop-down." - names, err := w.Jobs.BaseJobSettingsNameToJobIdMap(ctx, jobs.ListJobsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Jobs drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The ID of the job to be executed") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the id of the job to be executed") - } _, err = fmt.Sscan(args[0], &runNowReq.JobId) if err != nil { return fmt.Errorf("invalid JOB_ID: %s", args[0]) @@ -972,60 +1163,81 @@ var runNowCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range runNowOverrides { + fn(cmd, &runNowReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newRunNow()) + }) } // start submit command -var submitReq jobs.SubmitRun -var submitJson flags.JsonFlag -var submitSkipWait bool -var submitTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var submitOverrides []func( + *cobra.Command, + *jobs.SubmitRun, +) -func init() { - Cmd.AddCommand(submitCmd) +func newSubmit() *cobra.Command { + cmd := &cobra.Command{} - submitCmd.Flags().BoolVar(&submitSkipWait, "no-wait", submitSkipWait, `do not wait to reach TERMINATED or SKIPPED state`) - submitCmd.Flags().DurationVar(&submitTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach TERMINATED or SKIPPED state`) + var submitReq jobs.SubmitRun + var submitJson flags.JsonFlag + + var submitSkipWait bool + var submitTimeout time.Duration + + cmd.Flags().BoolVar(&submitSkipWait, "no-wait", submitSkipWait, `do not wait to reach TERMINATED or SKIPPED state`) + cmd.Flags().DurationVar(&submitTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach TERMINATED or SKIPPED state`) // TODO: short flags - submitCmd.Flags().Var(&submitJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&submitJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: access_control_list // TODO: complex arg: email_notifications // TODO: complex arg: git_source // TODO: complex arg: health - submitCmd.Flags().StringVar(&submitReq.IdempotencyToken, "idempotency-token", submitReq.IdempotencyToken, `An optional token that can be used to guarantee the idempotency of job run requests.`) + cmd.Flags().StringVar(&submitReq.IdempotencyToken, "idempotency-token", submitReq.IdempotencyToken, `An optional token that can be used to guarantee the idempotency of job run requests.`) // TODO: complex arg: notification_settings - submitCmd.Flags().StringVar(&submitReq.RunName, "run-name", submitReq.RunName, `An optional name for the run.`) + cmd.Flags().StringVar(&submitReq.RunName, "run-name", submitReq.RunName, `An optional name for the run.`) // TODO: array: tasks - submitCmd.Flags().IntVar(&submitReq.TimeoutSeconds, "timeout-seconds", submitReq.TimeoutSeconds, `An optional timeout applied to each run of this job.`) + cmd.Flags().IntVar(&submitReq.TimeoutSeconds, "timeout-seconds", submitReq.TimeoutSeconds, `An optional timeout applied to each run of this job.`) // TODO: complex arg: webhook_notifications -} - -var submitCmd = &cobra.Command{ - Use: "submit", - Short: `Create and trigger a one-time run.`, - Long: `Create and trigger a one-time run. + cmd.Use = "submit" + cmd.Short = `Create and trigger a one-time run.` + cmd.Long = `Create and trigger a one-time run. Submit a one-time run. This endpoint allows you to submit a workload directly without creating a job. Runs submitted using this endpoint don’t display in the UI. Use the jobs/runs/get API to check the run state after the job is - submitted.`, + submitted.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1061,37 +1273,66 @@ var submitCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range submitOverrides { + fn(cmd, &submitReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newSubmit()) + }) } // start update command -var updateReq jobs.UpdateJob -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *jobs.UpdateJob, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq jobs.UpdateJob + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: fields_to_remove // TODO: complex arg: new_settings -} - -var updateCmd = &cobra.Command{ - Use: "update JOB_ID", - Short: `Partially update a job.`, - Long: `Partially update a job. + cmd.Use = "update JOB_ID" + cmd.Short = `Partially update a job.` + cmd.Long = `Partially update a job. Add, update, or remove specific settings of an existing job. Use the ResetJob - to overwrite all job settings.`, + to overwrite all job settings.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1101,23 +1342,6 @@ var updateCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No JOB_ID argument specified. Loading names for Jobs drop-down." - names, err := w.Jobs.BaseJobSettingsNameToJobIdMap(ctx, jobs.ListJobsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Jobs drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The canonical identifier of the job to update") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the canonical identifier of the job to update") - } _, err = fmt.Sscan(args[0], &updateReq.JobId) if err != nil { return fmt.Errorf("invalid JOB_ID: %s", args[0]) @@ -1129,10 +1353,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Jobs diff --git a/cmd/workspace/jobs/overrides.go b/cmd/workspace/jobs/overrides.go index 93512c84a0..fd22dcbdb1 100644 --- a/cmd/workspace/jobs/overrides.go +++ b/cmd/workspace/jobs/overrides.go @@ -1,14 +1,25 @@ package jobs -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/databricks-sdk-go/service/jobs" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command, listReq *jobs.ListJobsRequest) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{range .}}{{green "%d" .JobId}} {{.Settings.Name}} {{end}}`) +} +func listRunsOverride(listRunsCmd *cobra.Command, listRunsReq *jobs.ListRunsRequest) { listRunsCmd.Annotations["template"] = cmdio.Heredoc(` {{header "Job ID"}} {{header "Run ID"}} {{header "Result State"}} URL {{range .}}{{green "%d" .JobId}} {{cyan "%d" .RunId}} {{if eq .State.ResultState "SUCCESS"}}{{"SUCCESS"|green}}{{else}}{{red "%s" .State.ResultState}}{{end}} {{.RunPageUrl}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) + listRunsOverrides = append(listRunsOverrides, listRunsOverride) +} diff --git a/cmd/workspace/libraries/libraries.go b/cmd/workspace/libraries/libraries.go index 70b5584ab0..e230bfb029 100755 --- a/cmd/workspace/libraries/libraries.go +++ b/cmd/workspace/libraries/libraries.go @@ -12,10 +12,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "libraries", - Short: `The Libraries API allows you to install and uninstall libraries and get the status of libraries on a cluster.`, - Long: `The Libraries API allows you to install and uninstall libraries and get the +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "libraries", + Short: `The Libraries API allows you to install and uninstall libraries and get the status of libraries on a cluster.`, + Long: `The Libraries API allows you to install and uninstall libraries and get the status of libraries on a cluster. To make third-party or custom code available to notebooks and jobs running on @@ -35,30 +40,43 @@ var Cmd = &cobra.Command{ When you uninstall a library from a cluster, the library is removed only when you restart the cluster. Until you restart the cluster, the status of the uninstalled library appears as Uninstall pending restart.`, - Annotations: map[string]string{ - "package": "compute", - }, + GroupID: "compute", + Annotations: map[string]string{ + "package": "compute", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start all-cluster-statuses command -func init() { - Cmd.AddCommand(allClusterStatusesCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var allClusterStatusesOverrides []func( + *cobra.Command, +) -} +func newAllClusterStatuses() *cobra.Command { + cmd := &cobra.Command{} -var allClusterStatusesCmd = &cobra.Command{ - Use: "all-cluster-statuses", - Short: `Get all statuses.`, - Long: `Get all statuses. + cmd.Use = "all-cluster-statuses" + cmd.Short = `Get all statuses.` + cmd.Long = `Get all statuses. Get the status of all libraries on all clusters. A status will be available for all libraries installed on this cluster via the API or the libraries UI as - well as libraries set to be installed on all clusters via the libraries UI.`, + well as libraries set to be installed on all clusters via the libraries UI.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.Libraries.AllClusterStatuses(ctx) @@ -66,25 +84,45 @@ var allClusterStatusesCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range allClusterStatusesOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newAllClusterStatuses()) + }) } // start cluster-status command -var clusterStatusReq compute.ClusterStatusRequest -func init() { - Cmd.AddCommand(clusterStatusCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var clusterStatusOverrides []func( + *cobra.Command, + *compute.ClusterStatusRequest, +) -} +func newClusterStatus() *cobra.Command { + cmd := &cobra.Command{} + + var clusterStatusReq compute.ClusterStatusRequest -var clusterStatusCmd = &cobra.Command{ - Use: "cluster-status CLUSTER_ID", - Short: `Get status.`, - Long: `Get status. + // TODO: short flags + + cmd.Use = "cluster-status CLUSTER_ID" + cmd.Short = `Get status.` + cmd.Long = `Get status. Get the status of libraries on a cluster. A status will be available for all libraries installed on this cluster via the API or the libraries UI as well as @@ -100,15 +138,17 @@ var clusterStatusCmd = &cobra.Command{ 3. Libraries that were previously requested on this cluster or on all clusters, but now marked for removal. Within this group there is no order - guarantee.`, + guarantee.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -119,38 +159,59 @@ var clusterStatusCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range clusterStatusOverrides { + fn(cmd, &clusterStatusReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newClusterStatus()) + }) } // start install command -var installReq compute.InstallLibraries -var installJson flags.JsonFlag -func init() { - Cmd.AddCommand(installCmd) - // TODO: short flags - installCmd.Flags().Var(&installJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var installOverrides []func( + *cobra.Command, + *compute.InstallLibraries, +) -} +func newInstall() *cobra.Command { + cmd := &cobra.Command{} + + var installReq compute.InstallLibraries + var installJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&installJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var installCmd = &cobra.Command{ - Use: "install", - Short: `Add a library.`, - Long: `Add a library. + cmd.Use = "install" + cmd.Short = `Add a library.` + cmd.Long = `Add a library. Add libraries to be installed on a cluster. The installation is asynchronous; it happens in the background after the completion of this request. **Note**: The actual set of libraries to be installed on a cluster is the union of the libraries specified via this method and the libraries set to be - installed on all clusters via the libraries UI.`, + installed on all clusters via the libraries UI.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -168,35 +229,56 @@ var installCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range installOverrides { + fn(cmd, &installReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newInstall()) + }) } // start uninstall command -var uninstallReq compute.UninstallLibraries -var uninstallJson flags.JsonFlag -func init() { - Cmd.AddCommand(uninstallCmd) - // TODO: short flags - uninstallCmd.Flags().Var(&uninstallJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var uninstallOverrides []func( + *cobra.Command, + *compute.UninstallLibraries, +) -} +func newUninstall() *cobra.Command { + cmd := &cobra.Command{} + + var uninstallReq compute.UninstallLibraries + var uninstallJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&uninstallJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var uninstallCmd = &cobra.Command{ - Use: "uninstall", - Short: `Uninstall libraries.`, - Long: `Uninstall libraries. + cmd.Use = "uninstall" + cmd.Short = `Uninstall libraries.` + cmd.Long = `Uninstall libraries. Set libraries to be uninstalled on a cluster. The libraries won't be uninstalled until the cluster is restarted. Uninstalling libraries that are - not installed on the cluster will have no impact but is not an error.`, + not installed on the cluster will have no impact but is not an error.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -214,10 +296,24 @@ var uninstallCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range uninstallOverrides { + fn(cmd, &uninstallReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUninstall()) + }) } // end service Libraries diff --git a/cmd/workspace/metastores/metastores.go b/cmd/workspace/metastores/metastores.go index 9db023a77e..4bed9fd17f 100755 --- a/cmd/workspace/metastores/metastores.go +++ b/cmd/workspace/metastores/metastores.go @@ -12,10 +12,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "metastores", - Short: `A metastore is the top-level container of objects in Unity Catalog.`, - Long: `A metastore is the top-level container of objects in Unity Catalog. It stores +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "metastores", + Short: `A metastore is the top-level container of objects in Unity Catalog.`, + Long: `A metastore is the top-level container of objects in Unity Catalog. It stores data assets (tables and views) and the permissions that govern access to them. Databricks account admins can create metastores and assign them to Databricks workspaces to control which workloads use each metastore. For a workspace to @@ -28,36 +33,53 @@ var Cmd = &cobra.Command{ workspaces created before Unity Catalog was released. If your workspace includes a legacy Hive metastore, the data in that metastore is available in a catalog named hive_metastore.`, - Annotations: map[string]string{ - "package": "catalog", - }, + GroupID: "catalog", + Annotations: map[string]string{ + "package": "catalog", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start assign command -var assignReq catalog.CreateMetastoreAssignment -func init() { - Cmd.AddCommand(assignCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var assignOverrides []func( + *cobra.Command, + *catalog.CreateMetastoreAssignment, +) -} +func newAssign() *cobra.Command { + cmd := &cobra.Command{} + + var assignReq catalog.CreateMetastoreAssignment + + // TODO: short flags -var assignCmd = &cobra.Command{ - Use: "assign METASTORE_ID DEFAULT_CATALOG_NAME WORKSPACE_ID", - Short: `Create an assignment.`, - Long: `Create an assignment. + cmd.Use = "assign METASTORE_ID DEFAULT_CATALOG_NAME WORKSPACE_ID" + cmd.Short = `Create an assignment.` + cmd.Long = `Create an assignment. Creates a new metastore assignment. If an assignment for the same __workspace_id__ exists, it will be overwritten by the new __metastore_id__ - and __default_catalog_name__. The caller must be an account admin.`, + and __default_catalog_name__. The caller must be an account admin.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(3) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -73,42 +95,64 @@ var assignCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range assignOverrides { + fn(cmd, &assignReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newAssign()) + }) } // start create command -var createReq catalog.CreateMetastore -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *catalog.CreateMetastore, +) - createCmd.Flags().StringVar(&createReq.Region, "region", createReq.Region, `Cloud region which the metastore serves (e.g., us-west-2, westus).`) +func newCreate() *cobra.Command { + cmd := &cobra.Command{} -} + var createReq catalog.CreateMetastore + var createJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var createCmd = &cobra.Command{ - Use: "create NAME STORAGE_ROOT", - Short: `Create a metastore.`, - Long: `Create a metastore. + cmd.Flags().StringVar(&createReq.Region, "region", createReq.Region, `Cloud region which the metastore serves (e.g., us-west-2, westus).`) + + cmd.Use = "create NAME STORAGE_ROOT" + cmd.Short = `Create a metastore.` + cmd.Long = `Create a metastore. - Creates a new metastore based on a provided name and storage root path.`, + Creates a new metastore based on a provided name and storage root path.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -127,29 +171,47 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start current command -func init() { - Cmd.AddCommand(currentCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var currentOverrides []func( + *cobra.Command, +) -} +func newCurrent() *cobra.Command { + cmd := &cobra.Command{} -var currentCmd = &cobra.Command{ - Use: "current", - Short: `Get metastore assignment for workspace.`, - Long: `Get metastore assignment for workspace. + cmd.Use = "current" + cmd.Short = `Get metastore assignment for workspace.` + cmd.Long = `Get metastore assignment for workspace. - Gets the metastore assignment for the workspace being accessed.`, + Gets the metastore assignment for the workspace being accessed.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.Metastores.Current(ctx) @@ -157,53 +219,62 @@ var currentCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range currentOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCurrent()) + }) } // start delete command -var deleteReq catalog.DeleteMetastoreRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *catalog.DeleteMetastoreRequest, +) - deleteCmd.Flags().BoolVar(&deleteReq.Force, "force", deleteReq.Force, `Force deletion even if the metastore is not empty.`) +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -} + var deleteReq catalog.DeleteMetastoreRequest + + // TODO: short flags -var deleteCmd = &cobra.Command{ - Use: "delete ID", - Short: `Delete a metastore.`, - Long: `Delete a metastore. + cmd.Flags().BoolVar(&deleteReq.Force, "force", deleteReq.Force, `Force deletion even if the metastore is not empty.`) + + cmd.Use = "delete ID" + cmd.Short = `Delete a metastore.` + cmd.Long = `Delete a metastore. - Deletes a metastore. The caller must be a metastore admin.`, + Deletes a metastore. The caller must be a metastore admin.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Metastores drop-down." - names, err := w.Metastores.MetastoreInfoNameToMetastoreIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Metastores drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID of the metastore") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id of the metastore") - } deleteReq.Id = args[0] err = w.Metastores.Delete(ctx, deleteReq) @@ -211,43 +282,65 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start enable-optimization command -var enableOptimizationReq catalog.UpdatePredictiveOptimization -var enableOptimizationJson flags.JsonFlag -func init() { - Cmd.AddCommand(enableOptimizationCmd) - // TODO: short flags - enableOptimizationCmd.Flags().Var(&enableOptimizationJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var enableOptimizationOverrides []func( + *cobra.Command, + *catalog.UpdatePredictiveOptimization, +) -} +func newEnableOptimization() *cobra.Command { + cmd := &cobra.Command{} -var enableOptimizationCmd = &cobra.Command{ - Use: "enable-optimization METASTORE_ID ENABLE", - Short: `Toggle predictive optimization on the metastore.`, - Long: `Toggle predictive optimization on the metastore. + var enableOptimizationReq catalog.UpdatePredictiveOptimization + var enableOptimizationJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&enableOptimizationJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "enable-optimization METASTORE_ID ENABLE" + cmd.Short = `Toggle predictive optimization on the metastore.` + cmd.Long = `Toggle predictive optimization on the metastore. - Enables or disables predictive optimization on the metastore.`, + Enables or disables predictive optimization on the metastore.` // This command is being previewed; hide from help output. - Hidden: true, + cmd.Hidden = true + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -269,52 +362,61 @@ var enableOptimizationCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range enableOptimizationOverrides { + fn(cmd, &enableOptimizationReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newEnableOptimization()) + }) } // start get command -var getReq catalog.GetMetastoreRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *catalog.GetMetastoreRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq catalog.GetMetastoreRequest -var getCmd = &cobra.Command{ - Use: "get ID", - Short: `Get a metastore.`, - Long: `Get a metastore. + // TODO: short flags + + cmd.Use = "get ID" + cmd.Short = `Get a metastore.` + cmd.Long = `Get a metastore. Gets a metastore that matches the supplied ID. The caller must be a metastore - admin to retrieve this info.`, + admin to retrieve this info.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Metastores drop-down." - names, err := w.Metastores.MetastoreInfoNameToMetastoreIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Metastores drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID of the metastore") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id of the metastore") - } getReq.Id = args[0] response, err := w.Metastores.Get(ctx, getReq) @@ -322,31 +424,49 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `List metastores.`, - Long: `List metastores. + cmd.Use = "list" + cmd.Short = `List metastores.` + cmd.Long = `List metastores. Gets an array of the available metastores (as __MetastoreInfo__ objects). The caller must be an admin to retrieve this info. There is no guarantee of a - specific ordering of the elements in the array.`, + specific ordering of the elements in the array.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.Metastores.ListAll(ctx) @@ -354,30 +474,48 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start summary command -func init() { - Cmd.AddCommand(summaryCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var summaryOverrides []func( + *cobra.Command, +) -} +func newSummary() *cobra.Command { + cmd := &cobra.Command{} -var summaryCmd = &cobra.Command{ - Use: "summary", - Short: `Get a metastore summary.`, - Long: `Get a metastore summary. + cmd.Use = "summary" + cmd.Short = `Get a metastore summary.` + cmd.Long = `Get a metastore summary. Gets information about a metastore. This summary includes the storage - credential, the cloud vendor, the cloud region, and the global metastore ID.`, + credential, the cloud vendor, the cloud region, and the global metastore ID.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.Metastores.Summary(ctx) @@ -385,35 +523,57 @@ var summaryCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range summaryOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newSummary()) + }) } // start unassign command -var unassignReq catalog.UnassignRequest -func init() { - Cmd.AddCommand(unassignCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var unassignOverrides []func( + *cobra.Command, + *catalog.UnassignRequest, +) -} +func newUnassign() *cobra.Command { + cmd := &cobra.Command{} -var unassignCmd = &cobra.Command{ - Use: "unassign WORKSPACE_ID METASTORE_ID", - Short: `Delete an assignment.`, - Long: `Delete an assignment. + var unassignReq catalog.UnassignRequest + + // TODO: short flags + + cmd.Use = "unassign WORKSPACE_ID METASTORE_ID" + cmd.Short = `Delete an assignment.` + cmd.Long = `Delete an assignment. - Deletes a metastore assignment. The caller must be an account administrator.`, + Deletes a metastore assignment. The caller must be an account administrator.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -428,60 +588,69 @@ var unassignCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range unassignOverrides { + fn(cmd, &unassignReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUnassign()) + }) } // start update command -var updateReq catalog.UpdateMetastore -func init() { - Cmd.AddCommand(updateCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *catalog.UpdateMetastore, +) - updateCmd.Flags().StringVar(&updateReq.DeltaSharingOrganizationName, "delta-sharing-organization-name", updateReq.DeltaSharingOrganizationName, `The organization name of a Delta Sharing entity, to be used in Databricks-to-Databricks Delta Sharing as the official name.`) - updateCmd.Flags().Int64Var(&updateReq.DeltaSharingRecipientTokenLifetimeInSeconds, "delta-sharing-recipient-token-lifetime-in-seconds", updateReq.DeltaSharingRecipientTokenLifetimeInSeconds, `The lifetime of delta sharing recipient token in seconds.`) - updateCmd.Flags().Var(&updateReq.DeltaSharingScope, "delta-sharing-scope", `The scope of Delta Sharing enabled for the metastore.`) - updateCmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `The user-specified name of the metastore.`) - updateCmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `The owner of the metastore.`) - updateCmd.Flags().StringVar(&updateReq.PrivilegeModelVersion, "privilege-model-version", updateReq.PrivilegeModelVersion, `Privilege model version of the metastore, of the form major.minor (e.g., 1.0).`) - updateCmd.Flags().StringVar(&updateReq.StorageRootCredentialId, "storage-root-credential-id", updateReq.StorageRootCredentialId, `UUID of storage credential to access the metastore storage_root.`) +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} -} + var updateReq catalog.UpdateMetastore + + // TODO: short flags -var updateCmd = &cobra.Command{ - Use: "update ID", - Short: `Update a metastore.`, - Long: `Update a metastore. + cmd.Flags().StringVar(&updateReq.DeltaSharingOrganizationName, "delta-sharing-organization-name", updateReq.DeltaSharingOrganizationName, `The organization name of a Delta Sharing entity, to be used in Databricks-to-Databricks Delta Sharing as the official name.`) + cmd.Flags().Int64Var(&updateReq.DeltaSharingRecipientTokenLifetimeInSeconds, "delta-sharing-recipient-token-lifetime-in-seconds", updateReq.DeltaSharingRecipientTokenLifetimeInSeconds, `The lifetime of delta sharing recipient token in seconds.`) + cmd.Flags().Var(&updateReq.DeltaSharingScope, "delta-sharing-scope", `The scope of Delta Sharing enabled for the metastore.`) + cmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `The user-specified name of the metastore.`) + cmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `The owner of the metastore.`) + cmd.Flags().StringVar(&updateReq.PrivilegeModelVersion, "privilege-model-version", updateReq.PrivilegeModelVersion, `Privilege model version of the metastore, of the form major.minor (e.g., 1.0).`) + cmd.Flags().StringVar(&updateReq.StorageRootCredentialId, "storage-root-credential-id", updateReq.StorageRootCredentialId, `UUID of storage credential to access the metastore storage_root.`) + + cmd.Use = "update ID" + cmd.Short = `Update a metastore.` + cmd.Long = `Update a metastore. Updates information for a specific metastore. The caller must be a metastore - admin.`, + admin.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Metastores drop-down." - names, err := w.Metastores.MetastoreInfoNameToMetastoreIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Metastores drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID of the metastore") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id of the metastore") - } updateReq.Id = args[0] response, err := w.Metastores.Update(ctx, updateReq) @@ -489,57 +658,66 @@ var updateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // start update-assignment command -var updateAssignmentReq catalog.UpdateMetastoreAssignment -func init() { - Cmd.AddCommand(updateAssignmentCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateAssignmentOverrides []func( + *cobra.Command, + *catalog.UpdateMetastoreAssignment, +) - updateAssignmentCmd.Flags().StringVar(&updateAssignmentReq.DefaultCatalogName, "default-catalog-name", updateAssignmentReq.DefaultCatalogName, `The name of the default catalog for the metastore.`) - updateAssignmentCmd.Flags().StringVar(&updateAssignmentReq.MetastoreId, "metastore-id", updateAssignmentReq.MetastoreId, `The unique ID of the metastore.`) +func newUpdateAssignment() *cobra.Command { + cmd := &cobra.Command{} -} + var updateAssignmentReq catalog.UpdateMetastoreAssignment + + // TODO: short flags + + cmd.Flags().StringVar(&updateAssignmentReq.DefaultCatalogName, "default-catalog-name", updateAssignmentReq.DefaultCatalogName, `The name of the default catalog for the metastore.`) + cmd.Flags().StringVar(&updateAssignmentReq.MetastoreId, "metastore-id", updateAssignmentReq.MetastoreId, `The unique ID of the metastore.`) -var updateAssignmentCmd = &cobra.Command{ - Use: "update-assignment WORKSPACE_ID", - Short: `Update an assignment.`, - Long: `Update an assignment. + cmd.Use = "update-assignment WORKSPACE_ID" + cmd.Short = `Update an assignment.` + cmd.Long = `Update an assignment. Updates a metastore assignment. This operation can be used to update __metastore_id__ or __default_catalog_name__ for a specified Workspace, if the Workspace is already assigned a metastore. The caller must be an account admin - to update __metastore_id__; otherwise, the caller can be a Workspace admin.`, + to update __metastore_id__; otherwise, the caller can be a Workspace admin.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No WORKSPACE_ID argument specified. Loading names for Metastores drop-down." - names, err := w.Metastores.MetastoreInfoNameToMetastoreIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Metastores drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "A workspace ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have a workspace id") - } _, err = fmt.Sscan(args[0], &updateAssignmentReq.WorkspaceId) if err != nil { return fmt.Errorf("invalid WORKSPACE_ID: %s", args[0]) @@ -550,10 +728,24 @@ var updateAssignmentCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateAssignmentOverrides { + fn(cmd, &updateAssignmentReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdateAssignment()) + }) } // end service Metastores diff --git a/cmd/workspace/metastores/overrides.go b/cmd/workspace/metastores/overrides.go index 9d1c23ac2d..2c9ca6f79a 100644 --- a/cmd/workspace/metastores/overrides.go +++ b/cmd/workspace/metastores/overrides.go @@ -1,10 +1,17 @@ package metastores -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{header "ID"}} {{header "Name"}} {{"Region"}} {{range .}}{{.MetastoreId|green}} {{.Name|cyan}} {{.Region}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/workspace/model-registry/model-registry.go b/cmd/workspace/model-registry/model-registry.go index ce7f4806c9..d944e0d980 100755 --- a/cmd/workspace/model-registry/model-registry.go +++ b/cmd/workspace/model-registry/model-registry.go @@ -12,46 +12,68 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "model-registry", - Short: `MLflow Model Registry is a centralized model repository and a UI and set of APIs that enable you to manage the full lifecycle of MLflow Models.`, - Long: `MLflow Model Registry is a centralized model repository and a UI and set of +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "model-registry", + Short: `MLflow Model Registry is a centralized model repository and a UI and set of APIs that enable you to manage the full lifecycle of MLflow Models.`, + Long: `MLflow Model Registry is a centralized model repository and a UI and set of APIs that enable you to manage the full lifecycle of MLflow Models.`, - Annotations: map[string]string{ - "package": "ml", - }, + GroupID: "ml", + Annotations: map[string]string{ + "package": "ml", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start approve-transition-request command -var approveTransitionRequestReq ml.ApproveTransitionRequest -var approveTransitionRequestJson flags.JsonFlag -func init() { - Cmd.AddCommand(approveTransitionRequestCmd) - // TODO: short flags - approveTransitionRequestCmd.Flags().Var(&approveTransitionRequestJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var approveTransitionRequestOverrides []func( + *cobra.Command, + *ml.ApproveTransitionRequest, +) - approveTransitionRequestCmd.Flags().StringVar(&approveTransitionRequestReq.Comment, "comment", approveTransitionRequestReq.Comment, `User-provided comment on the action.`) +func newApproveTransitionRequest() *cobra.Command { + cmd := &cobra.Command{} -} + var approveTransitionRequestReq ml.ApproveTransitionRequest + var approveTransitionRequestJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&approveTransitionRequestJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var approveTransitionRequestCmd = &cobra.Command{ - Use: "approve-transition-request NAME VERSION STAGE ARCHIVE_EXISTING_VERSIONS", - Short: `Approve transition request.`, - Long: `Approve transition request. + cmd.Flags().StringVar(&approveTransitionRequestReq.Comment, "comment", approveTransitionRequestReq.Comment, `User-provided comment on the action.`) + + cmd.Use = "approve-transition-request NAME VERSION STAGE ARCHIVE_EXISTING_VERSIONS" + cmd.Short = `Approve transition request.` + cmd.Long = `Approve transition request. - Approves a model version stage transition request.`, + Approves a model version stage transition request.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(4) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -78,42 +100,64 @@ var approveTransitionRequestCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range approveTransitionRequestOverrides { + fn(cmd, &approveTransitionRequestReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newApproveTransitionRequest()) + }) } // start create-comment command -var createCommentReq ml.CreateComment -var createCommentJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCommentCmd) - // TODO: short flags - createCommentCmd.Flags().Var(&createCommentJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createCommentOverrides []func( + *cobra.Command, + *ml.CreateComment, +) -} +func newCreateComment() *cobra.Command { + cmd := &cobra.Command{} + + var createCommentReq ml.CreateComment + var createCommentJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&createCommentJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var createCommentCmd = &cobra.Command{ - Use: "create-comment NAME VERSION COMMENT", - Short: `Post a comment.`, - Long: `Post a comment. + cmd.Use = "create-comment NAME VERSION COMMENT" + cmd.Short = `Post a comment.` + cmd.Long = `Post a comment. Posts a comment on a model version. A comment can be submitted either by a user or programmatically to display relevant information about the model. For - example, test results or deployment errors.`, + example, test results or deployment errors.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(3) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -133,46 +177,68 @@ var createCommentCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createCommentOverrides { + fn(cmd, &createCommentReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreateComment()) + }) } // start create-model command -var createModelReq ml.CreateModelRequest -var createModelJson flags.JsonFlag -func init() { - Cmd.AddCommand(createModelCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createModelOverrides []func( + *cobra.Command, + *ml.CreateModelRequest, +) + +func newCreateModel() *cobra.Command { + cmd := &cobra.Command{} + + var createModelReq ml.CreateModelRequest + var createModelJson flags.JsonFlag + // TODO: short flags - createModelCmd.Flags().Var(&createModelJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createModelJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createModelCmd.Flags().StringVar(&createModelReq.Description, "description", createModelReq.Description, `Optional description for registered model.`) + cmd.Flags().StringVar(&createModelReq.Description, "description", createModelReq.Description, `Optional description for registered model.`) // TODO: array: tags -} - -var createModelCmd = &cobra.Command{ - Use: "create-model NAME", - Short: `Create a model.`, - Long: `Create a model. + cmd.Use = "create-model NAME" + cmd.Short = `Create a model.` + cmd.Long = `Create a model. Creates a new registered model with the name specified in the request body. Throws RESOURCE_ALREADY_EXISTS if a registered model with the given name - exists.`, + exists.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -190,45 +256,67 @@ var createModelCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createModelOverrides { + fn(cmd, &createModelReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreateModel()) + }) } // start create-model-version command -var createModelVersionReq ml.CreateModelVersionRequest -var createModelVersionJson flags.JsonFlag -func init() { - Cmd.AddCommand(createModelVersionCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createModelVersionOverrides []func( + *cobra.Command, + *ml.CreateModelVersionRequest, +) + +func newCreateModelVersion() *cobra.Command { + cmd := &cobra.Command{} + + var createModelVersionReq ml.CreateModelVersionRequest + var createModelVersionJson flags.JsonFlag + // TODO: short flags - createModelVersionCmd.Flags().Var(&createModelVersionJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createModelVersionJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createModelVersionCmd.Flags().StringVar(&createModelVersionReq.Description, "description", createModelVersionReq.Description, `Optional description for model version.`) - createModelVersionCmd.Flags().StringVar(&createModelVersionReq.RunId, "run-id", createModelVersionReq.RunId, `MLflow run ID for correlation, if source was generated by an experiment run in MLflow tracking server.`) - createModelVersionCmd.Flags().StringVar(&createModelVersionReq.RunLink, "run-link", createModelVersionReq.RunLink, `MLflow run link - this is the exact link of the run that generated this model version, potentially hosted at another instance of MLflow.`) + cmd.Flags().StringVar(&createModelVersionReq.Description, "description", createModelVersionReq.Description, `Optional description for model version.`) + cmd.Flags().StringVar(&createModelVersionReq.RunId, "run-id", createModelVersionReq.RunId, `MLflow run ID for correlation, if source was generated by an experiment run in MLflow tracking server.`) + cmd.Flags().StringVar(&createModelVersionReq.RunLink, "run-link", createModelVersionReq.RunLink, `MLflow run link - this is the exact link of the run that generated this model version, potentially hosted at another instance of MLflow.`) // TODO: array: tags -} - -var createModelVersionCmd = &cobra.Command{ - Use: "create-model-version NAME SOURCE", - Short: `Create a model version.`, - Long: `Create a model version. + cmd.Use = "create-model-version NAME SOURCE" + cmd.Short = `Create a model version.` + cmd.Long = `Create a model version. - Creates a model version.`, + Creates a model version.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -247,42 +335,64 @@ var createModelVersionCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createModelVersionOverrides { + fn(cmd, &createModelVersionReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreateModelVersion()) + }) } // start create-transition-request command -var createTransitionRequestReq ml.CreateTransitionRequest -var createTransitionRequestJson flags.JsonFlag -func init() { - Cmd.AddCommand(createTransitionRequestCmd) - // TODO: short flags - createTransitionRequestCmd.Flags().Var(&createTransitionRequestJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createTransitionRequestOverrides []func( + *cobra.Command, + *ml.CreateTransitionRequest, +) - createTransitionRequestCmd.Flags().StringVar(&createTransitionRequestReq.Comment, "comment", createTransitionRequestReq.Comment, `User-provided comment on the action.`) +func newCreateTransitionRequest() *cobra.Command { + cmd := &cobra.Command{} -} + var createTransitionRequestReq ml.CreateTransitionRequest + var createTransitionRequestJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&createTransitionRequestJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&createTransitionRequestReq.Comment, "comment", createTransitionRequestReq.Comment, `User-provided comment on the action.`) -var createTransitionRequestCmd = &cobra.Command{ - Use: "create-transition-request NAME VERSION STAGE", - Short: `Make a transition request.`, - Long: `Make a transition request. + cmd.Use = "create-transition-request NAME VERSION STAGE" + cmd.Short = `Make a transition request.` + cmd.Long = `Make a transition request. - Creates a model version stage transition request.`, + Creates a model version stage transition request.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(3) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -305,41 +415,62 @@ var createTransitionRequestCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createTransitionRequestOverrides { + fn(cmd, &createTransitionRequestReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreateTransitionRequest()) + }) } // start create-webhook command -var createWebhookReq ml.CreateRegistryWebhook -var createWebhookJson flags.JsonFlag -func init() { - Cmd.AddCommand(createWebhookCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createWebhookOverrides []func( + *cobra.Command, + *ml.CreateRegistryWebhook, +) + +func newCreateWebhook() *cobra.Command { + cmd := &cobra.Command{} + + var createWebhookReq ml.CreateRegistryWebhook + var createWebhookJson flags.JsonFlag + // TODO: short flags - createWebhookCmd.Flags().Var(&createWebhookJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createWebhookJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createWebhookCmd.Flags().StringVar(&createWebhookReq.Description, "description", createWebhookReq.Description, `User-specified description for the webhook.`) + cmd.Flags().StringVar(&createWebhookReq.Description, "description", createWebhookReq.Description, `User-specified description for the webhook.`) // TODO: complex arg: http_url_spec // TODO: complex arg: job_spec - createWebhookCmd.Flags().StringVar(&createWebhookReq.ModelName, "model-name", createWebhookReq.ModelName, `Name of the model whose events would trigger this webhook.`) - createWebhookCmd.Flags().Var(&createWebhookReq.Status, "status", `This describes an enum.`) - -} + cmd.Flags().StringVar(&createWebhookReq.ModelName, "model-name", createWebhookReq.ModelName, `Name of the model whose events would trigger this webhook.`) + cmd.Flags().Var(&createWebhookReq.Status, "status", `This describes an enum.`) -var createWebhookCmd = &cobra.Command{ - Use: "create-webhook", - Short: `Create a webhook.`, - Long: `Create a webhook. + cmd.Use = "create-webhook" + cmd.Short = `Create a webhook.` + cmd.Long = `Create a webhook. **NOTE**: This endpoint is in Public Preview. - Creates a registry webhook.`, + Creates a registry webhook.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -357,35 +488,57 @@ var createWebhookCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createWebhookOverrides { + fn(cmd, &createWebhookReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreateWebhook()) + }) } // start delete-comment command -var deleteCommentReq ml.DeleteCommentRequest -func init() { - Cmd.AddCommand(deleteCommentCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteCommentOverrides []func( + *cobra.Command, + *ml.DeleteCommentRequest, +) -} +func newDeleteComment() *cobra.Command { + cmd := &cobra.Command{} -var deleteCommentCmd = &cobra.Command{ - Use: "delete-comment ID", - Short: `Delete a comment.`, - Long: `Delete a comment. + var deleteCommentReq ml.DeleteCommentRequest + + // TODO: short flags + + cmd.Use = "delete-comment ID" + cmd.Short = `Delete a comment.` + cmd.Long = `Delete a comment. - Deletes a comment on a model version.`, + Deletes a comment on a model version.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -396,35 +549,57 @@ var deleteCommentCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteCommentOverrides { + fn(cmd, &deleteCommentReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDeleteComment()) + }) } // start delete-model command -var deleteModelReq ml.DeleteModelRequest -func init() { - Cmd.AddCommand(deleteModelCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteModelOverrides []func( + *cobra.Command, + *ml.DeleteModelRequest, +) -} +func newDeleteModel() *cobra.Command { + cmd := &cobra.Command{} -var deleteModelCmd = &cobra.Command{ - Use: "delete-model NAME", - Short: `Delete a model.`, - Long: `Delete a model. + var deleteModelReq ml.DeleteModelRequest + + // TODO: short flags + + cmd.Use = "delete-model NAME" + cmd.Short = `Delete a model.` + cmd.Long = `Delete a model. - Deletes a registered model.`, + Deletes a registered model.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -435,35 +610,57 @@ var deleteModelCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteModelOverrides { + fn(cmd, &deleteModelReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDeleteModel()) + }) } // start delete-model-tag command -var deleteModelTagReq ml.DeleteModelTagRequest -func init() { - Cmd.AddCommand(deleteModelTagCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteModelTagOverrides []func( + *cobra.Command, + *ml.DeleteModelTagRequest, +) -} +func newDeleteModelTag() *cobra.Command { + cmd := &cobra.Command{} -var deleteModelTagCmd = &cobra.Command{ - Use: "delete-model-tag NAME KEY", - Short: `Delete a model tag.`, - Long: `Delete a model tag. + var deleteModelTagReq ml.DeleteModelTagRequest + + // TODO: short flags + + cmd.Use = "delete-model-tag NAME KEY" + cmd.Short = `Delete a model tag.` + cmd.Long = `Delete a model tag. - Deletes the tag for a registered model.`, + Deletes the tag for a registered model.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -475,35 +672,57 @@ var deleteModelTagCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteModelTagOverrides { + fn(cmd, &deleteModelTagReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDeleteModelTag()) + }) } // start delete-model-version command -var deleteModelVersionReq ml.DeleteModelVersionRequest -func init() { - Cmd.AddCommand(deleteModelVersionCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteModelVersionOverrides []func( + *cobra.Command, + *ml.DeleteModelVersionRequest, +) -} +func newDeleteModelVersion() *cobra.Command { + cmd := &cobra.Command{} -var deleteModelVersionCmd = &cobra.Command{ - Use: "delete-model-version NAME VERSION", - Short: `Delete a model version.`, - Long: `Delete a model version. + var deleteModelVersionReq ml.DeleteModelVersionRequest + + // TODO: short flags + + cmd.Use = "delete-model-version NAME VERSION" + cmd.Short = `Delete a model version.` + cmd.Long = `Delete a model version. - Deletes a model version.`, + Deletes a model version.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -515,35 +734,57 @@ var deleteModelVersionCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteModelVersionOverrides { + fn(cmd, &deleteModelVersionReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDeleteModelVersion()) + }) } // start delete-model-version-tag command -var deleteModelVersionTagReq ml.DeleteModelVersionTagRequest -func init() { - Cmd.AddCommand(deleteModelVersionTagCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteModelVersionTagOverrides []func( + *cobra.Command, + *ml.DeleteModelVersionTagRequest, +) -} +func newDeleteModelVersionTag() *cobra.Command { + cmd := &cobra.Command{} -var deleteModelVersionTagCmd = &cobra.Command{ - Use: "delete-model-version-tag NAME VERSION KEY", - Short: `Delete a model version tag.`, - Long: `Delete a model version tag. + var deleteModelVersionTagReq ml.DeleteModelVersionTagRequest + + // TODO: short flags + + cmd.Use = "delete-model-version-tag NAME VERSION KEY" + cmd.Short = `Delete a model version tag.` + cmd.Long = `Delete a model version tag. - Deletes a model version tag.`, + Deletes a model version tag.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(3) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -556,37 +797,59 @@ var deleteModelVersionTagCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteModelVersionTagOverrides { + fn(cmd, &deleteModelVersionTagReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDeleteModelVersionTag()) + }) } // start delete-transition-request command -var deleteTransitionRequestReq ml.DeleteTransitionRequestRequest -func init() { - Cmd.AddCommand(deleteTransitionRequestCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteTransitionRequestOverrides []func( + *cobra.Command, + *ml.DeleteTransitionRequestRequest, +) - deleteTransitionRequestCmd.Flags().StringVar(&deleteTransitionRequestReq.Comment, "comment", deleteTransitionRequestReq.Comment, `User-provided comment on the action.`) +func newDeleteTransitionRequest() *cobra.Command { + cmd := &cobra.Command{} -} + var deleteTransitionRequestReq ml.DeleteTransitionRequestRequest -var deleteTransitionRequestCmd = &cobra.Command{ - Use: "delete-transition-request NAME VERSION STAGE CREATOR", - Short: `Delete a transition request.`, - Long: `Delete a transition request. + // TODO: short flags + + cmd.Flags().StringVar(&deleteTransitionRequestReq.Comment, "comment", deleteTransitionRequestReq.Comment, `User-provided comment on the action.`) + + cmd.Use = "delete-transition-request NAME VERSION STAGE CREATOR" + cmd.Short = `Delete a transition request.` + cmd.Long = `Delete a transition request. - Cancels a model version stage transition request.`, + Cancels a model version stage transition request.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(4) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -603,44 +866,66 @@ var deleteTransitionRequestCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteTransitionRequestOverrides { + fn(cmd, &deleteTransitionRequestReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDeleteTransitionRequest()) + }) } // start delete-webhook command -var deleteWebhookReq ml.DeleteWebhookRequest -var deleteWebhookJson flags.JsonFlag -func init() { - Cmd.AddCommand(deleteWebhookCmd) - // TODO: short flags - deleteWebhookCmd.Flags().Var(&deleteWebhookJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteWebhookOverrides []func( + *cobra.Command, + *ml.DeleteWebhookRequest, +) - deleteWebhookCmd.Flags().StringVar(&deleteWebhookReq.Id, "id", deleteWebhookReq.Id, `Webhook ID required to delete a registry webhook.`) +func newDeleteWebhook() *cobra.Command { + cmd := &cobra.Command{} -} + var deleteWebhookReq ml.DeleteWebhookRequest + var deleteWebhookJson flags.JsonFlag -var deleteWebhookCmd = &cobra.Command{ - Use: "delete-webhook", - Short: `Delete a webhook.`, - Long: `Delete a webhook. + // TODO: short flags + cmd.Flags().Var(&deleteWebhookJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&deleteWebhookReq.Id, "id", deleteWebhookReq.Id, `Webhook ID required to delete a registry webhook.`) + + cmd.Use = "delete-webhook" + cmd.Short = `Delete a webhook.` + cmd.Long = `Delete a webhook. **NOTE:** This endpoint is in Public Preview. - Deletes a registry webhook.`, + Deletes a registry webhook.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -657,42 +942,64 @@ var deleteWebhookCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteWebhookOverrides { + fn(cmd, &deleteWebhookReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDeleteWebhook()) + }) } // start get-latest-versions command -var getLatestVersionsReq ml.GetLatestVersionsRequest -var getLatestVersionsJson flags.JsonFlag -func init() { - Cmd.AddCommand(getLatestVersionsCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getLatestVersionsOverrides []func( + *cobra.Command, + *ml.GetLatestVersionsRequest, +) + +func newGetLatestVersions() *cobra.Command { + cmd := &cobra.Command{} + + var getLatestVersionsReq ml.GetLatestVersionsRequest + var getLatestVersionsJson flags.JsonFlag + // TODO: short flags - getLatestVersionsCmd.Flags().Var(&getLatestVersionsJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&getLatestVersionsJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: stages -} - -var getLatestVersionsCmd = &cobra.Command{ - Use: "get-latest-versions NAME", - Short: `Get the latest version.`, - Long: `Get the latest version. + cmd.Use = "get-latest-versions NAME" + cmd.Short = `Get the latest version.` + cmd.Long = `Get the latest version. - Gets the latest version of a registered model.`, + Gets the latest version of a registered model.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -710,39 +1017,61 @@ var getLatestVersionsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getLatestVersionsOverrides { + fn(cmd, &getLatestVersionsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetLatestVersions()) + }) } // start get-model command -var getModelReq ml.GetModelRequest -func init() { - Cmd.AddCommand(getModelCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getModelOverrides []func( + *cobra.Command, + *ml.GetModelRequest, +) -} +func newGetModel() *cobra.Command { + cmd := &cobra.Command{} -var getModelCmd = &cobra.Command{ - Use: "get-model NAME", - Short: `Get model.`, - Long: `Get model. + var getModelReq ml.GetModelRequest + + // TODO: short flags + + cmd.Use = "get-model NAME" + cmd.Short = `Get model.` + cmd.Long = `Get model. Get the details of a model. This is a Databricks workspace version of the [MLflow endpoint] that also returns the model's Databricks workspace ID and the permission level of the requesting user on the model. - [MLflow endpoint]: https://www.mlflow.org/docs/latest/rest-api.html#get-registeredmodel`, + [MLflow endpoint]: https://www.mlflow.org/docs/latest/rest-api.html#get-registeredmodel` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -753,35 +1082,57 @@ var getModelCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getModelOverrides { + fn(cmd, &getModelReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetModel()) + }) } // start get-model-version command -var getModelVersionReq ml.GetModelVersionRequest -func init() { - Cmd.AddCommand(getModelVersionCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getModelVersionOverrides []func( + *cobra.Command, + *ml.GetModelVersionRequest, +) -} +func newGetModelVersion() *cobra.Command { + cmd := &cobra.Command{} -var getModelVersionCmd = &cobra.Command{ - Use: "get-model-version NAME VERSION", - Short: `Get a model version.`, - Long: `Get a model version. + var getModelVersionReq ml.GetModelVersionRequest + + // TODO: short flags + + cmd.Use = "get-model-version NAME VERSION" + cmd.Short = `Get a model version.` + cmd.Long = `Get a model version. - Get a model version.`, + Get a model version.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -793,35 +1144,57 @@ var getModelVersionCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getModelVersionOverrides { + fn(cmd, &getModelVersionReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetModelVersion()) + }) } // start get-model-version-download-uri command -var getModelVersionDownloadUriReq ml.GetModelVersionDownloadUriRequest -func init() { - Cmd.AddCommand(getModelVersionDownloadUriCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getModelVersionDownloadUriOverrides []func( + *cobra.Command, + *ml.GetModelVersionDownloadUriRequest, +) -} +func newGetModelVersionDownloadUri() *cobra.Command { + cmd := &cobra.Command{} -var getModelVersionDownloadUriCmd = &cobra.Command{ - Use: "get-model-version-download-uri NAME VERSION", - Short: `Get a model version URI.`, - Long: `Get a model version URI. + var getModelVersionDownloadUriReq ml.GetModelVersionDownloadUriRequest + + // TODO: short flags + + cmd.Use = "get-model-version-download-uri NAME VERSION" + cmd.Short = `Get a model version URI.` + cmd.Long = `Get a model version URI. - Gets a URI to download the model version.`, + Gets a URI to download the model version.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -833,44 +1206,66 @@ var getModelVersionDownloadUriCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getModelVersionDownloadUriOverrides { + fn(cmd, &getModelVersionDownloadUriReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetModelVersionDownloadUri()) + }) } // start list-models command -var listModelsReq ml.ListModelsRequest -var listModelsJson flags.JsonFlag -func init() { - Cmd.AddCommand(listModelsCmd) - // TODO: short flags - listModelsCmd.Flags().Var(&listModelsJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listModelsOverrides []func( + *cobra.Command, + *ml.ListModelsRequest, +) - listModelsCmd.Flags().IntVar(&listModelsReq.MaxResults, "max-results", listModelsReq.MaxResults, `Maximum number of registered models desired.`) - listModelsCmd.Flags().StringVar(&listModelsReq.PageToken, "page-token", listModelsReq.PageToken, `Pagination token to go to the next page based on a previous query.`) +func newListModels() *cobra.Command { + cmd := &cobra.Command{} -} + var listModelsReq ml.ListModelsRequest + var listModelsJson flags.JsonFlag -var listModelsCmd = &cobra.Command{ - Use: "list-models", - Short: `List models.`, - Long: `List models. + // TODO: short flags + cmd.Flags().Var(&listModelsJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().IntVar(&listModelsReq.MaxResults, "max-results", listModelsReq.MaxResults, `Maximum number of registered models desired.`) + cmd.Flags().StringVar(&listModelsReq.PageToken, "page-token", listModelsReq.PageToken, `Pagination token to go to the next page based on a previous query.`) + + cmd.Use = "list-models" + cmd.Short = `List models.` + cmd.Long = `List models. Lists all available registered models, up to the limit specified in - __max_results__.`, + __max_results__.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -887,35 +1282,57 @@ var listModelsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listModelsOverrides { + fn(cmd, &listModelsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newListModels()) + }) } // start list-transition-requests command -var listTransitionRequestsReq ml.ListTransitionRequestsRequest -func init() { - Cmd.AddCommand(listTransitionRequestsCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listTransitionRequestsOverrides []func( + *cobra.Command, + *ml.ListTransitionRequestsRequest, +) -} +func newListTransitionRequests() *cobra.Command { + cmd := &cobra.Command{} -var listTransitionRequestsCmd = &cobra.Command{ - Use: "list-transition-requests NAME VERSION", - Short: `List transition requests.`, - Long: `List transition requests. + var listTransitionRequestsReq ml.ListTransitionRequestsRequest + + // TODO: short flags + + cmd.Use = "list-transition-requests NAME VERSION" + cmd.Short = `List transition requests.` + cmd.Long = `List transition requests. - Gets a list of all open stage transition requests for the model version.`, + Gets a list of all open stage transition requests for the model version.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -927,46 +1344,68 @@ var listTransitionRequestsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listTransitionRequestsOverrides { + fn(cmd, &listTransitionRequestsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newListTransitionRequests()) + }) } // start list-webhooks command -var listWebhooksReq ml.ListWebhooksRequest -var listWebhooksJson flags.JsonFlag -func init() { - Cmd.AddCommand(listWebhooksCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listWebhooksOverrides []func( + *cobra.Command, + *ml.ListWebhooksRequest, +) + +func newListWebhooks() *cobra.Command { + cmd := &cobra.Command{} + + var listWebhooksReq ml.ListWebhooksRequest + var listWebhooksJson flags.JsonFlag + // TODO: short flags - listWebhooksCmd.Flags().Var(&listWebhooksJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&listWebhooksJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: events - listWebhooksCmd.Flags().StringVar(&listWebhooksReq.ModelName, "model-name", listWebhooksReq.ModelName, `If not specified, all webhooks associated with the specified events are listed, regardless of their associated model.`) - listWebhooksCmd.Flags().StringVar(&listWebhooksReq.PageToken, "page-token", listWebhooksReq.PageToken, `Token indicating the page of artifact results to fetch.`) - -} + cmd.Flags().StringVar(&listWebhooksReq.ModelName, "model-name", listWebhooksReq.ModelName, `If not specified, all webhooks associated with the specified events are listed, regardless of their associated model.`) + cmd.Flags().StringVar(&listWebhooksReq.PageToken, "page-token", listWebhooksReq.PageToken, `Token indicating the page of artifact results to fetch.`) -var listWebhooksCmd = &cobra.Command{ - Use: "list-webhooks", - Short: `List registry webhooks.`, - Long: `List registry webhooks. + cmd.Use = "list-webhooks" + cmd.Short = `List registry webhooks.` + cmd.Long = `List registry webhooks. **NOTE:** This endpoint is in Public Preview. - Lists all registry webhooks.`, + Lists all registry webhooks.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -983,42 +1422,64 @@ var listWebhooksCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listWebhooksOverrides { + fn(cmd, &listWebhooksReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newListWebhooks()) + }) } // start reject-transition-request command -var rejectTransitionRequestReq ml.RejectTransitionRequest -var rejectTransitionRequestJson flags.JsonFlag -func init() { - Cmd.AddCommand(rejectTransitionRequestCmd) - // TODO: short flags - rejectTransitionRequestCmd.Flags().Var(&rejectTransitionRequestJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var rejectTransitionRequestOverrides []func( + *cobra.Command, + *ml.RejectTransitionRequest, +) - rejectTransitionRequestCmd.Flags().StringVar(&rejectTransitionRequestReq.Comment, "comment", rejectTransitionRequestReq.Comment, `User-provided comment on the action.`) +func newRejectTransitionRequest() *cobra.Command { + cmd := &cobra.Command{} -} + var rejectTransitionRequestReq ml.RejectTransitionRequest + var rejectTransitionRequestJson flags.JsonFlag -var rejectTransitionRequestCmd = &cobra.Command{ - Use: "reject-transition-request NAME VERSION STAGE", - Short: `Reject a transition request.`, - Long: `Reject a transition request. + // TODO: short flags + cmd.Flags().Var(&rejectTransitionRequestJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&rejectTransitionRequestReq.Comment, "comment", rejectTransitionRequestReq.Comment, `User-provided comment on the action.`) + + cmd.Use = "reject-transition-request NAME VERSION STAGE" + cmd.Short = `Reject a transition request.` + cmd.Long = `Reject a transition request. - Rejects a model version stage transition request.`, + Rejects a model version stage transition request.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(3) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1041,42 +1502,64 @@ var rejectTransitionRequestCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range rejectTransitionRequestOverrides { + fn(cmd, &rejectTransitionRequestReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newRejectTransitionRequest()) + }) } // start rename-model command -var renameModelReq ml.RenameModelRequest -var renameModelJson flags.JsonFlag -func init() { - Cmd.AddCommand(renameModelCmd) - // TODO: short flags - renameModelCmd.Flags().Var(&renameModelJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var renameModelOverrides []func( + *cobra.Command, + *ml.RenameModelRequest, +) - renameModelCmd.Flags().StringVar(&renameModelReq.NewName, "new-name", renameModelReq.NewName, `If provided, updates the name for this registered_model.`) +func newRenameModel() *cobra.Command { + cmd := &cobra.Command{} -} + var renameModelReq ml.RenameModelRequest + var renameModelJson flags.JsonFlag -var renameModelCmd = &cobra.Command{ - Use: "rename-model NAME", - Short: `Rename a model.`, - Long: `Rename a model. + // TODO: short flags + cmd.Flags().Var(&renameModelJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&renameModelReq.NewName, "new-name", renameModelReq.NewName, `If provided, updates the name for this registered_model.`) + + cmd.Use = "rename-model NAME" + cmd.Short = `Rename a model.` + cmd.Long = `Rename a model. - Renames a registered model.`, + Renames a registered model.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1094,45 +1577,67 @@ var renameModelCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range renameModelOverrides { + fn(cmd, &renameModelReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newRenameModel()) + }) } // start search-model-versions command -var searchModelVersionsReq ml.SearchModelVersionsRequest -var searchModelVersionsJson flags.JsonFlag -func init() { - Cmd.AddCommand(searchModelVersionsCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var searchModelVersionsOverrides []func( + *cobra.Command, + *ml.SearchModelVersionsRequest, +) + +func newSearchModelVersions() *cobra.Command { + cmd := &cobra.Command{} + + var searchModelVersionsReq ml.SearchModelVersionsRequest + var searchModelVersionsJson flags.JsonFlag + // TODO: short flags - searchModelVersionsCmd.Flags().Var(&searchModelVersionsJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&searchModelVersionsJson, "json", `either inline JSON string or @path/to/file.json with request body`) - searchModelVersionsCmd.Flags().StringVar(&searchModelVersionsReq.Filter, "filter", searchModelVersionsReq.Filter, `String filter condition, like "name='my-model-name'".`) - searchModelVersionsCmd.Flags().IntVar(&searchModelVersionsReq.MaxResults, "max-results", searchModelVersionsReq.MaxResults, `Maximum number of models desired.`) + cmd.Flags().StringVar(&searchModelVersionsReq.Filter, "filter", searchModelVersionsReq.Filter, `String filter condition, like "name='my-model-name'".`) + cmd.Flags().IntVar(&searchModelVersionsReq.MaxResults, "max-results", searchModelVersionsReq.MaxResults, `Maximum number of models desired.`) // TODO: array: order_by - searchModelVersionsCmd.Flags().StringVar(&searchModelVersionsReq.PageToken, "page-token", searchModelVersionsReq.PageToken, `Pagination token to go to next page based on previous search query.`) - -} + cmd.Flags().StringVar(&searchModelVersionsReq.PageToken, "page-token", searchModelVersionsReq.PageToken, `Pagination token to go to next page based on previous search query.`) -var searchModelVersionsCmd = &cobra.Command{ - Use: "search-model-versions", - Short: `Searches model versions.`, - Long: `Searches model versions. + cmd.Use = "search-model-versions" + cmd.Short = `Searches model versions.` + cmd.Long = `Searches model versions. - Searches for specific model versions based on the supplied __filter__.`, + Searches for specific model versions based on the supplied __filter__.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1149,45 +1654,67 @@ var searchModelVersionsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range searchModelVersionsOverrides { + fn(cmd, &searchModelVersionsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newSearchModelVersions()) + }) } // start search-models command -var searchModelsReq ml.SearchModelsRequest -var searchModelsJson flags.JsonFlag -func init() { - Cmd.AddCommand(searchModelsCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var searchModelsOverrides []func( + *cobra.Command, + *ml.SearchModelsRequest, +) + +func newSearchModels() *cobra.Command { + cmd := &cobra.Command{} + + var searchModelsReq ml.SearchModelsRequest + var searchModelsJson flags.JsonFlag + // TODO: short flags - searchModelsCmd.Flags().Var(&searchModelsJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&searchModelsJson, "json", `either inline JSON string or @path/to/file.json with request body`) - searchModelsCmd.Flags().StringVar(&searchModelsReq.Filter, "filter", searchModelsReq.Filter, `String filter condition, like "name LIKE 'my-model-name'".`) - searchModelsCmd.Flags().IntVar(&searchModelsReq.MaxResults, "max-results", searchModelsReq.MaxResults, `Maximum number of models desired.`) + cmd.Flags().StringVar(&searchModelsReq.Filter, "filter", searchModelsReq.Filter, `String filter condition, like "name LIKE 'my-model-name'".`) + cmd.Flags().IntVar(&searchModelsReq.MaxResults, "max-results", searchModelsReq.MaxResults, `Maximum number of models desired.`) // TODO: array: order_by - searchModelsCmd.Flags().StringVar(&searchModelsReq.PageToken, "page-token", searchModelsReq.PageToken, `Pagination token to go to the next page based on a previous search query.`) - -} + cmd.Flags().StringVar(&searchModelsReq.PageToken, "page-token", searchModelsReq.PageToken, `Pagination token to go to the next page based on a previous search query.`) -var searchModelsCmd = &cobra.Command{ - Use: "search-models", - Short: `Search models.`, - Long: `Search models. + cmd.Use = "search-models" + cmd.Short = `Search models.` + cmd.Long = `Search models. - Search for registered models based on the specified __filter__.`, + Search for registered models based on the specified __filter__.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1204,40 +1731,62 @@ var searchModelsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range searchModelsOverrides { + fn(cmd, &searchModelsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newSearchModels()) + }) } // start set-model-tag command -var setModelTagReq ml.SetModelTagRequest -var setModelTagJson flags.JsonFlag -func init() { - Cmd.AddCommand(setModelTagCmd) - // TODO: short flags - setModelTagCmd.Flags().Var(&setModelTagJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var setModelTagOverrides []func( + *cobra.Command, + *ml.SetModelTagRequest, +) -} +func newSetModelTag() *cobra.Command { + cmd := &cobra.Command{} -var setModelTagCmd = &cobra.Command{ - Use: "set-model-tag NAME KEY VALUE", - Short: `Set a tag.`, - Long: `Set a tag. + var setModelTagReq ml.SetModelTagRequest + var setModelTagJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&setModelTagJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "set-model-tag NAME KEY VALUE" + cmd.Short = `Set a tag.` + cmd.Long = `Set a tag. - Sets a tag on a registered model.`, + Sets a tag on a registered model.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(3) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1257,40 +1806,62 @@ var setModelTagCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range setModelTagOverrides { + fn(cmd, &setModelTagReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newSetModelTag()) + }) } // start set-model-version-tag command -var setModelVersionTagReq ml.SetModelVersionTagRequest -var setModelVersionTagJson flags.JsonFlag -func init() { - Cmd.AddCommand(setModelVersionTagCmd) - // TODO: short flags - setModelVersionTagCmd.Flags().Var(&setModelVersionTagJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var setModelVersionTagOverrides []func( + *cobra.Command, + *ml.SetModelVersionTagRequest, +) -} +func newSetModelVersionTag() *cobra.Command { + cmd := &cobra.Command{} -var setModelVersionTagCmd = &cobra.Command{ - Use: "set-model-version-tag NAME VERSION KEY VALUE", - Short: `Set a version tag.`, - Long: `Set a version tag. + var setModelVersionTagReq ml.SetModelVersionTagRequest + var setModelVersionTagJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&setModelVersionTagJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "set-model-version-tag NAME VERSION KEY VALUE" + cmd.Short = `Set a version tag.` + cmd.Long = `Set a version tag. - Sets a model version tag.`, + Sets a model version tag.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(4) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1311,44 +1882,66 @@ var setModelVersionTagCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range setModelVersionTagOverrides { + fn(cmd, &setModelVersionTagReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newSetModelVersionTag()) + }) } // start test-registry-webhook command -var testRegistryWebhookReq ml.TestRegistryWebhookRequest -var testRegistryWebhookJson flags.JsonFlag -func init() { - Cmd.AddCommand(testRegistryWebhookCmd) - // TODO: short flags - testRegistryWebhookCmd.Flags().Var(&testRegistryWebhookJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var testRegistryWebhookOverrides []func( + *cobra.Command, + *ml.TestRegistryWebhookRequest, +) - testRegistryWebhookCmd.Flags().Var(&testRegistryWebhookReq.Event, "event", `If event is specified, the test trigger uses the specified event.`) +func newTestRegistryWebhook() *cobra.Command { + cmd := &cobra.Command{} -} + var testRegistryWebhookReq ml.TestRegistryWebhookRequest + var testRegistryWebhookJson flags.JsonFlag -var testRegistryWebhookCmd = &cobra.Command{ - Use: "test-registry-webhook ID", - Short: `Test a webhook.`, - Long: `Test a webhook. + // TODO: short flags + cmd.Flags().Var(&testRegistryWebhookJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().Var(&testRegistryWebhookReq.Event, "event", `If event is specified, the test trigger uses the specified event.`) + + cmd.Use = "test-registry-webhook ID" + cmd.Short = `Test a webhook.` + cmd.Long = `Test a webhook. **NOTE:** This endpoint is in Public Preview. - Tests a registry webhook.`, + Tests a registry webhook.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1366,46 +1959,68 @@ var testRegistryWebhookCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range testRegistryWebhookOverrides { + fn(cmd, &testRegistryWebhookReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newTestRegistryWebhook()) + }) } // start transition-stage command -var transitionStageReq ml.TransitionModelVersionStageDatabricks -var transitionStageJson flags.JsonFlag -func init() { - Cmd.AddCommand(transitionStageCmd) - // TODO: short flags - transitionStageCmd.Flags().Var(&transitionStageJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var transitionStageOverrides []func( + *cobra.Command, + *ml.TransitionModelVersionStageDatabricks, +) - transitionStageCmd.Flags().StringVar(&transitionStageReq.Comment, "comment", transitionStageReq.Comment, `User-provided comment on the action.`) +func newTransitionStage() *cobra.Command { + cmd := &cobra.Command{} -} + var transitionStageReq ml.TransitionModelVersionStageDatabricks + var transitionStageJson flags.JsonFlag -var transitionStageCmd = &cobra.Command{ - Use: "transition-stage NAME VERSION STAGE ARCHIVE_EXISTING_VERSIONS", - Short: `Transition a stage.`, - Long: `Transition a stage. + // TODO: short flags + cmd.Flags().Var(&transitionStageJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&transitionStageReq.Comment, "comment", transitionStageReq.Comment, `User-provided comment on the action.`) + + cmd.Use = "transition-stage NAME VERSION STAGE ARCHIVE_EXISTING_VERSIONS" + cmd.Short = `Transition a stage.` + cmd.Long = `Transition a stage. Transition a model version's stage. This is a Databricks workspace version of the [MLflow endpoint] that also accepts a comment associated with the transition to be recorded.", - [MLflow endpoint]: https://www.mlflow.org/docs/latest/rest-api.html#transition-modelversion-stage`, + [MLflow endpoint]: https://www.mlflow.org/docs/latest/rest-api.html#transition-modelversion-stage` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(4) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1432,40 +2047,62 @@ var transitionStageCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range transitionStageOverrides { + fn(cmd, &transitionStageReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newTransitionStage()) + }) } // start update-comment command -var updateCommentReq ml.UpdateComment -var updateCommentJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCommentCmd) - // TODO: short flags - updateCommentCmd.Flags().Var(&updateCommentJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateCommentOverrides []func( + *cobra.Command, + *ml.UpdateComment, +) -} +func newUpdateComment() *cobra.Command { + cmd := &cobra.Command{} -var updateCommentCmd = &cobra.Command{ - Use: "update-comment ID COMMENT", - Short: `Update a comment.`, - Long: `Update a comment. + var updateCommentReq ml.UpdateComment + var updateCommentJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&updateCommentJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "update-comment ID COMMENT" + cmd.Short = `Update a comment.` + cmd.Long = `Update a comment. - Post an edit to a comment on a model version.`, + Post an edit to a comment on a model version.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1484,42 +2121,64 @@ var updateCommentCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateCommentOverrides { + fn(cmd, &updateCommentReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdateComment()) + }) } // start update-model command -var updateModelReq ml.UpdateModelRequest -var updateModelJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateModelCmd) - // TODO: short flags - updateModelCmd.Flags().Var(&updateModelJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateModelOverrides []func( + *cobra.Command, + *ml.UpdateModelRequest, +) - updateModelCmd.Flags().StringVar(&updateModelReq.Description, "description", updateModelReq.Description, `If provided, updates the description for this registered_model.`) +func newUpdateModel() *cobra.Command { + cmd := &cobra.Command{} -} + var updateModelReq ml.UpdateModelRequest + var updateModelJson flags.JsonFlag -var updateModelCmd = &cobra.Command{ - Use: "update-model NAME", - Short: `Update model.`, - Long: `Update model. + // TODO: short flags + cmd.Flags().Var(&updateModelJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&updateModelReq.Description, "description", updateModelReq.Description, `If provided, updates the description for this registered_model.`) + + cmd.Use = "update-model NAME" + cmd.Short = `Update model.` + cmd.Long = `Update model. - Updates a registered model.`, + Updates a registered model.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1537,42 +2196,64 @@ var updateModelCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateModelOverrides { + fn(cmd, &updateModelReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdateModel()) + }) } // start update-model-version command -var updateModelVersionReq ml.UpdateModelVersionRequest -var updateModelVersionJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateModelVersionCmd) - // TODO: short flags - updateModelVersionCmd.Flags().Var(&updateModelVersionJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateModelVersionOverrides []func( + *cobra.Command, + *ml.UpdateModelVersionRequest, +) - updateModelVersionCmd.Flags().StringVar(&updateModelVersionReq.Description, "description", updateModelVersionReq.Description, `If provided, updates the description for this registered_model.`) +func newUpdateModelVersion() *cobra.Command { + cmd := &cobra.Command{} -} + var updateModelVersionReq ml.UpdateModelVersionRequest + var updateModelVersionJson flags.JsonFlag -var updateModelVersionCmd = &cobra.Command{ - Use: "update-model-version NAME VERSION", - Short: `Update model version.`, - Long: `Update model version. + // TODO: short flags + cmd.Flags().Var(&updateModelVersionJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&updateModelVersionReq.Description, "description", updateModelVersionReq.Description, `If provided, updates the description for this registered_model.`) + + cmd.Use = "update-model-version NAME VERSION" + cmd.Short = `Update model version.` + cmd.Long = `Update model version. - Updates the model version.`, + Updates the model version.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1591,48 +2272,70 @@ var updateModelVersionCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateModelVersionOverrides { + fn(cmd, &updateModelVersionReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdateModelVersion()) + }) } // start update-webhook command -var updateWebhookReq ml.UpdateRegistryWebhook -var updateWebhookJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateWebhookCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateWebhookOverrides []func( + *cobra.Command, + *ml.UpdateRegistryWebhook, +) + +func newUpdateWebhook() *cobra.Command { + cmd := &cobra.Command{} + + var updateWebhookReq ml.UpdateRegistryWebhook + var updateWebhookJson flags.JsonFlag + // TODO: short flags - updateWebhookCmd.Flags().Var(&updateWebhookJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateWebhookJson, "json", `either inline JSON string or @path/to/file.json with request body`) - updateWebhookCmd.Flags().StringVar(&updateWebhookReq.Description, "description", updateWebhookReq.Description, `User-specified description for the webhook.`) + cmd.Flags().StringVar(&updateWebhookReq.Description, "description", updateWebhookReq.Description, `User-specified description for the webhook.`) // TODO: array: events // TODO: complex arg: http_url_spec // TODO: complex arg: job_spec - updateWebhookCmd.Flags().Var(&updateWebhookReq.Status, "status", `This describes an enum.`) - -} + cmd.Flags().Var(&updateWebhookReq.Status, "status", `This describes an enum.`) -var updateWebhookCmd = &cobra.Command{ - Use: "update-webhook ID", - Short: `Update a webhook.`, - Long: `Update a webhook. + cmd.Use = "update-webhook ID" + cmd.Short = `Update a webhook.` + cmd.Long = `Update a webhook. **NOTE:** This endpoint is in Public Preview. - Updates a registry webhook.`, + Updates a registry webhook.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -1650,10 +2353,24 @@ var updateWebhookCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateWebhookOverrides { + fn(cmd, &updateWebhookReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdateWebhook()) + }) } // end service ModelRegistry diff --git a/cmd/workspace/permissions/permissions.go b/cmd/workspace/permissions/permissions.go index c925012071..39454b248f 100755 --- a/cmd/workspace/permissions/permissions.go +++ b/cmd/workspace/permissions/permissions.go @@ -10,40 +10,62 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "permissions", - Short: `Permissions API are used to create read, write, edit, update and manage access for various users on different objects and endpoints.`, - Long: `Permissions API are used to create read, write, edit, update and manage access +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "permissions", + Short: `Permissions API are used to create read, write, edit, update and manage access for various users on different objects and endpoints.`, + Long: `Permissions API are used to create read, write, edit, update and manage access for various users on different objects and endpoints.`, - Annotations: map[string]string{ - "package": "iam", - }, + GroupID: "iam", + Annotations: map[string]string{ + "package": "iam", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start get command -var getReq iam.GetPermissionRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *iam.GetPermissionRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} -var getCmd = &cobra.Command{ - Use: "get REQUEST_OBJECT_TYPE REQUEST_OBJECT_ID", - Short: `Get object permissions.`, - Long: `Get object permissions. + var getReq iam.GetPermissionRequest + + // TODO: short flags + + cmd.Use = "get REQUEST_OBJECT_TYPE REQUEST_OBJECT_ID" + cmd.Short = `Get object permissions.` + cmd.Long = `Get object permissions. Gets the permission of an object. Objects can inherit permissions from their - parent objects or root objects.`, + parent objects or root objects.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -55,35 +77,57 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start get-permission-levels command -var getPermissionLevelsReq iam.GetPermissionLevelsRequest -func init() { - Cmd.AddCommand(getPermissionLevelsCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getPermissionLevelsOverrides []func( + *cobra.Command, + *iam.GetPermissionLevelsRequest, +) -} +func newGetPermissionLevels() *cobra.Command { + cmd := &cobra.Command{} -var getPermissionLevelsCmd = &cobra.Command{ - Use: "get-permission-levels REQUEST_OBJECT_TYPE REQUEST_OBJECT_ID", - Short: `Get permission levels.`, - Long: `Get permission levels. + var getPermissionLevelsReq iam.GetPermissionLevelsRequest + + // TODO: short flags + + cmd.Use = "get-permission-levels REQUEST_OBJECT_TYPE REQUEST_OBJECT_ID" + cmd.Short = `Get permission levels.` + cmd.Long = `Get permission levels. - Gets the permission levels that a user can have on an object.`, + Gets the permission levels that a user can have on an object.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -95,40 +139,62 @@ var getPermissionLevelsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getPermissionLevelsOverrides { + fn(cmd, &getPermissionLevelsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetPermissionLevels()) + }) } // start set command -var setReq iam.PermissionsRequest -var setJson flags.JsonFlag -func init() { - Cmd.AddCommand(setCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var setOverrides []func( + *cobra.Command, + *iam.PermissionsRequest, +) + +func newSet() *cobra.Command { + cmd := &cobra.Command{} + + var setReq iam.PermissionsRequest + var setJson flags.JsonFlag + // TODO: short flags - setCmd.Flags().Var(&setJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&setJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: access_control_list -} - -var setCmd = &cobra.Command{ - Use: "set REQUEST_OBJECT_TYPE REQUEST_OBJECT_ID", - Short: `Set permissions.`, - Long: `Set permissions. + cmd.Use = "set REQUEST_OBJECT_TYPE REQUEST_OBJECT_ID" + cmd.Short = `Set permissions.` + cmd.Long = `Set permissions. Sets permissions on object. Objects can inherit permissions from their parent - objects and root objects.`, + objects and root objects.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -146,39 +212,61 @@ var setCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range setOverrides { + fn(cmd, &setReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newSet()) + }) } // start update command -var updateReq iam.PermissionsRequest -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *iam.PermissionsRequest, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq iam.PermissionsRequest + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: access_control_list -} - -var updateCmd = &cobra.Command{ - Use: "update REQUEST_OBJECT_TYPE REQUEST_OBJECT_ID", - Short: `Update permission.`, - Long: `Update permission. + cmd.Use = "update REQUEST_OBJECT_TYPE REQUEST_OBJECT_ID" + cmd.Short = `Update permission.` + cmd.Long = `Update permission. - Updates the permissions on an object.`, + Updates the permissions on an object.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -196,10 +284,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Permissions diff --git a/cmd/workspace/pipelines/pipelines.go b/cmd/workspace/pipelines/pipelines.go index 10f37846da..652af89876 100755 --- a/cmd/workspace/pipelines/pipelines.go +++ b/cmd/workspace/pipelines/pipelines.go @@ -13,10 +13,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "pipelines", - Short: `The Delta Live Tables API allows you to create, edit, delete, start, and view details about pipelines.`, - Long: `The Delta Live Tables API allows you to create, edit, delete, start, and view +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "pipelines", + Short: `The Delta Live Tables API allows you to create, edit, delete, start, and view details about pipelines.`, + Long: `The Delta Live Tables API allows you to create, edit, delete, start, and view details about pipelines. Delta Live Tables is a framework for building reliable, maintainable, and @@ -30,40 +35,57 @@ var Cmd = &cobra.Command{ quality with Delta Live Tables expectations. Expectations allow you to define expected data quality and specify how to handle records that fail those expectations.`, - Annotations: map[string]string{ - "package": "pipelines", - }, + GroupID: "pipelines", + Annotations: map[string]string{ + "package": "pipelines", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq pipelines.CreatePipeline -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *pipelines.CreatePipeline, +) -} +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq pipelines.CreatePipeline + var createJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a pipeline.`, - Long: `Create a pipeline. + cmd.Use = "create" + cmd.Short = `Create a pipeline.` + cmd.Long = `Create a pipeline. Creates a new data processing pipeline based on the requested configuration. - If successful, this method returns the ID of the new pipeline.`, + If successful, this method returns the ID of the new pipeline.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -81,51 +103,60 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq pipelines.DeletePipelineRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *pipelines.DeletePipelineRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq pipelines.DeletePipelineRequest + + // TODO: short flags -var deleteCmd = &cobra.Command{ - Use: "delete PIPELINE_ID", - Short: `Delete a pipeline.`, - Long: `Delete a pipeline. + cmd.Use = "delete PIPELINE_ID" + cmd.Short = `Delete a pipeline.` + cmd.Long = `Delete a pipeline. - Deletes a pipeline.`, + Deletes a pipeline.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No PIPELINE_ID argument specified. Loading names for Pipelines drop-down." - names, err := w.Pipelines.PipelineStateInfoNameToPipelineIdMap(ctx, pipelines.ListPipelinesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Pipelines drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have ") - } deleteReq.PipelineId = args[0] err = w.Pipelines.Delete(ctx, deleteReq) @@ -133,55 +164,63 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq pipelines.GetPipelineRequest -var getSkipWait bool -var getTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *pipelines.GetPipelineRequest, +) -func init() { - Cmd.AddCommand(getCmd) +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq pipelines.GetPipelineRequest + + var getSkipWait bool + var getTimeout time.Duration - getCmd.Flags().BoolVar(&getSkipWait, "no-wait", getSkipWait, `do not wait to reach RUNNING state`) - getCmd.Flags().DurationVar(&getTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) + cmd.Flags().BoolVar(&getSkipWait, "no-wait", getSkipWait, `do not wait to reach RUNNING state`) + cmd.Flags().DurationVar(&getTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) // TODO: short flags -} + cmd.Use = "get PIPELINE_ID" + cmd.Short = `Get a pipeline.` + cmd.Long = `Get a pipeline.` + + cmd.Annotations = make(map[string]string) -var getCmd = &cobra.Command{ - Use: "get PIPELINE_ID", - Short: `Get a pipeline.`, - Long: `Get a pipeline.`, + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No PIPELINE_ID argument specified. Loading names for Pipelines drop-down." - names, err := w.Pipelines.PipelineStateInfoNameToPipelineIdMap(ctx, pipelines.ListPipelinesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Pipelines drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have ") - } getReq.PipelineId = args[0] response, err := w.Pipelines.Get(ctx, getReq) @@ -189,35 +228,57 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start get-update command -var getUpdateReq pipelines.GetUpdateRequest -func init() { - Cmd.AddCommand(getUpdateCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getUpdateOverrides []func( + *cobra.Command, + *pipelines.GetUpdateRequest, +) -} +func newGetUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var getUpdateReq pipelines.GetUpdateRequest -var getUpdateCmd = &cobra.Command{ - Use: "get-update PIPELINE_ID UPDATE_ID", - Short: `Get a pipeline update.`, - Long: `Get a pipeline update. + // TODO: short flags + + cmd.Use = "get-update PIPELINE_ID UPDATE_ID" + cmd.Short = `Get a pipeline update.` + cmd.Long = `Get a pipeline update. - Gets an update from an active pipeline.`, + Gets an update from an active pipeline.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -229,38 +290,64 @@ var getUpdateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getUpdateOverrides { + fn(cmd, &getUpdateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetUpdate()) + }) } // start list-pipeline-events command -var listPipelineEventsReq pipelines.ListPipelineEventsRequest -var listPipelineEventsJson flags.JsonFlag -func init() { - Cmd.AddCommand(listPipelineEventsCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listPipelineEventsOverrides []func( + *cobra.Command, + *pipelines.ListPipelineEventsRequest, +) + +func newListPipelineEvents() *cobra.Command { + cmd := &cobra.Command{} + + var listPipelineEventsReq pipelines.ListPipelineEventsRequest + var listPipelineEventsJson flags.JsonFlag + // TODO: short flags - listPipelineEventsCmd.Flags().Var(&listPipelineEventsJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&listPipelineEventsJson, "json", `either inline JSON string or @path/to/file.json with request body`) - listPipelineEventsCmd.Flags().StringVar(&listPipelineEventsReq.Filter, "filter", listPipelineEventsReq.Filter, `Criteria to select a subset of results, expressed using a SQL-like syntax.`) - listPipelineEventsCmd.Flags().IntVar(&listPipelineEventsReq.MaxResults, "max-results", listPipelineEventsReq.MaxResults, `Max number of entries to return in a single page.`) + cmd.Flags().StringVar(&listPipelineEventsReq.Filter, "filter", listPipelineEventsReq.Filter, `Criteria to select a subset of results, expressed using a SQL-like syntax.`) + cmd.Flags().IntVar(&listPipelineEventsReq.MaxResults, "max-results", listPipelineEventsReq.MaxResults, `Max number of entries to return in a single page.`) // TODO: array: order_by - listPipelineEventsCmd.Flags().StringVar(&listPipelineEventsReq.PageToken, "page-token", listPipelineEventsReq.PageToken, `Page token returned by previous call.`) - -} + cmd.Flags().StringVar(&listPipelineEventsReq.PageToken, "page-token", listPipelineEventsReq.PageToken, `Page token returned by previous call.`) -var listPipelineEventsCmd = &cobra.Command{ - Use: "list-pipeline-events PIPELINE_ID", - Short: `List pipeline events.`, - Long: `List pipeline events. + cmd.Use = "list-pipeline-events PIPELINE_ID" + cmd.Short = `List pipeline events.` + cmd.Long = `List pipeline events. - Retrieves events for a pipeline.`, + Retrieves events for a pipeline.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -270,23 +357,6 @@ var listPipelineEventsCmd = &cobra.Command{ return err } } - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No PIPELINE_ID argument specified. Loading names for Pipelines drop-down." - names, err := w.Pipelines.PipelineStateInfoNameToPipelineIdMap(ctx, pipelines.ListPipelinesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Pipelines drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have ") - } listPipelineEventsReq.PipelineId = args[0] response, err := w.Pipelines.ListPipelineEventsAll(ctx, listPipelineEventsReq) @@ -294,45 +364,67 @@ var listPipelineEventsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listPipelineEventsOverrides { + fn(cmd, &listPipelineEventsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newListPipelineEvents()) + }) } // start list-pipelines command -var listPipelinesReq pipelines.ListPipelinesRequest -var listPipelinesJson flags.JsonFlag -func init() { - Cmd.AddCommand(listPipelinesCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listPipelinesOverrides []func( + *cobra.Command, + *pipelines.ListPipelinesRequest, +) + +func newListPipelines() *cobra.Command { + cmd := &cobra.Command{} + + var listPipelinesReq pipelines.ListPipelinesRequest + var listPipelinesJson flags.JsonFlag + // TODO: short flags - listPipelinesCmd.Flags().Var(&listPipelinesJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&listPipelinesJson, "json", `either inline JSON string or @path/to/file.json with request body`) - listPipelinesCmd.Flags().StringVar(&listPipelinesReq.Filter, "filter", listPipelinesReq.Filter, `Select a subset of results based on the specified criteria.`) - listPipelinesCmd.Flags().IntVar(&listPipelinesReq.MaxResults, "max-results", listPipelinesReq.MaxResults, `The maximum number of entries to return in a single page.`) + cmd.Flags().StringVar(&listPipelinesReq.Filter, "filter", listPipelinesReq.Filter, `Select a subset of results based on the specified criteria.`) + cmd.Flags().IntVar(&listPipelinesReq.MaxResults, "max-results", listPipelinesReq.MaxResults, `The maximum number of entries to return in a single page.`) // TODO: array: order_by - listPipelinesCmd.Flags().StringVar(&listPipelinesReq.PageToken, "page-token", listPipelinesReq.PageToken, `Page token returned by previous call.`) + cmd.Flags().StringVar(&listPipelinesReq.PageToken, "page-token", listPipelinesReq.PageToken, `Page token returned by previous call.`) -} - -var listPipelinesCmd = &cobra.Command{ - Use: "list-pipelines", - Short: `List pipelines.`, - Long: `List pipelines. + cmd.Use = "list-pipelines" + cmd.Short = `List pipelines.` + cmd.Long = `List pipelines. - Lists pipelines defined in the Delta Live Tables system.`, + Lists pipelines defined in the Delta Live Tables system.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -349,55 +441,64 @@ var listPipelinesCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listPipelinesOverrides { + fn(cmd, &listPipelinesReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newListPipelines()) + }) } // start list-updates command -var listUpdatesReq pipelines.ListUpdatesRequest -func init() { - Cmd.AddCommand(listUpdatesCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listUpdatesOverrides []func( + *cobra.Command, + *pipelines.ListUpdatesRequest, +) - listUpdatesCmd.Flags().IntVar(&listUpdatesReq.MaxResults, "max-results", listUpdatesReq.MaxResults, `Max number of entries to return in a single page.`) - listUpdatesCmd.Flags().StringVar(&listUpdatesReq.PageToken, "page-token", listUpdatesReq.PageToken, `Page token returned by previous call.`) - listUpdatesCmd.Flags().StringVar(&listUpdatesReq.UntilUpdateId, "until-update-id", listUpdatesReq.UntilUpdateId, `If present, returns updates until and including this update_id.`) +func newListUpdates() *cobra.Command { + cmd := &cobra.Command{} -} + var listUpdatesReq pipelines.ListUpdatesRequest + + // TODO: short flags + + cmd.Flags().IntVar(&listUpdatesReq.MaxResults, "max-results", listUpdatesReq.MaxResults, `Max number of entries to return in a single page.`) + cmd.Flags().StringVar(&listUpdatesReq.PageToken, "page-token", listUpdatesReq.PageToken, `Page token returned by previous call.`) + cmd.Flags().StringVar(&listUpdatesReq.UntilUpdateId, "until-update-id", listUpdatesReq.UntilUpdateId, `If present, returns updates until and including this update_id.`) -var listUpdatesCmd = &cobra.Command{ - Use: "list-updates PIPELINE_ID", - Short: `List pipeline updates.`, - Long: `List pipeline updates. + cmd.Use = "list-updates PIPELINE_ID" + cmd.Short = `List pipeline updates.` + cmd.Long = `List pipeline updates. - List updates for an active pipeline.`, + List updates for an active pipeline.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No PIPELINE_ID argument specified. Loading names for Pipelines drop-down." - names, err := w.Pipelines.PipelineStateInfoNameToPipelineIdMap(ctx, pipelines.ListPipelinesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Pipelines drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The pipeline to return updates for") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the pipeline to return updates for") - } listUpdatesReq.PipelineId = args[0] response, err := w.Pipelines.ListUpdates(ctx, listUpdatesReq) @@ -405,57 +506,65 @@ var listUpdatesCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listUpdatesOverrides { + fn(cmd, &listUpdatesReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newListUpdates()) + }) } // start reset command -var resetReq pipelines.ResetRequest -var resetSkipWait bool -var resetTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var resetOverrides []func( + *cobra.Command, + *pipelines.ResetRequest, +) -func init() { - Cmd.AddCommand(resetCmd) +func newReset() *cobra.Command { + cmd := &cobra.Command{} - resetCmd.Flags().BoolVar(&resetSkipWait, "no-wait", resetSkipWait, `do not wait to reach RUNNING state`) - resetCmd.Flags().DurationVar(&resetTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) - // TODO: short flags + var resetReq pipelines.ResetRequest -} + var resetSkipWait bool + var resetTimeout time.Duration + + cmd.Flags().BoolVar(&resetSkipWait, "no-wait", resetSkipWait, `do not wait to reach RUNNING state`) + cmd.Flags().DurationVar(&resetTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) + // TODO: short flags -var resetCmd = &cobra.Command{ - Use: "reset PIPELINE_ID", - Short: `Reset a pipeline.`, - Long: `Reset a pipeline. + cmd.Use = "reset PIPELINE_ID" + cmd.Short = `Reset a pipeline.` + cmd.Long = `Reset a pipeline. - Resets a pipeline.`, + Resets a pipeline.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No PIPELINE_ID argument specified. Loading names for Pipelines drop-down." - names, err := w.Pipelines.PipelineStateInfoNameToPipelineIdMap(ctx, pipelines.ListPipelinesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Pipelines drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have ") - } resetReq.PipelineId = args[0] wait, err := w.Pipelines.Reset(ctx, resetReq) @@ -475,38 +584,64 @@ var resetCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range resetOverrides { + fn(cmd, &resetReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newReset()) + }) } // start start-update command -var startUpdateReq pipelines.StartUpdate -var startUpdateJson flags.JsonFlag -func init() { - Cmd.AddCommand(startUpdateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var startUpdateOverrides []func( + *cobra.Command, + *pipelines.StartUpdate, +) + +func newStartUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var startUpdateReq pipelines.StartUpdate + var startUpdateJson flags.JsonFlag + // TODO: short flags - startUpdateCmd.Flags().Var(&startUpdateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&startUpdateJson, "json", `either inline JSON string or @path/to/file.json with request body`) - startUpdateCmd.Flags().Var(&startUpdateReq.Cause, "cause", ``) - startUpdateCmd.Flags().BoolVar(&startUpdateReq.FullRefresh, "full-refresh", startUpdateReq.FullRefresh, `If true, this update will reset all tables before running.`) + cmd.Flags().Var(&startUpdateReq.Cause, "cause", ``) + cmd.Flags().BoolVar(&startUpdateReq.FullRefresh, "full-refresh", startUpdateReq.FullRefresh, `If true, this update will reset all tables before running.`) // TODO: array: full_refresh_selection // TODO: array: refresh_selection -} - -var startUpdateCmd = &cobra.Command{ - Use: "start-update PIPELINE_ID", - Short: `Queue a pipeline update.`, - Long: `Queue a pipeline update. + cmd.Use = "start-update PIPELINE_ID" + cmd.Short = `Queue a pipeline update.` + cmd.Long = `Queue a pipeline update. - Starts or queues a pipeline update.`, + Starts or queues a pipeline update.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -516,23 +651,6 @@ var startUpdateCmd = &cobra.Command{ return err } } - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No PIPELINE_ID argument specified. Loading names for Pipelines drop-down." - names, err := w.Pipelines.PipelineStateInfoNameToPipelineIdMap(ctx, pipelines.ListPipelinesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Pipelines drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have ") - } startUpdateReq.PipelineId = args[0] response, err := w.Pipelines.StartUpdate(ctx, startUpdateReq) @@ -540,57 +658,65 @@ var startUpdateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range startUpdateOverrides { + fn(cmd, &startUpdateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newStartUpdate()) + }) } // start stop command -var stopReq pipelines.StopRequest -var stopSkipWait bool -var stopTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var stopOverrides []func( + *cobra.Command, + *pipelines.StopRequest, +) -func init() { - Cmd.AddCommand(stopCmd) +func newStop() *cobra.Command { + cmd := &cobra.Command{} - stopCmd.Flags().BoolVar(&stopSkipWait, "no-wait", stopSkipWait, `do not wait to reach IDLE state`) - stopCmd.Flags().DurationVar(&stopTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach IDLE state`) - // TODO: short flags + var stopReq pipelines.StopRequest -} + var stopSkipWait bool + var stopTimeout time.Duration + + cmd.Flags().BoolVar(&stopSkipWait, "no-wait", stopSkipWait, `do not wait to reach IDLE state`) + cmd.Flags().DurationVar(&stopTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach IDLE state`) + // TODO: short flags -var stopCmd = &cobra.Command{ - Use: "stop PIPELINE_ID", - Short: `Stop a pipeline.`, - Long: `Stop a pipeline. + cmd.Use = "stop PIPELINE_ID" + cmd.Short = `Stop a pipeline.` + cmd.Long = `Stop a pipeline. - Stops a pipeline.`, + Stops a pipeline.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No PIPELINE_ID argument specified. Loading names for Pipelines drop-down." - names, err := w.Pipelines.PipelineStateInfoNameToPipelineIdMap(ctx, pipelines.ListPipelinesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Pipelines drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have ") - } stopReq.PipelineId = args[0] wait, err := w.Pipelines.Stop(ctx, stopReq) @@ -610,53 +736,82 @@ var stopCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range stopOverrides { + fn(cmd, &stopReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newStop()) + }) } // start update command -var updateReq pipelines.EditPipeline -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *pipelines.EditPipeline, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq pipelines.EditPipeline + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) - updateCmd.Flags().BoolVar(&updateReq.AllowDuplicateNames, "allow-duplicate-names", updateReq.AllowDuplicateNames, `If false, deployment will fail if name has changed and conflicts the name of another pipeline.`) - updateCmd.Flags().StringVar(&updateReq.Catalog, "catalog", updateReq.Catalog, `A catalog in Unity Catalog to publish data from this pipeline to.`) - updateCmd.Flags().StringVar(&updateReq.Channel, "channel", updateReq.Channel, `DLT Release Channel that specifies which version to use.`) + cmd.Flags().BoolVar(&updateReq.AllowDuplicateNames, "allow-duplicate-names", updateReq.AllowDuplicateNames, `If false, deployment will fail if name has changed and conflicts the name of another pipeline.`) + cmd.Flags().StringVar(&updateReq.Catalog, "catalog", updateReq.Catalog, `A catalog in Unity Catalog to publish data from this pipeline to.`) + cmd.Flags().StringVar(&updateReq.Channel, "channel", updateReq.Channel, `DLT Release Channel that specifies which version to use.`) // TODO: array: clusters // TODO: map via StringToStringVar: configuration - updateCmd.Flags().BoolVar(&updateReq.Continuous, "continuous", updateReq.Continuous, `Whether the pipeline is continuous or triggered.`) - updateCmd.Flags().BoolVar(&updateReq.Development, "development", updateReq.Development, `Whether the pipeline is in Development mode.`) - updateCmd.Flags().StringVar(&updateReq.Edition, "edition", updateReq.Edition, `Pipeline product edition.`) - updateCmd.Flags().Int64Var(&updateReq.ExpectedLastModified, "expected-last-modified", updateReq.ExpectedLastModified, `If present, the last-modified time of the pipeline settings before the edit.`) + cmd.Flags().BoolVar(&updateReq.Continuous, "continuous", updateReq.Continuous, `Whether the pipeline is continuous or triggered.`) + cmd.Flags().BoolVar(&updateReq.Development, "development", updateReq.Development, `Whether the pipeline is in Development mode.`) + cmd.Flags().StringVar(&updateReq.Edition, "edition", updateReq.Edition, `Pipeline product edition.`) + cmd.Flags().Int64Var(&updateReq.ExpectedLastModified, "expected-last-modified", updateReq.ExpectedLastModified, `If present, the last-modified time of the pipeline settings before the edit.`) // TODO: complex arg: filters - updateCmd.Flags().StringVar(&updateReq.Id, "id", updateReq.Id, `Unique identifier for this pipeline.`) + cmd.Flags().StringVar(&updateReq.Id, "id", updateReq.Id, `Unique identifier for this pipeline.`) // TODO: array: libraries - updateCmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `Friendly identifier for this pipeline.`) - updateCmd.Flags().BoolVar(&updateReq.Photon, "photon", updateReq.Photon, `Whether Photon is enabled for this pipeline.`) - updateCmd.Flags().StringVar(&updateReq.PipelineId, "pipeline-id", updateReq.PipelineId, `Unique identifier for this pipeline.`) - updateCmd.Flags().BoolVar(&updateReq.Serverless, "serverless", updateReq.Serverless, `Whether serverless compute is enabled for this pipeline.`) - updateCmd.Flags().StringVar(&updateReq.Storage, "storage", updateReq.Storage, `DBFS root directory for storing checkpoints and tables.`) - updateCmd.Flags().StringVar(&updateReq.Target, "target", updateReq.Target, `Target schema (database) to add tables in this pipeline to.`) + cmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `Friendly identifier for this pipeline.`) + cmd.Flags().BoolVar(&updateReq.Photon, "photon", updateReq.Photon, `Whether Photon is enabled for this pipeline.`) + cmd.Flags().StringVar(&updateReq.PipelineId, "pipeline-id", updateReq.PipelineId, `Unique identifier for this pipeline.`) + cmd.Flags().BoolVar(&updateReq.Serverless, "serverless", updateReq.Serverless, `Whether serverless compute is enabled for this pipeline.`) + cmd.Flags().StringVar(&updateReq.Storage, "storage", updateReq.Storage, `DBFS root directory for storing checkpoints and tables.`) + cmd.Flags().StringVar(&updateReq.Target, "target", updateReq.Target, `Target schema (database) to add tables in this pipeline to.`) // TODO: complex arg: trigger -} - -var updateCmd = &cobra.Command{ - Use: "update PIPELINE_ID", - Short: `Edit a pipeline.`, - Long: `Edit a pipeline. + cmd.Use = "update PIPELINE_ID" + cmd.Short = `Edit a pipeline.` + cmd.Long = `Edit a pipeline. - Updates a pipeline with the supplied configuration.`, + Updates a pipeline with the supplied configuration.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -666,23 +821,6 @@ var updateCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No PIPELINE_ID argument specified. Loading names for Pipelines drop-down." - names, err := w.Pipelines.PipelineStateInfoNameToPipelineIdMap(ctx, pipelines.ListPipelinesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Pipelines drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique identifier for this pipeline") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique identifier for this pipeline") - } updateReq.PipelineId = args[0] } @@ -691,10 +829,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Pipelines diff --git a/cmd/workspace/policy-families/policy-families.go b/cmd/workspace/policy-families/policy-families.go index 8954afa1dd..532317f7f2 100755 --- a/cmd/workspace/policy-families/policy-families.go +++ b/cmd/workspace/policy-families/policy-families.go @@ -10,10 +10,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "policy-families", - Short: `View available policy families.`, - Long: `View available policy families. A policy family contains a policy definition +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "policy-families", + Short: `View available policy families.`, + Long: `View available policy families. A policy family contains a policy definition providing best practices for configuring clusters for a particular use case. Databricks manages and provides policy families for several common cluster use @@ -22,34 +27,51 @@ var Cmd = &cobra.Command{ Policy families cannot be used directly to create clusters. Instead, you create cluster policies using a policy family. Cluster policies created using a policy family inherit the policy family's policy definition.`, - Annotations: map[string]string{ - "package": "compute", - }, + GroupID: "compute", + Annotations: map[string]string{ + "package": "compute", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start get command -var getReq compute.GetPolicyFamilyRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *compute.GetPolicyFamilyRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} -var getCmd = &cobra.Command{ - Use: "get POLICY_FAMILY_ID", - Short: `Get policy family information.`, - Long: `Get policy family information. + var getReq compute.GetPolicyFamilyRequest + + // TODO: short flags + + cmd.Use = "get POLICY_FAMILY_ID" + cmd.Short = `Get policy family information.` + cmd.Long = `Get policy family information. - Retrieve the information for an policy family based on its identifier.`, + Retrieve the information for an policy family based on its identifier.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -60,43 +82,65 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq compute.ListPolicyFamiliesRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *compute.ListPolicyFamiliesRequest, +) - listCmd.Flags().Int64Var(&listReq.MaxResults, "max-results", listReq.MaxResults, `The max number of policy families to return.`) - listCmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `A token that can be used to get the next page of results.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq compute.ListPolicyFamiliesRequest + var listJson flags.JsonFlag -var listCmd = &cobra.Command{ - Use: "list", - Short: `List policy families.`, - Long: `List policy families. + // TODO: short flags + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().Int64Var(&listReq.MaxResults, "max-results", listReq.MaxResults, `The max number of policy families to return.`) + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `A token that can be used to get the next page of results.`) + + cmd.Use = "list" + cmd.Short = `List policy families.` + cmd.Long = `List policy families. - Retrieve a list of policy families. This API is paginated.`, + Retrieve a list of policy families. This API is paginated.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -113,10 +157,24 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // end service PolicyFamilies diff --git a/cmd/workspace/providers/providers.go b/cmd/workspace/providers/providers.go index 58ed33954a..e5a41e128f 100755 --- a/cmd/workspace/providers/providers.go +++ b/cmd/workspace/providers/providers.go @@ -12,47 +12,69 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "providers", - Short: `Databricks Providers REST API.`, - Long: `Databricks Providers REST API`, - Annotations: map[string]string{ - "package": "sharing", - }, +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "providers", + Short: `Databricks Providers REST API.`, + Long: `Databricks Providers REST API`, + GroupID: "sharing", + Annotations: map[string]string{ + "package": "sharing", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq sharing.CreateProvider -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *sharing.CreateProvider, +) - createCmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `Description about the provider.`) - createCmd.Flags().StringVar(&createReq.RecipientProfileStr, "recipient-profile-str", createReq.RecipientProfileStr, `This field is required when the __authentication_type__ is **TOKEN** or not provided.`) +func newCreate() *cobra.Command { + cmd := &cobra.Command{} -} + var createReq sharing.CreateProvider + var createJson flags.JsonFlag -var createCmd = &cobra.Command{ - Use: "create NAME AUTHENTICATION_TYPE", - Short: `Create an auth provider.`, - Long: `Create an auth provider. + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `Description about the provider.`) + cmd.Flags().StringVar(&createReq.RecipientProfileStr, "recipient-profile-str", createReq.RecipientProfileStr, `This field is required when the __authentication_type__ is **TOKEN** or not provided.`) + + cmd.Use = "create NAME AUTHENTICATION_TYPE" + cmd.Short = `Create an auth provider.` + cmd.Long = `Create an auth provider. Creates a new authentication provider minimally based on a name and - authentication type. The caller must be an admin on the metastore.`, + authentication type. The caller must be an admin on the metastore.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -74,52 +96,61 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq sharing.DeleteProviderRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *sharing.DeleteProviderRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete NAME", - Short: `Delete a provider.`, - Long: `Delete a provider. + var deleteReq sharing.DeleteProviderRequest + + // TODO: short flags + + cmd.Use = "delete NAME" + cmd.Short = `Delete a provider.` + cmd.Long = `Delete a provider. Deletes an authentication provider, if the caller is a metastore admin or is - the owner of the provider.`, + the owner of the provider.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No NAME argument specified. Loading names for Providers drop-down." - names, err := w.Providers.ProviderInfoNameToMetastoreIdMap(ctx, sharing.ListProvidersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Providers drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Name of the provider") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have name of the provider") - } deleteReq.Name = args[0] err = w.Providers.Delete(ctx, deleteReq) @@ -127,53 +158,62 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq sharing.GetProviderRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *sharing.GetProviderRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq sharing.GetProviderRequest + + // TODO: short flags -var getCmd = &cobra.Command{ - Use: "get NAME", - Short: `Get a provider.`, - Long: `Get a provider. + cmd.Use = "get NAME" + cmd.Short = `Get a provider.` + cmd.Long = `Get a provider. Gets a specific authentication provider. The caller must supply the name of the provider, and must either be a metastore admin or the owner of the - provider.`, + provider.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No NAME argument specified. Loading names for Providers drop-down." - names, err := w.Providers.ProviderInfoNameToMetastoreIdMap(ctx, sharing.ListProvidersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Providers drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Name of the provider") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have name of the provider") - } getReq.Name = args[0] response, err := w.Providers.Get(ctx, getReq) @@ -181,45 +221,67 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq sharing.ListProvidersRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *sharing.ListProvidersRequest, +) - listCmd.Flags().StringVar(&listReq.DataProviderGlobalMetastoreId, "data-provider-global-metastore-id", listReq.DataProviderGlobalMetastoreId, `If not provided, all providers will be returned.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq sharing.ListProvidersRequest + var listJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&listReq.DataProviderGlobalMetastoreId, "data-provider-global-metastore-id", listReq.DataProviderGlobalMetastoreId, `If not provided, all providers will be returned.`) -var listCmd = &cobra.Command{ - Use: "list", - Short: `List providers.`, - Long: `List providers. + cmd.Use = "list" + cmd.Short = `List providers.` + cmd.Long = `List providers. Gets an array of available authentication providers. The caller must either be a metastore admin or the owner of the providers. Providers not owned by the caller are not included in the response. There is no guarantee of a specific - ordering of the elements in the array.`, + ordering of the elements in the array.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -236,53 +298,62 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start list-shares command -var listSharesReq sharing.ListSharesRequest -func init() { - Cmd.AddCommand(listSharesCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listSharesOverrides []func( + *cobra.Command, + *sharing.ListSharesRequest, +) -} +func newListShares() *cobra.Command { + cmd := &cobra.Command{} + + var listSharesReq sharing.ListSharesRequest + + // TODO: short flags -var listSharesCmd = &cobra.Command{ - Use: "list-shares NAME", - Short: `List shares by Provider.`, - Long: `List shares by Provider. + cmd.Use = "list-shares NAME" + cmd.Short = `List shares by Provider.` + cmd.Long = `List shares by Provider. Gets an array of a specified provider's shares within the metastore where: - * the caller is a metastore admin, or * the caller is the owner.`, + * the caller is a metastore admin, or * the caller is the owner.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No NAME argument specified. Loading names for Providers drop-down." - names, err := w.Providers.ProviderInfoNameToMetastoreIdMap(ctx, sharing.ListProvidersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Providers drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Name of the provider in which to list shares") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have name of the provider in which to list shares") - } listSharesReq.Name = args[0] response, err := w.Providers.ListSharesAll(ctx, listSharesReq) @@ -290,41 +361,70 @@ var listSharesCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listSharesOverrides { + fn(cmd, &listSharesReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newListShares()) + }) } // start update command -var updateReq sharing.UpdateProvider -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) - // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *sharing.UpdateProvider, +) - updateCmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `Description about the provider.`) - updateCmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `The name of the Provider.`) - updateCmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `Username of Provider owner.`) - updateCmd.Flags().StringVar(&updateReq.RecipientProfileStr, "recipient-profile-str", updateReq.RecipientProfileStr, `This field is required when the __authentication_type__ is **TOKEN** or not provided.`) +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} -} + var updateReq sharing.UpdateProvider + var updateJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var updateCmd = &cobra.Command{ - Use: "update NAME", - Short: `Update a provider.`, - Long: `Update a provider. + cmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `Description about the provider.`) + cmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `The name of the Provider.`) + cmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `Username of Provider owner.`) + cmd.Flags().StringVar(&updateReq.RecipientProfileStr, "recipient-profile-str", updateReq.RecipientProfileStr, `This field is required when the __authentication_type__ is **TOKEN** or not provided.`) + + cmd.Use = "update NAME" + cmd.Short = `Update a provider.` + cmd.Long = `Update a provider. Updates the information for an authentication provider, if the caller is a metastore admin or is the owner of the provider. If the update changes the provider name, the caller must be both a metastore admin and the owner of the - provider.`, + provider.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -334,23 +434,6 @@ var updateCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No NAME argument specified. Loading names for Providers drop-down." - names, err := w.Providers.ProviderInfoNameToMetastoreIdMap(ctx, sharing.ListProvidersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Providers drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The name of the Provider") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the name of the provider") - } updateReq.Name = args[0] } @@ -359,10 +442,24 @@ var updateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Providers diff --git a/cmd/workspace/queries/overrides.go b/cmd/workspace/queries/overrides.go index 86f47388ec..a06dabdeba 100644 --- a/cmd/workspace/queries/overrides.go +++ b/cmd/workspace/queries/overrides.go @@ -1,11 +1,19 @@ package queries -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/databricks-sdk-go/service/sql" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command, listReq *sql.ListQueriesRequest) { // TODO: figure out colored/non-colored headers and colspan shifts listCmd.Annotations["template"] = cmdio.Heredoc(` {{header "ID"}} {{header "Name"}} {{header "Author"}} {{range .}}{{.Id|green}} {{.Name|cyan}} {{.User.Email|cyan}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/workspace/queries/queries.go b/cmd/workspace/queries/queries.go index 8cf3527830..b1c94ddcde 100755 --- a/cmd/workspace/queries/queries.go +++ b/cmd/workspace/queries/queries.go @@ -12,33 +12,53 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "queries", - Short: `These endpoints are used for CRUD operations on query definitions.`, - Long: `These endpoints are used for CRUD operations on query definitions. Query +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "queries", + Short: `These endpoints are used for CRUD operations on query definitions.`, + Long: `These endpoints are used for CRUD operations on query definitions. Query definitions include the target SQL warehouse, query text, name, description, tags, parameters, and visualizations. Queries can be scheduled using the sql_task type of the Jobs API, e.g. :method:jobs/create.`, - Annotations: map[string]string{ - "package": "sql", - }, + GroupID: "sql", + Annotations: map[string]string{ + "package": "sql", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq sql.QueryPostContent -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *sql.QueryPostContent, +) -} +func newCreate() *cobra.Command { + cmd := &cobra.Command{} -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a new query definition.`, - Long: `Create a new query definition. + var createReq sql.QueryPostContent + var createJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "create" + cmd.Short = `Create a new query definition.` + cmd.Long = `Create a new query definition. Creates a new query definition. Queries created with this endpoint belong to the authenticated user making the request. @@ -48,18 +68,20 @@ var createCmd = &cobra.Command{ available SQL warehouses. Or you can copy the data_source_id from an existing query. - **Note**: You cannot add a visualization until you create the query.`, + **Note**: You cannot add a visualization until you create the query.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -77,53 +99,62 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq sql.DeleteQueryRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *sql.DeleteQueryRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq sql.DeleteQueryRequest -var deleteCmd = &cobra.Command{ - Use: "delete QUERY_ID", - Short: `Delete a query.`, - Long: `Delete a query. + // TODO: short flags + + cmd.Use = "delete QUERY_ID" + cmd.Short = `Delete a query.` + cmd.Long = `Delete a query. Moves a query to the trash. Trashed queries immediately disappear from searches and list views, and they cannot be used for alerts. The trash is - deleted after 30 days.`, + deleted after 30 days.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No QUERY_ID argument specified. Loading names for Queries drop-down." - names, err := w.Queries.QueryNameToIdMap(ctx, sql.ListQueriesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Queries drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have ") - } deleteReq.QueryId = args[0] err = w.Queries.Delete(ctx, deleteReq) @@ -131,52 +162,61 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq sql.GetQueryRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *sql.GetQueryRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq sql.GetQueryRequest -var getCmd = &cobra.Command{ - Use: "get QUERY_ID", - Short: `Get a query definition.`, - Long: `Get a query definition. + // TODO: short flags + + cmd.Use = "get QUERY_ID" + cmd.Short = `Get a query definition.` + cmd.Long = `Get a query definition. Retrieve a query object definition along with contextual permissions - information about the currently authenticated user.`, + information about the currently authenticated user.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No QUERY_ID argument specified. Loading names for Queries drop-down." - names, err := w.Queries.QueryNameToIdMap(ctx, sql.ListQueriesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Queries drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have ") - } getReq.QueryId = args[0] response, err := w.Queries.Get(ctx, getReq) @@ -184,46 +224,68 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq sql.ListQueriesRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *sql.ListQueriesRequest, +) - listCmd.Flags().StringVar(&listReq.Order, "order", listReq.Order, `Name of query attribute to order by.`) - listCmd.Flags().IntVar(&listReq.Page, "page", listReq.Page, `Page number to retrieve.`) - listCmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, `Number of queries to return per page.`) - listCmd.Flags().StringVar(&listReq.Q, "q", listReq.Q, `Full text search term.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq sql.ListQueriesRequest + var listJson flags.JsonFlag -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get a list of queries.`, - Long: `Get a list of queries. + // TODO: short flags + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&listReq.Order, "order", listReq.Order, `Name of query attribute to order by.`) + cmd.Flags().IntVar(&listReq.Page, "page", listReq.Page, `Page number to retrieve.`) + cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, `Number of queries to return per page.`) + cmd.Flags().StringVar(&listReq.Q, "q", listReq.Q, `Full text search term.`) + + cmd.Use = "list" + cmd.Short = `Get a list of queries.` + cmd.Long = `Get a list of queries. Gets a list of queries. Optionally, this list can be filtered by a search - term.`, + term.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -240,52 +302,61 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start restore command -var restoreReq sql.RestoreQueryRequest -func init() { - Cmd.AddCommand(restoreCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var restoreOverrides []func( + *cobra.Command, + *sql.RestoreQueryRequest, +) -} +func newRestore() *cobra.Command { + cmd := &cobra.Command{} + + var restoreReq sql.RestoreQueryRequest -var restoreCmd = &cobra.Command{ - Use: "restore QUERY_ID", - Short: `Restore a query.`, - Long: `Restore a query. + // TODO: short flags + + cmd.Use = "restore QUERY_ID" + cmd.Short = `Restore a query.` + cmd.Long = `Restore a query. Restore a query that has been moved to the trash. A restored query appears in - list views and searches. You can use restored queries for alerts.`, + list views and searches. You can use restored queries for alerts.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No QUERY_ID argument specified. Loading names for Queries drop-down." - names, err := w.Queries.QueryNameToIdMap(ctx, sql.ListQueriesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Queries drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have ") - } restoreReq.QueryId = args[0] err = w.Queries.Restore(ctx, restoreReq) @@ -293,41 +364,67 @@ var restoreCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range restoreOverrides { + fn(cmd, &restoreReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newRestore()) + }) } // start update command -var updateReq sql.QueryEditContent -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *sql.QueryEditContent, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq sql.QueryEditContent + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) - updateCmd.Flags().StringVar(&updateReq.DataSourceId, "data-source-id", updateReq.DataSourceId, `Data source ID.`) - updateCmd.Flags().StringVar(&updateReq.Description, "description", updateReq.Description, `General description that conveys additional information about this query such as usage notes.`) - updateCmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `The title of this query that appears in list views, widget headings, and on the query page.`) + cmd.Flags().StringVar(&updateReq.DataSourceId, "data-source-id", updateReq.DataSourceId, `Data source ID.`) + cmd.Flags().StringVar(&updateReq.Description, "description", updateReq.Description, `General description that conveys additional information about this query such as usage notes.`) + cmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `The title of this query that appears in list views, widget headings, and on the query page.`) // TODO: any: options - updateCmd.Flags().StringVar(&updateReq.Query, "query", updateReq.Query, `The text of the query to be run.`) + cmd.Flags().StringVar(&updateReq.Query, "query", updateReq.Query, `The text of the query to be run.`) -} - -var updateCmd = &cobra.Command{ - Use: "update QUERY_ID", - Short: `Change a query definition.`, - Long: `Change a query definition. + cmd.Use = "update QUERY_ID" + cmd.Short = `Change a query definition.` + cmd.Long = `Change a query definition. Modify this query definition. - **Note**: You cannot undo this operation.`, + **Note**: You cannot undo this operation.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -337,23 +434,6 @@ var updateCmd = &cobra.Command{ return err } } - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No QUERY_ID argument specified. Loading names for Queries drop-down." - names, err := w.Queries.QueryNameToIdMap(ctx, sql.ListQueriesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Queries drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have ") - } updateReq.QueryId = args[0] response, err := w.Queries.Update(ctx, updateReq) @@ -361,10 +441,24 @@ var updateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Queries diff --git a/cmd/workspace/query-history/overrides.go b/cmd/workspace/query-history/overrides.go index 7e70206972..e0d79423cc 100644 --- a/cmd/workspace/query-history/overrides.go +++ b/cmd/workspace/query-history/overrides.go @@ -1,10 +1,18 @@ package query_history -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/databricks-sdk-go/service/sql" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command, listReq *sql.ListQueryHistoryRequest) { // TODO: figure out the right format listCmd.Annotations["template"] = cmdio.Heredoc(` {{range .}}{{.UserName}} {{cyan "%s" .Status}} {{.QueryText}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/workspace/query-history/query-history.go b/cmd/workspace/query-history/query-history.go index 5b1e86d0d4..1593d6766a 100755 --- a/cmd/workspace/query-history/query-history.go +++ b/cmd/workspace/query-history/query-history.go @@ -10,50 +10,72 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "query-history", - Short: `Access the history of queries through SQL warehouses.`, - Long: `Access the history of queries through SQL warehouses.`, - Annotations: map[string]string{ - "package": "sql", - }, +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "query-history", + Short: `Access the history of queries through SQL warehouses.`, + Long: `Access the history of queries through SQL warehouses.`, + GroupID: "sql", + Annotations: map[string]string{ + "package": "sql", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start list command -var listReq sql.ListQueryHistoryRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *sql.ListQueryHistoryRequest, +) + +func newList() *cobra.Command { + cmd := &cobra.Command{} + + var listReq sql.ListQueryHistoryRequest + var listJson flags.JsonFlag + // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: filter_by - listCmd.Flags().BoolVar(&listReq.IncludeMetrics, "include-metrics", listReq.IncludeMetrics, `Whether to include metrics about query.`) - listCmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Limit the number of results returned in one page.`) - listCmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `A token that can be used to get the next page of results.`) - -} + cmd.Flags().BoolVar(&listReq.IncludeMetrics, "include-metrics", listReq.IncludeMetrics, `Whether to include metrics about query.`) + cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Limit the number of results returned in one page.`) + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `A token that can be used to get the next page of results.`) -var listCmd = &cobra.Command{ - Use: "list", - Short: `List Queries.`, - Long: `List Queries. + cmd.Use = "list" + cmd.Short = `List Queries.` + cmd.Long = `List Queries. List the history of queries through SQL warehouses. - You can filter by user ID, warehouse ID, status, and time range.`, + You can filter by user ID, warehouse ID, status, and time range.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -70,10 +92,24 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // end service QueryHistory diff --git a/cmd/workspace/recipient-activation/recipient-activation.go b/cmd/workspace/recipient-activation/recipient-activation.go index 33bc54ef2b..fa0e6a83f9 100755 --- a/cmd/workspace/recipient-activation/recipient-activation.go +++ b/cmd/workspace/recipient-activation/recipient-activation.go @@ -9,38 +9,60 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "recipient-activation", - Short: `Databricks Recipient Activation REST API.`, - Long: `Databricks Recipient Activation REST API`, - Annotations: map[string]string{ - "package": "sharing", - }, +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "recipient-activation", + Short: `Databricks Recipient Activation REST API.`, + Long: `Databricks Recipient Activation REST API`, + GroupID: "sharing", + Annotations: map[string]string{ + "package": "sharing", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start get-activation-url-info command -var getActivationUrlInfoReq sharing.GetActivationUrlInfoRequest -func init() { - Cmd.AddCommand(getActivationUrlInfoCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getActivationUrlInfoOverrides []func( + *cobra.Command, + *sharing.GetActivationUrlInfoRequest, +) -} +func newGetActivationUrlInfo() *cobra.Command { + cmd := &cobra.Command{} -var getActivationUrlInfoCmd = &cobra.Command{ - Use: "get-activation-url-info ACTIVATION_URL", - Short: `Get a share activation URL.`, - Long: `Get a share activation URL. + var getActivationUrlInfoReq sharing.GetActivationUrlInfoRequest + + // TODO: short flags + + cmd.Use = "get-activation-url-info ACTIVATION_URL" + cmd.Short = `Get a share activation URL.` + cmd.Long = `Get a share activation URL. - Gets an activation URL for a share.`, + Gets an activation URL for a share.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -51,36 +73,58 @@ var getActivationUrlInfoCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getActivationUrlInfoOverrides { + fn(cmd, &getActivationUrlInfoReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetActivationUrlInfo()) + }) } // start retrieve-token command -var retrieveTokenReq sharing.RetrieveTokenRequest -func init() { - Cmd.AddCommand(retrieveTokenCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var retrieveTokenOverrides []func( + *cobra.Command, + *sharing.RetrieveTokenRequest, +) -} +func newRetrieveToken() *cobra.Command { + cmd := &cobra.Command{} -var retrieveTokenCmd = &cobra.Command{ - Use: "retrieve-token ACTIVATION_URL", - Short: `Get an access token.`, - Long: `Get an access token. + var retrieveTokenReq sharing.RetrieveTokenRequest + + // TODO: short flags + + cmd.Use = "retrieve-token ACTIVATION_URL" + cmd.Short = `Get an access token.` + cmd.Long = `Get an access token. Retrieve access token with an activation url. This is a public API without any - authentication.`, + authentication.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -91,10 +135,24 @@ var retrieveTokenCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range retrieveTokenOverrides { + fn(cmd, &retrieveTokenReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newRetrieveToken()) + }) } // end service RecipientActivation diff --git a/cmd/workspace/recipients/recipients.go b/cmd/workspace/recipients/recipients.go index bb8f9b17f7..10430cdf23 100755 --- a/cmd/workspace/recipients/recipients.go +++ b/cmd/workspace/recipients/recipients.go @@ -12,52 +12,74 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "recipients", - Short: `Databricks Recipients REST API.`, - Long: `Databricks Recipients REST API`, - Annotations: map[string]string{ - "package": "sharing", - }, +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "recipients", + Short: `Databricks Recipients REST API.`, + Long: `Databricks Recipients REST API`, + GroupID: "sharing", + Annotations: map[string]string{ + "package": "sharing", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq sharing.CreateRecipient -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *sharing.CreateRecipient, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq sharing.CreateRecipient + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createCmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `Description about the recipient.`) + cmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `Description about the recipient.`) // TODO: any: data_recipient_global_metastore_id // TODO: complex arg: ip_access_list - createCmd.Flags().StringVar(&createReq.Owner, "owner", createReq.Owner, `Username of the recipient owner.`) + cmd.Flags().StringVar(&createReq.Owner, "owner", createReq.Owner, `Username of the recipient owner.`) // TODO: complex arg: properties_kvpairs - createCmd.Flags().StringVar(&createReq.SharingCode, "sharing-code", createReq.SharingCode, `The one-time sharing code provided by the data recipient.`) + cmd.Flags().StringVar(&createReq.SharingCode, "sharing-code", createReq.SharingCode, `The one-time sharing code provided by the data recipient.`) -} - -var createCmd = &cobra.Command{ - Use: "create NAME AUTHENTICATION_TYPE", - Short: `Create a share recipient.`, - Long: `Create a share recipient. + cmd.Use = "create NAME AUTHENTICATION_TYPE" + cmd.Short = `Create a share recipient.` + cmd.Long = `Create a share recipient. Creates a new recipient with the delta sharing authentication type in the metastore. The caller must be a metastore admin or has the - **CREATE_RECIPIENT** privilege on the metastore.`, + **CREATE_RECIPIENT** privilege on the metastore.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -79,52 +101,61 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq sharing.DeleteRecipientRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *sharing.DeleteRecipientRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq sharing.DeleteRecipientRequest + + // TODO: short flags -var deleteCmd = &cobra.Command{ - Use: "delete NAME", - Short: `Delete a share recipient.`, - Long: `Delete a share recipient. + cmd.Use = "delete NAME" + cmd.Short = `Delete a share recipient.` + cmd.Long = `Delete a share recipient. Deletes the specified recipient from the metastore. The caller must be the - owner of the recipient.`, + owner of the recipient.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No NAME argument specified. Loading names for Recipients drop-down." - names, err := w.Recipients.RecipientInfoNameToMetastoreIdMap(ctx, sharing.ListRecipientsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Recipients drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Name of the recipient") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have name of the recipient") - } deleteReq.Name = args[0] err = w.Recipients.Delete(ctx, deleteReq) @@ -132,53 +163,62 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq sharing.GetRecipientRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *sharing.GetRecipientRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq sharing.GetRecipientRequest -var getCmd = &cobra.Command{ - Use: "get NAME", - Short: `Get a share recipient.`, - Long: `Get a share recipient. + // TODO: short flags + + cmd.Use = "get NAME" + cmd.Short = `Get a share recipient.` + cmd.Long = `Get a share recipient. Gets a share recipient from the metastore if: - * the caller is the owner of the share recipient, or: * is a metastore admin`, + * the caller is the owner of the share recipient, or: * is a metastore admin` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No NAME argument specified. Loading names for Recipients drop-down." - names, err := w.Recipients.RecipientInfoNameToMetastoreIdMap(ctx, sharing.ListRecipientsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Recipients drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Name of the recipient") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have name of the recipient") - } getReq.Name = args[0] response, err := w.Recipients.Get(ctx, getReq) @@ -186,45 +226,67 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq sharing.ListRecipientsRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *sharing.ListRecipientsRequest, +) - listCmd.Flags().StringVar(&listReq.DataRecipientGlobalMetastoreId, "data-recipient-global-metastore-id", listReq.DataRecipientGlobalMetastoreId, `If not provided, all recipients will be returned.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq sharing.ListRecipientsRequest + var listJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&listReq.DataRecipientGlobalMetastoreId, "data-recipient-global-metastore-id", listReq.DataRecipientGlobalMetastoreId, `If not provided, all recipients will be returned.`) -var listCmd = &cobra.Command{ - Use: "list", - Short: `List share recipients.`, - Long: `List share recipients. + cmd.Use = "list" + cmd.Short = `List share recipients.` + cmd.Long = `List share recipients. Gets an array of all share recipients within the current metastore where: * the caller is a metastore admin, or * the caller is the owner. There is no - guarantee of a specific ordering of the elements in the array.`, + guarantee of a specific ordering of the elements in the array.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -241,36 +303,58 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start rotate-token command -var rotateTokenReq sharing.RotateRecipientToken -func init() { - Cmd.AddCommand(rotateTokenCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var rotateTokenOverrides []func( + *cobra.Command, + *sharing.RotateRecipientToken, +) -} +func newRotateToken() *cobra.Command { + cmd := &cobra.Command{} + + var rotateTokenReq sharing.RotateRecipientToken -var rotateTokenCmd = &cobra.Command{ - Use: "rotate-token EXISTING_TOKEN_EXPIRE_IN_SECONDS NAME", - Short: `Rotate a token.`, - Long: `Rotate a token. + // TODO: short flags + + cmd.Use = "rotate-token EXISTING_TOKEN_EXPIRE_IN_SECONDS NAME" + cmd.Short = `Rotate a token.` + cmd.Long = `Rotate a token. Refreshes the specified recipient's delta sharing authentication token with - the provided token info. The caller must be the owner of the recipient.`, + the provided token info. The caller must be the owner of the recipient.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -285,52 +369,61 @@ var rotateTokenCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range rotateTokenOverrides { + fn(cmd, &rotateTokenReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newRotateToken()) + }) } // start share-permissions command -var sharePermissionsReq sharing.SharePermissionsRequest -func init() { - Cmd.AddCommand(sharePermissionsCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var sharePermissionsOverrides []func( + *cobra.Command, + *sharing.SharePermissionsRequest, +) -} +func newSharePermissions() *cobra.Command { + cmd := &cobra.Command{} + + var sharePermissionsReq sharing.SharePermissionsRequest + + // TODO: short flags -var sharePermissionsCmd = &cobra.Command{ - Use: "share-permissions NAME", - Short: `Get recipient share permissions.`, - Long: `Get recipient share permissions. + cmd.Use = "share-permissions NAME" + cmd.Short = `Get recipient share permissions.` + cmd.Long = `Get recipient share permissions. Gets the share permissions for the specified Recipient. The caller must be a - metastore admin or the owner of the Recipient.`, + metastore admin or the owner of the Recipient.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No NAME argument specified. Loading names for Recipients drop-down." - names, err := w.Recipients.RecipientInfoNameToMetastoreIdMap(ctx, sharing.ListRecipientsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Recipients drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The name of the Recipient") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the name of the recipient") - } sharePermissionsReq.Name = args[0] response, err := w.Recipients.SharePermissions(ctx, sharePermissionsReq) @@ -338,41 +431,70 @@ var sharePermissionsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range sharePermissionsOverrides { + fn(cmd, &sharePermissionsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newSharePermissions()) + }) } // start update command -var updateReq sharing.UpdateRecipient -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *sharing.UpdateRecipient, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq sharing.UpdateRecipient + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) - updateCmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `Description about the recipient.`) + cmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `Description about the recipient.`) // TODO: complex arg: ip_access_list - updateCmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `Name of Recipient.`) - updateCmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `Username of the recipient owner.`) + cmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `Name of Recipient.`) + cmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `Username of the recipient owner.`) // TODO: complex arg: properties_kvpairs -} - -var updateCmd = &cobra.Command{ - Use: "update NAME", - Short: `Update a share recipient.`, - Long: `Update a share recipient. + cmd.Use = "update NAME" + cmd.Short = `Update a share recipient.` + cmd.Long = `Update a share recipient. Updates an existing recipient in the metastore. The caller must be a metastore admin or the owner of the recipient. If the recipient name will be updated, - the user must be both a metastore admin and the owner of the recipient.`, + the user must be both a metastore admin and the owner of the recipient.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -382,23 +504,6 @@ var updateCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No NAME argument specified. Loading names for Recipients drop-down." - names, err := w.Recipients.RecipientInfoNameToMetastoreIdMap(ctx, sharing.ListRecipientsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Recipients drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Name of Recipient") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have name of recipient") - } updateReq.Name = args[0] } @@ -407,10 +512,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Recipients diff --git a/cmd/workspace/repos/overrides.go b/cmd/workspace/repos/overrides.go index 127a794a51..f6f26f81d3 100644 --- a/cmd/workspace/repos/overrides.go +++ b/cmd/workspace/repos/overrides.go @@ -7,16 +7,19 @@ import ( "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/cli/libs/flags" "github.com/databricks/databricks-sdk-go" "github.com/databricks/databricks-sdk-go/service/workspace" "github.com/spf13/cobra" ) -func init() { +func listOverride(listCmd *cobra.Command, listReq *workspace.ListReposRequest) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{range .}}{{green "%d" .Id}} {{.Path}} {{.Branch|blue}} {{.Url|cyan}} {{end}}`) +} +func createOverride(createCmd *cobra.Command, createReq *workspace.CreateRepo) { createCmd.Use = "create URL [PROVIDER]" createCmd.Args = func(cmd *cobra.Command, args []string) error { // If the provider argument is not specified, we try to detect it from the URL. @@ -26,11 +29,13 @@ func init() { } return check(cmd, args) } + + createJson := createCmd.Flag("json").Value.(*flags.JsonFlag) createCmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) if cmd.Flags().Changed("json") { - err = createJson.Unmarshal(&createReq) + err = createJson.Unmarshal(createReq) if err != nil { return err } @@ -46,13 +51,15 @@ func init() { } } } - response, err := w.Repos.Create(ctx, createReq) + response, err := w.Repos.Create(ctx, *createReq) if err != nil { return err } return cmdio.Render(ctx, response) } +} +func deleteOverride(deleteCmd *cobra.Command, deleteReq *workspace.DeleteRepoRequest) { deleteCmd.Use = "delete REPO_ID_OR_PATH" deleteCmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() @@ -62,13 +69,15 @@ func init() { if err != nil { return err } - err = w.Repos.Delete(ctx, deleteReq) + err = w.Repos.Delete(ctx, *deleteReq) if err != nil { return err } return nil } +} +func getOverride(getCmd *cobra.Command, getReq *workspace.GetRepoRequest) { getCmd.Use = "get REPO_ID_OR_PATH" getCmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() @@ -78,14 +87,18 @@ func init() { return err } - response, err := w.Repos.Get(ctx, getReq) + response, err := w.Repos.Get(ctx, *getReq) if err != nil { return err } return cmdio.Render(ctx, response) } +} +func updateOverride(updateCmd *cobra.Command, updateReq *workspace.UpdateRepo) { updateCmd.Use = "update REPO_ID_OR_PATH" + + updateJson := updateCmd.Flag("json").Value.(*flags.JsonFlag) updateCmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -101,7 +114,7 @@ func init() { } } - err = w.Repos.Update(ctx, updateReq) + err = w.Repos.Update(ctx, *updateReq) if err != nil { return err } @@ -147,3 +160,11 @@ func repoArgumentToRepoID(ctx context.Context, w *databricks.WorkspaceClient, ar } return oi.ObjectId, nil } + +func init() { + listOverrides = append(listOverrides, listOverride) + createOverrides = append(createOverrides, createOverride) + deleteOverrides = append(deleteOverrides, deleteOverride) + getOverrides = append(getOverrides, getOverride) + updateOverrides = append(updateOverrides, updateOverride) +} diff --git a/cmd/workspace/repos/repos.go b/cmd/workspace/repos/repos.go index fdd9556d49..087a62449e 100755 --- a/cmd/workspace/repos/repos.go +++ b/cmd/workspace/repos/repos.go @@ -12,10 +12,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "repos", - Short: `The Repos API allows users to manage their git repos.`, - Long: `The Repos API allows users to manage their git repos. Users can use the API to +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "repos", + Short: `The Repos API allows users to manage their git repos.`, + Long: `The Repos API allows users to manage their git repos. Users can use the API to access all repos that they have manage permissions on. Databricks Repos is a visual Git client in Databricks. It supports common Git @@ -25,44 +30,61 @@ var Cmd = &cobra.Command{ Within Repos you can develop code in notebooks or other files and follow data science and engineering code development best practices using Git for version control, collaboration, and CI/CD.`, - Annotations: map[string]string{ - "package": "workspace", - }, + GroupID: "workspace", + Annotations: map[string]string{ + "package": "workspace", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq workspace.CreateRepo -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *workspace.CreateRepo, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq workspace.CreateRepo + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createCmd.Flags().StringVar(&createReq.Path, "path", createReq.Path, `Desired path for the repo in the workspace.`) + cmd.Flags().StringVar(&createReq.Path, "path", createReq.Path, `Desired path for the repo in the workspace.`) // TODO: complex arg: sparse_checkout -} - -var createCmd = &cobra.Command{ - Use: "create URL PROVIDER", - Short: `Create a repo.`, - Long: `Create a repo. + cmd.Use = "create URL PROVIDER" + cmd.Short = `Create a repo.` + cmd.Long = `Create a repo. Creates a repo in the workspace and links it to the remote Git repo specified. Note that repos created programmatically must be linked to a remote Git repo, - unlike repos created in the browser.`, + unlike repos created in the browser.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -81,51 +103,60 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq workspace.DeleteRepoRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *workspace.DeleteRepoRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete REPO_ID", - Short: `Delete a repo.`, - Long: `Delete a repo. + var deleteReq workspace.DeleteRepoRequest + + // TODO: short flags + + cmd.Use = "delete REPO_ID" + cmd.Short = `Delete a repo.` + cmd.Long = `Delete a repo. - Deletes the specified repo.`, + Deletes the specified repo.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No REPO_ID argument specified. Loading names for Repos drop-down." - names, err := w.Repos.RepoInfoPathToIdMap(ctx, workspace.ListReposRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Repos drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The ID for the corresponding repo to access") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the id for the corresponding repo to access") - } _, err = fmt.Sscan(args[0], &deleteReq.RepoId) if err != nil { return fmt.Errorf("invalid REPO_ID: %s", args[0]) @@ -136,51 +167,60 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq workspace.GetRepoRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *workspace.GetRepoRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq workspace.GetRepoRequest + + // TODO: short flags -var getCmd = &cobra.Command{ - Use: "get REPO_ID", - Short: `Get a repo.`, - Long: `Get a repo. + cmd.Use = "get REPO_ID" + cmd.Short = `Get a repo.` + cmd.Long = `Get a repo. - Returns the repo with the given repo ID.`, + Returns the repo with the given repo ID.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No REPO_ID argument specified. Loading names for Repos drop-down." - names, err := w.Repos.RepoInfoPathToIdMap(ctx, workspace.ListReposRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Repos drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The ID for the corresponding repo to access") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the id for the corresponding repo to access") - } _, err = fmt.Sscan(args[0], &getReq.RepoId) if err != nil { return fmt.Errorf("invalid REPO_ID: %s", args[0]) @@ -191,44 +231,66 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq workspace.ListReposRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *workspace.ListReposRequest, +) - listCmd.Flags().StringVar(&listReq.NextPageToken, "next-page-token", listReq.NextPageToken, `Token used to get the next page of results.`) - listCmd.Flags().StringVar(&listReq.PathPrefix, "path-prefix", listReq.PathPrefix, `Filters repos that have paths starting with the given path prefix.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq workspace.ListReposRequest + var listJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&listReq.NextPageToken, "next-page-token", listReq.NextPageToken, `Token used to get the next page of results.`) + cmd.Flags().StringVar(&listReq.PathPrefix, "path-prefix", listReq.PathPrefix, `Filters repos that have paths starting with the given path prefix.`) -var listCmd = &cobra.Command{ - Use: "list", - Short: `Get repos.`, - Long: `Get repos. + cmd.Use = "list" + cmd.Short = `Get repos.` + cmd.Long = `Get repos. Returns repos that the calling user has Manage permissions on. Results are - paginated with each page containing twenty repos.`, + paginated with each page containing twenty repos.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -245,38 +307,64 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq workspace.UpdateRepo -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *workspace.UpdateRepo, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq workspace.UpdateRepo + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) - updateCmd.Flags().StringVar(&updateReq.Branch, "branch", updateReq.Branch, `Branch that the local version of the repo is checked out to.`) + cmd.Flags().StringVar(&updateReq.Branch, "branch", updateReq.Branch, `Branch that the local version of the repo is checked out to.`) // TODO: complex arg: sparse_checkout - updateCmd.Flags().StringVar(&updateReq.Tag, "tag", updateReq.Tag, `Tag that the local version of the repo is checked out to.`) + cmd.Flags().StringVar(&updateReq.Tag, "tag", updateReq.Tag, `Tag that the local version of the repo is checked out to.`) -} - -var updateCmd = &cobra.Command{ - Use: "update REPO_ID", - Short: `Update a repo.`, - Long: `Update a repo. + cmd.Use = "update REPO_ID" + cmd.Short = `Update a repo.` + cmd.Long = `Update a repo. Updates the repo to a different branch or tag, or updates the repo to the - latest commit on the same branch.`, + latest commit on the same branch.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -286,23 +374,6 @@ var updateCmd = &cobra.Command{ return err } } - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No REPO_ID argument specified. Loading names for Repos drop-down." - names, err := w.Repos.RepoInfoPathToIdMap(ctx, workspace.ListReposRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Repos drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The ID for the corresponding repo to access") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the id for the corresponding repo to access") - } _, err = fmt.Sscan(args[0], &updateReq.RepoId) if err != nil { return fmt.Errorf("invalid REPO_ID: %s", args[0]) @@ -313,10 +384,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Repos diff --git a/cmd/workspace/schemas/overrides.go b/cmd/workspace/schemas/overrides.go index 4ff8bf1248..180690b6e1 100644 --- a/cmd/workspace/schemas/overrides.go +++ b/cmd/workspace/schemas/overrides.go @@ -1,10 +1,18 @@ package schemas -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/databricks-sdk-go/service/catalog" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command, listReq *catalog.ListSchemasRequest) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{header "Full Name"}} {{header "Owner"}} {{header "Comment"}} {{range .}}{{.FullName|green}} {{.Owner|cyan}} {{.Comment}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/workspace/schemas/schemas.go b/cmd/workspace/schemas/schemas.go index 4a6eb33b96..e1ad7be4ca 100755 --- a/cmd/workspace/schemas/schemas.go +++ b/cmd/workspace/schemas/schemas.go @@ -3,8 +3,6 @@ package schemas import ( - "fmt" - "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/flags" @@ -12,53 +10,75 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "schemas", - Short: `A schema (also called a database) is the second layer of Unity Catalog’s three-level namespace.`, - Long: `A schema (also called a database) is the second layer of Unity Catalog’s +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "schemas", + Short: `A schema (also called a database) is the second layer of Unity Catalog’s three-level namespace.`, + Long: `A schema (also called a database) is the second layer of Unity Catalog’s three-level namespace. A schema organizes tables, views and functions. To access (or list) a table or view in a schema, users must have the USE_SCHEMA data permission on the schema and its parent catalog, and they must have the SELECT permission on the table or view.`, - Annotations: map[string]string{ - "package": "catalog", - }, + GroupID: "catalog", + Annotations: map[string]string{ + "package": "catalog", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq catalog.CreateSchema -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *catalog.CreateSchema, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq catalog.CreateSchema + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createCmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `User-provided free-form text description.`) + cmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `User-provided free-form text description.`) // TODO: map via StringToStringVar: properties - createCmd.Flags().StringVar(&createReq.StorageRoot, "storage-root", createReq.StorageRoot, `Storage root URL for managed tables within schema.`) + cmd.Flags().StringVar(&createReq.StorageRoot, "storage-root", createReq.StorageRoot, `Storage root URL for managed tables within schema.`) -} - -var createCmd = &cobra.Command{ - Use: "create NAME CATALOG_NAME", - Short: `Create a schema.`, - Long: `Create a schema. + cmd.Use = "create NAME CATALOG_NAME" + cmd.Short = `Create a schema.` + cmd.Long = `Create a schema. Creates a new schema for catalog in the Metatastore. The caller must be a metastore admin, or have the **CREATE_SCHEMA** privilege in the parent - catalog.`, + catalog.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -77,52 +97,61 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq catalog.DeleteSchemaRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *catalog.DeleteSchemaRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq catalog.DeleteSchemaRequest + + // TODO: short flags -var deleteCmd = &cobra.Command{ - Use: "delete FULL_NAME", - Short: `Delete a schema.`, - Long: `Delete a schema. + cmd.Use = "delete FULL_NAME" + cmd.Short = `Delete a schema.` + cmd.Long = `Delete a schema. Deletes the specified schema from the parent catalog. The caller must be the - owner of the schema or an owner of the parent catalog.`, + owner of the schema or an owner of the parent catalog.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No FULL_NAME argument specified. Loading names for Schemas drop-down." - names, err := w.Schemas.SchemaInfoNameToFullNameMap(ctx, catalog.ListSchemasRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Schemas drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Full name of the schema") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have full name of the schema") - } deleteReq.FullName = args[0] err = w.Schemas.Delete(ctx, deleteReq) @@ -130,53 +159,62 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq catalog.GetSchemaRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *catalog.GetSchemaRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq catalog.GetSchemaRequest -var getCmd = &cobra.Command{ - Use: "get FULL_NAME", - Short: `Get a schema.`, - Long: `Get a schema. + // TODO: short flags + + cmd.Use = "get FULL_NAME" + cmd.Short = `Get a schema.` + cmd.Long = `Get a schema. Gets the specified schema within the metastore. The caller must be a metastore admin, the owner of the schema, or a user that has the **USE_SCHEMA** - privilege on the schema.`, + privilege on the schema.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No FULL_NAME argument specified. Loading names for Schemas drop-down." - names, err := w.Schemas.SchemaInfoNameToFullNameMap(ctx, catalog.ListSchemasRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Schemas drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Full name of the schema") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have full name of the schema") - } getReq.FullName = args[0] response, err := w.Schemas.Get(ctx, getReq) @@ -184,39 +222,61 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq catalog.ListSchemasRequest -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *catalog.ListSchemasRequest, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} + + var listReq catalog.ListSchemasRequest + + // TODO: short flags -var listCmd = &cobra.Command{ - Use: "list CATALOG_NAME", - Short: `List schemas.`, - Long: `List schemas. + cmd.Use = "list CATALOG_NAME" + cmd.Short = `List schemas.` + cmd.Long = `List schemas. Gets an array of schemas for a catalog in the metastore. If the caller is the metastore admin or the owner of the parent catalog, all schemas for the catalog will be retrieved. Otherwise, only schemas owned by the caller (or for which the caller has the **USE_SCHEMA** privilege) will be retrieved. There is - no guarantee of a specific ordering of the elements in the array.`, + no guarantee of a specific ordering of the elements in the array.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -227,42 +287,68 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq catalog.UpdateSchema -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *catalog.UpdateSchema, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq catalog.UpdateSchema + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) - updateCmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `User-provided free-form text description.`) - updateCmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `Name of schema, relative to parent catalog.`) - updateCmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `Username of current owner of schema.`) + cmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `User-provided free-form text description.`) + cmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `Name of schema, relative to parent catalog.`) + cmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `Username of current owner of schema.`) // TODO: map via StringToStringVar: properties -} - -var updateCmd = &cobra.Command{ - Use: "update FULL_NAME", - Short: `Update a schema.`, - Long: `Update a schema. + cmd.Use = "update FULL_NAME" + cmd.Short = `Update a schema.` + cmd.Long = `Update a schema. Updates a schema for a catalog. The caller must be the owner of the schema or a metastore admin. If the caller is a metastore admin, only the __owner__ field can be changed in the update. If the __name__ field must be updated, the caller must be a metastore admin or have the **CREATE_SCHEMA** privilege on - the parent catalog.`, + the parent catalog.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -272,23 +358,6 @@ var updateCmd = &cobra.Command{ return err } } - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No FULL_NAME argument specified. Loading names for Schemas drop-down." - names, err := w.Schemas.SchemaInfoNameToFullNameMap(ctx, catalog.ListSchemasRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Schemas drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Full name of the schema") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have full name of the schema") - } updateReq.FullName = args[0] response, err := w.Schemas.Update(ctx, updateReq) @@ -296,10 +365,24 @@ var updateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Schemas diff --git a/cmd/workspace/secrets/overrides.go b/cmd/workspace/secrets/overrides.go index 5443aca285..40c7bababe 100644 --- a/cmd/workspace/secrets/overrides.go +++ b/cmd/workspace/secrets/overrides.go @@ -1,121 +1,22 @@ package secrets import ( - "encoding/base64" - "fmt" - "io" - "os" - - "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" - "github.com/databricks/cli/libs/flags" - "github.com/databricks/databricks-sdk-go/service/workspace" "github.com/spf13/cobra" ) -func init() { +func cmdOverride(cmd *cobra.Command) { + cmd.AddCommand(newPutSecret()) +} + +func listScopesOverride(listScopesCmd *cobra.Command) { listScopesCmd.Annotations["template"] = cmdio.Heredoc(` {{header "Scope"}} {{header "Backend Type"}} {{range .}}{{.Name|green}} {{.BackendType}} {{end}}`) - - Cmd.AddCommand(putSecretCmd) - // TODO: short flags - putSecretCmd.Flags().Var(&putSecretJson, "json", `either inline JSON string or @path/to/file.json with request body`) - - putSecretCmd.Flags().StringVar(&putSecretReq.BytesValue, "bytes-value", putSecretReq.BytesValue, `If specified, value will be stored as bytes.`) - putSecretCmd.Flags().StringVar(&putSecretReq.StringValue, "string-value", putSecretReq.StringValue, `If specified, note that the value will be stored in UTF-8 (MB4) form.`) } -var putSecretReq workspace.PutSecret -var putSecretJson flags.JsonFlag - -var putSecretCmd = &cobra.Command{ - Use: "put-secret SCOPE KEY", - Short: `Add a secret.`, - Long: `Add a secret. - - Inserts a secret under the provided scope with the given name. If a secret - already exists with the same name, this command overwrites the existing - secret's value. The server encrypts the secret using the secret scope's - encryption settings before storing it. - - You must have WRITE or MANAGE permission on the secret scope. The secret - key must consist of alphanumeric characters, dashes, underscores, and periods, - and cannot exceed 128 characters. The maximum allowed secret value size is 128 - KB. The maximum number of secrets in a given scope is 1000. - - The arguments "string-value" or "bytes-value" specify the type of the secret, - which will determine the value returned when the secret value is requested. - - You can specify the secret value in one of three ways: - * Specify the value as a string using the --string-value flag. - * Input the secret when prompted interactively (single-line secrets). - * Pass the secret via standard input (multi-line secrets). - `, - - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { - check := cobra.ExactArgs(2) - if cmd.Flags().Changed("json") { - check = cobra.ExactArgs(0) - } - return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { - ctx := cmd.Context() - w := root.WorkspaceClient(ctx) - - bytesValueChanged := cmd.Flags().Changed("bytes-value") - stringValueChanged := cmd.Flags().Changed("string-value") - if bytesValueChanged && stringValueChanged { - return fmt.Errorf("cannot specify both --bytes-value and --string-value") - } - - if cmd.Flags().Changed("json") { - err = putSecretJson.Unmarshal(&putSecretReq) - if err != nil { - return err - } - } else { - putSecretReq.Scope = args[0] - putSecretReq.Key = args[1] - - switch { - case bytesValueChanged: - // Bytes value set; encode as base64. - putSecretReq.BytesValue = base64.StdEncoding.EncodeToString([]byte(putSecretReq.BytesValue)) - case stringValueChanged: - // String value set; nothing to do. - default: - // Neither is specified; read secret value from stdin. - bytes, err := promptSecret(cmd) - if err != nil { - return err - } - putSecretReq.BytesValue = base64.StdEncoding.EncodeToString(bytes) - } - } - - err = w.Secrets.PutSecret(ctx, putSecretReq) - if err != nil { - return err - } - return nil - }, -} - -func promptSecret(cmd *cobra.Command) ([]byte, error) { - // If stdin is a TTY, prompt for the secret. - if !cmdio.IsInTTY(cmd.Context()) { - return io.ReadAll(os.Stdin) - } - - value, err := cmdio.Secret(cmd.Context(), "Please enter your secret value") - if err != nil { - return nil, err - } - - return []byte(value), nil +func init() { + cmdOverrides = append(cmdOverrides, cmdOverride) + listScopesOverrides = append(listScopesOverrides, listScopesOverride) } diff --git a/cmd/workspace/secrets/put_secret.go b/cmd/workspace/secrets/put_secret.go new file mode 100644 index 0000000000..2fbf49c5c0 --- /dev/null +++ b/cmd/workspace/secrets/put_secret.go @@ -0,0 +1,122 @@ +package secrets + +import ( + "encoding/base64" + "fmt" + "io" + "os" + + "github.com/databricks/cli/cmd/root" + "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/cli/libs/flags" + "github.com/databricks/databricks-sdk-go/service/workspace" + "github.com/spf13/cobra" +) + +func newPutSecret() *cobra.Command { + cmd := &cobra.Command{} + + var putSecretReq workspace.PutSecret + var putSecretJson flags.JsonFlag + + cmd.Flags().Var(&putSecretJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&putSecretReq.BytesValue, "bytes-value", putSecretReq.BytesValue, `If specified, value will be stored as bytes.`) + cmd.Flags().StringVar(&putSecretReq.StringValue, "string-value", putSecretReq.StringValue, `If specified, note that the value will be stored in UTF-8 (MB4) form.`) + + cmd.Use = "put-secret SCOPE KEY" + cmd.Short = `Add a secret.` + cmd.Long = `Add a secret. + + Inserts a secret under the provided scope with the given name. If a secret + already exists with the same name, this command overwrites the existing + secret's value. The server encrypts the secret using the secret scope's + encryption settings before storing it. + + You must have WRITE or MANAGE permission on the secret scope. The secret + key must consist of alphanumeric characters, dashes, underscores, and periods, + and cannot exceed 128 characters. The maximum allowed secret value size is 128 + KB. The maximum number of secrets in a given scope is 1000. + + The arguments "string-value" or "bytes-value" specify the type of the secret, + which will determine the value returned when the secret value is requested. + + You can specify the secret value in one of three ways: + * Specify the value as a string using the --string-value flag. + * Input the secret when prompted interactively (single-line secrets). + * Pass the secret via standard input (multi-line secrets). + ` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(2) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := root.WorkspaceClient(ctx) + + bytesValueChanged := cmd.Flags().Changed("bytes-value") + stringValueChanged := cmd.Flags().Changed("string-value") + if bytesValueChanged && stringValueChanged { + return fmt.Errorf("cannot specify both --bytes-value and --string-value") + } + + if cmd.Flags().Changed("json") { + err = putSecretJson.Unmarshal(&putSecretReq) + if err != nil { + return err + } + } else { + putSecretReq.Scope = args[0] + putSecretReq.Key = args[1] + + switch { + case bytesValueChanged: + // Bytes value set; encode as base64. + putSecretReq.BytesValue = base64.StdEncoding.EncodeToString([]byte(putSecretReq.BytesValue)) + case stringValueChanged: + // String value set; nothing to do. + default: + // Neither is specified; read secret value from stdin. + bytes, err := promptSecret(cmd) + if err != nil { + return err + } + putSecretReq.BytesValue = base64.StdEncoding.EncodeToString(bytes) + } + } + + err = w.Secrets.PutSecret(ctx, putSecretReq) + if err != nil { + return err + } + return nil + } + + // Disable completions since they are not applicable. + // Potential future follow up to auto complete secret scopes for the first argument. + cmd.ValidArgsFunction = cobra.NoFileCompletions + + return cmd +} + +func promptSecret(cmd *cobra.Command) ([]byte, error) { + // If stdin is a TTY, prompt for the secret. + if !cmdio.IsInTTY(cmd.Context()) { + return io.ReadAll(os.Stdin) + } + + value, err := cmdio.Secret(cmd.Context(), "Please enter your secret value") + if err != nil { + return nil, err + } + + return []byte(value), nil +} diff --git a/cmd/workspace/secrets/secrets.go b/cmd/workspace/secrets/secrets.go index fada4d1fe5..a8b907ac42 100755 --- a/cmd/workspace/secrets/secrets.go +++ b/cmd/workspace/secrets/secrets.go @@ -12,10 +12,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "secrets", - Short: `The Secrets API allows you to manage secrets, secret scopes, and access permissions.`, - Long: `The Secrets API allows you to manage secrets, secret scopes, and access +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "secrets", + Short: `The Secrets API allows you to manage secrets, secret scopes, and access permissions.`, + Long: `The Secrets API allows you to manage secrets, secret scopes, and access permissions. Sometimes accessing data requires that you authenticate to external data @@ -27,45 +32,62 @@ var Cmd = &cobra.Command{ Databricks secrets. While Databricks makes an effort to redact secret values that might be displayed in notebooks, it is not possible to prevent such users from reading secrets.`, - Annotations: map[string]string{ - "package": "workspace", - }, + GroupID: "workspace", + Annotations: map[string]string{ + "package": "workspace", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create-scope command -var createScopeReq workspace.CreateScope -var createScopeJson flags.JsonFlag -func init() { - Cmd.AddCommand(createScopeCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createScopeOverrides []func( + *cobra.Command, + *workspace.CreateScope, +) + +func newCreateScope() *cobra.Command { + cmd := &cobra.Command{} + + var createScopeReq workspace.CreateScope + var createScopeJson flags.JsonFlag + // TODO: short flags - createScopeCmd.Flags().Var(&createScopeJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createScopeJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: backend_azure_keyvault - createScopeCmd.Flags().StringVar(&createScopeReq.InitialManagePrincipal, "initial-manage-principal", createScopeReq.InitialManagePrincipal, `The principal that is initially granted MANAGE permission to the created scope.`) - createScopeCmd.Flags().Var(&createScopeReq.ScopeBackendType, "scope-backend-type", `The backend type the scope will be created with.`) + cmd.Flags().StringVar(&createScopeReq.InitialManagePrincipal, "initial-manage-principal", createScopeReq.InitialManagePrincipal, `The principal that is initially granted MANAGE permission to the created scope.`) + cmd.Flags().Var(&createScopeReq.ScopeBackendType, "scope-backend-type", `The backend type the scope will be created with.`) -} - -var createScopeCmd = &cobra.Command{ - Use: "create-scope SCOPE", - Short: `Create a new secret scope.`, - Long: `Create a new secret scope. + cmd.Use = "create-scope SCOPE" + cmd.Short = `Create a new secret scope.` + cmd.Long = `Create a new secret scope. The scope name must consist of alphanumeric characters, dashes, underscores, and periods, and may not exceed 128 characters. The maximum number of scopes - in a workspace is 100.`, + in a workspace is 100.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -83,45 +105,67 @@ var createScopeCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createScopeOverrides { + fn(cmd, &createScopeReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreateScope()) + }) } // start delete-acl command -var deleteAclReq workspace.DeleteAcl -var deleteAclJson flags.JsonFlag -func init() { - Cmd.AddCommand(deleteAclCmd) - // TODO: short flags - deleteAclCmd.Flags().Var(&deleteAclJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteAclOverrides []func( + *cobra.Command, + *workspace.DeleteAcl, +) -} +func newDeleteAcl() *cobra.Command { + cmd := &cobra.Command{} + + var deleteAclReq workspace.DeleteAcl + var deleteAclJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&deleteAclJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var deleteAclCmd = &cobra.Command{ - Use: "delete-acl SCOPE PRINCIPAL", - Short: `Delete an ACL.`, - Long: `Delete an ACL. + cmd.Use = "delete-acl SCOPE PRINCIPAL" + cmd.Short = `Delete an ACL.` + cmd.Long = `Delete an ACL. Deletes the given ACL on the given scope. Users must have the MANAGE permission to invoke this API. Throws RESOURCE_DOES_NOT_EXIST if no such secret scope, principal, or ACL exists. Throws PERMISSION_DENIED if the user does not have permission to make this - API call.`, + API call.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -140,44 +184,66 @@ var deleteAclCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteAclOverrides { + fn(cmd, &deleteAclReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDeleteAcl()) + }) } // start delete-scope command -var deleteScopeReq workspace.DeleteScope -var deleteScopeJson flags.JsonFlag -func init() { - Cmd.AddCommand(deleteScopeCmd) - // TODO: short flags - deleteScopeCmd.Flags().Var(&deleteScopeJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteScopeOverrides []func( + *cobra.Command, + *workspace.DeleteScope, +) -} +func newDeleteScope() *cobra.Command { + cmd := &cobra.Command{} + + var deleteScopeReq workspace.DeleteScope + var deleteScopeJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&deleteScopeJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var deleteScopeCmd = &cobra.Command{ - Use: "delete-scope SCOPE", - Short: `Delete a secret scope.`, - Long: `Delete a secret scope. + cmd.Use = "delete-scope SCOPE" + cmd.Short = `Delete a secret scope.` + cmd.Long = `Delete a secret scope. Deletes a secret scope. Throws RESOURCE_DOES_NOT_EXIST if the scope does not exist. Throws PERMISSION_DENIED if the user does not have permission to make this API - call.`, + call.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -195,45 +261,67 @@ var deleteScopeCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteScopeOverrides { + fn(cmd, &deleteScopeReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDeleteScope()) + }) } // start delete-secret command -var deleteSecretReq workspace.DeleteSecret -var deleteSecretJson flags.JsonFlag -func init() { - Cmd.AddCommand(deleteSecretCmd) - // TODO: short flags - deleteSecretCmd.Flags().Var(&deleteSecretJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteSecretOverrides []func( + *cobra.Command, + *workspace.DeleteSecret, +) -} +func newDeleteSecret() *cobra.Command { + cmd := &cobra.Command{} -var deleteSecretCmd = &cobra.Command{ - Use: "delete-secret SCOPE KEY", - Short: `Delete a secret.`, - Long: `Delete a secret. + var deleteSecretReq workspace.DeleteSecret + var deleteSecretJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&deleteSecretJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "delete-secret SCOPE KEY" + cmd.Short = `Delete a secret.` + cmd.Long = `Delete a secret. Deletes the secret stored in this secret scope. You must have WRITE or MANAGE permission on the secret scope. Throws RESOURCE_DOES_NOT_EXIST if no such secret scope or secret exists. Throws PERMISSION_DENIED if the user does not have permission to make this - API call.`, + API call.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -252,40 +340,62 @@ var deleteSecretCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteSecretOverrides { + fn(cmd, &deleteSecretReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDeleteSecret()) + }) } // start get-acl command -var getAclReq workspace.GetAclRequest -func init() { - Cmd.AddCommand(getAclCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getAclOverrides []func( + *cobra.Command, + *workspace.GetAclRequest, +) -} +func newGetAcl() *cobra.Command { + cmd := &cobra.Command{} + + var getAclReq workspace.GetAclRequest -var getAclCmd = &cobra.Command{ - Use: "get-acl SCOPE PRINCIPAL", - Short: `Get secret ACL details.`, - Long: `Get secret ACL details. + // TODO: short flags + + cmd.Use = "get-acl SCOPE PRINCIPAL" + cmd.Short = `Get secret ACL details.` + cmd.Long = `Get secret ACL details. Gets the details about the given ACL, such as the group and permission. Users must have the MANAGE permission to invoke this API. Throws RESOURCE_DOES_NOT_EXIST if no such secret scope exists. Throws PERMISSION_DENIED if the user does not have permission to make this API - call.`, + call.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -297,40 +407,62 @@ var getAclCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getAclOverrides { + fn(cmd, &getAclReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetAcl()) + }) } // start list-acls command -var listAclsReq workspace.ListAclsRequest -func init() { - Cmd.AddCommand(listAclsCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listAclsOverrides []func( + *cobra.Command, + *workspace.ListAclsRequest, +) -} +func newListAcls() *cobra.Command { + cmd := &cobra.Command{} + + var listAclsReq workspace.ListAclsRequest + + // TODO: short flags -var listAclsCmd = &cobra.Command{ - Use: "list-acls SCOPE", - Short: `Lists ACLs.`, - Long: `Lists ACLs. + cmd.Use = "list-acls SCOPE" + cmd.Short = `Lists ACLs.` + cmd.Long = `Lists ACLs. List the ACLs for a given secret scope. Users must have the MANAGE permission to invoke this API. Throws RESOURCE_DOES_NOT_EXIST if no such secret scope exists. Throws PERMISSION_DENIED if the user does not have permission to make this API - call.`, + call.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -341,32 +473,50 @@ var listAclsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listAclsOverrides { + fn(cmd, &listAclsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newListAcls()) + }) } // start list-scopes command -func init() { - Cmd.AddCommand(listScopesCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listScopesOverrides []func( + *cobra.Command, +) -} +func newListScopes() *cobra.Command { + cmd := &cobra.Command{} -var listScopesCmd = &cobra.Command{ - Use: "list-scopes", - Short: `List all scopes.`, - Long: `List all scopes. + cmd.Use = "list-scopes" + cmd.Short = `List all scopes.` + cmd.Long = `List all scopes. Lists all secret scopes available in the workspace. Throws PERMISSION_DENIED if the user does not have permission to make this - API call.`, + API call.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.Secrets.ListScopesAll(ctx) @@ -374,25 +524,45 @@ var listScopesCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listScopesOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newListScopes()) + }) } // start list-secrets command -var listSecretsReq workspace.ListSecretsRequest -func init() { - Cmd.AddCommand(listSecretsCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listSecretsOverrides []func( + *cobra.Command, + *workspace.ListSecretsRequest, +) -} +func newListSecrets() *cobra.Command { + cmd := &cobra.Command{} + + var listSecretsReq workspace.ListSecretsRequest + + // TODO: short flags -var listSecretsCmd = &cobra.Command{ - Use: "list-secrets SCOPE", - Short: `List secret keys.`, - Long: `List secret keys. + cmd.Use = "list-secrets SCOPE" + cmd.Short = `List secret keys.` + cmd.Long = `List secret keys. Lists the secret keys that are stored at this scope. This is a metadata-only operation; secret data cannot be retrieved using this API. Users need the READ @@ -401,15 +571,17 @@ var listSecretsCmd = &cobra.Command{ The lastUpdatedTimestamp returned is in milliseconds since epoch. Throws RESOURCE_DOES_NOT_EXIST if no such secret scope exists. Throws PERMISSION_DENIED if the user does not have permission to make this API - call.`, + call.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -420,27 +592,47 @@ var listSecretsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listSecretsOverrides { + fn(cmd, &listSecretsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newListSecrets()) + }) } // start put-acl command -var putAclReq workspace.PutAcl -var putAclJson flags.JsonFlag -func init() { - Cmd.AddCommand(putAclCmd) - // TODO: short flags - putAclCmd.Flags().Var(&putAclJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var putAclOverrides []func( + *cobra.Command, + *workspace.PutAcl, +) -} +func newPutAcl() *cobra.Command { + cmd := &cobra.Command{} + + var putAclReq workspace.PutAcl + var putAclJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&putAclJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var putAclCmd = &cobra.Command{ - Use: "put-acl SCOPE PRINCIPAL PERMISSION", - Short: `Create/update an ACL.`, - Long: `Create/update an ACL. + cmd.Use = "put-acl SCOPE PRINCIPAL PERMISSION" + cmd.Short = `Create/update an ACL.` + cmd.Long = `Create/update an ACL. Creates or overwrites the Access Control List (ACL) associated with the given principal (user or group) on the specified scope point. @@ -467,18 +659,20 @@ var putAclCmd = &cobra.Command{ RESOURCE_ALREADY_EXISTS if a permission for the principal already exists. Throws INVALID_PARAMETER_VALUE if the permission or principal is invalid. Throws PERMISSION_DENIED if the user does not have permission to make this - API call.`, + API call.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(3) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -501,10 +695,24 @@ var putAclCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range putAclOverrides { + fn(cmd, &putAclReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newPutAcl()) + }) } // end service Secrets diff --git a/cmd/workspace/service-principals/overrides.go b/cmd/workspace/service-principals/overrides.go index c335bead69..185549b7c5 100644 --- a/cmd/workspace/service-principals/overrides.go +++ b/cmd/workspace/service-principals/overrides.go @@ -1,9 +1,17 @@ package service_principals -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/databricks-sdk-go/service/iam" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command, listReq *iam.ListServicePrincipalsRequest) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{range .}}{{.Id|green}} {{.ApplicationId}} {{.DisplayName}} {{range .Groups}}{{.Display}} {{end}} {{if .Active}}{{"ACTIVE"|green}}{{else}}DISABLED{{end}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/workspace/service-principals/service-principals.go b/cmd/workspace/service-principals/service-principals.go index 4bb75d2b49..787ca29efe 100755 --- a/cmd/workspace/service-principals/service-principals.go +++ b/cmd/workspace/service-principals/service-principals.go @@ -3,8 +3,6 @@ package service_principals import ( - "fmt" - "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/flags" @@ -12,57 +10,79 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "service-principals", - Short: `Identities for use with jobs, automated tools, and systems such as scripts, apps, and CI/CD platforms.`, - Long: `Identities for use with jobs, automated tools, and systems such as scripts, +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "service-principals", + Short: `Identities for use with jobs, automated tools, and systems such as scripts, apps, and CI/CD platforms.`, + Long: `Identities for use with jobs, automated tools, and systems such as scripts, apps, and CI/CD platforms. Databricks recommends creating service principals to run production jobs or modify production data. If all processes that act on production data run with service principals, interactive users do not need any write, delete, or modify privileges in production. This eliminates the risk of a user overwriting production data by accident.`, - Annotations: map[string]string{ - "package": "iam", - }, + GroupID: "iam", + Annotations: map[string]string{ + "package": "iam", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq iam.ServicePrincipal -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *iam.ServicePrincipal, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq iam.ServicePrincipal + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createCmd.Flags().BoolVar(&createReq.Active, "active", createReq.Active, `If this user is active.`) - createCmd.Flags().StringVar(&createReq.ApplicationId, "application-id", createReq.ApplicationId, `UUID relating to the service principal.`) - createCmd.Flags().StringVar(&createReq.DisplayName, "display-name", createReq.DisplayName, `String that represents a concatenation of given and family names.`) + cmd.Flags().BoolVar(&createReq.Active, "active", createReq.Active, `If this user is active.`) + cmd.Flags().StringVar(&createReq.ApplicationId, "application-id", createReq.ApplicationId, `UUID relating to the service principal.`) + cmd.Flags().StringVar(&createReq.DisplayName, "display-name", createReq.DisplayName, `String that represents a concatenation of given and family names.`) // TODO: array: entitlements - createCmd.Flags().StringVar(&createReq.ExternalId, "external-id", createReq.ExternalId, ``) + cmd.Flags().StringVar(&createReq.ExternalId, "external-id", createReq.ExternalId, ``) // TODO: array: groups - createCmd.Flags().StringVar(&createReq.Id, "id", createReq.Id, `Databricks service principal ID.`) + cmd.Flags().StringVar(&createReq.Id, "id", createReq.Id, `Databricks service principal ID.`) // TODO: array: roles -} - -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a service principal.`, - Long: `Create a service principal. + cmd.Use = "create" + cmd.Short = `Create a service principal.` + cmd.Long = `Create a service principal. - Creates a new service principal in the Databricks workspace.`, + Creates a new service principal in the Databricks workspace.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -79,51 +99,60 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq iam.DeleteServicePrincipalRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *iam.DeleteServicePrincipalRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete ID", - Short: `Delete a service principal.`, - Long: `Delete a service principal. + var deleteReq iam.DeleteServicePrincipalRequest + + // TODO: short flags + + cmd.Use = "delete ID" + cmd.Short = `Delete a service principal.` + cmd.Long = `Delete a service principal. - Delete a single service principal in the Databricks workspace.`, + Delete a single service principal in the Databricks workspace.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Service Principals drop-down." - names, err := w.ServicePrincipals.ServicePrincipalDisplayNameToIdMap(ctx, iam.ListServicePrincipalsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Service Principals drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID for a service principal in the Databricks workspace") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id for a service principal in the databricks workspace") - } deleteReq.Id = args[0] err = w.ServicePrincipals.Delete(ctx, deleteReq) @@ -131,52 +160,61 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq iam.GetServicePrincipalRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *iam.GetServicePrincipalRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq iam.GetServicePrincipalRequest -var getCmd = &cobra.Command{ - Use: "get ID", - Short: `Get service principal details.`, - Long: `Get service principal details. + // TODO: short flags + + cmd.Use = "get ID" + cmd.Short = `Get service principal details.` + cmd.Long = `Get service principal details. Gets the details for a single service principal define in the Databricks - workspace.`, + workspace.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Service Principals drop-down." - names, err := w.ServicePrincipals.ServicePrincipalDisplayNameToIdMap(ctx, iam.ListServicePrincipalsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Service Principals drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID for a service principal in the Databricks workspace") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id for a service principal in the databricks workspace") - } getReq.Id = args[0] response, err := w.ServicePrincipals.Get(ctx, getReq) @@ -184,48 +222,70 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq iam.ListServicePrincipalsRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *iam.ListServicePrincipalsRequest, +) - listCmd.Flags().StringVar(&listReq.Attributes, "attributes", listReq.Attributes, `Comma-separated list of attributes to return in response.`) - listCmd.Flags().IntVar(&listReq.Count, "count", listReq.Count, `Desired number of results per page.`) - listCmd.Flags().StringVar(&listReq.ExcludedAttributes, "excluded-attributes", listReq.ExcludedAttributes, `Comma-separated list of attributes to exclude in response.`) - listCmd.Flags().StringVar(&listReq.Filter, "filter", listReq.Filter, `Query by which the results have to be filtered.`) - listCmd.Flags().StringVar(&listReq.SortBy, "sort-by", listReq.SortBy, `Attribute to sort the results.`) - listCmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order to sort the results.`) - listCmd.Flags().IntVar(&listReq.StartIndex, "start-index", listReq.StartIndex, `Specifies the index of the first result.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq iam.ListServicePrincipalsRequest + var listJson flags.JsonFlag -var listCmd = &cobra.Command{ - Use: "list", - Short: `List service principals.`, - Long: `List service principals. + // TODO: short flags + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&listReq.Attributes, "attributes", listReq.Attributes, `Comma-separated list of attributes to return in response.`) + cmd.Flags().IntVar(&listReq.Count, "count", listReq.Count, `Desired number of results per page.`) + cmd.Flags().StringVar(&listReq.ExcludedAttributes, "excluded-attributes", listReq.ExcludedAttributes, `Comma-separated list of attributes to exclude in response.`) + cmd.Flags().StringVar(&listReq.Filter, "filter", listReq.Filter, `Query by which the results have to be filtered.`) + cmd.Flags().StringVar(&listReq.SortBy, "sort-by", listReq.SortBy, `Attribute to sort the results.`) + cmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order to sort the results.`) + cmd.Flags().IntVar(&listReq.StartIndex, "start-index", listReq.StartIndex, `Specifies the index of the first result.`) + + cmd.Use = "list" + cmd.Short = `List service principals.` + cmd.Long = `List service principals. - Gets the set of service principals associated with a Databricks workspace.`, + Gets the set of service principals associated with a Databricks workspace.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -242,37 +302,63 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start patch command -var patchReq iam.PartialUpdate -var patchJson flags.JsonFlag -func init() { - Cmd.AddCommand(patchCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var patchOverrides []func( + *cobra.Command, + *iam.PartialUpdate, +) + +func newPatch() *cobra.Command { + cmd := &cobra.Command{} + + var patchReq iam.PartialUpdate + var patchJson flags.JsonFlag + // TODO: short flags - patchCmd.Flags().Var(&patchJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&patchJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: Operations // TODO: array: schema -} - -var patchCmd = &cobra.Command{ - Use: "patch ID", - Short: `Update service principal details.`, - Long: `Update service principal details. + cmd.Use = "patch ID" + cmd.Short = `Update service principal details.` + cmd.Long = `Update service principal details. Partially updates the details of a single service principal in the Databricks - workspace.`, + workspace.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -282,23 +368,6 @@ var patchCmd = &cobra.Command{ return err } } - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Service Principals drop-down." - names, err := w.ServicePrincipals.ServicePrincipalDisplayNameToIdMap(ctx, iam.ListServicePrincipalsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Service Principals drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID for a service principal in the Databricks workspace") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id for a service principal in the databricks workspace") - } patchReq.Id = args[0] err = w.ServicePrincipals.Patch(ctx, patchReq) @@ -306,44 +375,73 @@ var patchCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range patchOverrides { + fn(cmd, &patchReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newPatch()) + }) } // start update command -var updateReq iam.ServicePrincipal -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *iam.ServicePrincipal, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq iam.ServicePrincipal + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) - updateCmd.Flags().BoolVar(&updateReq.Active, "active", updateReq.Active, `If this user is active.`) - updateCmd.Flags().StringVar(&updateReq.ApplicationId, "application-id", updateReq.ApplicationId, `UUID relating to the service principal.`) - updateCmd.Flags().StringVar(&updateReq.DisplayName, "display-name", updateReq.DisplayName, `String that represents a concatenation of given and family names.`) + cmd.Flags().BoolVar(&updateReq.Active, "active", updateReq.Active, `If this user is active.`) + cmd.Flags().StringVar(&updateReq.ApplicationId, "application-id", updateReq.ApplicationId, `UUID relating to the service principal.`) + cmd.Flags().StringVar(&updateReq.DisplayName, "display-name", updateReq.DisplayName, `String that represents a concatenation of given and family names.`) // TODO: array: entitlements - updateCmd.Flags().StringVar(&updateReq.ExternalId, "external-id", updateReq.ExternalId, ``) + cmd.Flags().StringVar(&updateReq.ExternalId, "external-id", updateReq.ExternalId, ``) // TODO: array: groups - updateCmd.Flags().StringVar(&updateReq.Id, "id", updateReq.Id, `Databricks service principal ID.`) + cmd.Flags().StringVar(&updateReq.Id, "id", updateReq.Id, `Databricks service principal ID.`) // TODO: array: roles -} - -var updateCmd = &cobra.Command{ - Use: "update ID", - Short: `Replace service principal.`, - Long: `Replace service principal. + cmd.Use = "update ID" + cmd.Short = `Replace service principal.` + cmd.Long = `Replace service principal. Updates the details of a single service principal. - This action replaces the existing service principal with the same name.`, + This action replaces the existing service principal with the same name.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -353,23 +451,6 @@ var updateCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Service Principals drop-down." - names, err := w.ServicePrincipals.ServicePrincipalDisplayNameToIdMap(ctx, iam.ListServicePrincipalsRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Service Principals drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Databricks service principal ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have databricks service principal id") - } updateReq.Id = args[0] } @@ -378,10 +459,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service ServicePrincipals diff --git a/cmd/workspace/serving-endpoints/serving-endpoints.go b/cmd/workspace/serving-endpoints/serving-endpoints.go index 46c830ebc9..33b0abac7a 100755 --- a/cmd/workspace/serving-endpoints/serving-endpoints.go +++ b/cmd/workspace/serving-endpoints/serving-endpoints.go @@ -13,10 +13,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "serving-endpoints", - Short: `The Serving Endpoints API allows you to create, update, and delete model serving endpoints.`, - Long: `The Serving Endpoints API allows you to create, update, and delete model +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "serving-endpoints", + Short: `The Serving Endpoints API allows you to create, update, and delete model serving endpoints.`, + Long: `The Serving Endpoints API allows you to create, update, and delete model serving endpoints. You can use a serving endpoint to serve models from the Databricks Model @@ -29,35 +34,52 @@ var Cmd = &cobra.Command{ settings to define how requests should be routed to your served models behind an endpoint. Additionally, you can configure the scale of resources that should be applied to each served model.`, - Annotations: map[string]string{ - "package": "serving", - }, + GroupID: "serving", + Annotations: map[string]string{ + "package": "serving", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start build-logs command -var buildLogsReq serving.BuildLogsRequest -func init() { - Cmd.AddCommand(buildLogsCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var buildLogsOverrides []func( + *cobra.Command, + *serving.BuildLogsRequest, +) -} +func newBuildLogs() *cobra.Command { + cmd := &cobra.Command{} -var buildLogsCmd = &cobra.Command{ - Use: "build-logs NAME SERVED_MODEL_NAME", - Short: `Retrieve the logs associated with building the model's environment for a given serving endpoint's served model.`, - Long: `Retrieve the logs associated with building the model's environment for a given + var buildLogsReq serving.BuildLogsRequest + + // TODO: short flags + + cmd.Use = "build-logs NAME SERVED_MODEL_NAME" + cmd.Short = `Retrieve the logs associated with building the model's environment for a given serving endpoint's served model.` + cmd.Long = `Retrieve the logs associated with building the model's environment for a given serving endpoint's served model. - Retrieves the build logs associated with the provided served model.`, + Retrieves the build logs associated with the provided served model.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -69,37 +91,57 @@ var buildLogsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range buildLogsOverrides { + fn(cmd, &buildLogsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newBuildLogs()) + }) } // start create command -var createReq serving.CreateServingEndpoint -var createJson flags.JsonFlag -var createSkipWait bool -var createTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *serving.CreateServingEndpoint, +) -func init() { - Cmd.AddCommand(createCmd) +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq serving.CreateServingEndpoint + var createJson flags.JsonFlag + + var createSkipWait bool + var createTimeout time.Duration - createCmd.Flags().BoolVar(&createSkipWait, "no-wait", createSkipWait, `do not wait to reach NOT_UPDATING state`) - createCmd.Flags().DurationVar(&createTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach NOT_UPDATING state`) + cmd.Flags().BoolVar(&createSkipWait, "no-wait", createSkipWait, `do not wait to reach NOT_UPDATING state`) + cmd.Flags().DurationVar(&createTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach NOT_UPDATING state`) // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) -} + cmd.Use = "create" + cmd.Short = `Create a new serving endpoint.` + cmd.Long = `Create a new serving endpoint.` -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a new serving endpoint.`, - Long: `Create a new serving endpoint.`, + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -130,33 +172,55 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq serving.DeleteServingEndpointRequest -func init() { - Cmd.AddCommand(deleteCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *serving.DeleteServingEndpointRequest, +) + +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq serving.DeleteServingEndpointRequest + // TODO: short flags -} + cmd.Use = "delete NAME" + cmd.Short = `Delete a serving endpoint.` + cmd.Long = `Delete a serving endpoint.` -var deleteCmd = &cobra.Command{ - Use: "delete NAME", - Short: `Delete a serving endpoint.`, - Long: `Delete a serving endpoint.`, + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -167,36 +231,58 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start export-metrics command -var exportMetricsReq serving.ExportMetricsRequest -func init() { - Cmd.AddCommand(exportMetricsCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var exportMetricsOverrides []func( + *cobra.Command, + *serving.ExportMetricsRequest, +) -} +func newExportMetrics() *cobra.Command { + cmd := &cobra.Command{} + + var exportMetricsReq serving.ExportMetricsRequest + + // TODO: short flags -var exportMetricsCmd = &cobra.Command{ - Use: "export-metrics NAME", - Short: `Retrieve the metrics associated with a serving endpoint.`, - Long: `Retrieve the metrics associated with a serving endpoint. + cmd.Use = "export-metrics NAME" + cmd.Short = `Retrieve the metrics associated with a serving endpoint.` + cmd.Long = `Retrieve the metrics associated with a serving endpoint. Retrieves the metrics associated with the provided serving endpoint in either - Prometheus or OpenMetrics exposition format.`, + Prometheus or OpenMetrics exposition format.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -207,35 +293,57 @@ var exportMetricsCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range exportMetricsOverrides { + fn(cmd, &exportMetricsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newExportMetrics()) + }) } // start get command -var getReq serving.GetServingEndpointRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *serving.GetServingEndpointRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq serving.GetServingEndpointRequest + + // TODO: short flags -var getCmd = &cobra.Command{ - Use: "get NAME", - Short: `Get a single serving endpoint.`, - Long: `Get a single serving endpoint. + cmd.Use = "get NAME" + cmd.Short = `Get a single serving endpoint.` + cmd.Long = `Get a single serving endpoint. - Retrieves the details for a single serving endpoint.`, + Retrieves the details for a single serving endpoint.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -246,27 +354,45 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `Retrieve all serving endpoints.`, - Long: `Retrieve all serving endpoints.`, + cmd.Use = "list" + cmd.Short = `Retrieve all serving endpoints.` + cmd.Long = `Retrieve all serving endpoints.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.ServingEndpoints.ListAll(ctx) @@ -274,36 +400,58 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start logs command -var logsReq serving.LogsRequest -func init() { - Cmd.AddCommand(logsCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var logsOverrides []func( + *cobra.Command, + *serving.LogsRequest, +) -} +func newLogs() *cobra.Command { + cmd := &cobra.Command{} -var logsCmd = &cobra.Command{ - Use: "logs NAME SERVED_MODEL_NAME", - Short: `Retrieve the most recent log lines associated with a given serving endpoint's served model.`, - Long: `Retrieve the most recent log lines associated with a given serving endpoint's + var logsReq serving.LogsRequest + + // TODO: short flags + + cmd.Use = "logs NAME SERVED_MODEL_NAME" + cmd.Short = `Retrieve the most recent log lines associated with a given serving endpoint's served model.` + cmd.Long = `Retrieve the most recent log lines associated with a given serving endpoint's served model. - Retrieves the service logs associated with the provided served model.`, + Retrieves the service logs associated with the provided served model.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -315,33 +463,55 @@ var logsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range logsOverrides { + fn(cmd, &logsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newLogs()) + }) } // start query command -var queryReq serving.QueryRequest -func init() { - Cmd.AddCommand(queryCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var queryOverrides []func( + *cobra.Command, + *serving.QueryRequest, +) + +func newQuery() *cobra.Command { + cmd := &cobra.Command{} + + var queryReq serving.QueryRequest + // TODO: short flags -} + cmd.Use = "query NAME" + cmd.Short = `Query a serving endpoint with provided model input.` + cmd.Long = `Query a serving endpoint with provided model input.` -var queryCmd = &cobra.Command{ - Use: "query NAME", - Short: `Query a serving endpoint with provided model input.`, - Long: `Query a serving endpoint with provided model input.`, + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -352,44 +522,64 @@ var queryCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range queryOverrides { + fn(cmd, &queryReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newQuery()) + }) } // start update-config command -var updateConfigReq serving.EndpointCoreConfigInput -var updateConfigJson flags.JsonFlag -var updateConfigSkipWait bool -var updateConfigTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateConfigOverrides []func( + *cobra.Command, + *serving.EndpointCoreConfigInput, +) -func init() { - Cmd.AddCommand(updateConfigCmd) +func newUpdateConfig() *cobra.Command { + cmd := &cobra.Command{} - updateConfigCmd.Flags().BoolVar(&updateConfigSkipWait, "no-wait", updateConfigSkipWait, `do not wait to reach NOT_UPDATING state`) - updateConfigCmd.Flags().DurationVar(&updateConfigTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach NOT_UPDATING state`) + var updateConfigReq serving.EndpointCoreConfigInput + var updateConfigJson flags.JsonFlag + + var updateConfigSkipWait bool + var updateConfigTimeout time.Duration + + cmd.Flags().BoolVar(&updateConfigSkipWait, "no-wait", updateConfigSkipWait, `do not wait to reach NOT_UPDATING state`) + cmd.Flags().DurationVar(&updateConfigTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach NOT_UPDATING state`) // TODO: short flags - updateConfigCmd.Flags().Var(&updateConfigJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateConfigJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: traffic_config -} - -var updateConfigCmd = &cobra.Command{ - Use: "update-config", - Short: `Update a serving endpoint with a new config.`, - Long: `Update a serving endpoint with a new config. + cmd.Use = "update-config" + cmd.Short = `Update a serving endpoint with a new config.` + cmd.Long = `Update a serving endpoint with a new config. Updates any combination of the serving endpoint's served models, the compute configuration of those served models, and the endpoint's traffic config. An endpoint that already has an update in progress can not be updated until the - current update completes or fails.`, + current update completes or fails.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -420,10 +610,24 @@ var updateConfigCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateConfigOverrides { + fn(cmd, &updateConfigReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdateConfig()) + }) } // end service ServingEndpoints diff --git a/cmd/workspace/shares/shares.go b/cmd/workspace/shares/shares.go index 2580b060e3..7643567a9d 100755 --- a/cmd/workspace/shares/shares.go +++ b/cmd/workspace/shares/shares.go @@ -10,47 +10,69 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "shares", - Short: `Databricks Shares REST API.`, - Long: `Databricks Shares REST API`, - Annotations: map[string]string{ - "package": "sharing", - }, +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "shares", + Short: `Databricks Shares REST API.`, + Long: `Databricks Shares REST API`, + GroupID: "sharing", + Annotations: map[string]string{ + "package": "sharing", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq sharing.CreateShare -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *sharing.CreateShare, +) - createCmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `User-provided free-form text description.`) +func newCreate() *cobra.Command { + cmd := &cobra.Command{} -} + var createReq sharing.CreateShare + var createJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `User-provided free-form text description.`) -var createCmd = &cobra.Command{ - Use: "create NAME", - Short: `Create a share.`, - Long: `Create a share. + cmd.Use = "create NAME" + cmd.Short = `Create a share.` + cmd.Long = `Create a share. Creates a new share for data objects. Data objects can be added after creation with **update**. The caller must be a metastore admin or have the - **CREATE_SHARE** privilege on the metastore.`, + **CREATE_SHARE** privilege on the metastore.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -68,36 +90,58 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq sharing.DeleteShareRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *sharing.DeleteShareRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete NAME", - Short: `Delete a share.`, - Long: `Delete a share. + var deleteReq sharing.DeleteShareRequest + + // TODO: short flags + + cmd.Use = "delete NAME" + cmd.Short = `Delete a share.` + cmd.Long = `Delete a share. Deletes a data object share from the metastore. The caller must be an owner of - the share.`, + the share.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -108,38 +152,60 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq sharing.GetShareRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *sharing.GetShareRequest, +) - getCmd.Flags().BoolVar(&getReq.IncludeSharedData, "include-shared-data", getReq.IncludeSharedData, `Query for data to include in the share.`) +func newGet() *cobra.Command { + cmd := &cobra.Command{} -} + var getReq sharing.GetShareRequest + + // TODO: short flags + + cmd.Flags().BoolVar(&getReq.IncludeSharedData, "include-shared-data", getReq.IncludeSharedData, `Query for data to include in the share.`) -var getCmd = &cobra.Command{ - Use: "get NAME", - Short: `Get a share.`, - Long: `Get a share. + cmd.Use = "get NAME" + cmd.Short = `Get a share.` + cmd.Long = `Get a share. Gets a data object share from the metastore. The caller must be a metastore - admin or the owner of the share.`, + admin or the owner of the share.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -150,31 +216,49 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `List shares.`, - Long: `List shares. + cmd.Use = "list" + cmd.Short = `List shares.` + cmd.Long = `List shares. Gets an array of data object shares from the metastore. The caller must be a metastore admin or the owner of the share. There is no guarantee of a specific - ordering of the elements in the array.`, + ordering of the elements in the array.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.Shares.ListAll(ctx) @@ -182,36 +266,58 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start share-permissions command -var sharePermissionsReq sharing.SharePermissionsRequest -func init() { - Cmd.AddCommand(sharePermissionsCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var sharePermissionsOverrides []func( + *cobra.Command, + *sharing.SharePermissionsRequest, +) -} +func newSharePermissions() *cobra.Command { + cmd := &cobra.Command{} + + var sharePermissionsReq sharing.SharePermissionsRequest -var sharePermissionsCmd = &cobra.Command{ - Use: "share-permissions NAME", - Short: `Get permissions.`, - Long: `Get permissions. + // TODO: short flags + + cmd.Use = "share-permissions NAME" + cmd.Short = `Get permissions.` + cmd.Long = `Get permissions. Gets the permissions for a data share from the metastore. The caller must be a - metastore admin or the owner of the share.`, + metastore admin or the owner of the share.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -222,32 +328,52 @@ var sharePermissionsCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range sharePermissionsOverrides { + fn(cmd, &sharePermissionsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newSharePermissions()) + }) } // start update command -var updateReq sharing.UpdateShare -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *sharing.UpdateShare, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq sharing.UpdateShare + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) - updateCmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `User-provided free-form text description.`) - updateCmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `Name of the share.`) - updateCmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `Username of current owner of share.`) + cmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `User-provided free-form text description.`) + cmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `Name of the share.`) + cmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `Username of current owner of share.`) // TODO: array: updates -} - -var updateCmd = &cobra.Command{ - Use: "update NAME", - Short: `Update a share.`, - Long: `Update a share. + cmd.Use = "update NAME" + cmd.Short = `Update a share.` + cmd.Long = `Update a share. Updates the share with the changes and data objects in the request. The caller must be the owner of the share or a metastore admin. @@ -262,18 +388,20 @@ var updateCmd = &cobra.Command{ indefinitely for recipients to be able to access the table. Typically, you should use a group as the share owner. - Table removals through **update** do not require additional privileges.`, + Table removals through **update** do not require additional privileges.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -291,43 +419,65 @@ var updateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // start update-permissions command -var updatePermissionsReq sharing.UpdateSharePermissions -var updatePermissionsJson flags.JsonFlag -func init() { - Cmd.AddCommand(updatePermissionsCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updatePermissionsOverrides []func( + *cobra.Command, + *sharing.UpdateSharePermissions, +) + +func newUpdatePermissions() *cobra.Command { + cmd := &cobra.Command{} + + var updatePermissionsReq sharing.UpdateSharePermissions + var updatePermissionsJson flags.JsonFlag + // TODO: short flags - updatePermissionsCmd.Flags().Var(&updatePermissionsJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updatePermissionsJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: changes -} - -var updatePermissionsCmd = &cobra.Command{ - Use: "update-permissions NAME", - Short: `Update permissions.`, - Long: `Update permissions. + cmd.Use = "update-permissions NAME" + cmd.Short = `Update permissions.` + cmd.Long = `Update permissions. Updates the permissions for a data share in the metastore. The caller must be a metastore admin or an owner of the share. For new recipient grants, the user must also be the owner of the recipients. - recipient revocations do not require additional privileges.`, + recipient revocations do not require additional privileges.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -344,10 +494,24 @@ var updatePermissionsCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updatePermissionsOverrides { + fn(cmd, &updatePermissionsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdatePermissions()) + }) } // end service Shares diff --git a/cmd/workspace/storage-credentials/overrides.go b/cmd/workspace/storage-credentials/overrides.go index 8bce9ffa2f..37c18ca6ce 100644 --- a/cmd/workspace/storage-credentials/overrides.go +++ b/cmd/workspace/storage-credentials/overrides.go @@ -1,10 +1,17 @@ package storage_credentials -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{header "ID"}} {{header "Name"}} {{header "Credentials"}} {{range .}}{{.Id|green}} {{.Name|cyan}} {{if .AwsIamRole}}{{.AwsIamRole.RoleArn}}{{end}}{{if .AzureServicePrincipal}}{{.AzureServicePrincipal.ApplicationId}}{{end}}{{if .GcpServiceAccountKey}}{{.Email}}{{end}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/workspace/storage-credentials/storage-credentials.go b/cmd/workspace/storage-credentials/storage-credentials.go index bbd7dd581e..337fddcfef 100755 --- a/cmd/workspace/storage-credentials/storage-credentials.go +++ b/cmd/workspace/storage-credentials/storage-credentials.go @@ -3,8 +3,6 @@ package storage_credentials import ( - "fmt" - "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/flags" @@ -12,10 +10,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "storage-credentials", - Short: `A storage credential represents an authentication and authorization mechanism for accessing data stored on your cloud tenant.`, - Long: `A storage credential represents an authentication and authorization mechanism +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "storage-credentials", + Short: `A storage credential represents an authentication and authorization mechanism for accessing data stored on your cloud tenant.`, + Long: `A storage credential represents an authentication and authorization mechanism for accessing data stored on your cloud tenant. Each storage credential is subject to Unity Catalog access-control policies that control which users and groups can access the credential. If a user does not have access to a storage @@ -28,34 +31,49 @@ var Cmd = &cobra.Command{ To create storage credentials, you must be a Databricks account admin. The account admin who creates the storage credential can delegate ownership to another user or group to manage permissions on it.`, - Annotations: map[string]string{ - "package": "catalog", - }, + GroupID: "catalog", + Annotations: map[string]string{ + "package": "catalog", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq catalog.CreateStorageCredential -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *catalog.CreateStorageCredential, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq catalog.CreateStorageCredential + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: aws_iam_role // TODO: complex arg: azure_managed_identity // TODO: complex arg: azure_service_principal - createCmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `Comment associated with the credential.`) + cmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `Comment associated with the credential.`) // TODO: output-only field - createCmd.Flags().BoolVar(&createReq.ReadOnly, "read-only", createReq.ReadOnly, `Whether the storage credential is only usable for read operations.`) - createCmd.Flags().BoolVar(&createReq.SkipValidation, "skip-validation", createReq.SkipValidation, `Supplying true to this argument skips validation of the created credential.`) + cmd.Flags().BoolVar(&createReq.ReadOnly, "read-only", createReq.ReadOnly, `Whether the storage credential is only usable for read operations.`) + cmd.Flags().BoolVar(&createReq.SkipValidation, "skip-validation", createReq.SkipValidation, `Supplying true to this argument skips validation of the created credential.`) -} - -var createCmd = &cobra.Command{ - Use: "create NAME", - Short: `Create a storage credential.`, - Long: `Create a storage credential. + cmd.Use = "create NAME" + cmd.Short = `Create a storage credential.` + cmd.Long = `Create a storage credential. Creates a new storage credential. The request object is specific to the cloud: @@ -64,18 +82,20 @@ var createCmd = &cobra.Command{ **DatabricksGcpServiceAccount** for GCP managed credentials. The caller must be a metastore admin and have the - **CREATE_STORAGE_CREDENTIAL** privilege on the metastore.`, + **CREATE_STORAGE_CREDENTIAL** privilege on the metastore.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -93,54 +113,63 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq catalog.DeleteStorageCredentialRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *catalog.DeleteStorageCredentialRequest, +) - deleteCmd.Flags().BoolVar(&deleteReq.Force, "force", deleteReq.Force, `Force deletion even if there are dependent external locations or external tables.`) +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -} + var deleteReq catalog.DeleteStorageCredentialRequest + + // TODO: short flags + + cmd.Flags().BoolVar(&deleteReq.Force, "force", deleteReq.Force, `Force deletion even if there are dependent external locations or external tables.`) -var deleteCmd = &cobra.Command{ - Use: "delete NAME", - Short: `Delete a credential.`, - Long: `Delete a credential. + cmd.Use = "delete NAME" + cmd.Short = `Delete a credential.` + cmd.Long = `Delete a credential. Deletes a storage credential from the metastore. The caller must be an owner - of the storage credential.`, + of the storage credential.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No NAME argument specified. Loading names for Storage Credentials drop-down." - names, err := w.StorageCredentials.StorageCredentialInfoNameToIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Storage Credentials drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Name of the storage credential") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have name of the storage credential") - } deleteReq.Name = args[0] err = w.StorageCredentials.Delete(ctx, deleteReq) @@ -148,53 +177,62 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq catalog.GetStorageCredentialRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *catalog.GetStorageCredentialRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} -var getCmd = &cobra.Command{ - Use: "get NAME", - Short: `Get a credential.`, - Long: `Get a credential. + var getReq catalog.GetStorageCredentialRequest + + // TODO: short flags + + cmd.Use = "get NAME" + cmd.Short = `Get a credential.` + cmd.Long = `Get a credential. Gets a storage credential from the metastore. The caller must be a metastore admin, the owner of the storage credential, or have some permission on the - storage credential.`, + storage credential.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No NAME argument specified. Loading names for Storage Credentials drop-down." - names, err := w.StorageCredentials.StorageCredentialInfoNameToIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Storage Credentials drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Name of the storage credential") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have name of the storage credential") - } getReq.Name = args[0] response, err := w.StorageCredentials.Get(ctx, getReq) @@ -202,33 +240,51 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `List credentials.`, - Long: `List credentials. + cmd.Use = "list" + cmd.Short = `List credentials.` + cmd.Long = `List credentials. Gets an array of storage credentials (as __StorageCredentialInfo__ objects). The array is limited to only those storage credentials the caller has permission to access. If the caller is a metastore admin, all storage credentials will be retrieved. There is no guarantee of a specific ordering of - the elements in the array.`, + the elements in the array.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.StorageCredentials.ListAll(ctx) @@ -236,46 +292,75 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start update command -var updateReq catalog.UpdateStorageCredential -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *catalog.UpdateStorageCredential, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq catalog.UpdateStorageCredential + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: aws_iam_role // TODO: complex arg: azure_managed_identity // TODO: complex arg: azure_service_principal - updateCmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `Comment associated with the credential.`) + cmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `Comment associated with the credential.`) // TODO: output-only field - updateCmd.Flags().BoolVar(&updateReq.Force, "force", updateReq.Force, `Force update even if there are dependent external locations or external tables.`) - updateCmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `The credential name.`) - updateCmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `Username of current owner of credential.`) - updateCmd.Flags().BoolVar(&updateReq.ReadOnly, "read-only", updateReq.ReadOnly, `Whether the storage credential is only usable for read operations.`) - updateCmd.Flags().BoolVar(&updateReq.SkipValidation, "skip-validation", updateReq.SkipValidation, `Supplying true to this argument skips validation of the updated credential.`) - -} - -var updateCmd = &cobra.Command{ - Use: "update NAME", - Short: `Update a credential.`, - Long: `Update a credential. + cmd.Flags().BoolVar(&updateReq.Force, "force", updateReq.Force, `Force update even if there are dependent external locations or external tables.`) + cmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `The credential name.`) + cmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `Username of current owner of credential.`) + cmd.Flags().BoolVar(&updateReq.ReadOnly, "read-only", updateReq.ReadOnly, `Whether the storage credential is only usable for read operations.`) + cmd.Flags().BoolVar(&updateReq.SkipValidation, "skip-validation", updateReq.SkipValidation, `Supplying true to this argument skips validation of the updated credential.`) + + cmd.Use = "update NAME" + cmd.Short = `Update a credential.` + cmd.Long = `Update a credential. Updates a storage credential on the metastore. The caller must be the owner of the storage credential or a metastore admin. If the caller is a metastore - admin, only the __owner__ credential can be changed.`, + admin, only the __owner__ credential can be changed.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -285,23 +370,6 @@ var updateCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No NAME argument specified. Loading names for Storage Credentials drop-down." - names, err := w.StorageCredentials.StorageCredentialInfoNameToIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Storage Credentials drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The credential name") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the credential name") - } updateReq.Name = args[0] } @@ -310,36 +378,56 @@ var updateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // start validate command -var validateReq catalog.ValidateStorageCredential -var validateJson flags.JsonFlag -func init() { - Cmd.AddCommand(validateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var validateOverrides []func( + *cobra.Command, + *catalog.ValidateStorageCredential, +) + +func newValidate() *cobra.Command { + cmd := &cobra.Command{} + + var validateReq catalog.ValidateStorageCredential + var validateJson flags.JsonFlag + // TODO: short flags - validateCmd.Flags().Var(&validateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&validateJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: aws_iam_role // TODO: complex arg: azure_managed_identity // TODO: complex arg: azure_service_principal // TODO: output-only field - validateCmd.Flags().StringVar(&validateReq.ExternalLocationName, "external-location-name", validateReq.ExternalLocationName, `The name of an existing external location to validate.`) - validateCmd.Flags().BoolVar(&validateReq.ReadOnly, "read-only", validateReq.ReadOnly, `Whether the storage credential is only usable for read operations.`) + cmd.Flags().StringVar(&validateReq.ExternalLocationName, "external-location-name", validateReq.ExternalLocationName, `The name of an existing external location to validate.`) + cmd.Flags().BoolVar(&validateReq.ReadOnly, "read-only", validateReq.ReadOnly, `Whether the storage credential is only usable for read operations.`) // TODO: any: storage_credential_name - validateCmd.Flags().StringVar(&validateReq.Url, "url", validateReq.Url, `The external location url to validate.`) + cmd.Flags().StringVar(&validateReq.Url, "url", validateReq.Url, `The external location url to validate.`) -} - -var validateCmd = &cobra.Command{ - Use: "validate", - Short: `Validate a storage credential.`, - Long: `Validate a storage credential. + cmd.Use = "validate" + cmd.Short = `Validate a storage credential.` + cmd.Long = `Validate a storage credential. Validates a storage credential. At least one of __external_location_name__ and __url__ need to be provided. If only one of them is provided, it will be used @@ -352,18 +440,20 @@ var validateCmd = &cobra.Command{ The caller must be a metastore admin or the storage credential owner or have the **CREATE_EXTERNAL_LOCATION** privilege on the metastore and the storage - credential.`, + credential.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -380,10 +470,24 @@ var validateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range validateOverrides { + fn(cmd, &validateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newValidate()) + }) } // end service StorageCredentials diff --git a/cmd/workspace/system-schemas/system-schemas.go b/cmd/workspace/system-schemas/system-schemas.go index fed5e5e527..2dd729f1b1 100755 --- a/cmd/workspace/system-schemas/system-schemas.go +++ b/cmd/workspace/system-schemas/system-schemas.go @@ -11,44 +11,66 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "system-schemas", - Short: `A system schema is a schema that lives within the system catalog.`, - Long: `A system schema is a schema that lives within the system catalog. A system +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "system-schemas", + Short: `A system schema is a schema that lives within the system catalog.`, + Long: `A system schema is a schema that lives within the system catalog. A system schema may contain information about customer usage of Unity Catalog such as audit-logs, billing-logs, lineage information, etc.`, - Annotations: map[string]string{ - "package": "catalog", - }, + GroupID: "catalog", + Annotations: map[string]string{ + "package": "catalog", + }, - // This service is being previewed; hide from help output. - Hidden: true, + // This service is being previewed; hide from help output. + Hidden: true, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start disable command -var disableReq catalog.DisableRequest -func init() { - Cmd.AddCommand(disableCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var disableOverrides []func( + *cobra.Command, + *catalog.DisableRequest, +) -} +func newDisable() *cobra.Command { + cmd := &cobra.Command{} -var disableCmd = &cobra.Command{ - Use: "disable METASTORE_ID SCHEMA_NAME", - Short: `Disable a system schema.`, - Long: `Disable a system schema. + var disableReq catalog.DisableRequest + + // TODO: short flags + + cmd.Use = "disable METASTORE_ID SCHEMA_NAME" + cmd.Short = `Disable a system schema.` + cmd.Long = `Disable a system schema. Disables the system schema and removes it from the system catalog. The caller - must be an account admin or a metastore admin.`, + must be an account admin or a metastore admin.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -63,36 +85,58 @@ var disableCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range disableOverrides { + fn(cmd, &disableReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDisable()) + }) } // start enable command -var enableReq catalog.EnableRequest -func init() { - Cmd.AddCommand(enableCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var enableOverrides []func( + *cobra.Command, + *catalog.EnableRequest, +) -} +func newEnable() *cobra.Command { + cmd := &cobra.Command{} + + var enableReq catalog.EnableRequest + + // TODO: short flags -var enableCmd = &cobra.Command{ - Use: "enable METASTORE_ID SCHEMA_NAME", - Short: `Enable a system schema.`, - Long: `Enable a system schema. + cmd.Use = "enable METASTORE_ID SCHEMA_NAME" + cmd.Short = `Enable a system schema.` + cmd.Long = `Enable a system schema. Enables the system schema and adds it to the system catalog. The caller must - be an account admin or a metastore admin.`, + be an account admin or a metastore admin.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -107,36 +151,58 @@ var enableCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range enableOverrides { + fn(cmd, &enableReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newEnable()) + }) } // start list command -var listReq catalog.ListSystemSchemasRequest -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *catalog.ListSystemSchemasRequest, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list METASTORE_ID", - Short: `List system schemas.`, - Long: `List system schemas. + var listReq catalog.ListSystemSchemasRequest + + // TODO: short flags + + cmd.Use = "list METASTORE_ID" + cmd.Short = `List system schemas.` + cmd.Long = `List system schemas. Gets an array of system schemas for a metastore. The caller must be an account - admin or a metastore admin.`, + admin or a metastore admin.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -147,10 +213,24 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // end service SystemSchemas diff --git a/cmd/workspace/table-constraints/table-constraints.go b/cmd/workspace/table-constraints/table-constraints.go index d9588b8fcd..023846a65e 100755 --- a/cmd/workspace/table-constraints/table-constraints.go +++ b/cmd/workspace/table-constraints/table-constraints.go @@ -12,10 +12,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "table-constraints", - Short: `Primary key and foreign key constraints encode relationships between fields in tables.`, - Long: `Primary key and foreign key constraints encode relationships between fields in +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "table-constraints", + Short: `Primary key and foreign key constraints encode relationships between fields in tables.`, + Long: `Primary key and foreign key constraints encode relationships between fields in tables. Primary and foreign keys are informational only and are not enforced. Foreign @@ -28,26 +33,41 @@ var Cmd = &cobra.Command{ You can declare primary keys and foreign keys as part of the table specification during table creation. You can also add or drop constraints on existing tables.`, - Annotations: map[string]string{ - "package": "catalog", - }, + GroupID: "catalog", + Annotations: map[string]string{ + "package": "catalog", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq catalog.CreateTableConstraint -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *catalog.CreateTableConstraint, +) -} +func newCreate() *cobra.Command { + cmd := &cobra.Command{} -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a table constraint.`, - Long: `Create a table constraint. + var createReq catalog.CreateTableConstraint + var createJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "create" + cmd.Short = `Create a table constraint.` + cmd.Long = `Create a table constraint. Creates a new table constraint. @@ -58,11 +78,12 @@ var createCmd = &cobra.Command{ __ForeignKeyConstraint__, the user must have the **USE_CATALOG** privilege on the referenced parent table's catalog, the **USE_SCHEMA** privilege on the referenced parent table's schema, and be the owner of the referenced parent - table.`, + table.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -80,25 +101,45 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq catalog.DeleteTableConstraintRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *catalog.DeleteTableConstraintRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq catalog.DeleteTableConstraintRequest -var deleteCmd = &cobra.Command{ - Use: "delete FULL_NAME CONSTRAINT_NAME CASCADE", - Short: `Delete a table constraint.`, - Long: `Delete a table constraint. + // TODO: short flags + + cmd.Use = "delete FULL_NAME CONSTRAINT_NAME CASCADE" + cmd.Short = `Delete a table constraint.` + cmd.Long = `Delete a table constraint. Deletes a table constraint. @@ -108,15 +149,17 @@ var deleteCmd = &cobra.Command{ schema, and be the owner of the table. - if __cascade__ argument is **true**, the user must have the following permissions on all of the child tables: the **USE_CATALOG** privilege on the table's catalog, the **USE_SCHEMA** privilege - on the table's schema, and be the owner of the table.`, + on the table's schema, and be the owner of the table.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(3) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -132,10 +175,24 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // end service TableConstraints diff --git a/cmd/workspace/tables/overrides.go b/cmd/workspace/tables/overrides.go index ed9c86ed5e..35fc351a47 100644 --- a/cmd/workspace/tables/overrides.go +++ b/cmd/workspace/tables/overrides.go @@ -1,10 +1,18 @@ package tables -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/databricks-sdk-go/service/catalog" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command, listReq *catalog.ListTablesRequest) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{header "Full Name"}} {{header "Table Type"}} {{range .}}{{.FullName|green}} {{blue "%s" .TableType}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/workspace/tables/tables.go b/cmd/workspace/tables/tables.go index d57b72f1be..b7b45de46d 100755 --- a/cmd/workspace/tables/tables.go +++ b/cmd/workspace/tables/tables.go @@ -3,18 +3,21 @@ package tables import ( - "fmt" - "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" "github.com/databricks/databricks-sdk-go/service/catalog" "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "tables", - Short: `A table resides in the third layer of Unity Catalog’s three-level namespace.`, - Long: `A table resides in the third layer of Unity Catalog’s three-level namespace. +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "tables", + Short: `A table resides in the third layer of Unity Catalog’s three-level namespace.`, + Long: `A table resides in the third layer of Unity Catalog’s three-level namespace. It contains rows of data. To create a table, users must have CREATE_TABLE and USE_SCHEMA permissions on the schema, and they must have the USE_CATALOG permission on its parent catalog. To query a table, users must have the SELECT @@ -23,54 +26,58 @@ var Cmd = &cobra.Command{ A table can be managed or external. From an API perspective, a __VIEW__ is a particular kind of table (rather than a managed or external table).`, - Annotations: map[string]string{ - "package": "catalog", - }, + GroupID: "catalog", + Annotations: map[string]string{ + "package": "catalog", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start delete command -var deleteReq catalog.DeleteTableRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *catalog.DeleteTableRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete FULL_NAME", - Short: `Delete a table.`, - Long: `Delete a table. + var deleteReq catalog.DeleteTableRequest + + // TODO: short flags + + cmd.Use = "delete FULL_NAME" + cmd.Short = `Delete a table.` + cmd.Long = `Delete a table. Deletes a table from the specified parent catalog and schema. The caller must be the owner of the parent catalog, have the **USE_CATALOG** privilege on the parent catalog and be the owner of the parent schema, or be the owner of the table and have the **USE_CATALOG** privilege on the parent catalog and the - **USE_SCHEMA** privilege on the parent schema.`, + **USE_SCHEMA** privilege on the parent schema.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No FULL_NAME argument specified. Loading names for Tables drop-down." - names, err := w.Tables.TableInfoNameToTableIdMap(ctx, catalog.ListTablesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Tables drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Full name of the table") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have full name of the table") - } deleteReq.FullName = args[0] err = w.Tables.Delete(ctx, deleteReq) @@ -78,57 +85,66 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq catalog.GetTableRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *catalog.GetTableRequest, +) - getCmd.Flags().BoolVar(&getReq.IncludeDeltaMetadata, "include-delta-metadata", getReq.IncludeDeltaMetadata, `Whether delta metadata should be included in the response.`) +func newGet() *cobra.Command { + cmd := &cobra.Command{} -} + var getReq catalog.GetTableRequest + + // TODO: short flags -var getCmd = &cobra.Command{ - Use: "get FULL_NAME", - Short: `Get a table.`, - Long: `Get a table. + cmd.Flags().BoolVar(&getReq.IncludeDeltaMetadata, "include-delta-metadata", getReq.IncludeDeltaMetadata, `Whether delta metadata should be included in the response.`) + + cmd.Use = "get FULL_NAME" + cmd.Short = `Get a table.` + cmd.Long = `Get a table. Gets a table from the metastore for a specific catalog and schema. The caller must be a metastore admin, be the owner of the table and have the **USE_CATALOG** privilege on the parent catalog and the **USE_SCHEMA** privilege on the parent schema, or be the owner of the table and have the - **SELECT** privilege on it as well.`, + **SELECT** privilege on it as well.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No FULL_NAME argument specified. Loading names for Tables drop-down." - names, err := w.Tables.TableInfoNameToTableIdMap(ctx, catalog.ListTablesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Tables drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Full name of the table") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have full name of the table") - } getReq.FullName = args[0] response, err := w.Tables.Get(ctx, getReq) @@ -136,44 +152,66 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq catalog.ListTablesRequest -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *catalog.ListTablesRequest, +) - listCmd.Flags().BoolVar(&listReq.IncludeDeltaMetadata, "include-delta-metadata", listReq.IncludeDeltaMetadata, `Whether delta metadata should be included in the response.`) - listCmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Maximum number of tables to return (page length).`) - listCmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque token to send for the next page of results (pagination).`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq catalog.ListTablesRequest + + // TODO: short flags + + cmd.Flags().BoolVar(&listReq.IncludeDeltaMetadata, "include-delta-metadata", listReq.IncludeDeltaMetadata, `Whether delta metadata should be included in the response.`) + cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Maximum number of tables to return (page length).`) + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque token to send for the next page of results (pagination).`) -var listCmd = &cobra.Command{ - Use: "list CATALOG_NAME SCHEMA_NAME", - Short: `List tables.`, - Long: `List tables. + cmd.Use = "list CATALOG_NAME SCHEMA_NAME" + cmd.Short = `List tables.` + cmd.Long = `List tables. Gets an array of all tables for the current metastore under the parent catalog and schema. The caller must be a metastore admin or an owner of (or have the **SELECT** privilege on) the table. For the latter case, the caller must also be the owner or have the **USE_CATALOG** privilege on the parent catalog and the **USE_SCHEMA** privilege on the parent schema. There is no guarantee of a - specific ordering of the elements in the array.`, + specific ordering of the elements in the array.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -185,30 +223,50 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start list-summaries command -var listSummariesReq catalog.ListSummariesRequest -func init() { - Cmd.AddCommand(listSummariesCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listSummariesOverrides []func( + *cobra.Command, + *catalog.ListSummariesRequest, +) - listSummariesCmd.Flags().IntVar(&listSummariesReq.MaxResults, "max-results", listSummariesReq.MaxResults, `Maximum number of tables to return (page length).`) - listSummariesCmd.Flags().StringVar(&listSummariesReq.PageToken, "page-token", listSummariesReq.PageToken, `Opaque token to send for the next page of results (pagination).`) - listSummariesCmd.Flags().StringVar(&listSummariesReq.SchemaNamePattern, "schema-name-pattern", listSummariesReq.SchemaNamePattern, `A sql LIKE pattern (% and _) for schema names.`) - listSummariesCmd.Flags().StringVar(&listSummariesReq.TableNamePattern, "table-name-pattern", listSummariesReq.TableNamePattern, `A sql LIKE pattern (% and _) for table names.`) +func newListSummaries() *cobra.Command { + cmd := &cobra.Command{} -} + var listSummariesReq catalog.ListSummariesRequest + + // TODO: short flags -var listSummariesCmd = &cobra.Command{ - Use: "list-summaries CATALOG_NAME", - Short: `List table summaries.`, - Long: `List table summaries. + cmd.Flags().IntVar(&listSummariesReq.MaxResults, "max-results", listSummariesReq.MaxResults, `Maximum number of tables to return (page length).`) + cmd.Flags().StringVar(&listSummariesReq.PageToken, "page-token", listSummariesReq.PageToken, `Opaque token to send for the next page of results (pagination).`) + cmd.Flags().StringVar(&listSummariesReq.SchemaNamePattern, "schema-name-pattern", listSummariesReq.SchemaNamePattern, `A sql LIKE pattern (% and _) for schema names.`) + cmd.Flags().StringVar(&listSummariesReq.TableNamePattern, "table-name-pattern", listSummariesReq.TableNamePattern, `A sql LIKE pattern (% and _) for table names.`) + + cmd.Use = "list-summaries CATALOG_NAME" + cmd.Short = `List table summaries.` + cmd.Long = `List table summaries. Gets an array of summaries for tables for a schema and catalog within the metastore. The table summaries returned are either: @@ -220,31 +278,20 @@ var listSummariesCmd = &cobra.Command{ or **USE_SCHEMA** privilege on the schema, provided that the user also has ownership or the **USE_CATALOG** privilege on the parent catalog. - There is no guarantee of a specific ordering of the elements in the array.`, + There is no guarantee of a specific ordering of the elements in the array.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No CATALOG_NAME argument specified. Loading names for Tables drop-down." - names, err := w.Tables.TableInfoNameToTableIdMap(ctx, catalog.ListTablesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Tables drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Name of parent catalog for tables of interest") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have name of parent catalog for tables of interest") - } listSummariesReq.CatalogName = args[0] response, err := w.Tables.ListSummariesAll(ctx, listSummariesReq) @@ -252,60 +299,69 @@ var listSummariesCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listSummariesOverrides { + fn(cmd, &listSummariesReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newListSummaries()) + }) } // start update command -var updateReq catalog.UpdateTableRequest -func init() { - Cmd.AddCommand(updateCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *catalog.UpdateTableRequest, +) - updateCmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, ``) +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} -} + var updateReq catalog.UpdateTableRequest + + // TODO: short flags + + cmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, ``) -var updateCmd = &cobra.Command{ - Use: "update FULL_NAME", - Short: `Update a table owner.`, - Long: `Update a table owner. + cmd.Use = "update FULL_NAME" + cmd.Short = `Update a table owner.` + cmd.Long = `Update a table owner. Change the owner of the table. The caller must be the owner of the parent catalog, have the **USE_CATALOG** privilege on the parent catalog and be the owner of the parent schema, or be the owner of the table and have the **USE_CATALOG** privilege on the parent catalog and the **USE_SCHEMA** - privilege on the parent schema.`, + privilege on the parent schema.` // This command is being previewed; hide from help output. - Hidden: true, + cmd.Hidden = true - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No FULL_NAME argument specified. Loading names for Tables drop-down." - names, err := w.Tables.TableInfoNameToTableIdMap(ctx, catalog.ListTablesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Tables drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Full name of the table") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have full name of the table") - } updateReq.FullName = args[0] err = w.Tables.Update(ctx, updateReq) @@ -313,10 +369,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Tables diff --git a/cmd/workspace/token-management/overrides.go b/cmd/workspace/token-management/overrides.go index 2070e2a2b1..46967d37a0 100644 --- a/cmd/workspace/token-management/overrides.go +++ b/cmd/workspace/token-management/overrides.go @@ -1,10 +1,18 @@ package token_management -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/databricks-sdk-go/service/settings" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command, listReq *settings.ListTokenManagementRequest) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{header "ID"}} {{header "Created By"}} {{header "Comment"}} {{range .}}{{.TokenId|green}} {{.CreatedByUsername|cyan}} {{.Comment|cyan}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/workspace/token-management/token-management.go b/cmd/workspace/token-management/token-management.go index b5cc542c18..afd8fdb9e2 100755 --- a/cmd/workspace/token-management/token-management.go +++ b/cmd/workspace/token-management/token-management.go @@ -12,47 +12,69 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "token-management", - Short: `Enables administrators to get all tokens and delete tokens for other users.`, - Long: `Enables administrators to get all tokens and delete tokens for other users. +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "token-management", + Short: `Enables administrators to get all tokens and delete tokens for other users.`, + Long: `Enables administrators to get all tokens and delete tokens for other users. Admins can either get every token, get a specific token by ID, or get all tokens for a particular user.`, - Annotations: map[string]string{ - "package": "settings", - }, + GroupID: "settings", + Annotations: map[string]string{ + "package": "settings", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create-obo-token command -var createOboTokenReq settings.CreateOboTokenRequest -var createOboTokenJson flags.JsonFlag -func init() { - Cmd.AddCommand(createOboTokenCmd) - // TODO: short flags - createOboTokenCmd.Flags().Var(&createOboTokenJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOboTokenOverrides []func( + *cobra.Command, + *settings.CreateOboTokenRequest, +) - createOboTokenCmd.Flags().StringVar(&createOboTokenReq.Comment, "comment", createOboTokenReq.Comment, `Comment that describes the purpose of the token.`) +func newCreateOboToken() *cobra.Command { + cmd := &cobra.Command{} -} + var createOboTokenReq settings.CreateOboTokenRequest + var createOboTokenJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&createOboTokenJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&createOboTokenReq.Comment, "comment", createOboTokenReq.Comment, `Comment that describes the purpose of the token.`) -var createOboTokenCmd = &cobra.Command{ - Use: "create-obo-token APPLICATION_ID LIFETIME_SECONDS", - Short: `Create on-behalf token.`, - Long: `Create on-behalf token. + cmd.Use = "create-obo-token APPLICATION_ID LIFETIME_SECONDS" + cmd.Short = `Create on-behalf token.` + cmd.Long = `Create on-behalf token. - Creates a token on behalf of a service principal.`, + Creates a token on behalf of a service principal.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -74,51 +96,60 @@ var createOboTokenCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOboTokenOverrides { + fn(cmd, &createOboTokenReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreateOboToken()) + }) } // start delete command -var deleteReq settings.DeleteTokenManagementRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *settings.DeleteTokenManagementRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete TOKEN_ID", - Short: `Delete a token.`, - Long: `Delete a token. + var deleteReq settings.DeleteTokenManagementRequest + + // TODO: short flags + + cmd.Use = "delete TOKEN_ID" + cmd.Short = `Delete a token.` + cmd.Long = `Delete a token. - Deletes a token, specified by its ID.`, + Deletes a token, specified by its ID.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No TOKEN_ID argument specified. Loading names for Token Management drop-down." - names, err := w.TokenManagement.TokenInfoCommentToTokenIdMap(ctx, settings.ListTokenManagementRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Token Management drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The ID of the token to get") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the id of the token to get") - } deleteReq.TokenId = args[0] err = w.TokenManagement.Delete(ctx, deleteReq) @@ -126,51 +157,60 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq settings.GetTokenManagementRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *settings.GetTokenManagementRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq settings.GetTokenManagementRequest -var getCmd = &cobra.Command{ - Use: "get TOKEN_ID", - Short: `Get token info.`, - Long: `Get token info. + // TODO: short flags + + cmd.Use = "get TOKEN_ID" + cmd.Short = `Get token info.` + cmd.Long = `Get token info. - Gets information about a token, specified by its ID.`, + Gets information about a token, specified by its ID.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No TOKEN_ID argument specified. Loading names for Token Management drop-down." - names, err := w.TokenManagement.TokenInfoCommentToTokenIdMap(ctx, settings.ListTokenManagementRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Token Management drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The ID of the token to get") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the id of the token to get") - } getReq.TokenId = args[0] response, err := w.TokenManagement.Get(ctx, getReq) @@ -178,43 +218,65 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq settings.ListTokenManagementRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *settings.ListTokenManagementRequest, +) - listCmd.Flags().StringVar(&listReq.CreatedById, "created-by-id", listReq.CreatedById, `User ID of the user that created the token.`) - listCmd.Flags().StringVar(&listReq.CreatedByUsername, "created-by-username", listReq.CreatedByUsername, `Username of the user that created the token.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq settings.ListTokenManagementRequest + var listJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var listCmd = &cobra.Command{ - Use: "list", - Short: `List all tokens.`, - Long: `List all tokens. + cmd.Flags().StringVar(&listReq.CreatedById, "created-by-id", listReq.CreatedById, `User ID of the user that created the token.`) + cmd.Flags().StringVar(&listReq.CreatedByUsername, "created-by-username", listReq.CreatedByUsername, `Username of the user that created the token.`) + + cmd.Use = "list" + cmd.Short = `List all tokens.` + cmd.Long = `List all tokens. - Lists all tokens associated with the specified workspace or user.`, + Lists all tokens associated with the specified workspace or user.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -231,10 +293,24 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // end service TokenManagement diff --git a/cmd/workspace/tokens/overrides.go b/cmd/workspace/tokens/overrides.go index b5673c0e9e..09c51758e6 100644 --- a/cmd/workspace/tokens/overrides.go +++ b/cmd/workspace/tokens/overrides.go @@ -1,10 +1,17 @@ package tokens -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{header "ID"}} {{header "Expiry time"}} {{header "Comment"}} {{range .}}{{.TokenId|green}} {{cyan "%d" .ExpiryTime}} {{.Comment|cyan}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/workspace/tokens/tokens.go b/cmd/workspace/tokens/tokens.go index c121793b65..1e6ea7141a 100755 --- a/cmd/workspace/tokens/tokens.go +++ b/cmd/workspace/tokens/tokens.go @@ -3,8 +3,6 @@ package tokens import ( - "fmt" - "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/flags" @@ -12,50 +10,72 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "tokens", - Short: `The Token API allows you to create, list, and revoke tokens that can be used to authenticate and access Databricks REST APIs.`, - Long: `The Token API allows you to create, list, and revoke tokens that can be used +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "tokens", + Short: `The Token API allows you to create, list, and revoke tokens that can be used to authenticate and access Databricks REST APIs.`, + Long: `The Token API allows you to create, list, and revoke tokens that can be used to authenticate and access Databricks REST APIs.`, - Annotations: map[string]string{ - "package": "settings", - }, + GroupID: "settings", + Annotations: map[string]string{ + "package": "settings", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq settings.CreateTokenRequest -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *settings.CreateTokenRequest, +) - createCmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `Optional description to attach to the token.`) - createCmd.Flags().Int64Var(&createReq.LifetimeSeconds, "lifetime-seconds", createReq.LifetimeSeconds, `The lifetime of the token, in seconds.`) +func newCreate() *cobra.Command { + cmd := &cobra.Command{} -} + var createReq settings.CreateTokenRequest + var createJson flags.JsonFlag -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a user token.`, - Long: `Create a user token. + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `Optional description to attach to the token.`) + cmd.Flags().Int64Var(&createReq.LifetimeSeconds, "lifetime-seconds", createReq.LifetimeSeconds, `The lifetime of the token, in seconds.`) + + cmd.Use = "create" + cmd.Short = `Create a user token.` + cmd.Long = `Create a user token. Creates and returns a token for a user. If this call is made through token authentication, it creates a token with the same client ID as the authenticated token. If the user's token quota is exceeded, this call returns - an error **QUOTA_EXCEEDED**.`, + an error **QUOTA_EXCEEDED**.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -72,36 +92,65 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq settings.RevokeTokenRequest -var deleteJson flags.JsonFlag -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags - deleteCmd.Flags().Var(&deleteJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *settings.RevokeTokenRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq settings.RevokeTokenRequest + var deleteJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&deleteJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var deleteCmd = &cobra.Command{ - Use: "delete TOKEN_ID", - Short: `Revoke token.`, - Long: `Revoke token. + cmd.Use = "delete TOKEN_ID" + cmd.Short = `Revoke token.` + cmd.Long = `Revoke token. Revokes an access token. If a token with the specified ID is not valid, this call returns an error - **RESOURCE_DOES_NOT_EXIST**.`, + **RESOURCE_DOES_NOT_EXIST**.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -111,23 +160,6 @@ var deleteCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No TOKEN_ID argument specified. Loading names for Tokens drop-down." - names, err := w.Tokens.TokenInfoCommentToTokenIdMap(ctx) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Tokens drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The ID of the token to be revoked") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the id of the token to be revoked") - } deleteReq.TokenId = args[0] } @@ -136,29 +168,47 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start list command -func init() { - Cmd.AddCommand(listCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} -var listCmd = &cobra.Command{ - Use: "list", - Short: `List tokens.`, - Long: `List tokens. + cmd.Use = "list" + cmd.Short = `List tokens.` + cmd.Long = `List tokens. - Lists all the valid tokens for a user-workspace pair.`, + Lists all the valid tokens for a user-workspace pair.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.Tokens.ListAll(ctx) @@ -166,10 +216,24 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // end service Tokens diff --git a/cmd/workspace/users/overrides.go b/cmd/workspace/users/overrides.go index 45447a0ae5..a985ccf8cd 100644 --- a/cmd/workspace/users/overrides.go +++ b/cmd/workspace/users/overrides.go @@ -1,10 +1,18 @@ package users -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/databricks-sdk-go/service/iam" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command, listReq *iam.ListUsersRequest) { listReq.Attributes = "id,userName,groups,active" listCmd.Annotations["template"] = cmdio.Heredoc(` {{range .}}{{.Id|green}} {{.UserName}} {{range .Groups}}{{.Display}} {{end}} {{if .Active}}{{"ACTIVE"|green}}{{else}}DISABLED{{end}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/workspace/users/users.go b/cmd/workspace/users/users.go index 71fdcf9ed8..e81beb02f2 100755 --- a/cmd/workspace/users/users.go +++ b/cmd/workspace/users/users.go @@ -3,8 +3,6 @@ package users import ( - "fmt" - "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/flags" @@ -12,10 +10,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "users", - Short: `User identities recognized by Databricks and represented by email addresses.`, - Long: `User identities recognized by Databricks and represented by email addresses. +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "users", + Short: `User identities recognized by Databricks and represented by email addresses.`, + Long: `User identities recognized by Databricks and represented by email addresses. Databricks recommends using SCIM provisioning to sync users and groups automatically from your identity provider to your Databricks workspace. SCIM @@ -26,51 +29,68 @@ var Cmd = &cobra.Command{ provider and that user’s account will also be removed from Databricks workspace. This ensures a consistent offboarding process and prevents unauthorized users from accessing sensitive data.`, - Annotations: map[string]string{ - "package": "iam", - }, + GroupID: "iam", + Annotations: map[string]string{ + "package": "iam", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq iam.User -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *iam.User, +) + +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq iam.User + var createJson flags.JsonFlag + // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createCmd.Flags().BoolVar(&createReq.Active, "active", createReq.Active, `If this user is active.`) - createCmd.Flags().StringVar(&createReq.DisplayName, "display-name", createReq.DisplayName, `String that represents a concatenation of given and family names.`) + cmd.Flags().BoolVar(&createReq.Active, "active", createReq.Active, `If this user is active.`) + cmd.Flags().StringVar(&createReq.DisplayName, "display-name", createReq.DisplayName, `String that represents a concatenation of given and family names.`) // TODO: array: emails // TODO: array: entitlements - createCmd.Flags().StringVar(&createReq.ExternalId, "external-id", createReq.ExternalId, ``) + cmd.Flags().StringVar(&createReq.ExternalId, "external-id", createReq.ExternalId, ``) // TODO: array: groups - createCmd.Flags().StringVar(&createReq.Id, "id", createReq.Id, `Databricks user ID.`) + cmd.Flags().StringVar(&createReq.Id, "id", createReq.Id, `Databricks user ID.`) // TODO: complex arg: name // TODO: array: roles - createCmd.Flags().StringVar(&createReq.UserName, "user-name", createReq.UserName, `Email address of the Databricks user.`) + cmd.Flags().StringVar(&createReq.UserName, "user-name", createReq.UserName, `Email address of the Databricks user.`) -} - -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a new user.`, - Long: `Create a new user. + cmd.Use = "create" + cmd.Short = `Create a new user.` + cmd.Long = `Create a new user. Creates a new user in the Databricks workspace. This new user will also be - added to the Databricks account.`, + added to the Databricks account.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -87,52 +107,61 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq iam.DeleteUserRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *iam.DeleteUserRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -var deleteCmd = &cobra.Command{ - Use: "delete ID", - Short: `Delete a user.`, - Long: `Delete a user. + var deleteReq iam.DeleteUserRequest + + // TODO: short flags + + cmd.Use = "delete ID" + cmd.Short = `Delete a user.` + cmd.Long = `Delete a user. Deletes a user. Deleting a user from a Databricks workspace also removes - objects associated with the user.`, + objects associated with the user.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Users drop-down." - names, err := w.Users.UserUserNameToIdMap(ctx, iam.ListUsersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Users drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID for a user in the Databricks workspace") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id for a user in the databricks workspace") - } deleteReq.Id = args[0] err = w.Users.Delete(ctx, deleteReq) @@ -140,51 +169,60 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start get command -var getReq iam.GetUserRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *iam.GetUserRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} + + var getReq iam.GetUserRequest -var getCmd = &cobra.Command{ - Use: "get ID", - Short: `Get user details.`, - Long: `Get user details. + // TODO: short flags + + cmd.Use = "get ID" + cmd.Short = `Get user details.` + cmd.Long = `Get user details. - Gets information for a specific user in Databricks workspace.`, + Gets information for a specific user in Databricks workspace.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Users drop-down." - names, err := w.Users.UserUserNameToIdMap(ctx, iam.ListUsersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Users drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID for a user in the Databricks workspace") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id for a user in the databricks workspace") - } getReq.Id = args[0] response, err := w.Users.Get(ctx, getReq) @@ -192,48 +230,70 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start list command -var listReq iam.ListUsersRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *iam.ListUsersRequest, +) - listCmd.Flags().StringVar(&listReq.Attributes, "attributes", listReq.Attributes, `Comma-separated list of attributes to return in response.`) - listCmd.Flags().IntVar(&listReq.Count, "count", listReq.Count, `Desired number of results per page.`) - listCmd.Flags().StringVar(&listReq.ExcludedAttributes, "excluded-attributes", listReq.ExcludedAttributes, `Comma-separated list of attributes to exclude in response.`) - listCmd.Flags().StringVar(&listReq.Filter, "filter", listReq.Filter, `Query by which the results have to be filtered.`) - listCmd.Flags().StringVar(&listReq.SortBy, "sort-by", listReq.SortBy, `Attribute to sort the results.`) - listCmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order to sort the results.`) - listCmd.Flags().IntVar(&listReq.StartIndex, "start-index", listReq.StartIndex, `Specifies the index of the first result.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq iam.ListUsersRequest + var listJson flags.JsonFlag -var listCmd = &cobra.Command{ - Use: "list", - Short: `List users.`, - Long: `List users. + // TODO: short flags + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&listReq.Attributes, "attributes", listReq.Attributes, `Comma-separated list of attributes to return in response.`) + cmd.Flags().IntVar(&listReq.Count, "count", listReq.Count, `Desired number of results per page.`) + cmd.Flags().StringVar(&listReq.ExcludedAttributes, "excluded-attributes", listReq.ExcludedAttributes, `Comma-separated list of attributes to exclude in response.`) + cmd.Flags().StringVar(&listReq.Filter, "filter", listReq.Filter, `Query by which the results have to be filtered.`) + cmd.Flags().StringVar(&listReq.SortBy, "sort-by", listReq.SortBy, `Attribute to sort the results.`) + cmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order to sort the results.`) + cmd.Flags().IntVar(&listReq.StartIndex, "start-index", listReq.StartIndex, `Specifies the index of the first result.`) + + cmd.Use = "list" + cmd.Short = `List users.` + cmd.Long = `List users. - Gets details for all the users associated with a Databricks workspace.`, + Gets details for all the users associated with a Databricks workspace.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -250,37 +310,63 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start patch command -var patchReq iam.PartialUpdate -var patchJson flags.JsonFlag -func init() { - Cmd.AddCommand(patchCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var patchOverrides []func( + *cobra.Command, + *iam.PartialUpdate, +) + +func newPatch() *cobra.Command { + cmd := &cobra.Command{} + + var patchReq iam.PartialUpdate + var patchJson flags.JsonFlag + // TODO: short flags - patchCmd.Flags().Var(&patchJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&patchJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: Operations // TODO: array: schema -} - -var patchCmd = &cobra.Command{ - Use: "patch ID", - Short: `Update user details.`, - Long: `Update user details. + cmd.Use = "patch ID" + cmd.Short = `Update user details.` + cmd.Long = `Update user details. Partially updates a user resource by applying the supplied operations on - specific user attributes.`, + specific user attributes.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -290,23 +376,6 @@ var patchCmd = &cobra.Command{ return err } } - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Users drop-down." - names, err := w.Users.UserUserNameToIdMap(ctx, iam.ListUsersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Users drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Unique ID for a user in the Databricks workspace") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have unique id for a user in the databricks workspace") - } patchReq.Id = args[0] err = w.Users.Patch(ctx, patchReq) @@ -314,44 +383,73 @@ var patchCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range patchOverrides { + fn(cmd, &patchReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newPatch()) + }) } // start update command -var updateReq iam.User -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *iam.User, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq iam.User + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) - updateCmd.Flags().BoolVar(&updateReq.Active, "active", updateReq.Active, `If this user is active.`) - updateCmd.Flags().StringVar(&updateReq.DisplayName, "display-name", updateReq.DisplayName, `String that represents a concatenation of given and family names.`) + cmd.Flags().BoolVar(&updateReq.Active, "active", updateReq.Active, `If this user is active.`) + cmd.Flags().StringVar(&updateReq.DisplayName, "display-name", updateReq.DisplayName, `String that represents a concatenation of given and family names.`) // TODO: array: emails // TODO: array: entitlements - updateCmd.Flags().StringVar(&updateReq.ExternalId, "external-id", updateReq.ExternalId, ``) + cmd.Flags().StringVar(&updateReq.ExternalId, "external-id", updateReq.ExternalId, ``) // TODO: array: groups - updateCmd.Flags().StringVar(&updateReq.Id, "id", updateReq.Id, `Databricks user ID.`) + cmd.Flags().StringVar(&updateReq.Id, "id", updateReq.Id, `Databricks user ID.`) // TODO: complex arg: name // TODO: array: roles - updateCmd.Flags().StringVar(&updateReq.UserName, "user-name", updateReq.UserName, `Email address of the Databricks user.`) - -} + cmd.Flags().StringVar(&updateReq.UserName, "user-name", updateReq.UserName, `Email address of the Databricks user.`) -var updateCmd = &cobra.Command{ - Use: "update ID", - Short: `Replace a user.`, - Long: `Replace a user. + cmd.Use = "update ID" + cmd.Short = `Replace a user.` + cmd.Long = `Replace a user. - Replaces a user's information with the data supplied in request.`, + Replaces a user's information with the data supplied in request.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -361,23 +459,6 @@ var updateCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Users drop-down." - names, err := w.Users.UserUserNameToIdMap(ctx, iam.ListUsersRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Users drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Databricks user ID") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have databricks user id") - } updateReq.Id = args[0] } @@ -386,10 +467,24 @@ var updateCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Users diff --git a/cmd/workspace/volumes/volumes.go b/cmd/workspace/volumes/volumes.go index e020700aa8..72c1ff7c45 100755 --- a/cmd/workspace/volumes/volumes.go +++ b/cmd/workspace/volumes/volumes.go @@ -12,10 +12,15 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "volumes", - Short: `Volumes are a Unity Catalog (UC) capability for accessing, storing, governing, organizing and processing files.`, - Long: `Volumes are a Unity Catalog (UC) capability for accessing, storing, governing, +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "volumes", + Short: `Volumes are a Unity Catalog (UC) capability for accessing, storing, governing, organizing and processing files.`, + Long: `Volumes are a Unity Catalog (UC) capability for accessing, storing, governing, organizing and processing files. Use cases include running machine learning on unstructured data such as image, audio, video, or PDF files, organizing data sets during the data exploration stages in data science, working with @@ -23,32 +28,47 @@ var Cmd = &cobra.Command{ storing library and config files of arbitrary formats such as .whl or .txt centrally and providing secure access across workspaces to it, or transforming and querying non-tabular data files in ETL.`, - Annotations: map[string]string{ - "package": "catalog", - }, + GroupID: "catalog", + Annotations: map[string]string{ + "package": "catalog", + }, - // This service is being previewed; hide from help output. - Hidden: true, + // This service is being previewed; hide from help output. + Hidden: true, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq catalog.CreateVolumeRequestContent -var createJson flags.JsonFlag -func init() { - Cmd.AddCommand(createCmd) - // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *catalog.CreateVolumeRequestContent, +) - createCmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `The comment attached to the volume.`) - createCmd.Flags().StringVar(&createReq.StorageLocation, "storage-location", createReq.StorageLocation, `The storage location on the cloud.`) +func newCreate() *cobra.Command { + cmd := &cobra.Command{} -} + var createReq catalog.CreateVolumeRequestContent + var createJson flags.JsonFlag -var createCmd = &cobra.Command{ - Use: "create CATALOG_NAME NAME SCHEMA_NAME VOLUME_TYPE", - Short: `Create a Volume.`, - Long: `Create a Volume. + // TODO: short flags + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `The comment attached to the volume.`) + cmd.Flags().StringVar(&createReq.StorageLocation, "storage-location", createReq.StorageLocation, `The storage location on the cloud.`) + + cmd.Use = "create CATALOG_NAME NAME SCHEMA_NAME VOLUME_TYPE" + cmd.Short = `Create a Volume.` + cmd.Long = `Create a Volume. Creates a new volume. @@ -67,18 +87,20 @@ var createCmd = &cobra.Command{ must have **CREATE EXTERNAL VOLUME** privilege on the external location. - There are no other tables, nor volumes existing in the specified storage location. - The specified storage location is not under the location of other - tables, nor volumes, or catalogs or schemas.`, + tables, nor volumes, or catalogs or schemas.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(4) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -102,55 +124,64 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq catalog.DeleteVolumeRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *catalog.DeleteVolumeRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq catalog.DeleteVolumeRequest + + // TODO: short flags -var deleteCmd = &cobra.Command{ - Use: "delete FULL_NAME_ARG", - Short: `Delete a Volume.`, - Long: `Delete a Volume. + cmd.Use = "delete FULL_NAME_ARG" + cmd.Short = `Delete a Volume.` + cmd.Long = `Delete a Volume. Deletes a volume from the specified parent catalog and schema. The caller must be a metastore admin or an owner of the volume. For the latter case, the caller must also be the owner or have the **USE_CATALOG** privilege - on the parent catalog and the **USE_SCHEMA** privilege on the parent schema.`, + on the parent catalog and the **USE_SCHEMA** privilege on the parent schema.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No FULL_NAME_ARG argument specified. Loading names for Volumes drop-down." - names, err := w.Volumes.VolumeInfoNameToVolumeIdMap(ctx, catalog.ListVolumesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Volumes drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The three-level (fully qualified) name of the volume") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the three-level (fully qualified) name of the volume") - } deleteReq.FullNameArg = args[0] err = w.Volumes.Delete(ctx, deleteReq) @@ -158,25 +189,45 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start list command -var listReq catalog.ListVolumesRequest -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *catalog.ListVolumesRequest, +) -} +func newList() *cobra.Command { + cmd := &cobra.Command{} + + var listReq catalog.ListVolumesRequest -var listCmd = &cobra.Command{ - Use: "list CATALOG_NAME SCHEMA_NAME", - Short: `List Volumes.`, - Long: `List Volumes. + // TODO: short flags + + cmd.Use = "list CATALOG_NAME SCHEMA_NAME" + cmd.Short = `List Volumes.` + cmd.Long = `List Volumes. Gets an array of all volumes for the current metastore under the parent catalog and schema. @@ -188,15 +239,17 @@ var listCmd = &cobra.Command{ also be the owner or have the **USE_CATALOG** privilege on the parent catalog and the **USE_SCHEMA** privilege on the parent schema. - There is no guarantee of a specific ordering of the elements in the array.`, + There is no guarantee of a specific ordering of the elements in the array.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(2) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -208,56 +261,65 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start read command -var readReq catalog.ReadVolumeRequest -func init() { - Cmd.AddCommand(readCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var readOverrides []func( + *cobra.Command, + *catalog.ReadVolumeRequest, +) -} +func newRead() *cobra.Command { + cmd := &cobra.Command{} + + var readReq catalog.ReadVolumeRequest + + // TODO: short flags -var readCmd = &cobra.Command{ - Use: "read FULL_NAME_ARG", - Short: `Get a Volume.`, - Long: `Get a Volume. + cmd.Use = "read FULL_NAME_ARG" + cmd.Short = `Get a Volume.` + cmd.Long = `Get a Volume. Gets a volume from the metastore for a specific catalog and schema. The caller must be a metastore admin or an owner of (or have the **READ VOLUME** privilege on) the volume. For the latter case, the caller must also be the owner or have the **USE_CATALOG** privilege on the parent catalog and - the **USE_SCHEMA** privilege on the parent schema.`, + the **USE_SCHEMA** privilege on the parent schema.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No FULL_NAME_ARG argument specified. Loading names for Volumes drop-down." - names, err := w.Volumes.VolumeInfoNameToVolumeIdMap(ctx, catalog.ListVolumesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Volumes drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The three-level (fully qualified) name of the volume") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the three-level (fully qualified) name of the volume") - } readReq.FullNameArg = args[0] response, err := w.Volumes.Read(ctx, readReq) @@ -265,29 +327,49 @@ var readCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range readOverrides { + fn(cmd, &readReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newRead()) + }) } // start update command -var updateReq catalog.UpdateVolumeRequestContent -func init() { - Cmd.AddCommand(updateCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *catalog.UpdateVolumeRequestContent, +) - updateCmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `The comment attached to the volume.`) - updateCmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `The name of the volume.`) - updateCmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `The identifier of the user who owns the volume.`) +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} -} + var updateReq catalog.UpdateVolumeRequestContent -var updateCmd = &cobra.Command{ - Use: "update FULL_NAME_ARG", - Short: `Update a Volume.`, - Long: `Update a Volume. + // TODO: short flags + + cmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `The comment attached to the volume.`) + cmd.Flags().StringVar(&updateReq.Name, "name", updateReq.Name, `The name of the volume.`) + cmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `The identifier of the user who owns the volume.`) + + cmd.Use = "update FULL_NAME_ARG" + cmd.Short = `Update a Volume.` + cmd.Long = `Update a Volume. Updates the specified volume under the specified parent catalog and schema. @@ -296,31 +378,20 @@ var updateCmd = &cobra.Command{ on the parent catalog and the **USE_SCHEMA** privilege on the parent schema. Currently only the name, the owner or the comment of the volume could be - updated.`, + updated.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No FULL_NAME_ARG argument specified. Loading names for Volumes drop-down." - names, err := w.Volumes.VolumeInfoNameToVolumeIdMap(ctx, catalog.ListVolumesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Volumes drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The three-level (fully qualified) name of the volume") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the three-level (fully qualified) name of the volume") - } updateReq.FullNameArg = args[0] response, err := w.Volumes.Update(ctx, updateReq) @@ -328,10 +399,24 @@ var updateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service Volumes diff --git a/cmd/workspace/warehouses/overrides.go b/cmd/workspace/warehouses/overrides.go index 82319d6fc9..0714937c25 100644 --- a/cmd/workspace/warehouses/overrides.go +++ b/cmd/workspace/warehouses/overrides.go @@ -1,10 +1,18 @@ package warehouses -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/databricks-sdk-go/service/sql" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command, listReq *sql.ListWarehousesRequest) { listCmd.Annotations["template"] = cmdio.Heredoc(` {{header "ID"}} {{header "Name"}} {{header "Size"}} {{header "State"}} {{range .}}{{.Id|green}} {{.Name|cyan}} {{.ClusterSize|cyan}} {{if eq .State "RUNNING"}}{{"RUNNING"|green}}{{else if eq .State "STOPPED"}}{{"STOPPED"|red}}{{else}}{{blue "%s" .State}}{{end}} {{end}}`) } + +func init() { + listOverrides = append(listOverrides, listOverride) +} diff --git a/cmd/workspace/warehouses/warehouses.go b/cmd/workspace/warehouses/warehouses.go index a29c4031e4..1d7dde0331 100755 --- a/cmd/workspace/warehouses/warehouses.go +++ b/cmd/workspace/warehouses/warehouses.go @@ -13,65 +13,86 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "warehouses", - Short: `A SQL warehouse is a compute resource that lets you run SQL commands on data objects within Databricks SQL.`, - Long: `A SQL warehouse is a compute resource that lets you run SQL commands on data +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "warehouses", + Short: `A SQL warehouse is a compute resource that lets you run SQL commands on data objects within Databricks SQL.`, + Long: `A SQL warehouse is a compute resource that lets you run SQL commands on data objects within Databricks SQL. Compute resources are infrastructure resources that provide processing capabilities in the cloud.`, - Annotations: map[string]string{ - "package": "sql", - }, + GroupID: "sql", + Annotations: map[string]string{ + "package": "sql", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start create command -var createReq sql.CreateWarehouseRequest -var createJson flags.JsonFlag -var createSkipWait bool -var createTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createOverrides []func( + *cobra.Command, + *sql.CreateWarehouseRequest, +) -func init() { - Cmd.AddCommand(createCmd) +func newCreate() *cobra.Command { + cmd := &cobra.Command{} + + var createReq sql.CreateWarehouseRequest + var createJson flags.JsonFlag - createCmd.Flags().BoolVar(&createSkipWait, "no-wait", createSkipWait, `do not wait to reach RUNNING state`) - createCmd.Flags().DurationVar(&createTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) + var createSkipWait bool + var createTimeout time.Duration + + cmd.Flags().BoolVar(&createSkipWait, "no-wait", createSkipWait, `do not wait to reach RUNNING state`) + cmd.Flags().DurationVar(&createTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) // TODO: short flags - createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createCmd.Flags().IntVar(&createReq.AutoStopMins, "auto-stop-mins", createReq.AutoStopMins, `The amount of time in minutes that a SQL warehouse must be idle (i.e., no RUNNING queries) before it is automatically stopped.`) + cmd.Flags().IntVar(&createReq.AutoStopMins, "auto-stop-mins", createReq.AutoStopMins, `The amount of time in minutes that a SQL warehouse must be idle (i.e., no RUNNING queries) before it is automatically stopped.`) // TODO: complex arg: channel - createCmd.Flags().StringVar(&createReq.ClusterSize, "cluster-size", createReq.ClusterSize, `Size of the clusters allocated for this warehouse.`) - createCmd.Flags().StringVar(&createReq.CreatorName, "creator-name", createReq.CreatorName, `warehouse creator name.`) - createCmd.Flags().BoolVar(&createReq.EnablePhoton, "enable-photon", createReq.EnablePhoton, `Configures whether the warehouse should use Photon optimized clusters.`) - createCmd.Flags().BoolVar(&createReq.EnableServerlessCompute, "enable-serverless-compute", createReq.EnableServerlessCompute, `Configures whether the warehouse should use serverless compute.`) - createCmd.Flags().StringVar(&createReq.InstanceProfileArn, "instance-profile-arn", createReq.InstanceProfileArn, `Deprecated.`) - createCmd.Flags().IntVar(&createReq.MaxNumClusters, "max-num-clusters", createReq.MaxNumClusters, `Maximum number of clusters that the autoscaler will create to handle concurrent queries.`) - createCmd.Flags().IntVar(&createReq.MinNumClusters, "min-num-clusters", createReq.MinNumClusters, `Minimum number of available clusters that will be maintained for this SQL warehouse.`) - createCmd.Flags().StringVar(&createReq.Name, "name", createReq.Name, `Logical name for the cluster.`) - createCmd.Flags().Var(&createReq.SpotInstancePolicy, "spot-instance-policy", `Configurations whether the warehouse should use spot instances.`) + cmd.Flags().StringVar(&createReq.ClusterSize, "cluster-size", createReq.ClusterSize, `Size of the clusters allocated for this warehouse.`) + cmd.Flags().StringVar(&createReq.CreatorName, "creator-name", createReq.CreatorName, `warehouse creator name.`) + cmd.Flags().BoolVar(&createReq.EnablePhoton, "enable-photon", createReq.EnablePhoton, `Configures whether the warehouse should use Photon optimized clusters.`) + cmd.Flags().BoolVar(&createReq.EnableServerlessCompute, "enable-serverless-compute", createReq.EnableServerlessCompute, `Configures whether the warehouse should use serverless compute.`) + cmd.Flags().StringVar(&createReq.InstanceProfileArn, "instance-profile-arn", createReq.InstanceProfileArn, `Deprecated.`) + cmd.Flags().IntVar(&createReq.MaxNumClusters, "max-num-clusters", createReq.MaxNumClusters, `Maximum number of clusters that the autoscaler will create to handle concurrent queries.`) + cmd.Flags().IntVar(&createReq.MinNumClusters, "min-num-clusters", createReq.MinNumClusters, `Minimum number of available clusters that will be maintained for this SQL warehouse.`) + cmd.Flags().StringVar(&createReq.Name, "name", createReq.Name, `Logical name for the cluster.`) + cmd.Flags().Var(&createReq.SpotInstancePolicy, "spot-instance-policy", `Configurations whether the warehouse should use spot instances.`) // TODO: complex arg: tags - createCmd.Flags().Var(&createReq.WarehouseType, "warehouse-type", `Warehouse type: PRO or CLASSIC.`) - -} + cmd.Flags().Var(&createReq.WarehouseType, "warehouse-type", `Warehouse type: PRO or CLASSIC.`) -var createCmd = &cobra.Command{ - Use: "create", - Short: `Create a warehouse.`, - Long: `Create a warehouse. + cmd.Use = "create" + cmd.Short = `Create a warehouse.` + cmd.Long = `Create a warehouse. - Creates a new SQL warehouse.`, + Creates a new SQL warehouse.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -107,51 +128,60 @@ var createCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createOverrides { + fn(cmd, &createReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newCreate()) + }) } // start delete command -var deleteReq sql.DeleteWarehouseRequest -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *sql.DeleteWarehouseRequest, +) -} +func newDelete() *cobra.Command { + cmd := &cobra.Command{} + + var deleteReq sql.DeleteWarehouseRequest + + // TODO: short flags -var deleteCmd = &cobra.Command{ - Use: "delete ID", - Short: `Delete a warehouse.`, - Long: `Delete a warehouse. + cmd.Use = "delete ID" + cmd.Short = `Delete a warehouse.` + cmd.Long = `Delete a warehouse. - Deletes a SQL warehouse.`, + Deletes a SQL warehouse.` - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Warehouses drop-down." - names, err := w.Warehouses.EndpointInfoNameToIdMap(ctx, sql.ListWarehousesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Warehouses drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Required") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have required") - } deleteReq.Id = args[0] err = w.Warehouses.Delete(ctx, deleteReq) @@ -159,53 +189,78 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start edit command -var editReq sql.EditWarehouseRequest -var editJson flags.JsonFlag -var editSkipWait bool -var editTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var editOverrides []func( + *cobra.Command, + *sql.EditWarehouseRequest, +) -func init() { - Cmd.AddCommand(editCmd) +func newEdit() *cobra.Command { + cmd := &cobra.Command{} + + var editReq sql.EditWarehouseRequest + var editJson flags.JsonFlag - editCmd.Flags().BoolVar(&editSkipWait, "no-wait", editSkipWait, `do not wait to reach RUNNING state`) - editCmd.Flags().DurationVar(&editTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) + var editSkipWait bool + var editTimeout time.Duration + + cmd.Flags().BoolVar(&editSkipWait, "no-wait", editSkipWait, `do not wait to reach RUNNING state`) + cmd.Flags().DurationVar(&editTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) // TODO: short flags - editCmd.Flags().Var(&editJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&editJson, "json", `either inline JSON string or @path/to/file.json with request body`) - editCmd.Flags().IntVar(&editReq.AutoStopMins, "auto-stop-mins", editReq.AutoStopMins, `The amount of time in minutes that a SQL warehouse must be idle (i.e., no RUNNING queries) before it is automatically stopped.`) + cmd.Flags().IntVar(&editReq.AutoStopMins, "auto-stop-mins", editReq.AutoStopMins, `The amount of time in minutes that a SQL warehouse must be idle (i.e., no RUNNING queries) before it is automatically stopped.`) // TODO: complex arg: channel - editCmd.Flags().StringVar(&editReq.ClusterSize, "cluster-size", editReq.ClusterSize, `Size of the clusters allocated for this warehouse.`) - editCmd.Flags().StringVar(&editReq.CreatorName, "creator-name", editReq.CreatorName, `warehouse creator name.`) - editCmd.Flags().BoolVar(&editReq.EnablePhoton, "enable-photon", editReq.EnablePhoton, `Configures whether the warehouse should use Photon optimized clusters.`) - editCmd.Flags().BoolVar(&editReq.EnableServerlessCompute, "enable-serverless-compute", editReq.EnableServerlessCompute, `Configures whether the warehouse should use serverless compute.`) - editCmd.Flags().StringVar(&editReq.InstanceProfileArn, "instance-profile-arn", editReq.InstanceProfileArn, `Deprecated.`) - editCmd.Flags().IntVar(&editReq.MaxNumClusters, "max-num-clusters", editReq.MaxNumClusters, `Maximum number of clusters that the autoscaler will create to handle concurrent queries.`) - editCmd.Flags().IntVar(&editReq.MinNumClusters, "min-num-clusters", editReq.MinNumClusters, `Minimum number of available clusters that will be maintained for this SQL warehouse.`) - editCmd.Flags().StringVar(&editReq.Name, "name", editReq.Name, `Logical name for the cluster.`) - editCmd.Flags().Var(&editReq.SpotInstancePolicy, "spot-instance-policy", `Configurations whether the warehouse should use spot instances.`) + cmd.Flags().StringVar(&editReq.ClusterSize, "cluster-size", editReq.ClusterSize, `Size of the clusters allocated for this warehouse.`) + cmd.Flags().StringVar(&editReq.CreatorName, "creator-name", editReq.CreatorName, `warehouse creator name.`) + cmd.Flags().BoolVar(&editReq.EnablePhoton, "enable-photon", editReq.EnablePhoton, `Configures whether the warehouse should use Photon optimized clusters.`) + cmd.Flags().BoolVar(&editReq.EnableServerlessCompute, "enable-serverless-compute", editReq.EnableServerlessCompute, `Configures whether the warehouse should use serverless compute.`) + cmd.Flags().StringVar(&editReq.InstanceProfileArn, "instance-profile-arn", editReq.InstanceProfileArn, `Deprecated.`) + cmd.Flags().IntVar(&editReq.MaxNumClusters, "max-num-clusters", editReq.MaxNumClusters, `Maximum number of clusters that the autoscaler will create to handle concurrent queries.`) + cmd.Flags().IntVar(&editReq.MinNumClusters, "min-num-clusters", editReq.MinNumClusters, `Minimum number of available clusters that will be maintained for this SQL warehouse.`) + cmd.Flags().StringVar(&editReq.Name, "name", editReq.Name, `Logical name for the cluster.`) + cmd.Flags().Var(&editReq.SpotInstancePolicy, "spot-instance-policy", `Configurations whether the warehouse should use spot instances.`) // TODO: complex arg: tags - editCmd.Flags().Var(&editReq.WarehouseType, "warehouse-type", `Warehouse type: PRO or CLASSIC.`) + cmd.Flags().Var(&editReq.WarehouseType, "warehouse-type", `Warehouse type: PRO or CLASSIC.`) -} - -var editCmd = &cobra.Command{ - Use: "edit ID", - Short: `Update a warehouse.`, - Long: `Update a warehouse. + cmd.Use = "edit ID" + cmd.Short = `Update a warehouse.` + cmd.Long = `Update a warehouse. - Updates the configuration for a SQL warehouse.`, + Updates the configuration for a SQL warehouse.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -215,23 +270,6 @@ var editCmd = &cobra.Command{ return err } } - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Warehouses drop-down." - names, err := w.Warehouses.EndpointInfoNameToIdMap(ctx, sql.ListWarehousesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Warehouses drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Required") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have required") - } editReq.Id = args[0] wait, err := w.Warehouses.Edit(ctx, editReq) @@ -258,57 +296,65 @@ var editCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range editOverrides { + fn(cmd, &editReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newEdit()) + }) } // start get command -var getReq sql.GetWarehouseRequest -var getSkipWait bool -var getTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *sql.GetWarehouseRequest, +) -func init() { - Cmd.AddCommand(getCmd) +func newGet() *cobra.Command { + cmd := &cobra.Command{} - getCmd.Flags().BoolVar(&getSkipWait, "no-wait", getSkipWait, `do not wait to reach RUNNING state`) - getCmd.Flags().DurationVar(&getTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) - // TODO: short flags + var getReq sql.GetWarehouseRequest -} + var getSkipWait bool + var getTimeout time.Duration -var getCmd = &cobra.Command{ - Use: "get ID", - Short: `Get warehouse info.`, - Long: `Get warehouse info. + cmd.Flags().BoolVar(&getSkipWait, "no-wait", getSkipWait, `do not wait to reach RUNNING state`) + cmd.Flags().DurationVar(&getTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) + // TODO: short flags + + cmd.Use = "get ID" + cmd.Short = `Get warehouse info.` + cmd.Long = `Get warehouse info. - Gets the information for a single SQL warehouse.`, + Gets the information for a single SQL warehouse.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Warehouses drop-down." - names, err := w.Warehouses.EndpointInfoNameToIdMap(ctx, sql.ListWarehousesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Warehouses drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Required") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have required") - } getReq.Id = args[0] response, err := w.Warehouses.Get(ctx, getReq) @@ -316,30 +362,48 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start get-workspace-warehouse-config command -func init() { - Cmd.AddCommand(getWorkspaceWarehouseConfigCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getWorkspaceWarehouseConfigOverrides []func( + *cobra.Command, +) -} +func newGetWorkspaceWarehouseConfig() *cobra.Command { + cmd := &cobra.Command{} -var getWorkspaceWarehouseConfigCmd = &cobra.Command{ - Use: "get-workspace-warehouse-config", - Short: `Get the workspace configuration.`, - Long: `Get the workspace configuration. + cmd.Use = "get-workspace-warehouse-config" + cmd.Short = `Get the workspace configuration.` + cmd.Long = `Get the workspace configuration. Gets the workspace level configuration that is shared by all SQL warehouses in - a workspace.`, + a workspace.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) response, err := w.Warehouses.GetWorkspaceWarehouseConfig(ctx) @@ -347,42 +411,64 @@ var getWorkspaceWarehouseConfigCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getWorkspaceWarehouseConfigOverrides { + fn(cmd) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetWorkspaceWarehouseConfig()) + }) } // start list command -var listReq sql.ListWarehousesRequest -var listJson flags.JsonFlag -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags - listCmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *sql.ListWarehousesRequest, +) - listCmd.Flags().IntVar(&listReq.RunAsUserId, "run-as-user-id", listReq.RunAsUserId, `Service Principal which will be used to fetch the list of warehouses.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq sql.ListWarehousesRequest + var listJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var listCmd = &cobra.Command{ - Use: "list", - Short: `List warehouses.`, - Long: `List warehouses. + cmd.Flags().IntVar(&listReq.RunAsUserId, "run-as-user-id", listReq.RunAsUserId, `Service Principal which will be used to fetch the list of warehouses.`) + + cmd.Use = "list" + cmd.Short = `List warehouses.` + cmd.Long = `List warehouses. - Lists all SQL warehouses that a user has manager permissions on.`, + Lists all SQL warehouses that a user has manager permissions on.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -399,51 +485,73 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start set-workspace-warehouse-config command -var setWorkspaceWarehouseConfigReq sql.SetWorkspaceWarehouseConfigRequest -var setWorkspaceWarehouseConfigJson flags.JsonFlag -func init() { - Cmd.AddCommand(setWorkspaceWarehouseConfigCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var setWorkspaceWarehouseConfigOverrides []func( + *cobra.Command, + *sql.SetWorkspaceWarehouseConfigRequest, +) + +func newSetWorkspaceWarehouseConfig() *cobra.Command { + cmd := &cobra.Command{} + + var setWorkspaceWarehouseConfigReq sql.SetWorkspaceWarehouseConfigRequest + var setWorkspaceWarehouseConfigJson flags.JsonFlag + // TODO: short flags - setWorkspaceWarehouseConfigCmd.Flags().Var(&setWorkspaceWarehouseConfigJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&setWorkspaceWarehouseConfigJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: complex arg: channel // TODO: complex arg: config_param // TODO: array: data_access_config // TODO: array: enabled_warehouse_types // TODO: complex arg: global_param - setWorkspaceWarehouseConfigCmd.Flags().StringVar(&setWorkspaceWarehouseConfigReq.GoogleServiceAccount, "google-service-account", setWorkspaceWarehouseConfigReq.GoogleServiceAccount, `GCP only: Google Service Account used to pass to cluster to access Google Cloud Storage.`) - setWorkspaceWarehouseConfigCmd.Flags().StringVar(&setWorkspaceWarehouseConfigReq.InstanceProfileArn, "instance-profile-arn", setWorkspaceWarehouseConfigReq.InstanceProfileArn, `AWS Only: Instance profile used to pass IAM role to the cluster.`) - setWorkspaceWarehouseConfigCmd.Flags().Var(&setWorkspaceWarehouseConfigReq.SecurityPolicy, "security-policy", `Security policy for warehouses.`) + cmd.Flags().StringVar(&setWorkspaceWarehouseConfigReq.GoogleServiceAccount, "google-service-account", setWorkspaceWarehouseConfigReq.GoogleServiceAccount, `GCP only: Google Service Account used to pass to cluster to access Google Cloud Storage.`) + cmd.Flags().StringVar(&setWorkspaceWarehouseConfigReq.InstanceProfileArn, "instance-profile-arn", setWorkspaceWarehouseConfigReq.InstanceProfileArn, `AWS Only: Instance profile used to pass IAM role to the cluster.`) + cmd.Flags().Var(&setWorkspaceWarehouseConfigReq.SecurityPolicy, "security-policy", `Security policy for warehouses.`) // TODO: complex arg: sql_configuration_parameters -} - -var setWorkspaceWarehouseConfigCmd = &cobra.Command{ - Use: "set-workspace-warehouse-config", - Short: `Set the workspace configuration.`, - Long: `Set the workspace configuration. + cmd.Use = "set-workspace-warehouse-config" + cmd.Short = `Set the workspace configuration.` + cmd.Long = `Set the workspace configuration. Sets the workspace level configuration that is shared by all SQL warehouses in - a workspace.`, + a workspace.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -460,57 +568,65 @@ var setWorkspaceWarehouseConfigCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range setWorkspaceWarehouseConfigOverrides { + fn(cmd, &setWorkspaceWarehouseConfigReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newSetWorkspaceWarehouseConfig()) + }) } // start start command -var startReq sql.StartRequest -var startSkipWait bool -var startTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var startOverrides []func( + *cobra.Command, + *sql.StartRequest, +) -func init() { - Cmd.AddCommand(startCmd) +func newStart() *cobra.Command { + cmd := &cobra.Command{} - startCmd.Flags().BoolVar(&startSkipWait, "no-wait", startSkipWait, `do not wait to reach RUNNING state`) - startCmd.Flags().DurationVar(&startTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) - // TODO: short flags + var startReq sql.StartRequest -} + var startSkipWait bool + var startTimeout time.Duration + + cmd.Flags().BoolVar(&startSkipWait, "no-wait", startSkipWait, `do not wait to reach RUNNING state`) + cmd.Flags().DurationVar(&startTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach RUNNING state`) + // TODO: short flags -var startCmd = &cobra.Command{ - Use: "start ID", - Short: `Start a warehouse.`, - Long: `Start a warehouse. + cmd.Use = "start ID" + cmd.Short = `Start a warehouse.` + cmd.Long = `Start a warehouse. - Starts a SQL warehouse.`, + Starts a SQL warehouse.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Warehouses drop-down." - names, err := w.Warehouses.EndpointInfoNameToIdMap(ctx, sql.ListWarehousesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Warehouses drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Required") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have required") - } startReq.Id = args[0] wait, err := w.Warehouses.Start(ctx, startReq) @@ -537,57 +653,65 @@ var startCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range startOverrides { + fn(cmd, &startReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newStart()) + }) } // start stop command -var stopReq sql.StopRequest -var stopSkipWait bool -var stopTimeout time.Duration +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var stopOverrides []func( + *cobra.Command, + *sql.StopRequest, +) -func init() { - Cmd.AddCommand(stopCmd) +func newStop() *cobra.Command { + cmd := &cobra.Command{} - stopCmd.Flags().BoolVar(&stopSkipWait, "no-wait", stopSkipWait, `do not wait to reach STOPPED state`) - stopCmd.Flags().DurationVar(&stopTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach STOPPED state`) - // TODO: short flags + var stopReq sql.StopRequest -} + var stopSkipWait bool + var stopTimeout time.Duration -var stopCmd = &cobra.Command{ - Use: "stop ID", - Short: `Stop a warehouse.`, - Long: `Stop a warehouse. + cmd.Flags().BoolVar(&stopSkipWait, "no-wait", stopSkipWait, `do not wait to reach STOPPED state`) + cmd.Flags().DurationVar(&stopTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach STOPPED state`) + // TODO: short flags + + cmd.Use = "stop ID" + cmd.Short = `Stop a warehouse.` + cmd.Long = `Stop a warehouse. - Stops a SQL warehouse.`, + Stops a SQL warehouse.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No ID argument specified. Loading names for Warehouses drop-down." - names, err := w.Warehouses.EndpointInfoNameToIdMap(ctx, sql.ListWarehousesRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Warehouses drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "Required") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have required") - } stopReq.Id = args[0] wait, err := w.Warehouses.Stop(ctx, stopReq) @@ -614,10 +738,24 @@ var stopCmd = &cobra.Command{ return err } return cmdio.Render(ctx, info) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range stopOverrides { + fn(cmd, &stopReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newStop()) + }) } // end service Warehouses diff --git a/cmd/workspace/workspace-bindings/workspace-bindings.go b/cmd/workspace/workspace-bindings/workspace-bindings.go index 8780106b1d..3d7fa677cc 100755 --- a/cmd/workspace/workspace-bindings/workspace-bindings.go +++ b/cmd/workspace/workspace-bindings/workspace-bindings.go @@ -10,44 +10,66 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "workspace-bindings", - Short: `A catalog in Databricks can be configured as __OPEN__ or __ISOLATED__.`, - Long: `A catalog in Databricks can be configured as __OPEN__ or __ISOLATED__. An +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "workspace-bindings", + Short: `A catalog in Databricks can be configured as __OPEN__ or __ISOLATED__.`, + Long: `A catalog in Databricks can be configured as __OPEN__ or __ISOLATED__. An __OPEN__ catalog can be accessed from any workspace, while an __ISOLATED__ catalog can only be access from a configured list of workspaces. A catalog's workspace bindings can be configured by a metastore admin or the owner of the catalog.`, - Annotations: map[string]string{ - "package": "catalog", - }, + GroupID: "catalog", + Annotations: map[string]string{ + "package": "catalog", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start get command -var getReq catalog.GetWorkspaceBindingRequest -func init() { - Cmd.AddCommand(getCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getOverrides []func( + *cobra.Command, + *catalog.GetWorkspaceBindingRequest, +) -} +func newGet() *cobra.Command { + cmd := &cobra.Command{} -var getCmd = &cobra.Command{ - Use: "get NAME", - Short: `Get catalog workspace bindings.`, - Long: `Get catalog workspace bindings. + var getReq catalog.GetWorkspaceBindingRequest + + // TODO: short flags + + cmd.Use = "get NAME" + cmd.Short = `Get catalog workspace bindings.` + cmd.Long = `Get catalog workspace bindings. Gets workspace bindings of the catalog. The caller must be a metastore admin - or an owner of the catalog.`, + or an owner of the catalog.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -58,41 +80,63 @@ var getCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getOverrides { + fn(cmd, &getReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGet()) + }) } // start update command -var updateReq catalog.UpdateWorkspaceBindings -var updateJson flags.JsonFlag -func init() { - Cmd.AddCommand(updateCmd) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateOverrides []func( + *cobra.Command, + *catalog.UpdateWorkspaceBindings, +) + +func newUpdate() *cobra.Command { + cmd := &cobra.Command{} + + var updateReq catalog.UpdateWorkspaceBindings + var updateJson flags.JsonFlag + // TODO: short flags - updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: assign_workspaces // TODO: array: unassign_workspaces -} - -var updateCmd = &cobra.Command{ - Use: "update NAME", - Short: `Update catalog workspace bindings.`, - Long: `Update catalog workspace bindings. + cmd.Use = "update NAME" + cmd.Short = `Update catalog workspace bindings.` + cmd.Long = `Update catalog workspace bindings. Updates workspace bindings of the catalog. The caller must be a metastore - admin or an owner of the catalog.`, + admin or an owner of the catalog.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -109,10 +153,24 @@ var updateCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateOverrides { + fn(cmd, &updateReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newUpdate()) + }) } // end service WorkspaceBindings diff --git a/cmd/workspace/workspace-conf/workspace-conf.go b/cmd/workspace/workspace-conf/workspace-conf.go index f2f0bb7598..d828f66ea4 100755 --- a/cmd/workspace/workspace-conf/workspace-conf.go +++ b/cmd/workspace/workspace-conf/workspace-conf.go @@ -10,38 +10,60 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "workspace-conf", - Short: `This API allows updating known workspace settings for advanced users.`, - Long: `This API allows updating known workspace settings for advanced users.`, - Annotations: map[string]string{ - "package": "settings", - }, +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "workspace-conf", + Short: `This API allows updating known workspace settings for advanced users.`, + Long: `This API allows updating known workspace settings for advanced users.`, + GroupID: "settings", + Annotations: map[string]string{ + "package": "settings", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start get-status command -var getStatusReq settings.GetStatusRequest -func init() { - Cmd.AddCommand(getStatusCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getStatusOverrides []func( + *cobra.Command, + *settings.GetStatusRequest, +) -} +func newGetStatus() *cobra.Command { + cmd := &cobra.Command{} -var getStatusCmd = &cobra.Command{ - Use: "get-status KEYS", - Short: `Check configuration status.`, - Long: `Check configuration status. + var getStatusReq settings.GetStatusRequest + + // TODO: short flags + + cmd.Use = "get-status KEYS" + cmd.Short = `Check configuration status.` + cmd.Long = `Check configuration status. - Gets the configuration status for a workspace.`, + Gets the configuration status for a workspace.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -52,41 +74,63 @@ var getStatusCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getStatusOverrides { + fn(cmd, &getStatusReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetStatus()) + }) } // start set-status command -var setStatusReq settings.WorkspaceConf -var setStatusJson flags.JsonFlag -func init() { - Cmd.AddCommand(setStatusCmd) - // TODO: short flags - setStatusCmd.Flags().Var(&setStatusJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var setStatusOverrides []func( + *cobra.Command, + *settings.WorkspaceConf, +) -} +func newSetStatus() *cobra.Command { + cmd := &cobra.Command{} -var setStatusCmd = &cobra.Command{ - Use: "set-status", - Short: `Enable/disable features.`, - Long: `Enable/disable features. + var setStatusReq settings.WorkspaceConf + var setStatusJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&setStatusJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "set-status" + cmd.Short = `Enable/disable features.` + cmd.Long = `Enable/disable features. Sets the configuration status for a workspace, including enabling or disabling - it.`, + it.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -103,10 +147,24 @@ var setStatusCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range setStatusOverrides { + fn(cmd, &setStatusReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newSetStatus()) + }) } // end service WorkspaceConf diff --git a/cmd/workspace/workspace/export_dir.go b/cmd/workspace/workspace/export_dir.go index 1c3fe968f1..4f50a96e4d 100644 --- a/cmd/workspace/workspace/export_dir.go +++ b/cmd/workspace/workspace/export_dir.go @@ -15,9 +15,19 @@ import ( "github.com/spf13/cobra" ) +type exportDirOptions struct { + sourceDir string + targetDir string + overwrite bool +} + // The callback function exports the file specified at relPath. This function is // meant to be used in conjunction with fs.WalkDir -func exportFileCallback(ctx context.Context, workspaceFiler filer.Filer, sourceDir, targetDir string) func(string, fs.DirEntry, error) error { +func (opts exportDirOptions) callback(ctx context.Context, workspaceFiler filer.Filer) func(string, fs.DirEntry, error) error { + sourceDir := opts.sourceDir + targetDir := opts.targetDir + overwrite := opts.overwrite + return func(relPath string, d fs.DirEntry, err error) error { if err != nil { return err @@ -55,7 +65,7 @@ func exportFileCallback(ctx context.Context, workspaceFiler filer.Filer, sourceD // Skip file if a file already exists in path. // os.Stat returns a fs.ErrNotExist if a file does not exist at path. // If a file exists, and overwrite is not set, we skip exporting the file - if _, err := os.Stat(targetPath); err == nil && !exportOverwrite { + if _, err := os.Stat(targetPath); err == nil && !overwrite { // Log event that this file/directory has been skipped return cmdio.RenderWithTemplate(ctx, newFileSkippedEvent(relPath, targetPath), "{{.SourcePath}} -> {{.TargetPath}} (skipped; already exists)\n") } @@ -80,46 +90,56 @@ func exportFileCallback(ctx context.Context, workspaceFiler filer.Filer, sourceD } } -var exportDirCommand = &cobra.Command{ - Use: "export-dir SOURCE_PATH TARGET_PATH", - Short: `Export a directory from a Databricks workspace to the local file system.`, - Long: ` -Export a directory recursively from a Databricks workspace to the local file system. -Notebooks will have one of the following extensions added .scala, .py, .sql, or .r -based on the language type. -`, - PreRunE: root.MustWorkspaceClient, - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) (err error) { +func newExportDir() *cobra.Command { + cmd := &cobra.Command{} + + var opts exportDirOptions + + cmd.Flags().BoolVar(&opts.overwrite, "overwrite", false, "overwrite existing local files") + + cmd.Use = "export-dir SOURCE_PATH TARGET_PATH" + cmd.Short = `Export a directory from a Databricks workspace to the local file system.` + cmd.Long = ` + Export a directory recursively from a Databricks workspace to the local file system. + Notebooks will have one of the following extensions added .scala, .py, .sql, or .r + based on the language type. + ` + + cmd.Annotations = make(map[string]string) + cmd.Args = cobra.ExactArgs(2) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - sourceDir := args[0] - targetDir := args[1] + opts.sourceDir = args[0] + opts.targetDir = args[1] // Initialize a filer and a file system on the source directory - workspaceFiler, err := filer.NewWorkspaceFilesClient(w, sourceDir) + workspaceFiler, err := filer.NewWorkspaceFilesClient(w, opts.sourceDir) if err != nil { return err } workspaceFS := filer.NewFS(ctx, workspaceFiler) // TODO: print progress events on stderr instead: https://github.com/databricks/cli/issues/448 - err = cmdio.RenderJson(ctx, newExportStartedEvent(sourceDir)) + err = cmdio.RenderJson(ctx, newExportStartedEvent(opts.sourceDir)) if err != nil { return err } - err = fs.WalkDir(workspaceFS, ".", exportFileCallback(ctx, workspaceFiler, sourceDir, targetDir)) + err = fs.WalkDir(workspaceFS, ".", opts.callback(ctx, workspaceFiler)) if err != nil { return err } - return cmdio.RenderJson(ctx, newExportCompletedEvent(targetDir)) - }, -} + return cmdio.RenderJson(ctx, newExportCompletedEvent(opts.targetDir)) + } -var exportOverwrite bool + return cmd +} func init() { - exportDirCommand.Flags().BoolVar(&exportOverwrite, "overwrite", false, "overwrite existing local files") - Cmd.AddCommand(exportDirCommand) + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newExportDir()) + }) } diff --git a/cmd/workspace/workspace/import_dir.go b/cmd/workspace/workspace/import_dir.go index af9c38ca36..bc0b80667c 100644 --- a/cmd/workspace/workspace/import_dir.go +++ b/cmd/workspace/workspace/import_dir.go @@ -16,6 +16,12 @@ import ( "github.com/spf13/cobra" ) +type importDirOptions struct { + sourceDir string + targetDir string + overwrite bool +} + // The callback function imports the file specified at sourcePath. This function is // meant to be used in conjunction with fs.WalkDir // @@ -31,7 +37,11 @@ import ( // 1. Read the notebook, referring to it using it's local name "foo\\myNotebook.py" // 2. API call to import the notebook to the workspace, using it API payload name "foo/myNotebook.py" // 3. The notebook is materialized in the workspace using it's remote name "foo/myNotebook" -func importFileCallback(ctx context.Context, workspaceFiler filer.Filer, sourceDir, targetDir string) func(string, fs.DirEntry, error) error { +func (opts importDirOptions) callback(ctx context.Context, workspaceFiler filer.Filer) func(string, fs.DirEntry, error) error { + sourceDir := opts.sourceDir + targetDir := opts.targetDir + overwrite := opts.overwrite + return func(sourcePath string, d fs.DirEntry, err error) error { if err != nil { return err @@ -72,7 +82,7 @@ func importFileCallback(ctx context.Context, workspaceFiler filer.Filer, sourceD defer f.Close() // Create file in WSFS - if importOverwrite { + if overwrite { err = workspaceFiler.Write(ctx, nameForApiCall, f, filer.OverwriteIfExists) if err != nil { return err @@ -94,45 +104,55 @@ func importFileCallback(ctx context.Context, workspaceFiler filer.Filer, sourceD } } -var importDirCommand = &cobra.Command{ - Use: "import-dir SOURCE_PATH TARGET_PATH", - Short: `Import a directory from the local filesystem to a Databricks workspace.`, - Long: ` +func newImportDir() *cobra.Command { + cmd := &cobra.Command{} + + var opts importDirOptions + + cmd.Flags().BoolVar(&opts.overwrite, "overwrite", false, "overwrite existing workspace files") + + cmd.Use = "import-dir SOURCE_PATH TARGET_PATH" + cmd.Short = `Import a directory from the local filesystem to a Databricks workspace.` + cmd.Long = ` Import a directory recursively from the local file system to a Databricks workspace. Notebooks will have their extensions (one of .scala, .py, .sql, .ipynb, .r) stripped -`, - PreRunE: root.MustWorkspaceClient, - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) (err error) { +` + + cmd.Annotations = make(map[string]string) + cmd.Args = cobra.ExactArgs(2) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - sourceDir := args[0] - targetDir := args[1] + opts.sourceDir = args[0] + opts.targetDir = args[1] // Initialize a filer rooted at targetDir - workspaceFiler, err := filer.NewWorkspaceFilesClient(w, targetDir) + workspaceFiler, err := filer.NewWorkspaceFilesClient(w, opts.targetDir) if err != nil { return err } // TODO: print progress events on stderr instead: https://github.com/databricks/cli/issues/448 - err = cmdio.RenderJson(ctx, newImportStartedEvent(sourceDir)) + err = cmdio.RenderJson(ctx, newImportStartedEvent(opts.sourceDir)) if err != nil { return err } // Walk local directory tree and import files to the workspace - err = filepath.WalkDir(sourceDir, importFileCallback(ctx, workspaceFiler, sourceDir, targetDir)) + err = filepath.WalkDir(opts.sourceDir, opts.callback(ctx, workspaceFiler)) if err != nil { return err } - return cmdio.RenderJson(ctx, newImportCompletedEvent(targetDir)) - }, -} + return cmdio.RenderJson(ctx, newImportCompletedEvent(opts.targetDir)) + } -var importOverwrite bool + return cmd +} func init() { - importDirCommand.Flags().BoolVar(&importOverwrite, "overwrite", false, "overwrite existing workspace files") - Cmd.AddCommand(importDirCommand) + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newImportDir()) + }) } diff --git a/cmd/workspace/workspace/overrides.go b/cmd/workspace/workspace/overrides.go index e1b97c5983..9cae5bef54 100644 --- a/cmd/workspace/workspace/overrides.go +++ b/cmd/workspace/workspace/overrides.go @@ -1,14 +1,25 @@ package workspace -import "github.com/databricks/cli/libs/cmdio" +import ( + "github.com/databricks/cli/libs/cmdio" + "github.com/databricks/databricks-sdk-go/service/workspace" + "github.com/spf13/cobra" +) -func init() { +func listOverride(listCmd *cobra.Command, listReq *workspace.ListWorkspaceRequest) { listReq.Path = "/" listCmd.Annotations["template"] = cmdio.Heredoc(` {{header "ID"}} {{header "Type"}} {{header "Language"}} {{header "Path"}} {{range .}}{{green "%d" .ObjectId}} {{blue "%s" .ObjectType}} {{cyan "%s" .Language}} {{.Path|cyan}} {{end}}`) +} +func exportOverride(exportCmd *cobra.Command, exportReq *workspace.ExportRequest) { // The export command prints the contents of the file to stdout by default. exportCmd.Annotations["template"] = `{{.Content | b64_decode}}` } + +func init() { + listOverrides = append(listOverrides, listOverride) + exportOverrides = append(exportOverrides, exportOverride) +} diff --git a/cmd/workspace/workspace/workspace.go b/cmd/workspace/workspace/workspace.go index ab9c6aec0f..153fffe431 100755 --- a/cmd/workspace/workspace/workspace.go +++ b/cmd/workspace/workspace/workspace.go @@ -3,8 +3,6 @@ package workspace import ( - "fmt" - "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/flags" @@ -12,36 +10,56 @@ import ( "github.com/spf13/cobra" ) -var Cmd = &cobra.Command{ - Use: "workspace", - Short: `The Workspace API allows you to list, import, export, and delete notebooks and folders.`, - Long: `The Workspace API allows you to list, import, export, and delete notebooks and +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var cmdOverrides []func(*cobra.Command) + +func New() *cobra.Command { + cmd := &cobra.Command{ + Use: "workspace", + Short: `The Workspace API allows you to list, import, export, and delete notebooks and folders.`, + Long: `The Workspace API allows you to list, import, export, and delete notebooks and folders. A notebook is a web-based interface to a document that contains runnable code, visualizations, and explanatory text.`, - Annotations: map[string]string{ - "package": "workspace", - }, + GroupID: "workspace", + Annotations: map[string]string{ + "package": "workspace", + }, + } + + // Apply optional overrides to this command. + for _, fn := range cmdOverrides { + fn(cmd) + } + + return cmd } // start delete command -var deleteReq workspace.Delete -var deleteJson flags.JsonFlag -func init() { - Cmd.AddCommand(deleteCmd) - // TODO: short flags - deleteCmd.Flags().Var(&deleteJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteOverrides []func( + *cobra.Command, + *workspace.Delete, +) - deleteCmd.Flags().BoolVar(&deleteReq.Recursive, "recursive", deleteReq.Recursive, `The flag that specifies whether to delete the object recursively.`) +func newDelete() *cobra.Command { + cmd := &cobra.Command{} -} + var deleteReq workspace.Delete + var deleteJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&deleteJson, "json", `either inline JSON string or @path/to/file.json with request body`) -var deleteCmd = &cobra.Command{ - Use: "delete PATH", - Short: `Delete a workspace object.`, - Long: `Delete a workspace object. + cmd.Flags().BoolVar(&deleteReq.Recursive, "recursive", deleteReq.Recursive, `The flag that specifies whether to delete the object recursively.`) + + cmd.Use = "delete PATH" + cmd.Short = `Delete a workspace object.` + cmd.Long = `Delete a workspace object. Deletes an object or a directory (and optionally recursively deletes all objects in the directory). * If path does not exist, this call returns an @@ -50,11 +68,20 @@ var deleteCmd = &cobra.Command{ DIRECTORY_NOT_EMPTY. Object deletion cannot be undone and deleting a directory recursively is not - atomic.`, + atomic.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -64,23 +91,6 @@ var deleteCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No PATH argument specified. Loading names for Workspace drop-down." - names, err := w.Workspace.ObjectInfoPathToObjectIdMap(ctx, workspace.ListWorkspaceRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Workspace drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The absolute path of the notebook or directory") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the absolute path of the notebook or directory") - } deleteReq.Path = args[0] } @@ -89,27 +99,47 @@ var deleteCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteOverrides { + fn(cmd, &deleteReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newDelete()) + }) } // start export command -var exportReq workspace.ExportRequest -func init() { - Cmd.AddCommand(exportCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var exportOverrides []func( + *cobra.Command, + *workspace.ExportRequest, +) - exportCmd.Flags().Var(&exportReq.Format, "format", `This specifies the format of the exported file.`) +func newExport() *cobra.Command { + cmd := &cobra.Command{} -} + var exportReq workspace.ExportRequest + + // TODO: short flags + + cmd.Flags().Var(&exportReq.Format, "format", `This specifies the format of the exported file.`) -var exportCmd = &cobra.Command{ - Use: "export PATH", - Short: `Export a workspace object.`, - Long: `Export a workspace object. + cmd.Use = "export PATH" + cmd.Short = `Export a workspace object.` + cmd.Long = `Export a workspace object. Exports an object or the contents of an entire directory. @@ -118,31 +148,20 @@ var exportCmd = &cobra.Command{ If the exported data would exceed size limit, this call returns MAX_NOTEBOOK_SIZE_EXCEEDED. Currently, this API does not support exporting a - library.`, + library.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + return check(cmd, args) + } - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No PATH argument specified. Loading names for Workspace drop-down." - names, err := w.Workspace.ObjectInfoPathToObjectIdMap(ctx, workspace.ListWorkspaceRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Workspace drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The absolute path of the object or directory") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the absolute path of the object or directory") - } exportReq.Path = args[0] response, err := w.Workspace.Export(ctx, exportReq) @@ -150,36 +169,58 @@ var exportCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range exportOverrides { + fn(cmd, &exportReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newExport()) + }) } // start get-status command -var getStatusReq workspace.GetStatusRequest -func init() { - Cmd.AddCommand(getStatusCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getStatusOverrides []func( + *cobra.Command, + *workspace.GetStatusRequest, +) -} +func newGetStatus() *cobra.Command { + cmd := &cobra.Command{} + + var getStatusReq workspace.GetStatusRequest + + // TODO: short flags -var getStatusCmd = &cobra.Command{ - Use: "get-status PATH", - Short: `Get status.`, - Long: `Get status. + cmd.Use = "get-status PATH" + cmd.Short = `Get status.` + cmd.Long = `Get status. Gets the status of an object or a directory. If path does not exist, this - call returns an error RESOURCE_DOES_NOT_EXIST.`, + call returns an error RESOURCE_DOES_NOT_EXIST.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -190,48 +231,70 @@ var getStatusCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getStatusOverrides { + fn(cmd, &getStatusReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newGetStatus()) + }) } // start import command -var importReq workspace.Import -var importJson flags.JsonFlag -func init() { - Cmd.AddCommand(importCmd) - // TODO: short flags - importCmd.Flags().Var(&importJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var importOverrides []func( + *cobra.Command, + *workspace.Import, +) - importCmd.Flags().StringVar(&importReq.Content, "content", importReq.Content, `The base64-encoded content.`) - importCmd.Flags().Var(&importReq.Format, "format", `This specifies the format of the file to be imported.`) - importCmd.Flags().Var(&importReq.Language, "language", `The language of the object.`) - importCmd.Flags().BoolVar(&importReq.Overwrite, "overwrite", importReq.Overwrite, `The flag that specifies whether to overwrite existing object.`) +func newImport() *cobra.Command { + cmd := &cobra.Command{} -} + var importReq workspace.Import + var importJson flags.JsonFlag + + // TODO: short flags + cmd.Flags().Var(&importJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&importReq.Content, "content", importReq.Content, `The base64-encoded content.`) + cmd.Flags().Var(&importReq.Format, "format", `This specifies the format of the file to be imported.`) + cmd.Flags().Var(&importReq.Language, "language", `The language of the object.`) + cmd.Flags().BoolVar(&importReq.Overwrite, "overwrite", importReq.Overwrite, `The flag that specifies whether to overwrite existing object.`) -var importCmd = &cobra.Command{ - Use: "import PATH", - Short: `Import a workspace object.`, - Long: `Import a workspace object. + cmd.Use = "import PATH" + cmd.Short = `Import a workspace object.` + cmd.Long = `Import a workspace object. Imports a workspace object (for example, a notebook or file) or the contents of an entire directory. If path already exists and overwrite is set to false, this call returns an error RESOURCE_ALREADY_EXISTS. One can only - use DBC format to import a directory.`, + use DBC format to import a directory.` - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -249,39 +312,61 @@ var importCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range importOverrides { + fn(cmd, &importReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newImport()) + }) } // start list command -var listReq workspace.ListWorkspaceRequest -func init() { - Cmd.AddCommand(listCmd) - // TODO: short flags +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listOverrides []func( + *cobra.Command, + *workspace.ListWorkspaceRequest, +) - listCmd.Flags().IntVar(&listReq.NotebooksModifiedAfter, "notebooks-modified-after", listReq.NotebooksModifiedAfter, `UTC timestamp in milliseconds.`) +func newList() *cobra.Command { + cmd := &cobra.Command{} -} + var listReq workspace.ListWorkspaceRequest + + // TODO: short flags -var listCmd = &cobra.Command{ - Use: "list PATH", - Short: `List contents.`, - Long: `List contents. + cmd.Flags().IntVar(&listReq.NotebooksModifiedAfter, "notebooks-modified-after", listReq.NotebooksModifiedAfter, `UTC timestamp in milliseconds.`) + + cmd.Use = "list PATH" + cmd.Short = `List contents.` + cmd.Long = `List contents. Lists the contents of a directory, or the object if it is not a directory. If the input path does not exist, this call returns an error - RESOURCE_DOES_NOT_EXIST.`, + RESOURCE_DOES_NOT_EXIST.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - Args: func(cmd *cobra.Command, args []string) error { + cmd.Args = func(cmd *cobra.Command, args []string) error { check := cobra.ExactArgs(1) return check(cmd, args) - }, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -292,38 +377,67 @@ var listCmd = &cobra.Command{ return err } return cmdio.Render(ctx, response) - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listOverrides { + fn(cmd, &listReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newList()) + }) } // start mkdirs command -var mkdirsReq workspace.Mkdirs -var mkdirsJson flags.JsonFlag -func init() { - Cmd.AddCommand(mkdirsCmd) - // TODO: short flags - mkdirsCmd.Flags().Var(&mkdirsJson, "json", `either inline JSON string or @path/to/file.json with request body`) +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var mkdirsOverrides []func( + *cobra.Command, + *workspace.Mkdirs, +) -} +func newMkdirs() *cobra.Command { + cmd := &cobra.Command{} + + var mkdirsReq workspace.Mkdirs + var mkdirsJson flags.JsonFlag -var mkdirsCmd = &cobra.Command{ - Use: "mkdirs PATH", - Short: `Create a directory.`, - Long: `Create a directory. + // TODO: short flags + cmd.Flags().Var(&mkdirsJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "mkdirs PATH" + cmd.Short = `Create a directory.` + cmd.Long = `Create a directory. Creates the specified directory (and necessary parent directories if they do not exist). If there is an object (not a directory) at any prefix of the input path, this call returns an error RESOURCE_ALREADY_EXISTS. Note that if this operation fails it may have succeeded in creating some of - the necessary parent directories.`, + the necessary parent directories.` + + cmd.Annotations = make(map[string]string) - Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, - RunE: func(cmd *cobra.Command, args []string) (err error) { + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := cobra.ExactArgs(1) + if cmd.Flags().Changed("json") { + check = cobra.ExactArgs(0) + } + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -333,23 +447,6 @@ var mkdirsCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - promptSpinner := cmdio.Spinner(ctx) - promptSpinner <- "No PATH argument specified. Loading names for Workspace drop-down." - names, err := w.Workspace.ObjectInfoPathToObjectIdMap(ctx, workspace.ListWorkspaceRequest{}) - close(promptSpinner) - if err != nil { - return fmt.Errorf("failed to load names for Workspace drop-down. Please manually specify required arguments. Original error: %w", err) - } - id, err := cmdio.Select(ctx, names, "The absolute path of the directory") - if err != nil { - return err - } - args = append(args, id) - } - if len(args) != 1 { - return fmt.Errorf("expected to have the absolute path of the directory") - } mkdirsReq.Path = args[0] } @@ -358,10 +455,24 @@ var mkdirsCmd = &cobra.Command{ return err } return nil - }, + } + // Disable completions since they are not applicable. // Can be overridden by manual implementation in `override.go`. - ValidArgsFunction: cobra.NoFileCompletions, + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range mkdirsOverrides { + fn(cmd, &mkdirsReq) + } + + return cmd +} + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + cmd.AddCommand(newMkdirs()) + }) } // end service Workspace diff --git a/internal/helpers.go b/internal/helpers.go index 449b6d9aba..194f0eee4d 100644 --- a/internal/helpers.go +++ b/internal/helpers.go @@ -15,7 +15,7 @@ import ( "testing" "time" - "github.com/databricks/cli/cmd/root" + "github.com/databricks/cli/cmd" _ "github.com/databricks/cli/cmd/version" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -117,7 +117,7 @@ func (t *cobraTestRunner) RunBackground() { var stdoutW, stderrW io.WriteCloser stdoutR, stdoutW = io.Pipe() stderrR, stderrW = io.Pipe() - root := root.RootCmd + root := cmd.New() root.SetOut(stdoutW) root.SetErr(stderrW) root.SetArgs(t.args) diff --git a/main.go b/main.go index 959c9b2958..414e42d0b6 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "github.com/databricks/cli/cmd" _ "github.com/databricks/cli/cmd/account" _ "github.com/databricks/cli/cmd/api" _ "github.com/databricks/cli/cmd/auth" @@ -15,5 +16,5 @@ import ( ) func main() { - root.Execute() + root.Execute(cmd.New()) } diff --git a/main_test.go b/main_test.go index 4c7a8ebc39..6a5d194484 100644 --- a/main_test.go +++ b/main_test.go @@ -3,7 +3,7 @@ package main import ( "testing" - "github.com/databricks/cli/cmd/root" + "github.com/databricks/cli/cmd" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" ) @@ -15,7 +15,7 @@ func TestCommandsDontUseUnderscoreInName(t *testing.T) { // This test lives in the main package because this is where // all commands are imported. // - queue := []*cobra.Command{root.RootCmd} + queue := []*cobra.Command{cmd.New()} for len(queue) > 0 { cmd := queue[0] assert.NotContains(t, cmd.Name(), "_")