diff --git a/.codegen/service.go.tmpl b/.codegen/service.go.tmpl index d098432b68..16c7dc9769 100644 --- a/.codegen/service.go.tmpl +++ b/.codegen/service.go.tmpl @@ -56,6 +56,7 @@ func init() { {{else if .Entity.IsAny }}// TODO: any: {{.Name}} {{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 "`"}}`) {{end}} @@ -129,35 +130,38 @@ var {{.CamelName}}Cmd = &cobra.Command{ } {{end}} {{if $wait -}} + wait, err := {{if .Service.IsAccounts}}a{{else}}w{{end}}.{{.Service.PascalName}}.{{.PascalName}}(ctx{{if .Request}}, {{.CamelName}}Req{{end}}) + if err != nil { + return err + } if {{.CamelName}}SkipWait { - {{template "method-call" .}} + {{if .Response -}} + return cmdio.Render(ctx, wait.Response) + {{- else -}} + return nil + {{- end}} } spinner := cmdio.Spinner(ctx) - info, err := {{if .Service.IsAccounts}}a{{else}}w{{end}}.{{.Service.PascalName}}.{{.PascalName}}AndWait(ctx{{if .Request}}, {{.CamelName}}Req{{end}}, - retries.Timeout[{{.Service.Package.Name}}.{{.Wait.Poll.Response.PascalName}}]({{.CamelName}}Timeout), - func(i *retries.Info[{{.Service.Package.Name}}.{{.Wait.Poll.Response.PascalName}}]) { - if i.Info == nil { - return - } - {{if .Wait.MessagePath -}} - {{if .Wait.ComplexMessagePath -}} - if i.Info.{{.Wait.MessagePathHead.PascalName}} == nil { - return - } - status := i.Info{{range .Wait.StatusPath}}.{{.PascalName}}{{end}} - statusMessage := fmt.Sprintf("current status: %s", status) - if i.Info.{{.Wait.MessagePathHead.PascalName}} != nil { - statusMessage = i.Info{{range .Wait.MessagePath}}.{{.PascalName}}{{end}} - } - {{- else -}} - statusMessage := i.Info{{range .Wait.MessagePath}}.{{.PascalName}}{{end}} - {{- end}} - {{- else -}} - status := i.Info{{range .Wait.StatusPath}}.{{.PascalName}}{{end}} - statusMessage := fmt.Sprintf("current status: %s", status) - {{- end}} - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *{{.Service.Package.Name}}.{{.Wait.Poll.Response.PascalName}}) { + {{if .Wait.MessagePath -}} + {{if .Wait.ComplexMessagePath -}} + if i.{{.Wait.MessagePathHead.PascalName}} == nil { + return + } + status := i{{range .Wait.StatusPath}}.{{.PascalName}}{{end}} + statusMessage := fmt.Sprintf("current status: %s", status) + if i.{{.Wait.MessagePathHead.PascalName}} != nil { + statusMessage = i{{range .Wait.MessagePath}}.{{.PascalName}}{{end}} + } + {{- else -}} + statusMessage := i{{range .Wait.MessagePath}}.{{.PascalName}}{{end}} + {{- end}} + {{- else -}} + status := i{{range .Wait.StatusPath}}.{{.PascalName}}{{end}} + statusMessage := fmt.Sprintf("current status: %s", status) + {{- end}} + spinner <- statusMessage + }).GetWithTimeout({{.CamelName}}Timeout) close(spinner) if err != nil { return err diff --git a/.gitattributes b/.gitattributes index 6afe6939f9..8b95da2070 100755 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ +cmd/account/access-control/access-control.go linguist-generated=true cmd/account/billable-usage/billable-usage.go linguist-generated=true cmd/account/budgets/budgets.go linguist-generated=true cmd/account/cmd.go linguist-generated=true @@ -15,6 +16,7 @@ cmd/account/private-access/private-access.go linguist-generated=true cmd/account/published-app-integration/published-app-integration.go linguist-generated=true cmd/account/service-principal-secrets/service-principal-secrets.go linguist-generated=true cmd/account/service-principals/service-principals.go linguist-generated=true +cmd/account/settings/settings.go linguist-generated=true cmd/account/storage-credentials/storage-credentials.go linguist-generated=true cmd/account/storage/storage.go linguist-generated=true cmd/account/users/users.go linguist-generated=true @@ -26,6 +28,7 @@ cmd/workspace/catalogs/catalogs.go linguist-generated=true cmd/workspace/cluster-policies/cluster-policies.go linguist-generated=true cmd/workspace/clusters/clusters.go linguist-generated=true cmd/workspace/cmd.go linguist-generated=true +cmd/workspace/connections/connections.go linguist-generated=true cmd/workspace/current-user/current-user.go linguist-generated=true cmd/workspace/dashboards/dashboards.go linguist-generated=true cmd/workspace/data-sources/data-sources.go linguist-generated=true @@ -58,6 +61,7 @@ cmd/workspace/service-principals/service-principals.go linguist-generated=true cmd/workspace/serving-endpoints/serving-endpoints.go linguist-generated=true cmd/workspace/shares/shares.go linguist-generated=true cmd/workspace/storage-credentials/storage-credentials.go linguist-generated=true +cmd/workspace/system-schemas/system-schemas.go linguist-generated=true cmd/workspace/table-constraints/table-constraints.go linguist-generated=true cmd/workspace/tables/tables.go linguist-generated=true cmd/workspace/token-management/token-management.go linguist-generated=true diff --git a/bundle/run/job.go b/bundle/run/job.go index eeb8568909..b5ada9461e 100644 --- a/bundle/run/job.go +++ b/bundle/run/job.go @@ -12,7 +12,6 @@ import ( "github.com/databricks/cli/bundle/run/progress" "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/log" - "github.com/databricks/databricks-sdk-go/retries" "github.com/databricks/databricks-sdk-go/service/jobs" "github.com/fatih/color" flag "github.com/spf13/pflag" @@ -145,27 +144,17 @@ func (r *jobRunner) logFailedTasks(ctx context.Context, runId int64) { } } -func pullRunIdCallback(runId *int64) func(info *retries.Info[jobs.Run]) { - return func(info *retries.Info[jobs.Run]) { - i := info.Info - if i == nil { - return - } - +func pullRunIdCallback(runId *int64) func(info *jobs.Run) { + return func(i *jobs.Run) { if *runId == 0 { *runId = i.RunId } } } -func logDebugCallback(ctx context.Context, runId *int64) func(info *retries.Info[jobs.Run]) { +func logDebugCallback(ctx context.Context, runId *int64) func(info *jobs.Run) { var prevState *jobs.RunState - return func(info *retries.Info[jobs.Run]) { - i := info.Info - if i == nil { - return - } - + return func(i *jobs.Run) { state := i.State if state == nil { return @@ -173,23 +162,18 @@ func logDebugCallback(ctx context.Context, runId *int64) func(info *retries.Info // Log the job run URL as soon as it is available. if prevState == nil { - log.Infof(ctx, "Run available at %s", info.Info.RunPageUrl) + log.Infof(ctx, "Run available at %s", i.RunPageUrl) } if prevState == nil || prevState.LifeCycleState != state.LifeCycleState { - log.Infof(ctx, "Run status: %s", info.Info.State.LifeCycleState) + log.Infof(ctx, "Run status: %s", i.State.LifeCycleState) prevState = state } } } -func logProgressCallback(ctx context.Context, progressLogger *cmdio.Logger) func(info *retries.Info[jobs.Run]) { +func logProgressCallback(ctx context.Context, progressLogger *cmdio.Logger) func(info *jobs.Run) { var prevState *jobs.RunState - return func(info *retries.Info[jobs.Run]) { - i := info.Info - if i == nil { - return - } - + return func(i *jobs.Run) { state := i.State if state == nil { return @@ -255,8 +239,15 @@ func (r *jobRunner) Run(ctx context.Context, opts *Options) (output.RunOutput, e } logProgress := logProgressCallback(ctx, progressLogger) - run, err := w.Jobs.RunNowAndWait(ctx, *req, - retries.Timeout[jobs.Run](jobRunTimeout), pullRunId, logDebug, logProgress) + waiter, err := w.Jobs.RunNow(ctx, *req) + if err != nil { + return nil, fmt.Errorf("cannot start job") + } + run, err := waiter.OnProgress(func(r *jobs.Run) { + pullRunId(r) + logDebug(r) + logProgress(r) + }).GetWithTimeout(jobRunTimeout) if err != nil && runId != nil { r.logFailedTasks(ctx, *runId) } diff --git a/cmd/account/access-control/access-control.go b/cmd/account/access-control/access-control.go new file mode 100755 index 0000000000..ce695a9bb2 --- /dev/null +++ b/cmd/account/access-control/access-control.go @@ -0,0 +1,172 @@ +// Code generated from OpenAPI specs by Databricks SDK Generator. DO NOT EDIT. + +package access_control + +import ( + "fmt" + + "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/iam" + "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 + 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.`, +} + +// start get command + +var getReq iam.GetAccountAccessControlRequest +var getJson flags.JsonFlag + +func init() { + Cmd.AddCommand(getCmd) + // TODO: short flags + getCmd.Flags().Var(&getJson, "json", `either inline JSON string or @path/to/file.json with request body`) + +} + +var getCmd = &cobra.Command{ + Use: "get NAME ETAG", + Short: `Get a rule set.`, + 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.`, + + 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.MustAccountClient, + RunE: func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + a := root.AccountClient(ctx) + if cmd.Flags().Changed("json") { + err = getJson.Unmarshal(&getReq) + if err != nil { + return err + } + } else { + getReq.Name = args[0] + getReq.Etag = args[1] + } + + response, err := a.AccessControl.Get(ctx, getReq) + if err != nil { + return err + } + return cmdio.Render(ctx, response) + }, +} + +// start list command + +var listReq iam.ListAccountAccessControlRequest +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`) + +} + +var listCmd = &cobra.Command{ + Use: "list NAME", + Short: `List assignable roles on a resource.`, + Long: `List assignable roles on 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.`, + + Annotations: map[string]string{}, + 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) { + ctx := cmd.Context() + a := root.AccountClient(ctx) + if cmd.Flags().Changed("json") { + err = listJson.Unmarshal(&listReq) + if err != nil { + return err + } + } else { + listReq.Name = args[0] + } + + response, err := a.AccessControl.List(ctx, listReq) + if err != nil { + return err + } + return cmdio.Render(ctx, response) + }, +} + +// start update command + +var updateReq iam.UpdateRuleSetRequest +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`) + +} + +var updateCmd = &cobra.Command{ + Use: "update", + Short: `Update a rule set.`, + 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.`, + + Annotations: map[string]string{}, + PreRunE: root.MustAccountClient, + RunE: func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + a := root.AccountClient(ctx) + if cmd.Flags().Changed("json") { + err = updateJson.Unmarshal(&updateReq) + if err != nil { + return err + } + } else { + updateReq.Name = args[0] + _, err = fmt.Sscan(args[1], &updateReq.RuleSet) + if err != nil { + return fmt.Errorf("invalid RULE_SET: %s", args[1]) + } + updateReq.Etag = args[2] + } + + response, err := a.AccessControl.Update(ctx, updateReq) + if err != nil { + return err + } + return cmdio.Render(ctx, response) + }, +} + +// end service AccountAccessControl diff --git a/cmd/account/cmd.go b/cmd/account/cmd.go index b392aa38fb..9fc5c36691 100644 --- a/cmd/account/cmd.go +++ b/cmd/account/cmd.go @@ -6,6 +6,7 @@ import ( "github.com/databricks/cli/cmd/root" "github.com/spf13/cobra" + account_access_control "github.com/databricks/cli/cmd/account/access-control" billable_usage "github.com/databricks/cli/cmd/account/billable-usage" budgets "github.com/databricks/cli/cmd/account/budgets" credentials "github.com/databricks/cli/cmd/account/credentials" @@ -22,6 +23,7 @@ import ( published_app_integration "github.com/databricks/cli/cmd/account/published-app-integration" service_principal_secrets "github.com/databricks/cli/cmd/account/service-principal-secrets" account_service_principals "github.com/databricks/cli/cmd/account/service-principals" + account_settings "github.com/databricks/cli/cmd/account/settings" storage "github.com/databricks/cli/cmd/account/storage" account_storage_credentials "github.com/databricks/cli/cmd/account/storage-credentials" account_users "github.com/databricks/cli/cmd/account/users" @@ -38,6 +40,7 @@ var accountCmd = &cobra.Command{ func init() { root.RootCmd.AddCommand(accountCmd) + accountCmd.AddCommand(account_access_control.Cmd) accountCmd.AddCommand(billable_usage.Cmd) accountCmd.AddCommand(budgets.Cmd) accountCmd.AddCommand(credentials.Cmd) @@ -54,6 +57,7 @@ func init() { 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) diff --git a/cmd/account/metastore-assignments/metastore-assignments.go b/cmd/account/metastore-assignments/metastore-assignments.go index 98846685d6..22b4091dbf 100755 --- a/cmd/account/metastore-assignments/metastore-assignments.go +++ b/cmd/account/metastore-assignments/metastore-assignments.go @@ -20,7 +20,7 @@ var Cmd = &cobra.Command{ // start create command -var createReq catalog.CreateMetastoreAssignment +var createReq catalog.AccountsCreateMetastoreAssignment var createJson flags.JsonFlag func init() { @@ -28,18 +28,21 @@ func init() { // TODO: short flags createCmd.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 METASTORE_ID DEFAULT_CATALOG_NAME WORKSPACE_ID", + Use: "create WORKSPACE_ID METASTORE_ID", Short: `Assigns a workspace to a metastore.`, Long: `Assigns a workspace to a metastore. - Creates an assignment to a metastore for a workspace`, + 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.`, Annotations: map[string]string{}, Args: func(cmd *cobra.Command, args []string) error { - check := cobra.ExactArgs(3) + check := cobra.ExactArgs(2) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } @@ -55,12 +58,11 @@ var createCmd = &cobra.Command{ return err } } else { - createReq.MetastoreId = args[0] - createReq.DefaultCatalogName = args[1] - _, err = fmt.Sscan(args[2], &createReq.WorkspaceId) + _, err = fmt.Sscan(args[0], &createReq.WorkspaceId) if err != nil { - return fmt.Errorf("invalid WORKSPACE_ID: %s", args[2]) + return fmt.Errorf("invalid WORKSPACE_ID: %s", args[0]) } + createReq.MetastoreId = args[1] } response, err := a.MetastoreAssignments.Create(ctx, createReq) @@ -89,7 +91,8 @@ var deleteCmd = &cobra.Command{ Long: `Delete a metastore assignment. Deletes a metastore assignment to a workspace, leaving the workspace with no - metastore.`, + metastore. Please add a header X-Databricks-Account-Console-API-Version: 2.0 + to access this API.`, Annotations: map[string]string{}, Args: func(cmd *cobra.Command, args []string) error { @@ -144,7 +147,8 @@ var getCmd = &cobra.Command{ 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.`, + 404 returned. Please add a header X-Databricks-Account-Console-API-Version: + 2.0 to access this API.`, Annotations: map[string]string{}, Args: func(cmd *cobra.Command, args []string) error { @@ -196,7 +200,8 @@ var listCmd = &cobra.Command{ Long: `Get all workspaces assigned to a metastore. Gets a list of all Databricks workspace IDs that have been assigned to given - metastore.`, + metastore. Please add a header X-Databricks-Account-Console-API-Version: 2.0 + to access this API`, Annotations: map[string]string{}, Args: func(cmd *cobra.Command, args []string) error { @@ -229,7 +234,7 @@ var listCmd = &cobra.Command{ // start update command -var updateReq catalog.UpdateMetastoreAssignment +var updateReq catalog.AccountsUpdateMetastoreAssignment var updateJson flags.JsonFlag func init() { @@ -237,8 +242,7 @@ func init() { // TODO: short flags updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) - updateCmd.Flags().StringVar(&updateReq.DefaultCatalogName, "default-catalog-name", updateReq.DefaultCatalogName, `The name of the default catalog for the metastore.`) - updateCmd.Flags().StringVar(&updateReq.MetastoreId, "metastore-id", updateReq.MetastoreId, `The unique ID of the metastore.`) + // TODO: complex arg: metastore_assignment } @@ -248,7 +252,8 @@ var updateCmd = &cobra.Command{ 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`, + default catalog may be updated. Please add a header + X-Databricks-Account-Console-API-Version: 2.0 to access this API.`, Annotations: map[string]string{}, Args: func(cmd *cobra.Command, args []string) error { diff --git a/cmd/account/metastores/metastores.go b/cmd/account/metastores/metastores.go index 20072f6c95..a828d605a0 100755 --- a/cmd/account/metastores/metastores.go +++ b/cmd/account/metastores/metastores.go @@ -19,7 +19,7 @@ var Cmd = &cobra.Command{ // start create command -var createReq catalog.CreateMetastore +var createReq catalog.AccountsCreateMetastore var createJson flags.JsonFlag func init() { @@ -27,20 +27,21 @@ func init() { // TODO: short flags createCmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) - createCmd.Flags().StringVar(&createReq.Region, "region", createReq.Region, `Cloud region which the metastore serves (e.g., us-west-2, westus).`) + // TODO: complex arg: metastore_info } var createCmd = &cobra.Command{ - Use: "create NAME STORAGE_ROOT", + Use: "create", Short: `Create metastore.`, Long: `Create metastore. - Creates a Unity Catalog metastore.`, + Creates a Unity Catalog metastore. Please add a header + X-Databricks-Account-Console-API-Version: 2.0 to access this API.`, Annotations: map[string]string{}, Args: func(cmd *cobra.Command, args []string) error { - check := cobra.ExactArgs(2) + check := cobra.ExactArgs(0) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } @@ -56,8 +57,6 @@ var createCmd = &cobra.Command{ return err } } else { - createReq.Name = args[0] - createReq.StorageRoot = args[1] } response, err := a.Metastores.Create(ctx, createReq) @@ -85,7 +84,8 @@ var deleteCmd = &cobra.Command{ Short: `Delete a metastore.`, Long: `Delete a metastore. - Deletes a Unity Catalog metastore for an account, both specified by ID.`, + 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.`, Annotations: map[string]string{}, Args: func(cmd *cobra.Command, args []string) error { @@ -133,7 +133,8 @@ var getCmd = &cobra.Command{ Short: `Get a metastore.`, Long: `Get a metastore. - Gets a Unity Catalog metastore from an account, both specified by ID.`, + 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.`, Annotations: map[string]string{}, Args: func(cmd *cobra.Command, args []string) error { @@ -176,7 +177,9 @@ var listCmd = &cobra.Command{ Short: `Get all metastores associated with an account.`, Long: `Get all metastores associated with an account. - Gets all Unity Catalog metastores associated with an account specified by ID.`, + 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.`, Annotations: map[string]string{}, PreRunE: root.MustAccountClient, @@ -193,7 +196,7 @@ var listCmd = &cobra.Command{ // start update command -var updateReq catalog.UpdateMetastore +var updateReq catalog.AccountsUpdateMetastore var updateJson flags.JsonFlag func init() { @@ -201,13 +204,7 @@ func init() { // TODO: short flags updateCmd.Flags().Var(&updateJson, "json", `either inline JSON string or @path/to/file.json with request body`) - 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.`) + // TODO: complex arg: metastore_info } @@ -216,7 +213,8 @@ var updateCmd = &cobra.Command{ Short: `Update a metastore.`, Long: `Update a metastore. - Updates an existing Unity Catalog metastore.`, + Updates an existing Unity Catalog metastore. Please add a header + X-Databricks-Account-Console-API-Version: 2.0 to access this API.`, Annotations: map[string]string{}, Args: func(cmd *cobra.Command, args []string) error { diff --git a/cmd/account/settings/settings.go b/cmd/account/settings/settings.go new file mode 100755 index 0000000000..2c689be734 --- /dev/null +++ b/cmd/account/settings/settings.go @@ -0,0 +1,68 @@ +// Code generated from OpenAPI specs by Databricks SDK Generator. DO NOT EDIT. + +package settings + +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/service/settings" + "github.com/spf13/cobra" +) + +var Cmd = &cobra.Command{ + Use: "settings", + Short: `TBD.`, + Long: `TBD`, +} + +// start read-personal-compute-setting command + +var readPersonalComputeSettingReq settings.ReadPersonalComputeSettingRequest +var readPersonalComputeSettingJson flags.JsonFlag + +func init() { + Cmd.AddCommand(readPersonalComputeSettingCmd) + // TODO: short flags + readPersonalComputeSettingCmd.Flags().Var(&readPersonalComputeSettingJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + readPersonalComputeSettingCmd.Flags().StringVar(&readPersonalComputeSettingReq.Etag, "etag", readPersonalComputeSettingReq.Etag, `TBD.`) + +} + +var readPersonalComputeSettingCmd = &cobra.Command{ + Use: "read-personal-compute-setting", + Short: `Get Personal Compute setting.`, + Long: `Get Personal Compute setting. + + TBD`, + + Annotations: map[string]string{}, + 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) { + ctx := cmd.Context() + a := root.AccountClient(ctx) + if cmd.Flags().Changed("json") { + err = readPersonalComputeSettingJson.Unmarshal(&readPersonalComputeSettingReq) + if err != nil { + return err + } + } else { + } + + response, err := a.Settings.ReadPersonalComputeSetting(ctx, readPersonalComputeSettingReq) + if err != nil { + return err + } + return cmdio.Render(ctx, response) + }, +} + +// end service AccountSettings diff --git a/cmd/account/storage-credentials/storage-credentials.go b/cmd/account/storage-credentials/storage-credentials.go index 8c633e24fb..72e1875003 100755 --- a/cmd/account/storage-credentials/storage-credentials.go +++ b/cmd/account/storage-credentials/storage-credentials.go @@ -18,7 +18,7 @@ var Cmd = &cobra.Command{ // start create command -var createReq catalog.CreateStorageCredential +var createReq catalog.AccountsCreateStorageCredential var createJson flags.JsonFlag func init() { @@ -26,17 +26,12 @@ func init() { // TODO: short flags createCmd.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_service_principal - createCmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `Comment associated with the credential.`) - // TODO: complex arg: gcp_service_account_key - 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.`) + // TODO: complex arg: credential_info } var createCmd = &cobra.Command{ - Use: "create NAME METASTORE_ID", + Use: "create METASTORE_ID", Short: `Create a storage credential.`, Long: `Create a storage credential. @@ -50,7 +45,7 @@ var createCmd = &cobra.Command{ Annotations: map[string]string{}, Args: func(cmd *cobra.Command, args []string) error { - check := cobra.ExactArgs(2) + check := cobra.ExactArgs(1) if cmd.Flags().Changed("json") { check = cobra.ExactArgs(0) } @@ -66,8 +61,7 @@ var createCmd = &cobra.Command{ return err } } else { - createReq.Name = args[0] - createReq.MetastoreId = args[1] + createReq.MetastoreId = args[0] } response, err := a.StorageCredentials.Create(ctx, createReq) @@ -230,7 +224,7 @@ var listCmd = &cobra.Command{ // start update command -var updateReq catalog.UpdateStorageCredential +var updateReq catalog.AccountsUpdateStorageCredential var updateJson flags.JsonFlag func init() { @@ -238,15 +232,7 @@ func init() { // TODO: short flags updateCmd.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_service_principal - updateCmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `Comment associated with the credential.`) - updateCmd.Flags().BoolVar(&updateReq.Force, "force", updateReq.Force, `Force update even if there are dependent external locations or external tables.`) - // TODO: complex arg: gcp_service_account_key - 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.`) + // TODO: complex arg: credential_info } diff --git a/cmd/account/workspaces/workspaces.go b/cmd/account/workspaces/workspaces.go index ebe793cdd5..2e2dd0b9c1 100755 --- a/cmd/account/workspaces/workspaces.go +++ b/cmd/account/workspaces/workspaces.go @@ -9,7 +9,6 @@ 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/retries" "github.com/databricks/databricks-sdk-go/service/provisioning" "github.com/spf13/cobra" ) @@ -93,23 +92,18 @@ var createCmd = &cobra.Command{ createReq.WorkspaceName = args[0] } + wait, err := a.Workspaces.Create(ctx, createReq) + if err != nil { + return err + } if createSkipWait { - response, err := a.Workspaces.Create(ctx, createReq) - if err != nil { - return err - } - return cmdio.Render(ctx, response) + return cmdio.Render(ctx, wait.Response) } spinner := cmdio.Spinner(ctx) - info, err := a.Workspaces.CreateAndWait(ctx, createReq, - retries.Timeout[provisioning.Workspace](createTimeout), - func(i *retries.Info[provisioning.Workspace]) { - if i.Info == nil { - return - } - statusMessage := i.Info.WorkspaceStatusMessage - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *provisioning.Workspace) { + statusMessage := i.WorkspaceStatusMessage + spinner <- statusMessage + }).GetWithTimeout(createTimeout) close(spinner) if err != nil { return err @@ -466,23 +460,18 @@ var updateCmd = &cobra.Command{ } } + wait, err := a.Workspaces.Update(ctx, updateReq) + if err != nil { + return err + } if updateSkipWait { - err = a.Workspaces.Update(ctx, updateReq) - if err != nil { - return err - } return nil } spinner := cmdio.Spinner(ctx) - info, err := a.Workspaces.UpdateAndWait(ctx, updateReq, - retries.Timeout[provisioning.Workspace](updateTimeout), - func(i *retries.Info[provisioning.Workspace]) { - if i.Info == nil { - return - } - statusMessage := i.Info.WorkspaceStatusMessage - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *provisioning.Workspace) { + statusMessage := i.WorkspaceStatusMessage + spinner <- statusMessage + }).GetWithTimeout(updateTimeout) close(spinner) if err != nil { return err diff --git a/cmd/workspace/clusters/clusters.go b/cmd/workspace/clusters/clusters.go index 3a1eb6429e..f33914d773 100755 --- a/cmd/workspace/clusters/clusters.go +++ b/cmd/workspace/clusters/clusters.go @@ -9,7 +9,6 @@ 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/retries" "github.com/databricks/databricks-sdk-go/service/compute" "github.com/spf13/cobra" ) @@ -178,23 +177,18 @@ var createCmd = &cobra.Command{ createReq.SparkVersion = args[0] } + wait, err := w.Clusters.Create(ctx, createReq) + if err != nil { + return err + } if createSkipWait { - response, err := w.Clusters.Create(ctx, createReq) - if err != nil { - return err - } - return cmdio.Render(ctx, response) + return cmdio.Render(ctx, wait.Response) } spinner := cmdio.Spinner(ctx) - info, err := w.Clusters.CreateAndWait(ctx, createReq, - retries.Timeout[compute.ClusterInfo](createTimeout), - func(i *retries.Info[compute.ClusterInfo]) { - if i.Info == nil { - return - } - statusMessage := i.Info.StateMessage - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *compute.ClusterInfo) { + statusMessage := i.StateMessage + spinner <- statusMessage + }).GetWithTimeout(createTimeout) close(spinner) if err != nil { return err @@ -261,23 +255,18 @@ var deleteCmd = &cobra.Command{ deleteReq.ClusterId = args[0] } + wait, err := w.Clusters.Delete(ctx, deleteReq) + if err != nil { + return err + } if deleteSkipWait { - err = w.Clusters.Delete(ctx, deleteReq) - if err != nil { - return err - } return nil } spinner := cmdio.Spinner(ctx) - info, err := w.Clusters.DeleteAndWait(ctx, deleteReq, - retries.Timeout[compute.ClusterInfo](deleteTimeout), - func(i *retries.Info[compute.ClusterInfo]) { - if i.Info == nil { - return - } - statusMessage := i.Info.StateMessage - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *compute.ClusterInfo) { + statusMessage := i.StateMessage + spinner <- statusMessage + }).GetWithTimeout(deleteTimeout) close(spinner) if err != nil { return err @@ -310,6 +299,8 @@ func init() { 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.`) // TODO: map via StringToStringVar: custom_tags + editCmd.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.`) @@ -321,6 +312,7 @@ func init() { 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.`) // TODO: map via StringToStringVar: spark_conf // TODO: map via StringToStringVar: spark_env_vars // TODO: array: ssh_public_keys @@ -368,23 +360,18 @@ var editCmd = &cobra.Command{ editReq.SparkVersion = args[1] } + wait, err := w.Clusters.Edit(ctx, editReq) + if err != nil { + return err + } if editSkipWait { - err = w.Clusters.Edit(ctx, editReq) - if err != nil { - return err - } return nil } spinner := cmdio.Spinner(ctx) - info, err := w.Clusters.EditAndWait(ctx, editReq, - retries.Timeout[compute.ClusterInfo](editTimeout), - func(i *retries.Info[compute.ClusterInfo]) { - if i.Info == nil { - return - } - statusMessage := i.Info.StateMessage - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *compute.ClusterInfo) { + statusMessage := i.StateMessage + spinner <- statusMessage + }).GetWithTimeout(editTimeout) close(spinner) if err != nil { return err @@ -819,23 +806,18 @@ var resizeCmd = &cobra.Command{ resizeReq.ClusterId = args[0] } + wait, err := w.Clusters.Resize(ctx, resizeReq) + if err != nil { + return err + } if resizeSkipWait { - err = w.Clusters.Resize(ctx, resizeReq) - if err != nil { - return err - } return nil } spinner := cmdio.Spinner(ctx) - info, err := w.Clusters.ResizeAndWait(ctx, resizeReq, - retries.Timeout[compute.ClusterInfo](resizeTimeout), - func(i *retries.Info[compute.ClusterInfo]) { - if i.Info == nil { - return - } - statusMessage := i.Info.StateMessage - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *compute.ClusterInfo) { + statusMessage := i.StateMessage + spinner <- statusMessage + }).GetWithTimeout(resizeTimeout) close(spinner) if err != nil { return err @@ -902,23 +884,18 @@ var restartCmd = &cobra.Command{ restartReq.ClusterId = args[0] } + wait, err := w.Clusters.Restart(ctx, restartReq) + if err != nil { + return err + } if restartSkipWait { - err = w.Clusters.Restart(ctx, restartReq) - if err != nil { - return err - } return nil } spinner := cmdio.Spinner(ctx) - info, err := w.Clusters.RestartAndWait(ctx, restartReq, - retries.Timeout[compute.ClusterInfo](restartTimeout), - func(i *retries.Info[compute.ClusterInfo]) { - if i.Info == nil { - return - } - statusMessage := i.Info.StateMessage - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *compute.ClusterInfo) { + statusMessage := i.StateMessage + spinner <- statusMessage + }).GetWithTimeout(restartTimeout) close(spinner) if err != nil { return err @@ -1017,23 +994,18 @@ var startCmd = &cobra.Command{ startReq.ClusterId = args[0] } + wait, err := w.Clusters.Start(ctx, startReq) + if err != nil { + return err + } if startSkipWait { - err = w.Clusters.Start(ctx, startReq) - if err != nil { - return err - } return nil } spinner := cmdio.Spinner(ctx) - info, err := w.Clusters.StartAndWait(ctx, startReq, - retries.Timeout[compute.ClusterInfo](startTimeout), - func(i *retries.Info[compute.ClusterInfo]) { - if i.Info == nil { - return - } - statusMessage := i.Info.StateMessage - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *compute.ClusterInfo) { + statusMessage := i.StateMessage + spinner <- statusMessage + }).GetWithTimeout(startTimeout) close(spinner) if err != nil { return err diff --git a/cmd/workspace/cmd.go b/cmd/workspace/cmd.go index 19b69035e0..4bd0eb0973 100755 --- a/cmd/workspace/cmd.go +++ b/cmd/workspace/cmd.go @@ -9,6 +9,7 @@ import ( catalogs "github.com/databricks/cli/cmd/workspace/catalogs" cluster_policies "github.com/databricks/cli/cmd/workspace/cluster-policies" clusters "github.com/databricks/cli/cmd/workspace/clusters" + connections "github.com/databricks/cli/cmd/workspace/connections" current_user "github.com/databricks/cli/cmd/workspace/current-user" dashboards "github.com/databricks/cli/cmd/workspace/dashboards" data_sources "github.com/databricks/cli/cmd/workspace/data-sources" @@ -41,6 +42,7 @@ import ( serving_endpoints "github.com/databricks/cli/cmd/workspace/serving-endpoints" shares "github.com/databricks/cli/cmd/workspace/shares" storage_credentials "github.com/databricks/cli/cmd/workspace/storage-credentials" + system_schemas "github.com/databricks/cli/cmd/workspace/system-schemas" table_constraints "github.com/databricks/cli/cmd/workspace/table-constraints" tables "github.com/databricks/cli/cmd/workspace/tables" token_management "github.com/databricks/cli/cmd/workspace/token-management" @@ -59,6 +61,7 @@ func init() { root.RootCmd.AddCommand(catalogs.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) @@ -91,6 +94,7 @@ func init() { 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) diff --git a/cmd/workspace/connections/connections.go b/cmd/workspace/connections/connections.go new file mode 100755 index 0000000000..6b0f11a635 --- /dev/null +++ b/cmd/workspace/connections/connections.go @@ -0,0 +1,278 @@ +// Code generated from OpenAPI specs by Databricks SDK Generator. DO NOT EDIT. + +package connections + +import ( + "fmt" + + "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/catalog" + "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. + + A connection is an abstraction of an external data source that can be + connected from Databricks Compute. Creating a connection object is the first + step to managing external data sources within Unity Catalog, with the second + step being creating a data object (catalog, schema, or table) using the + connection. Data objects derived from a connection can be written to or read + from similar to other Unity Catalog data objects based on cloud storage. Users + may create different types of connections with each connection having a unique + set of configuration options to support credential management and other + settings.`, +} + +// start create command + +var createReq catalog.CreateConnection +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`) + + 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.`) + // TODO: map via StringToStringVar: properties_kvpairs + createCmd.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. + + 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.`, + + Annotations: map[string]string{}, + PreRunE: root.MustWorkspaceClient, + 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) + if err != nil { + return err + } + } else { + createReq.Name = args[0] + _, err = fmt.Sscan(args[1], &createReq.ConnectionType) + if err != nil { + return fmt.Errorf("invalid CONNECTION_TYPE: %s", args[1]) + } + _, err = fmt.Sscan(args[2], &createReq.OptionsKvpairs) + if err != nil { + return fmt.Errorf("invalid OPTIONS_KVPAIRS: %s", args[2]) + } + } + + response, err := w.Connections.Create(ctx, createReq) + if err != nil { + return err + } + return cmdio.Render(ctx, response) + }, +} + +// start delete command + +var deleteReq catalog.DeleteConnectionRequest +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`) + +} + +var deleteCmd = &cobra.Command{ + Use: "delete NAME_ARG", + Short: `Delete a connection.`, + Long: `Delete a connection. + + Deletes the connection that matches the supplied name.`, + + Annotations: map[string]string{}, + PreRunE: root.MustWorkspaceClient, + RunE: func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := root.WorkspaceClient(ctx) + if cmd.Flags().Changed("json") { + err = deleteJson.Unmarshal(&deleteReq) + if err != nil { + return err + } + } else { + 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) + if err != nil { + return err + } + return nil + }, +} + +// start get command + +var getReq catalog.GetConnectionRequest +var getJson flags.JsonFlag + +func init() { + Cmd.AddCommand(getCmd) + // TODO: short flags + getCmd.Flags().Var(&getJson, "json", `either inline JSON string or @path/to/file.json with request body`) + +} + +var getCmd = &cobra.Command{ + Use: "get NAME_ARG", + Short: `Get a connection.`, + Long: `Get a connection. + + Gets a connection from it's name.`, + + Annotations: map[string]string{}, + PreRunE: root.MustWorkspaceClient, + RunE: func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := root.WorkspaceClient(ctx) + if cmd.Flags().Changed("json") { + err = getJson.Unmarshal(&getReq) + if err != nil { + return err + } + } else { + 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) + if err != nil { + return err + } + return cmdio.Render(ctx, response) + }, +} + +// start list command + +func init() { + Cmd.AddCommand(listCmd) + +} + +var listCmd = &cobra.Command{ + Use: "list", + Short: `List connections.`, + Long: `List connections. + + List all connections.`, + + Annotations: map[string]string{}, + PreRunE: root.MustWorkspaceClient, + RunE: func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := root.WorkspaceClient(ctx) + response, err := w.Connections.ListAll(ctx) + if err != nil { + return err + } + return cmdio.Render(ctx, response) + }, +} + +// 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`) + +} + +var updateCmd = &cobra.Command{ + Use: "update", + Short: `Update a connection.`, + Long: `Update a connection. + + Updates the connection that matches the supplied name.`, + + Annotations: map[string]string{}, + PreRunE: root.MustWorkspaceClient, + RunE: func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := root.WorkspaceClient(ctx) + if cmd.Flags().Changed("json") { + err = updateJson.Unmarshal(&updateReq) + if err != nil { + return err + } + } else { + updateReq.Name = args[0] + _, err = fmt.Sscan(args[1], &updateReq.OptionsKvpairs) + if err != nil { + return fmt.Errorf("invalid OPTIONS_KVPAIRS: %s", args[1]) + } + updateReq.NameArg = args[2] + } + + response, err := w.Connections.Update(ctx, updateReq) + if err != nil { + return err + } + return cmdio.Render(ctx, response) + }, +} + +// end service Connections diff --git a/cmd/workspace/functions/functions.go b/cmd/workspace/functions/functions.go index fb801f10f4..34800f3068 100755 --- a/cmd/workspace/functions/functions.go +++ b/cmd/workspace/functions/functions.go @@ -146,14 +146,7 @@ var deleteCmd = &cobra.Command{ its parent catalog and the **USE_SCHEMA** privilege on its parent schema`, Annotations: map[string]string{}, - 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, + PreRunE: root.MustWorkspaceClient, RunE: func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -163,6 +156,23 @@ var deleteCmd = &cobra.Command{ return err } } else { + 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] } @@ -200,14 +210,7 @@ var getCmd = &cobra.Command{ **EXECUTE** privilege on the function itself`, Annotations: map[string]string{}, - 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, + PreRunE: root.MustWorkspaceClient, RunE: func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -217,6 +220,23 @@ var getCmd = &cobra.Command{ return err } } else { + 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] } @@ -275,7 +295,7 @@ var listCmd = &cobra.Command{ listReq.SchemaName = args[1] } - response, err := w.Functions.List(ctx, listReq) + response, err := w.Functions.ListAll(ctx, listReq) if err != nil { return err } @@ -312,14 +332,7 @@ var updateCmd = &cobra.Command{ function's parent schema.`, Annotations: map[string]string{}, - 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, + PreRunE: root.MustWorkspaceClient, RunE: func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -329,6 +342,23 @@ var updateCmd = &cobra.Command{ return err } } else { + 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] } diff --git a/cmd/workspace/jobs/jobs.go b/cmd/workspace/jobs/jobs.go index 77eea56861..fd79ee869d 100755 --- a/cmd/workspace/jobs/jobs.go +++ b/cmd/workspace/jobs/jobs.go @@ -9,7 +9,6 @@ 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/retries" "github.com/databricks/databricks-sdk-go/service/jobs" "github.com/spf13/cobra" ) @@ -158,30 +157,25 @@ var cancelRunCmd = &cobra.Command{ } } + wait, err := w.Jobs.CancelRun(ctx, cancelRunReq) + if err != nil { + return err + } if cancelRunSkipWait { - err = w.Jobs.CancelRun(ctx, cancelRunReq) - if err != nil { - return err - } return nil } spinner := cmdio.Spinner(ctx) - info, err := w.Jobs.CancelRunAndWait(ctx, cancelRunReq, - retries.Timeout[jobs.Run](cancelRunTimeout), - func(i *retries.Info[jobs.Run]) { - if i.Info == nil { - return - } - if i.Info.State == nil { - return - } - status := i.Info.State.LifeCycleState - statusMessage := fmt.Sprintf("current status: %s", status) - if i.Info.State != nil { - statusMessage = i.Info.State.StateMessage - } - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *jobs.Run) { + if i.State == nil { + return + } + status := i.State.LifeCycleState + statusMessage := fmt.Sprintf("current status: %s", status) + if i.State != nil { + statusMessage = i.State.StateMessage + } + spinner <- statusMessage + }).GetWithTimeout(cancelRunTimeout) close(spinner) if err != nil { return err @@ -652,6 +646,7 @@ func init() { 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.`) } @@ -706,6 +701,7 @@ func init() { 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.`) @@ -819,30 +815,25 @@ var repairRunCmd = &cobra.Command{ } } + wait, err := w.Jobs.RepairRun(ctx, repairRunReq) + if err != nil { + return err + } if repairRunSkipWait { - response, err := w.Jobs.RepairRun(ctx, repairRunReq) - if err != nil { - return err - } - return cmdio.Render(ctx, response) + return cmdio.Render(ctx, wait.Response) } spinner := cmdio.Spinner(ctx) - info, err := w.Jobs.RepairRunAndWait(ctx, repairRunReq, - retries.Timeout[jobs.Run](repairRunTimeout), - func(i *retries.Info[jobs.Run]) { - if i.Info == nil { - return - } - if i.Info.State == nil { - return - } - status := i.Info.State.LifeCycleState - statusMessage := fmt.Sprintf("current status: %s", status) - if i.Info.State != nil { - statusMessage = i.Info.State.StateMessage - } - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *jobs.Run) { + if i.State == nil { + return + } + status := i.State.LifeCycleState + statusMessage := fmt.Sprintf("current status: %s", status) + if i.State != nil { + statusMessage = i.State.StateMessage + } + spinner <- statusMessage + }).GetWithTimeout(repairRunTimeout) close(spinner) if err != nil { return err @@ -968,30 +959,25 @@ var runNowCmd = &cobra.Command{ } } + wait, err := w.Jobs.RunNow(ctx, runNowReq) + if err != nil { + return err + } if runNowSkipWait { - response, err := w.Jobs.RunNow(ctx, runNowReq) - if err != nil { - return err - } - return cmdio.Render(ctx, response) + return cmdio.Render(ctx, wait.Response) } spinner := cmdio.Spinner(ctx) - info, err := w.Jobs.RunNowAndWait(ctx, runNowReq, - retries.Timeout[jobs.Run](runNowTimeout), - func(i *retries.Info[jobs.Run]) { - if i.Info == nil { - return - } - if i.Info.State == nil { - return - } - status := i.Info.State.LifeCycleState - statusMessage := fmt.Sprintf("current status: %s", status) - if i.Info.State != nil { - statusMessage = i.Info.State.StateMessage - } - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *jobs.Run) { + if i.State == nil { + return + } + status := i.State.LifeCycleState + statusMessage := fmt.Sprintf("current status: %s", status) + if i.State != nil { + statusMessage = i.State.StateMessage + } + spinner <- statusMessage + }).GetWithTimeout(runNowTimeout) close(spinner) if err != nil { return err @@ -1056,30 +1042,25 @@ var submitCmd = &cobra.Command{ } else { } + wait, err := w.Jobs.Submit(ctx, submitReq) + if err != nil { + return err + } if submitSkipWait { - response, err := w.Jobs.Submit(ctx, submitReq) - if err != nil { - return err - } - return cmdio.Render(ctx, response) + return cmdio.Render(ctx, wait.Response) } spinner := cmdio.Spinner(ctx) - info, err := w.Jobs.SubmitAndWait(ctx, submitReq, - retries.Timeout[jobs.Run](submitTimeout), - func(i *retries.Info[jobs.Run]) { - if i.Info == nil { - return - } - if i.Info.State == nil { - return - } - status := i.Info.State.LifeCycleState - statusMessage := fmt.Sprintf("current status: %s", status) - if i.Info.State != nil { - statusMessage = i.Info.State.StateMessage - } - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *jobs.Run) { + if i.State == nil { + return + } + status := i.State.LifeCycleState + statusMessage := fmt.Sprintf("current status: %s", status) + if i.State != nil { + statusMessage = i.State.StateMessage + } + spinner <- statusMessage + }).GetWithTimeout(submitTimeout) close(spinner) if err != nil { return err diff --git a/cmd/workspace/pipelines/pipelines.go b/cmd/workspace/pipelines/pipelines.go index 8ef29664fc..95d49db846 100755 --- a/cmd/workspace/pipelines/pipelines.go +++ b/cmd/workspace/pipelines/pipelines.go @@ -9,7 +9,6 @@ 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/retries" "github.com/databricks/databricks-sdk-go/service/pipelines" "github.com/spf13/cobra" ) @@ -500,23 +499,18 @@ var resetCmd = &cobra.Command{ resetReq.PipelineId = args[0] } + wait, err := w.Pipelines.Reset(ctx, resetReq) + if err != nil { + return err + } if resetSkipWait { - err = w.Pipelines.Reset(ctx, resetReq) - if err != nil { - return err - } return nil } spinner := cmdio.Spinner(ctx) - info, err := w.Pipelines.ResetAndWait(ctx, resetReq, - retries.Timeout[pipelines.GetPipelineResponse](resetTimeout), - func(i *retries.Info[pipelines.GetPipelineResponse]) { - if i.Info == nil { - return - } - statusMessage := i.Info.Cause - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *pipelines.GetPipelineResponse) { + statusMessage := i.Cause + spinner <- statusMessage + }).GetWithTimeout(resetTimeout) close(spinner) if err != nil { return err @@ -643,23 +637,18 @@ var stopCmd = &cobra.Command{ stopReq.PipelineId = args[0] } + wait, err := w.Pipelines.Stop(ctx, stopReq) + if err != nil { + return err + } if stopSkipWait { - err = w.Pipelines.Stop(ctx, stopReq) - if err != nil { - return err - } return nil } spinner := cmdio.Spinner(ctx) - info, err := w.Pipelines.StopAndWait(ctx, stopReq, - retries.Timeout[pipelines.GetPipelineResponse](stopTimeout), - func(i *retries.Info[pipelines.GetPipelineResponse]) { - if i.Info == nil { - return - } - statusMessage := i.Info.Cause - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *pipelines.GetPipelineResponse) { + statusMessage := i.Cause + spinner <- statusMessage + }).GetWithTimeout(stopTimeout) close(spinner) if err != nil { return err diff --git a/cmd/workspace/serving-endpoints/serving-endpoints.go b/cmd/workspace/serving-endpoints/serving-endpoints.go index 72dbd94c51..08c455f980 100755 --- a/cmd/workspace/serving-endpoints/serving-endpoints.go +++ b/cmd/workspace/serving-endpoints/serving-endpoints.go @@ -9,7 +9,6 @@ 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/retries" "github.com/databricks/databricks-sdk-go/service/serving" "github.com/spf13/cobra" ) @@ -122,24 +121,19 @@ var createCmd = &cobra.Command{ } } + wait, err := w.ServingEndpoints.Create(ctx, createReq) + if err != nil { + return err + } if createSkipWait { - response, err := w.ServingEndpoints.Create(ctx, createReq) - if err != nil { - return err - } - return cmdio.Render(ctx, response) + return cmdio.Render(ctx, wait.Response) } spinner := cmdio.Spinner(ctx) - info, err := w.ServingEndpoints.CreateAndWait(ctx, createReq, - retries.Timeout[serving.ServingEndpointDetailed](createTimeout), - func(i *retries.Info[serving.ServingEndpointDetailed]) { - if i.Info == nil { - return - } - status := i.Info.State.ConfigUpdate - statusMessage := fmt.Sprintf("current status: %s", status) - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *serving.ServingEndpointDetailed) { + status := i.State.ConfigUpdate + statusMessage := fmt.Sprintf("current status: %s", status) + spinner <- statusMessage + }).GetWithTimeout(createTimeout) close(spinner) if err != nil { return err @@ -309,7 +303,7 @@ var listCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) (err error) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) - response, err := w.ServingEndpoints.List(ctx) + response, err := w.ServingEndpoints.ListAll(ctx) if err != nil { return err } @@ -460,24 +454,19 @@ var updateConfigCmd = &cobra.Command{ updateConfigReq.Name = args[1] } + wait, err := w.ServingEndpoints.UpdateConfig(ctx, updateConfigReq) + if err != nil { + return err + } if updateConfigSkipWait { - response, err := w.ServingEndpoints.UpdateConfig(ctx, updateConfigReq) - if err != nil { - return err - } - return cmdio.Render(ctx, response) + return cmdio.Render(ctx, wait.Response) } spinner := cmdio.Spinner(ctx) - info, err := w.ServingEndpoints.UpdateConfigAndWait(ctx, updateConfigReq, - retries.Timeout[serving.ServingEndpointDetailed](updateConfigTimeout), - func(i *retries.Info[serving.ServingEndpointDetailed]) { - if i.Info == nil { - return - } - status := i.Info.State.ConfigUpdate - statusMessage := fmt.Sprintf("current status: %s", status) - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *serving.ServingEndpointDetailed) { + status := i.State.ConfigUpdate + statusMessage := fmt.Sprintf("current status: %s", status) + spinner <- statusMessage + }).GetWithTimeout(updateConfigTimeout) close(spinner) if err != nil { return err diff --git a/cmd/workspace/storage-credentials/storage-credentials.go b/cmd/workspace/storage-credentials/storage-credentials.go index 4ff2b1a3e0..3532999be9 100755 --- a/cmd/workspace/storage-credentials/storage-credentials.go +++ b/cmd/workspace/storage-credentials/storage-credentials.go @@ -41,9 +41,10 @@ func init() { createCmd.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.`) - // TODO: complex arg: gcp_service_account_key + // 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.`) @@ -56,14 +57,22 @@ var createCmd = &cobra.Command{ Creates a new storage credential. The request object is specific to the cloud: - * **AwsIamRole** for AWS credentials * **AzureServicePrincipal** for Azure - credentials * **GcpServiceAcountKey** for GCP credentials. + * **AwsIamRole** for AWS credentials. * **AzureServicePrincipal** for Azure + credentials. * **AzureManagedIdentity** for Azure managed credentials. * + **DatabricksGcpServiceAccount** for GCP managed credentials. The caller must be a metastore admin and have the **CREATE_STORAGE_CREDENTIAL** privilege on the metastore.`, Annotations: map[string]string{}, - PreRunE: root.MustWorkspaceClient, + 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) { ctx := cmd.Context() w := root.WorkspaceClient(ctx) @@ -73,20 +82,6 @@ var createCmd = &cobra.Command{ return err } } else { - if len(args) == 0 { - names, err := w.StorageCredentials.StorageCredentialInfoNameToIdMap(ctx) - if err != nil { - return 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") - } createReq.Name = args[0] } @@ -132,9 +127,12 @@ var deleteCmd = &cobra.Command{ } } 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 err + 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 { @@ -189,9 +187,12 @@ var getCmd = &cobra.Command{ } } 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 err + 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 { @@ -255,10 +256,11 @@ func init() { updateCmd.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.`) + // TODO: output-only field updateCmd.Flags().BoolVar(&updateReq.Force, "force", updateReq.Force, `Force update even if there are dependent external locations or external tables.`) - // TODO: complex arg: gcp_service_account_key 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.`) @@ -287,9 +289,12 @@ var updateCmd = &cobra.Command{ } } 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 err + 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 { @@ -322,9 +327,10 @@ func init() { validateCmd.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.`) - // TODO: complex arg: gcp_service_account_key validateCmd.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.`) diff --git a/cmd/workspace/system-schemas/system-schemas.go b/cmd/workspace/system-schemas/system-schemas.go new file mode 100755 index 0000000000..3e6d0719be --- /dev/null +++ b/cmd/workspace/system-schemas/system-schemas.go @@ -0,0 +1,148 @@ +// Code generated from OpenAPI specs by Databricks SDK Generator. DO NOT EDIT. + +package system_schemas + +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/service/catalog" + "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 + schema may contain information about customer usage of Unity Catalog such as + audit-logs, billing-logs, lineage information, etc.`, +} + +// start disable command + +var disableReq catalog.DisableRequest +var disableJson flags.JsonFlag + +func init() { + Cmd.AddCommand(disableCmd) + // TODO: short flags + disableCmd.Flags().Var(&disableJson, "json", `either inline JSON string or @path/to/file.json with request body`) + +} + +var disableCmd = &cobra.Command{ + Use: "disable METASTORE_ID SCHEMA_NAME", + Short: `Disable a system schema.`, + 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.`, + + 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) + if cmd.Flags().Changed("json") { + err = disableJson.Unmarshal(&disableReq) + if err != nil { + return err + } + } else { + disableReq.MetastoreId = args[0] + disableReq.SchemaName = args[1] + } + + err = w.SystemSchemas.Disable(ctx, disableReq) + if err != nil { + return err + } + return nil + }, +} + +// start enable command + +func init() { + Cmd.AddCommand(enableCmd) + +} + +var enableCmd = &cobra.Command{ + Use: "enable", + Short: `Enable a system schema.`, + 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.`, + + Annotations: map[string]string{}, + PreRunE: root.MustWorkspaceClient, + RunE: func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := root.WorkspaceClient(ctx) + err = w.SystemSchemas.Enable(ctx) + if err != nil { + return err + } + return nil + }, +} + +// start list command + +var listReq catalog.ListSystemSchemasRequest +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`) + +} + +var listCmd = &cobra.Command{ + Use: "list METASTORE_ID", + Short: `List system schemas.`, + Long: `List system schemas. + + Gets an array of system schemas for a metastore. The caller must be an account + admin or a metastore admin.`, + + Annotations: map[string]string{}, + 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) { + ctx := cmd.Context() + w := root.WorkspaceClient(ctx) + if cmd.Flags().Changed("json") { + err = listJson.Unmarshal(&listReq) + if err != nil { + return err + } + } else { + listReq.MetastoreId = args[0] + } + + response, err := w.SystemSchemas.ListAll(ctx, listReq) + if err != nil { + return err + } + return cmdio.Render(ctx, response) + }, +} + +// end service SystemSchemas diff --git a/cmd/workspace/warehouses/warehouses.go b/cmd/workspace/warehouses/warehouses.go index 3387e36ee0..2b2311ec14 100755 --- a/cmd/workspace/warehouses/warehouses.go +++ b/cmd/workspace/warehouses/warehouses.go @@ -9,7 +9,6 @@ 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/retries" "github.com/databricks/databricks-sdk-go/service/sql" "github.com/spf13/cobra" ) @@ -80,30 +79,25 @@ var createCmd = &cobra.Command{ } else { } + wait, err := w.Warehouses.Create(ctx, createReq) + if err != nil { + return err + } if createSkipWait { - response, err := w.Warehouses.Create(ctx, createReq) - if err != nil { - return err - } - return cmdio.Render(ctx, response) + return cmdio.Render(ctx, wait.Response) } spinner := cmdio.Spinner(ctx) - info, err := w.Warehouses.CreateAndWait(ctx, createReq, - retries.Timeout[sql.GetWarehouseResponse](createTimeout), - func(i *retries.Info[sql.GetWarehouseResponse]) { - if i.Info == nil { - return - } - if i.Info.Health == nil { - return - } - status := i.Info.State - statusMessage := fmt.Sprintf("current status: %s", status) - if i.Info.Health != nil { - statusMessage = i.Info.Health.Summary - } - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *sql.GetWarehouseResponse) { + if i.Health == nil { + return + } + status := i.State + statusMessage := fmt.Sprintf("current status: %s", status) + if i.Health != nil { + statusMessage = i.Health.Summary + } + spinner <- statusMessage + }).GetWithTimeout(createTimeout) close(spinner) if err != nil { return err @@ -116,14 +110,9 @@ var createCmd = &cobra.Command{ var deleteReq sql.DeleteWarehouseRequest var deleteJson flags.JsonFlag -var deleteSkipWait bool -var deleteTimeout time.Duration func init() { Cmd.AddCommand(deleteCmd) - - deleteCmd.Flags().BoolVar(&deleteSkipWait, "no-wait", deleteSkipWait, `do not wait to reach DELETED state`) - deleteCmd.Flags().DurationVar(&deleteTimeout, "timeout", 20*time.Minute, `maximum amount of time to reach DELETED state`) // TODO: short flags deleteCmd.Flags().Var(&deleteJson, "json", `either inline JSON string or @path/to/file.json with request body`) @@ -167,35 +156,11 @@ var deleteCmd = &cobra.Command{ deleteReq.Id = args[0] } - if deleteSkipWait { - err = w.Warehouses.Delete(ctx, deleteReq) - if err != nil { - return err - } - return nil - } - spinner := cmdio.Spinner(ctx) - info, err := w.Warehouses.DeleteAndWait(ctx, deleteReq, - retries.Timeout[sql.GetWarehouseResponse](deleteTimeout), - func(i *retries.Info[sql.GetWarehouseResponse]) { - if i.Info == nil { - return - } - if i.Info.Health == nil { - return - } - status := i.Info.State - statusMessage := fmt.Sprintf("current status: %s", status) - if i.Info.Health != nil { - statusMessage = i.Info.Health.Summary - } - spinner <- statusMessage - }) - close(spinner) + err = w.Warehouses.Delete(ctx, deleteReq) if err != nil { return err } - return cmdio.Render(ctx, info) + return nil }, } @@ -268,30 +233,25 @@ var editCmd = &cobra.Command{ editReq.Id = args[0] } + wait, err := w.Warehouses.Edit(ctx, editReq) + if err != nil { + return err + } if editSkipWait { - err = w.Warehouses.Edit(ctx, editReq) - if err != nil { - return err - } return nil } spinner := cmdio.Spinner(ctx) - info, err := w.Warehouses.EditAndWait(ctx, editReq, - retries.Timeout[sql.GetWarehouseResponse](editTimeout), - func(i *retries.Info[sql.GetWarehouseResponse]) { - if i.Info == nil { - return - } - if i.Info.Health == nil { - return - } - status := i.Info.State - statusMessage := fmt.Sprintf("current status: %s", status) - if i.Info.Health != nil { - statusMessage = i.Info.Health.Summary - } - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *sql.GetWarehouseResponse) { + if i.Health == nil { + return + } + status := i.State + statusMessage := fmt.Sprintf("current status: %s", status) + if i.Health != nil { + statusMessage = i.Health.Summary + } + spinner <- statusMessage + }).GetWithTimeout(editTimeout) close(spinner) if err != nil { return err @@ -553,30 +513,25 @@ var startCmd = &cobra.Command{ startReq.Id = args[0] } + wait, err := w.Warehouses.Start(ctx, startReq) + if err != nil { + return err + } if startSkipWait { - err = w.Warehouses.Start(ctx, startReq) - if err != nil { - return err - } return nil } spinner := cmdio.Spinner(ctx) - info, err := w.Warehouses.StartAndWait(ctx, startReq, - retries.Timeout[sql.GetWarehouseResponse](startTimeout), - func(i *retries.Info[sql.GetWarehouseResponse]) { - if i.Info == nil { - return - } - if i.Info.Health == nil { - return - } - status := i.Info.State - statusMessage := fmt.Sprintf("current status: %s", status) - if i.Info.Health != nil { - statusMessage = i.Info.Health.Summary - } - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *sql.GetWarehouseResponse) { + if i.Health == nil { + return + } + status := i.State + statusMessage := fmt.Sprintf("current status: %s", status) + if i.Health != nil { + statusMessage = i.Health.Summary + } + spinner <- statusMessage + }).GetWithTimeout(startTimeout) close(spinner) if err != nil { return err @@ -640,30 +595,25 @@ var stopCmd = &cobra.Command{ stopReq.Id = args[0] } + wait, err := w.Warehouses.Stop(ctx, stopReq) + if err != nil { + return err + } if stopSkipWait { - err = w.Warehouses.Stop(ctx, stopReq) - if err != nil { - return err - } return nil } spinner := cmdio.Spinner(ctx) - info, err := w.Warehouses.StopAndWait(ctx, stopReq, - retries.Timeout[sql.GetWarehouseResponse](stopTimeout), - func(i *retries.Info[sql.GetWarehouseResponse]) { - if i.Info == nil { - return - } - if i.Info.Health == nil { - return - } - status := i.Info.State - statusMessage := fmt.Sprintf("current status: %s", status) - if i.Info.Health != nil { - statusMessage = i.Info.Health.Summary - } - spinner <- statusMessage - }) + info, err := wait.OnProgress(func(i *sql.GetWarehouseResponse) { + if i.Health == nil { + return + } + status := i.State + statusMessage := fmt.Sprintf("current status: %s", status) + if i.Health != nil { + statusMessage = i.Health.Summary + } + spinner <- statusMessage + }).GetWithTimeout(stopTimeout) close(spinner) if err != nil { return err diff --git a/go.mod b/go.mod index 14a42762d9..37e77b9676 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.18 require ( github.com/briandowns/spinner v1.23.0 // Apache 2.0 - github.com/databricks/databricks-sdk-go v0.9.0 // Apache 2.0 + github.com/databricks/databricks-sdk-go v0.9.1-0.20230609162050-fdf0bf49f7bd // Apache 2.0 github.com/fatih/color v1.15.0 // MIT github.com/ghodss/yaml v1.0.0 // MIT + NOTICE github.com/google/uuid v1.3.0 // BSD-3-Clause @@ -20,7 +20,7 @@ require ( github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 // MIT github.com/spf13/cobra v1.7.0 // Apache 2.0 github.com/spf13/pflag v1.0.5 // BSD-3-Clause - github.com/stretchr/testify v1.8.3 // MIT + github.com/stretchr/testify v1.8.4 // MIT github.com/whilp/git-urls v1.0.0 // MIT golang.org/x/exp v0.0.0-20230310171629-522b1b587ee0 golang.org/x/mod v0.10.0 @@ -32,17 +32,17 @@ require ( ) require ( - cloud.google.com/go/compute v1.19.0 // indirect + cloud.google.com/go/compute v1.19.3 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect github.com/cloudflare/circl v1.3.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-querystring v1.1.0 // indirect - github.com/google/s2a-go v0.1.3 // indirect + github.com/google/s2a-go v0.1.4 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -50,14 +50,14 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/zclconf/go-cty v1.13.0 // indirect go.opencensus.io v0.24.0 // indirect - golang.org/x/crypto v0.8.0 // indirect + golang.org/x/crypto v0.9.0 // indirect golang.org/x/net v0.10.0 // indirect golang.org/x/sys v0.8.0 // indirect golang.org/x/time v0.3.0 // indirect - google.golang.org/api v0.123.0 // indirect + google.golang.org/api v0.125.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect - google.golang.org/grpc v1.54.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect + google.golang.org/grpc v1.55.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index fe027d6fbc..2c13a0fb99 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go/compute v1.19.0 h1:+9zda3WGgW1ZSTlVppLCYFIr48Pa35q1uG2N1itbCEQ= -cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= +cloud.google.com/go/compute v1.19.3 h1:DcTwsFgGev/wV5+q8o2fzgcHOaac+DKGC91ZlvpsQds= +cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -34,8 +34,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/databricks/databricks-sdk-go v0.9.0 h1:wFeb4fk2EJ4I/pYpq/KK/O4TwqsDpNBJYauXcISMbRw= -github.com/databricks/databricks-sdk-go v0.9.0/go.mod h1:C0vVp7XV/Q8wf/LJCO1oADE8KLB0kcdukjwZMlwysA0= +github.com/databricks/databricks-sdk-go v0.9.1-0.20230609162050-fdf0bf49f7bd h1:mhituyVw1q1LA/l8V2dKK7JBZlAGDosolYylmVvL/YE= +github.com/databricks/databricks-sdk-go v0.9.1-0.20230609162050-fdf0bf49f7bd/go.mod h1:CjACzGP8eyLmKN0OQs8v8LPilp1FEFk2Tp6N7zT7cpQ= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -55,8 +55,9 @@ github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= github.com/go-git/go-git/v5 v5.6.1 h1:q4ZRqQl4pR/ZJHc1L5CFjGA1a10u76aV1iC+nh+bHsk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -85,14 +86,14 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/s2a-go v0.1.3 h1:FAgZmpLl/SXurPEZyCMPBIiiYeTbqfjlbdnCNTAkbGE= -github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= +github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/gax-go/v2 v2.8.0 h1:UBtEZqx1bjXtOQ5BVTkuYghXrr3N4V123VKJK67vJZc= +github.com/googleapis/gax-go/v2 v2.10.0 h1:ebSgKfMxynOdxw8QQuFOKMgomqeLGPqNLQox2bo42zg= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= @@ -147,8 +148,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/whilp/git-urls v1.0.0 h1:95f6UMWN5FKW71ECsXRUd3FVYiXdrE7aX4NZKcPmIjU= github.com/whilp/git-urls v1.0.0/go.mod h1:J16SAmobsqc3Qcy98brfl5f5+e0clUvg1krgwk/qCfE= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= @@ -162,8 +163,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= -golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20230310171629-522b1b587ee0 h1:LGJsf5LRplCck6jUCH3dBL2dmycNruWNF5xugkSlfXw= golang.org/x/exp v0.0.0-20230310171629-522b1b587ee0/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= @@ -242,8 +243,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.123.0 h1:yHVU//vA+qkOhm4reEC9LtzHVUCN/IqqNRl1iQ9xE20= -google.golang.org/api v0.123.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms= +google.golang.org/api v0.125.0 h1:7xGvEY4fyWbhWMHf3R2/4w7L4fXyfpRGE9g6lp8+DCk= +google.golang.org/api v0.125.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= @@ -252,8 +253,8 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -262,8 +263,8 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= -google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=