diff --git a/.codegen.json b/.codegen.json index cd1fa12edb3..b8ae2173341 100644 --- a/.codegen.json +++ b/.codegen.json @@ -1,7 +1,7 @@ { "formatter": "go run golang.org/x/tools/cmd/goimports@latest -w $FILENAMES && go fmt ./...", "services": { - ".codegen/service.go.tmpl": "cmd/{{if .IsAccounts}}account{{else}}workspace{{end}}/{{(.TrimPrefix \"account\").KebabName}}/{{(.TrimPrefix \"account\").KebabName}}.go" + ".codegen/service.go.tmpl": "cmd/{{if .IsAccounts}}account{{else}}workspace{{end}}/{{if .IsAccounts}}{{(.TrimPrefix \"account\").KebabName}}{{else}}{{.KebabName}}{{end}}/{{if .IsAccounts}}{{(.TrimPrefix \"account\").KebabName}}{{else}}{{.KebabName}}{{end}}.go" }, "batch": { ".codegen/cmds-workspace.go.tmpl": "cmd/workspace/cmd.go", diff --git a/.codegen/service.go.tmpl b/.codegen/service.go.tmpl index 89363235567..5337f77758d 100644 --- a/.codegen/service.go.tmpl +++ b/.codegen/service.go.tmpl @@ -1,6 +1,6 @@ // Code generated from OpenAPI specs by Databricks SDK Generator. DO NOT EDIT. -package {{(.TrimPrefix "account").SnakeName}} +package {{template "ServiceSnakeName" .}} import ( "github.com/databricks/cli/libs/cmdio" @@ -19,7 +19,7 @@ import ( {{define "service"}} var Cmd = &cobra.Command{ - Use: "{{(.TrimPrefix "account").KebabName}}", + Use: "{{template "ServiceKebabName" .}}", {{- if .Description }} Short: `{{.Summary | without "`"}}`, Long: `{{.Comment " " 80 | without "`"}}`, @@ -119,7 +119,7 @@ var {{.CamelName}}Cmd = &cobra.Command{ if len(args) == 0 { promptSpinner := cmdio.Spinner(ctx) promptSpinner <- "No{{range .Request.RequiredFields}} {{.ConstantName}}{{end}} argument specified. Loading names for {{.Service.TitleName}} drop-down." - names, err := {{if .Service.IsAccounts}}a{{else}}w{{end}}.{{(.Service.TrimPrefix "account").PascalName}}.{{.Service.List.NamedIdMap.PascalName}}(ctx{{if .Service.List.Request}}, {{.Service.Package.Name}}.{{.Service.List.Request.PascalName}}{}{{end}}) + names, err := {{if .Service.IsAccounts}}a{{else}}w{{end}}.{{template "ServicePascalName" .Service}}.{{.Service.List.NamedIdMap.PascalName}}(ctx{{if .Service.List.Request}}, {{.Service.Package.Name}}.{{.Service.List.Request.PascalName}}{}{{end}}) close(promptSpinner) if err != nil { return fmt.Errorf("failed to load names for {{.Service.TitleName}} drop-down. Please manually specify required arguments. Original error: %w", err) @@ -199,7 +199,7 @@ var {{.CamelName}}Cmd = &cobra.Command{ // end service {{.Name}}{{end}} {{- define "method-call" -}} - {{if .Response}}response, err :={{else}}err ={{end}} {{if .Service.IsAccounts}}a{{else}}w{{end}}.{{(.Service.TrimPrefix "account").PascalName}}.{{.PascalName}}{{if .Pagination}}All{{end}}(ctx{{if .Request}}, {{.CamelName}}Req{{end}}) + {{if .Response}}response, err :={{else}}err ={{end}} {{if .Service.IsAccounts}}a{{else}}w{{end}}.{{template "ServicePascalName" .Service}}.{{.PascalName}}{{if .Pagination}}All{{end}}(ctx{{if .Request}}, {{.CamelName}}Req{{end}}) if err != nil { return err } @@ -220,3 +220,15 @@ var {{.CamelName}}Cmd = &cobra.Command{ {{- else}}/* NOT PRIMITIVE */ {{- end -}} {{- end -}} + +{{- define "ServiceSnakeName" -}} +{{if .IsAccounts }}{{(.TrimPrefix "account").SnakeName }}{{ else }}{{ .SnakeName }}{{ end }} +{{- end -}} + +{{- define "ServicePascalName" -}} +{{if .IsAccounts }}{{(.TrimPrefix "account").PascalName }}{{ else }}{{ .PascalName }}{{ end }} +{{- end -}} + +{{- define "ServiceKebabName" -}} +{{if .IsAccounts }}{{(.TrimPrefix "account").KebabName }}{{ else }}{{ .KebabName }}{{ end }} +{{- end -}} diff --git a/.gitattributes b/.gitattributes index 8b95da20703..8276e2ade8b 100755 --- a/.gitattributes +++ b/.gitattributes @@ -23,6 +23,7 @@ cmd/account/users/users.go linguist-generated=true cmd/account/vpc-endpoints/vpc-endpoints.go linguist-generated=true cmd/account/workspace-assignment/workspace-assignment.go linguist-generated=true cmd/account/workspaces/workspaces.go linguist-generated=true +cmd/workspace/account-access-control-proxy/account-access-control-proxy.go linguist-generated=true cmd/workspace/alerts/alerts.go linguist-generated=true cmd/workspace/catalogs/catalogs.go linguist-generated=true cmd/workspace/cluster-policies/cluster-policies.go linguist-generated=true diff --git a/cmd/workspace/account-access-control-proxy/account-access-control-proxy.go b/cmd/workspace/account-access-control-proxy/account-access-control-proxy.go new file mode 100755 index 00000000000..c7e7c0ceb44 --- /dev/null +++ b/cmd/workspace/account-access-control-proxy/account-access-control-proxy.go @@ -0,0 +1,180 @@ +// Code generated from OpenAPI specs by Databricks SDK Generator. DO NOT EDIT. + +package account_access_control_proxy + +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: "account-access-control-proxy", + 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. A + workspace must belong to an account for these APIs to work.`, + Annotations: map[string]string{ + "package": "iam", + }, +} + +// start get-assignable-roles-for-resource command + +var getAssignableRolesForResourceReq iam.GetAssignableRolesForResourceRequest +var getAssignableRolesForResourceJson flags.JsonFlag + +func init() { + Cmd.AddCommand(getAssignableRolesForResourceCmd) + // TODO: short flags + getAssignableRolesForResourceCmd.Flags().Var(&getAssignableRolesForResourceJson, "json", `either inline JSON string or @path/to/file.json with request body`) + +} + +var getAssignableRolesForResourceCmd = &cobra.Command{ + Use: "get-assignable-roles-for-resource RESOURCE", + Short: `Get assignable roles for a resource.`, + Long: `Get assignable roles for a resource. + + 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.MustWorkspaceClient, + RunE: func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := root.WorkspaceClient(ctx) + if cmd.Flags().Changed("json") { + err = getAssignableRolesForResourceJson.Unmarshal(&getAssignableRolesForResourceReq) + if err != nil { + return err + } + } else { + getAssignableRolesForResourceReq.Resource = args[0] + } + + response, err := w.AccountAccessControlProxy.GetAssignableRolesForResource(ctx, getAssignableRolesForResourceReq) + if err != nil { + return err + } + return cmdio.Render(ctx, response) + }, + // Disable completions since they are not applicable. + // Can be overridden by manual implementation in `override.go`. + ValidArgsFunction: cobra.NoFileCompletions, +} + +// start get-rule-set command + +var getRuleSetReq iam.GetRuleSetRequest +var getRuleSetJson flags.JsonFlag + +func init() { + Cmd.AddCommand(getRuleSetCmd) + // TODO: short flags + getRuleSetCmd.Flags().Var(&getRuleSetJson, "json", `either inline JSON string or @path/to/file.json with request body`) + +} + +var getRuleSetCmd = &cobra.Command{ + Use: "get-rule-set 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.MustWorkspaceClient, + RunE: func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := root.WorkspaceClient(ctx) + if cmd.Flags().Changed("json") { + err = getRuleSetJson.Unmarshal(&getRuleSetReq) + if err != nil { + return err + } + } else { + getRuleSetReq.Name = args[0] + getRuleSetReq.Etag = args[1] + } + + response, err := w.AccountAccessControlProxy.GetRuleSet(ctx, getRuleSetReq) + if err != nil { + return err + } + return cmdio.Render(ctx, response) + }, + // Disable completions since they are not applicable. + // Can be overridden by manual implementation in `override.go`. + ValidArgsFunction: cobra.NoFileCompletions, +} + +// start update-rule-set command + +var updateRuleSetReq iam.UpdateRuleSetRequest +var updateRuleSetJson flags.JsonFlag + +func init() { + Cmd.AddCommand(updateRuleSetCmd) + // TODO: short flags + updateRuleSetCmd.Flags().Var(&updateRuleSetJson, "json", `either inline JSON string or @path/to/file.json with request body`) + +} + +var updateRuleSetCmd = &cobra.Command{ + Use: "update-rule-set", + Short: `Update a rule set.`, + Long: `Update a rule set. + + Replace the rules of a rule set. First, use a GET rule set request 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.MustWorkspaceClient, + RunE: func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := root.WorkspaceClient(ctx) + if cmd.Flags().Changed("json") { + err = updateRuleSetJson.Unmarshal(&updateRuleSetReq) + if err != nil { + return err + } + } else { + return fmt.Errorf("please provide command input in JSON format by specifying the --json flag") + } + + response, err := w.AccountAccessControlProxy.UpdateRuleSet(ctx, updateRuleSetReq) + if err != nil { + return err + } + return cmdio.Render(ctx, response) + }, + // Disable completions since they are not applicable. + // Can be overridden by manual implementation in `override.go`. + ValidArgsFunction: cobra.NoFileCompletions, +} + +// end service AccountAccessControlProxy diff --git a/cmd/workspace/cmd.go b/cmd/workspace/cmd.go index 68ce3ef06ea..74ba4f078ec 100755 --- a/cmd/workspace/cmd.go +++ b/cmd/workspace/cmd.go @@ -5,6 +5,7 @@ package workspace import ( "github.com/databricks/cli/cmd/root" + account_access_control_proxy "github.com/databricks/cli/cmd/workspace/account-access-control-proxy" alerts "github.com/databricks/cli/cmd/workspace/alerts" catalogs "github.com/databricks/cli/cmd/workspace/catalogs" cluster_policies "github.com/databricks/cli/cmd/workspace/cluster-policies" @@ -56,6 +57,7 @@ import ( ) func init() { + root.RootCmd.AddCommand(account_access_control_proxy.Cmd) root.RootCmd.AddCommand(alerts.Cmd) root.RootCmd.AddCommand(catalogs.Cmd) root.RootCmd.AddCommand(cluster_policies.Cmd) @@ -106,6 +108,7 @@ func init() { root.RootCmd.AddCommand(workspace_conf.Cmd) // Register commands with groups + account_access_control_proxy.Cmd.GroupID = "iam" alerts.Cmd.GroupID = "sql" catalogs.Cmd.GroupID = "catalog" cluster_policies.Cmd.GroupID = "compute"