Skip to content

Commit b4cc378

Browse files
authored
pipelines: extend command group (#4231)
## Changes Extend 'pipelines' command group with commands from Pipelines CLI. The existing commands are moved into "Management Commands". One exception is "stop" command that is present in both lists. We look into argument, and if it looks like pipeline_id, we interpret as "Management Command" calling Pipelines API, otherwise, we delegate into Pipelines CLI. The change is backward-compatible, and doesn't change the behaviour existing of CI scripts that can rely on Databricks CLI. In addition, until we declare this as shippable, the whole functionality is disabled and only visible with `ENABLE_PIPELINES_CLI=1` environment variable set. ``` $ databricks pipelines Available Commands deploy Deploy pipelines destroy Destroy a pipelines project dry-run Validate correctness of the pipeline's graph history Retrieve past runs for a pipeline init Initialize a new pipelines project logs Retrieve events for a pipeline open Open a pipeline in the browser run Run a pipeline stop Stop a pipeline Management Commands clone Clone a pipeline. create Create a pipeline. delete Delete a pipeline. get Get a pipeline. get-update Get a pipeline update. list-pipeline-events List pipeline events. list-pipelines List pipelines. list-updates List pipeline updates. start-update Start a pipeline. update Edit a pipeline. Permission Commands get-permission-levels Get pipeline permission levels. get-permissions Get pipeline permissions. set-permissions Set pipeline permissions. update-permissions Update pipeline permissions. ``` ## Why It allows using Pipelines CLI without installing "pipelines" command. ## Tests Acceptance tests. As a follow-up existing acceptance tests for Pipelines CLI will be updated to test both Databricks CLI and Pipelines CLI.
1 parent 797e55a commit b4cc378

File tree

11 files changed

+257
-2
lines changed

11 files changed

+257
-2
lines changed

acceptance/pipelines/databricks-cli-help-disabled/out.test.toml

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
The Lakeflow Spark Declarative Pipelines API allows you to create, edit,
2+
delete, start, and view details about pipelines.
3+
4+
Spark Declarative Pipelines is a framework for building reliable,
5+
maintainable, and testable data processing pipelines. You define the
6+
transformations to perform on your data, and Spark Declarative Pipelines
7+
manages task orchestration, cluster management, monitoring, data quality, and
8+
error handling.
9+
10+
Instead of defining your data pipelines using a series of separate Apache
11+
Spark tasks, Spark Declarative Pipelines manages how your data is transformed
12+
based on a target schema you define for each processing step. You can also
13+
enforce data quality with Spark Declarative Pipelines expectations.
14+
Expectations allow you to define expected data quality and specify how to
15+
handle records that fail those expectations.
16+
17+
Usage:
18+
databricks pipelines [flags]
19+
databricks pipelines [command]
20+
21+
Available Commands
22+
clone Clone a pipeline.
23+
create Create a pipeline.
24+
delete Delete a pipeline.
25+
get Get a pipeline.
26+
get-update Get a pipeline update.
27+
list-pipeline-events List pipeline events.
28+
list-pipelines List pipelines.
29+
list-updates List pipeline updates.
30+
start-update Start a pipeline.
31+
stop Stop a pipeline.
32+
update Edit a pipeline.
33+
34+
Permission Commands
35+
get-permission-levels Get pipeline permission levels.
36+
get-permissions Get pipeline permissions.
37+
set-permissions Set pipeline permissions.
38+
update-permissions Update pipeline permissions.
39+
40+
Flags:
41+
-h, --help help for pipelines
42+
43+
Global Flags:
44+
--debug enable debug logging
45+
-o, --output type output type: text or json (default text)
46+
-p, --profile string ~/.databrickscfg profile
47+
-t, --target string bundle target to use (if applicable)
48+
49+
Use "databricks pipelines [command] --help" for more information about a command.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
$CLI pipelines

acceptance/pipelines/databricks-cli-help/out.test.toml

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
The Lakeflow Spark Declarative Pipelines API allows you to create, edit,
2+
delete, start, and view details about pipelines.
3+
4+
Spark Declarative Pipelines is a framework for building reliable,
5+
maintainable, and testable data processing pipelines. You define the
6+
transformations to perform on your data, and Spark Declarative Pipelines
7+
manages task orchestration, cluster management, monitoring, data quality, and
8+
error handling.
9+
10+
Instead of defining your data pipelines using a series of separate Apache
11+
Spark tasks, Spark Declarative Pipelines manages how your data is transformed
12+
based on a target schema you define for each processing step. You can also
13+
enforce data quality with Spark Declarative Pipelines expectations.
14+
Expectations allow you to define expected data quality and specify how to
15+
handle records that fail those expectations.
16+
17+
Usage:
18+
databricks pipelines [flags]
19+
databricks pipelines [command]
20+
21+
Available Commands
22+
deploy Deploy pipelines
23+
destroy Destroy a pipelines project
24+
dry-run Validate correctness of the pipeline's graph
25+
history Retrieve past runs for a pipeline
26+
init Initialize a new pipelines project
27+
logs Retrieve events for a pipeline
28+
open Open a pipeline in the browser
29+
run Run a pipeline
30+
stop Stop a pipeline
31+
32+
Management Commands
33+
clone Clone a pipeline.
34+
create Create a pipeline.
35+
delete Delete a pipeline.
36+
get Get a pipeline.
37+
get-update Get a pipeline update.
38+
list-pipeline-events List pipeline events.
39+
list-pipelines List pipelines.
40+
list-updates List pipeline updates.
41+
start-update Start a pipeline.
42+
update Edit a pipeline.
43+
44+
Permission Commands
45+
get-permission-levels Get pipeline permission levels.
46+
get-permissions Get pipeline permissions.
47+
set-permissions Set pipeline permissions.
48+
update-permissions Update pipeline permissions.
49+
50+
Flags:
51+
-h, --help help for pipelines
52+
--var strings set values for variables defined in project config. Example: --var="foo=bar"
53+
54+
Global Flags:
55+
--debug enable debug logging
56+
-o, --output type output type: text or json (default text)
57+
-p, --profile string ~/.databrickscfg profile
58+
-t, --target string bundle target to use (if applicable)
59+
60+
Use "databricks pipelines [command] --help" for more information about a command.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ENABLE_PIPELINES_CLI=1 $CLI pipelines

cmd/cmd.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ func New(ctx context.Context) *cobra.Command {
5757
for _, cmd := range workspaceCommands {
5858
// Order the permissions subcommands after the main commands.
5959
for _, sub := range cmd.Commands() {
60+
// some commands override groups in overrides.go, leave them as-is
61+
if sub.GroupID != "" {
62+
continue
63+
}
64+
6065
switch {
6166
case strings.HasSuffix(sub.Name(), "-permissions"), strings.HasSuffix(sub.Name(), "-permission-levels"):
6267
sub.GroupID = permissionsGroup
@@ -73,6 +78,10 @@ func New(ctx context.Context) *cobra.Command {
7378
ID: mainGroup,
7479
Title: "Available Commands",
7580
},
81+
{
82+
ID: pipelines.ManagementGroupID,
83+
Title: "Management Commands",
84+
},
7685
{
7786
ID: permissionsGroup,
7887
Title: "Permission Commands",

cmd/pipelines/pipelines.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package pipelines
22

33
import (
44
"context"
5+
"os"
6+
"slices"
57

68
"github.com/databricks/cli/cmd/pipelines/root"
79
"github.com/spf13/cobra"
@@ -17,9 +19,39 @@ func New(ctx context.Context) *cobra.Command {
1719
cli.AddCommand(dryRunCommand())
1820
cli.AddCommand(authCommand())
1921
cli.AddCommand(destroyCommand())
20-
cli.AddCommand(stopCommand())
22+
cli.AddCommand(StopCommand())
2123
cli.AddCommand(historyCommand())
2224
cli.AddCommand(logsCommand())
2325
cli.AddCommand(versionCommand())
2426
return cli
2527
}
28+
29+
// ManagementGroupID contains auto-generated CLI commands for Pipelines API,
30+
// that are separate from main CLI commands defined in Commands.
31+
const ManagementGroupID = "management"
32+
33+
// Enabled disables Pipelines CLI in Databricks CLI until it's ready
34+
func Enabled() bool {
35+
value, ok := os.LookupEnv("ENABLE_PIPELINES_CLI")
36+
if !ok {
37+
return false
38+
}
39+
40+
return slices.Contains([]string{"1", "true", "t", "yes"}, value)
41+
}
42+
43+
// Commands returns the list of commands that are shared between
44+
// the standalone pipelines CLI and databricks pipelines.
45+
// Note: auth and version are excluded as they are only for standalone CLI.
46+
func Commands() []*cobra.Command {
47+
return []*cobra.Command{
48+
initCommand(),
49+
deployCommand(),
50+
destroyCommand(),
51+
runCommand(),
52+
dryRunCommand(),
53+
historyCommand(),
54+
logsCommand(),
55+
openCommand(),
56+
}
57+
}

cmd/pipelines/stop.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func resolveStopArgument(ctx context.Context, b *bundle.Bundle, args []string) (
3636
return "", errors.New("expected a KEY of the pipeline to stop")
3737
}
3838

39-
func stopCommand() *cobra.Command {
39+
func StopCommand() *cobra.Command {
4040
cmd := &cobra.Command{
4141
Use: "stop [KEY]",
4242
Short: "Stop a pipeline",
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package pipelines
2+
3+
import (
4+
"regexp"
5+
"slices"
6+
7+
pipelinesCli "github.com/databricks/cli/cmd/pipelines"
8+
"github.com/databricks/databricks-sdk-go/service/pipelines"
9+
"github.com/spf13/cobra"
10+
)
11+
12+
func init() {
13+
if !pipelinesCli.Enabled() {
14+
return
15+
}
16+
17+
cmdOverrides = append(cmdOverrides, func(cli *cobra.Command) {
18+
// all auto-generated commands apart from nonManagementCommands go into 'management' group
19+
nonManagementCommands := []string{
20+
// 'stop' command is overloaded as Pipelines API and Pipelines CLI command
21+
"stop",
22+
// permission commands are assigned into "permission" group in cmd/cmd.go
23+
// only if they don't have GroupID set
24+
"get-permission-levels",
25+
"get-permissions",
26+
"set-permissions",
27+
"update-permissions",
28+
}
29+
30+
for _, subCmd := range cli.Commands() {
31+
if slices.Contains(nonManagementCommands, subCmd.Name()) {
32+
continue
33+
}
34+
35+
if subCmd.GroupID == "" {
36+
subCmd.GroupID = pipelinesCli.ManagementGroupID
37+
}
38+
}
39+
40+
// main section is populated with commands from Pipelines CLI
41+
for _, pipelinesCmd := range pipelinesCli.Commands() {
42+
cli.AddCommand(pipelinesCmd)
43+
}
44+
45+
// Add --var flag support (from cli/pipelines/variables.go)
46+
cli.PersistentFlags().StringSlice("var", []string{}, `set values for variables defined in project config. Example: --var="foo=bar"`)
47+
})
48+
49+
// 'stop' command is different in context of bundle vs. management command
50+
stopOverrides = append(stopOverrides, func(cmd *cobra.Command, req *pipelines.StopRequest) {
51+
originalRunE := cmd.RunE
52+
cmd.RunE = func(cmd *cobra.Command, args []string) error {
53+
// For compatibility, if argument looks like pipeline ID, use API
54+
if len(args) > 0 && looksLikeUUID(args[0]) {
55+
return originalRunE(cmd, args)
56+
}
57+
// Looks like a bundle key or no args - use Lakeflow stop
58+
return pipelinesCli.StopCommand().RunE(cmd, args)
59+
}
60+
61+
// Update usage to reflect dual nature
62+
cmd.Use = "stop [KEY|PIPELINE_ID]"
63+
cmd.Short = "Stop a pipeline"
64+
cmd.Long = `Stop a pipeline.
65+
66+
With a bundle KEY: Stops the pipeline identified by KEY from your databricks.yml.
67+
If there is only one pipeline in the bundle, KEY is optional.
68+
69+
With a PIPELINE_ID: Stops the pipeline identified by the UUID using the API.`
70+
})
71+
}
72+
73+
var uuidRegex = regexp.MustCompile(`^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`)
74+
75+
// looksLikeUUID checks if a string matches the UUID format with lowercase hex digits
76+
func looksLikeUUID(s string) bool {
77+
return uuidRegex.MatchString(s)
78+
}

0 commit comments

Comments
 (0)