Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add --dry-run option for bundle deploy #1805

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions bundle/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ type Bundle struct {
// files
AutoApprove bool

// if true, the deploy changes are presented, but not applied
DryRun bool

// Tagging is used to normalize tag keys and values.
// The implementation depends on the cloud being targeted.
Tagging tags.Cloud
Expand Down
42 changes: 42 additions & 0 deletions bundle/phases/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,43 @@ func parseTerraformActions(changes []*tfjson.ResourceChange, toInclude func(typ
return res
}

func showDryRunChanges(ctx context.Context, plan *tfjson.Plan) {
updateActions := make([]terraformlib.Action, 0)
for _, rc := range plan.ResourceChanges {
if rc.Change.Actions.Update() {
updateActions = append(updateActions, terraformlib.Action{
Action: terraformlib.ActionTypeUpdate,
ResourceType: rc.Type,
ResourceName: rc.Name,
})
}
}
createActions := make([]terraformlib.Action, 0)
for _, rc := range plan.ResourceChanges {
if rc.Change.Actions.Create() {
createActions = append(createActions, terraformlib.Action{
Action: terraformlib.ActionTypeCreate,
ResourceType: rc.Type,
ResourceName: rc.Name,
})
}
}
if len(updateActions) > 0 {
cmdio.LogString(ctx, "The following resources will be updated:")
for _, a := range updateActions {
cmdio.Log(ctx, a)
}
cmdio.LogString(ctx, "")
}
if len(createActions) > 0 {
cmdio.LogString(ctx, "The following resources will be created:")
for _, a := range createActions {
cmdio.Log(ctx, a)
}
cmdio.LogString(ctx, "")
}
}

func approvalForDeploy(ctx context.Context, b *bundle.Bundle) (bool, error) {
tf := b.Terraform
if tf == nil {
Expand All @@ -63,6 +100,11 @@ func approvalForDeploy(ctx context.Context, b *bundle.Bundle) (bool, error) {
return false, err
}

if b.DryRun {
showDryRunChanges(ctx, plan)
return false, nil
}

schemaActions := parseTerraformActions(plan.ResourceChanges, func(typ string, actions tfjson.Actions) bool {
// Filter in only UC schema resources.
if typ != "databricks_schema" {
Expand Down
3 changes: 3 additions & 0 deletions cmd/bundle/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ func newDeployCommand() *cobra.Command {
var failOnActiveRuns bool
var clusterId string
var autoApprove bool
var dryRyn bool
var verbose bool
cmd.Flags().BoolVar(&force, "force", false, "Force-override Git branch validation.")
cmd.Flags().BoolVar(&forceLock, "force-lock", false, "Force acquisition of deployment lock.")
cmd.Flags().BoolVar(&failOnActiveRuns, "fail-on-active-runs", false, "Fail if there are running jobs or pipelines in the deployment.")
cmd.Flags().StringVar(&clusterId, "compute-id", "", "Override cluster in the deployment with the given compute ID.")
cmd.Flags().StringVarP(&clusterId, "cluster-id", "c", "", "Override cluster in the deployment with the given cluster ID.")
cmd.Flags().BoolVar(&autoApprove, "auto-approve", false, "Skip interactive approvals that might be required for deployment.")
cmd.Flags().BoolVar(&dryRyn, "dry-run", false, "Present changes that would be deployed without applying.")
cmd.Flags().MarkDeprecated("compute-id", "use --cluster-id instead")
cmd.Flags().BoolVar(&verbose, "verbose", false, "Enable verbose output.")
// Verbose flag currently only affects file sync output, it's used by the vscode extension
Expand All @@ -47,6 +49,7 @@ func newDeployCommand() *cobra.Command {
b.Config.Bundle.Force = force
b.Config.Bundle.Deployment.Lock.Force = forceLock
b.AutoApprove = autoApprove
b.DryRun = dryRyn

if cmd.Flag("compute-id").Changed {
b.Config.Bundle.ClusterId = clusterId
Expand Down
27 changes: 27 additions & 0 deletions internal/bundle/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,33 @@ func TestAccBundleDeployUcSchemaFailsWithoutAutoApprove(t *testing.T) {
assert.Contains(t, stdout.String(), "the deployment requires destructive actions, but current console does not support prompting. Please specify --auto-approve if you would like to skip prompts and proceed")
}

func TestAccBundleDeployUcSchemaIsNotAppliedWhenDryRun(t *testing.T) {
ctx, wt := acc.UcWorkspaceTest(t)
w := wt.W

uniqueId := uuid.New().String()
schemaName := "test-schema-" + uniqueId
catalogName := "main"

bundleRoot := setupUcSchemaBundle(t, ctx, w, uniqueId)

// Remove the UC schema from the resource configuration.
err := os.Remove(filepath.Join(bundleRoot, "schema.yml"))
require.NoError(t, err)

// Run dry-run for the bundle deployment
t.Setenv("BUNDLE_ROOT", bundleRoot)
t.Setenv("TERM", "dumb")
c := internal.NewCobraTestRunnerWithContext(t, ctx, "bundle", "deploy", "--dry-run")
stdout, _, err := c.Run()
require.NoError(t, err)

// Assert the schema was not deleted
_, err = w.Schemas.GetByFullName(ctx, strings.Join([]string{catalogName, schemaName}, "."))
require.NoError(t, err)
assert.Contains(t, stdout.String(), "Following changes would be deployed:")
}

func TestAccBundlePipelineDeleteWithoutAutoApprove(t *testing.T) {
ctx, wt := acc.WorkspaceTest(t)
w := wt.W
Expand Down