diff --git a/bundle/deploy/terraform/showplanfile.go b/bundle/deploy/terraform/showplanfile.go index 1521f2bff7..4399974393 100644 --- a/bundle/deploy/terraform/showplanfile.go +++ b/bundle/deploy/terraform/showplanfile.go @@ -72,15 +72,15 @@ func populatePlan(ctx context.Context, plan *deployplan.Plan, changes []*tfjson. var actionType deployplan.ActionType switch { case rc.Change.Actions.Delete(): - actionType = deployplan.ActionTypeDelete + actionType = deployplan.Delete case rc.Change.Actions.Replace(): - actionType = deployplan.ActionTypeRecreate + actionType = deployplan.Recreate case rc.Change.Actions.Create(): - actionType = deployplan.ActionTypeCreate + actionType = deployplan.Create case rc.Change.Actions.Update(): - actionType = deployplan.ActionTypeUpdate + actionType = deployplan.Update case rc.Change.Actions.NoOp(): - actionType = deployplan.ActionTypeSkip + actionType = deployplan.Skip default: continue } @@ -105,7 +105,7 @@ func populatePlan(ctx context.Context, plan *deployplan.Plan, changes []*tfjson. key = "resources." + group + "." + rc.Name } - plan.Plan[key] = &deployplan.PlanEntry{Action: actionType.String()} + plan.Plan[key] = &deployplan.PlanEntry{Action: actionType} } } diff --git a/bundle/deploy/terraform/showplanfile_test.go b/bundle/deploy/terraform/showplanfile_test.go index 0ce7d049ef..0ac62eb306 100644 --- a/bundle/deploy/terraform/showplanfile_test.go +++ b/bundle/deploy/terraform/showplanfile_test.go @@ -50,15 +50,15 @@ func TestPopulatePlan(t *testing.T) { // Assert that the actions list contains all expected actions expectedActions := []deployplan.Action{ { - ActionType: deployplan.ActionTypeCreate, + ActionType: deployplan.Create, ResourceKey: "resources.pipelines.create pipeline", }, { - ActionType: deployplan.ActionTypeDelete, + ActionType: deployplan.Delete, ResourceKey: "resources.pipelines.delete pipeline", }, { - ActionType: deployplan.ActionTypeRecreate, + ActionType: deployplan.Recreate, ResourceKey: "resources.pipelines.recreate pipeline", }, } @@ -66,13 +66,13 @@ func TestPopulatePlan(t *testing.T) { // Also test that the plan was populated correctly with expected entries assert.Contains(t, plan.Plan, "resources.pipelines.create pipeline") - assert.Equal(t, "create", plan.Plan["resources.pipelines.create pipeline"].Action) + assert.Equal(t, deployplan.Create, plan.Plan["resources.pipelines.create pipeline"].Action) assert.Contains(t, plan.Plan, "resources.pipelines.delete pipeline") - assert.Equal(t, "delete", plan.Plan["resources.pipelines.delete pipeline"].Action) + assert.Equal(t, deployplan.Delete, plan.Plan["resources.pipelines.delete pipeline"].Action) assert.Contains(t, plan.Plan, "resources.pipelines.recreate pipeline") - assert.Equal(t, "recreate", plan.Plan["resources.pipelines.recreate pipeline"].Action) + assert.Equal(t, deployplan.Recreate, plan.Plan["resources.pipelines.recreate pipeline"].Action) // Unknown resource type should not be in the plan assert.NotContains(t, plan.Plan, "resources.recreate whatever") diff --git a/bundle/deployplan/action.go b/bundle/deployplan/action.go index 6b561c18c4..e8e1427956 100644 --- a/bundle/deployplan/action.go +++ b/bundle/deployplan/action.go @@ -22,57 +22,36 @@ func (a Action) IsChildResource() bool { return len(items) == 4 } -type ActionType int +type ActionType string // Actions are ordered in increasing severity. // If case of several options, action with highest severity wins. // Note, Create/Delete are handled explicitly and never compared. const ( - ActionTypeUndefined ActionType = iota - ActionTypeSkip - ActionTypeResize - ActionTypeUpdate - ActionTypeUpdateWithID - ActionTypeCreate - ActionTypeRecreate - ActionTypeDelete + Undefined ActionType = "" + Skip ActionType = "skip" + Resize ActionType = "resize" + Update ActionType = "update" + UpdateWithID ActionType = "update_id" + Create ActionType = "create" + Recreate ActionType = "recreate" + Delete ActionType = "delete" ) -const ( - ActionTypeUndefinedString = "" - ActionTypeSkipString = "skip" - ActionTypeResizeString = "resize" - ActionTypeUpdateString = "update" - ActionTypeUpdateWithIDString = "update_id" - ActionTypeCreateString = "create" - ActionTypeRecreateString = "recreate" - ActionTypeDeleteString = "delete" -) - -var actionName = map[ActionType]string{ - ActionTypeSkip: ActionTypeSkipString, - ActionTypeResize: ActionTypeResizeString, - ActionTypeUpdate: ActionTypeUpdateString, - ActionTypeUpdateWithID: ActionTypeUpdateWithIDString, - ActionTypeCreate: ActionTypeCreateString, - ActionTypeRecreate: ActionTypeRecreateString, - ActionTypeDelete: ActionTypeDeleteString, -} - -var nameToAction = map[string]ActionType{} - -func init() { - for k, v := range actionName { - if _, ok := nameToAction[v]; ok { - panic("duplicate action string: " + v) - } - nameToAction[v] = k - } +var actionOrder = map[ActionType]int{ + Undefined: 0, + Skip: 1, + Resize: 2, + Update: 3, + UpdateWithID: 4, + Create: 5, + Recreate: 6, + Delete: 7, } func (a ActionType) KeepsID() bool { switch a { - case ActionTypeCreate, ActionTypeUpdateWithID, ActionTypeRecreate, ActionTypeDelete: + case Create, UpdateWithID, Recreate, Delete: return false default: return true @@ -81,30 +60,15 @@ func (a ActionType) KeepsID() bool { // StringShort short version of action string, without suffix func (a ActionType) StringShort() string { - items := strings.SplitN(actionName[a], "_", 2) + items := strings.SplitN(string(a), "_", 2) return items[0] } -// String returns the string representation of the action type. -func (a ActionType) String() string { - return actionName[a] -} - -func ActionTypeFromString(s string) ActionType { - actionType, ok := nameToAction[s] - if !ok { - return ActionTypeUndefined - } - return actionType -} - -// Filter returns actions that match the specified action type -func Filter(changes []Action, actionType ActionType) []Action { - var result []Action - for _, action := range changes { - if action.ActionType == actionType { - result = append(result, action) - } +// GetHigherAction returns the action with higher severity between a and b. +// Actions are ordered by severity in actionOrder map. +func GetHigherAction(a, b ActionType) ActionType { + if actionOrder[a] > actionOrder[b] { + return a } - return result + return b } diff --git a/bundle/deployplan/action_test.go b/bundle/deployplan/action_test.go deleted file mode 100644 index 953d697fff..0000000000 --- a/bundle/deployplan/action_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package deployplan - -import ( - "maps" - "slices" - "strings" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestStringShort(t *testing.T) { - shortMap := make(map[string][]string) - - keys := slices.Collect(maps.Keys(actionName)) - slices.Sort(keys) - - for _, a := range keys { - s := actionName[a] - require.Equal(t, a.String(), s) - short := a.StringShort() - require.NotEmpty(t, short) - require.True(t, strings.HasPrefix(s, short), "%q %q", s, short) - if short != s { - shortMap[short] = append(shortMap[short], s) - } - } - - require.Equal(t, map[string][]string{ - "update": { - "update_id", - }, - }, shortMap) -} diff --git a/bundle/deployplan/plan.go b/bundle/deployplan/plan.go index a134f00012..ea27165117 100644 --- a/bundle/deployplan/plan.go +++ b/bundle/deployplan/plan.go @@ -65,7 +65,7 @@ func LoadPlanFromFile(path string) (*Plan, error) { type PlanEntry struct { ID string `json:"id,omitempty"` DependsOn []DependsOnEntry `json:"depends_on,omitempty"` - Action string `json:"action,omitempty"` + Action ActionType `json:"action,omitempty"` NewState *structvar.StructVarJSON `json:"new_state,omitempty"` RemoteState any `json:"remote_state,omitempty"` Changes Changes `json:"changes,omitempty"` @@ -79,11 +79,11 @@ type DependsOnEntry struct { type Changes map[string]*ChangeDesc type ChangeDesc struct { - Action string `json:"action"` - Reason string `json:"reason,omitempty"` - Old any `json:"old,omitempty"` - New any `json:"new,omitempty"` - Remote any `json:"remote,omitempty"` + Action ActionType `json:"action"` + Reason string `json:"reason,omitempty"` + Old any `json:"old,omitempty"` + New any `json:"new,omitempty"` + Remote any `json:"remote,omitempty"` } // Possible values for Reason field @@ -118,10 +118,9 @@ func (c *Changes) HasChange(fieldPath string) bool { func (p *Plan) GetActions() []Action { actions := make([]Action, 0, len(p.Plan)) for key, entry := range p.Plan { - at := ActionTypeFromString(entry.Action) actions = append(actions, Action{ ResourceKey: key, - ActionType: at, + ActionType: entry.Action, }) } diff --git a/bundle/direct/apply.go b/bundle/direct/apply.go index 782ddc44db..04bb7054a2 100644 --- a/bundle/direct/apply.go +++ b/bundle/direct/apply.go @@ -28,7 +28,7 @@ func (d *DeploymentUnit) Destroy(ctx context.Context, db *dstate.DeploymentState } func (d *DeploymentUnit) Deploy(ctx context.Context, db *dstate.DeploymentState, newState any, actionType deployplan.ActionType, changes deployplan.Changes) error { - if actionType == deployplan.ActionTypeCreate { + if actionType == deployplan.Create { return d.Create(ctx, db, newState) } @@ -43,13 +43,13 @@ func (d *DeploymentUnit) Deploy(ctx context.Context, db *dstate.DeploymentState, } switch actionType { - case deployplan.ActionTypeRecreate: + case deployplan.Recreate: return d.Recreate(ctx, db, oldID, newState) - case deployplan.ActionTypeUpdate: + case deployplan.Update: return d.Update(ctx, db, oldID, newState, changes) - case deployplan.ActionTypeUpdateWithID: + case deployplan.UpdateWithID: return d.UpdateWithID(ctx, db, oldID, newState) - case deployplan.ActionTypeResize: + case deployplan.Resize: return d.Resize(ctx, db, oldID, newState) default: return fmt.Errorf("internal error: unexpected actionType: %#v", actionType) diff --git a/bundle/direct/bundle_apply.go b/bundle/direct/bundle_apply.go index c20da357ab..993eb7238a 100644 --- a/bundle/direct/bundle_apply.go +++ b/bundle/direct/bundle_apply.go @@ -55,15 +55,14 @@ func (b *DeploymentBundle) Apply(ctx context.Context, client *databricks.Workspa errorPrefix = "cannot migrate " + resourceKey } - at := deployplan.ActionTypeFromString(action) - if at == deployplan.ActionTypeUndefined { + if action == deployplan.Undefined { logdiag.LogError(ctx, fmt.Errorf("cannot deploy %s: unknown action %q", resourceKey, action)) return false } // If a dependency failed, report and skip execution for this node by returning false if failedDependency != nil { - if at != deployplan.ActionTypeSkip { + if action != deployplan.Skip { logdiag.LogError(ctx, fmt.Errorf("%s: dependency failed: %s", errorPrefix, *failedDependency)) } return false @@ -81,7 +80,7 @@ func (b *DeploymentBundle) Apply(ctx context.Context, client *databricks.Workspa DependsOn: entry.DependsOn, } - if at == deployplan.ActionTypeDelete { + if action == deployplan.Delete { if migrateMode { logdiag.LogError(ctx, fmt.Errorf("%s: Unexpected delete action during migration", errorPrefix)) return false @@ -96,7 +95,7 @@ func (b *DeploymentBundle) Apply(ctx context.Context, client *databricks.Workspa // We don't keep NewState around for 'skip' nodes - if at != deployplan.ActionTypeSkip { + if action != deployplan.Skip { if !b.resolveReferences(ctx, resourceKey, entry, errorPrefix, false) { return false } @@ -123,7 +122,7 @@ func (b *DeploymentBundle) Apply(ctx context.Context, client *databricks.Workspa err = b.StateDB.SaveState(resourceKey, dbentry.ID, sv.Value, entry.DependsOn) } else { // TODO: redo calcDiff to downgrade planned action if possible (?) - err = d.Deploy(ctx, &b.StateDB, sv.Value, at, entry.Changes) + err = d.Deploy(ctx, &b.StateDB, sv.Value, action, entry.Changes) } if err != nil { @@ -178,8 +177,8 @@ func (b *DeploymentBundle) LookupReferenceRemote(ctx context.Context, path *stru defer b.Plan.ReadUnlockEntry(targetResourceKey) - targetAction := deployplan.ActionTypeFromString(targetEntry.Action) - if targetAction == deployplan.ActionTypeUndefined { + targetAction := targetEntry.Action + if targetAction == deployplan.Undefined { return nil, fmt.Errorf("internal error: %s: missing action in the plan", targetResourceKey) } diff --git a/bundle/direct/bundle_plan.go b/bundle/direct/bundle_plan.go index d634fa460f..bd8cfa24c3 100644 --- a/bundle/direct/bundle_plan.go +++ b/bundle/direct/bundle_plan.go @@ -166,7 +166,7 @@ func (b *DeploymentBundle) CalculatePlan(ctx context.Context, client *databricks return false } - if entry.Action == deployplan.ActionTypeDelete.String() { + if entry.Action == deployplan.Delete { dbentry, hasEntry := b.StateDB.GetResourceEntry(resourceKey) if !hasEntry { logdiag.LogError(ctx, fmt.Errorf("%s: internal error, missing in state", errorPrefix)) @@ -197,7 +197,7 @@ func (b *DeploymentBundle) CalculatePlan(ctx context.Context, client *databricks dbentry, hasEntry := b.StateDB.GetResourceEntry(resourceKey) if !hasEntry { - entry.Action = deployplan.ActionTypeCreate.String() + entry.Action = deployplan.Create return true } @@ -243,7 +243,7 @@ func (b *DeploymentBundle) CalculatePlan(ctx context.Context, client *databricks // Including remoteState because in the near future remoteState is expected to become a superset struct of remoteStateComparable entry.RemoteState = remoteState - action := deployplan.ActionTypeSkip + var action deployplan.ActionType var remoteDiff []structdiff.Change var remoteStateComparable any @@ -276,23 +276,23 @@ func (b *DeploymentBundle) CalculatePlan(ctx context.Context, client *databricks if remoteState == nil { // Even if local action is "recreate" which is higher than "create", we should still pick "create" here // because we know remote does not exist. - action = deployplan.ActionTypeCreate + action = deployplan.Create } else { action = getMaxAction(entry.Changes) } - if action == deployplan.ActionTypeSkip { + if action == deployplan.Skip { // resource is not going to change, can use remoteState to resolve references b.RemoteStateCache.Store(resourceKey, remoteState) } // Validate that resources without DoUpdate don't have update actions - if action == deployplan.ActionTypeUpdate && !adapter.HasDoUpdate() { + if action == deployplan.Update && !adapter.HasDoUpdate() { logdiag.LogError(ctx, fmt.Errorf("%s: resource does not support update action but plan produced update", errorPrefix)) return false } - entry.Action = action.String() + entry.Action = action return true }) @@ -301,7 +301,7 @@ func (b *DeploymentBundle) CalculatePlan(ctx context.Context, client *databricks } for _, entry := range plan.Plan { - if entry.Action == deployplan.ActionTypeSkipString { + if entry.Action == deployplan.Skip { entry.NewState = nil } } @@ -310,9 +310,9 @@ func (b *DeploymentBundle) CalculatePlan(ctx context.Context, client *databricks } func getMaxAction(m map[string]*deployplan.ChangeDesc) deployplan.ActionType { - result := deployplan.ActionTypeSkip + result := deployplan.Skip for _, ch := range m { - result = max(result, deployplan.ActionTypeFromString(ch.Action)) + result = deployplan.GetHigherAction(result, ch.Action) } return result } @@ -373,17 +373,17 @@ func addPerFieldActions(ctx context.Context, adapter *dresources.Adapter, change // This could either be server-side default or a policy. // In any case, this is not a change we should react to. // Note, we only consider struct fields here. Adding/removing elements to/from maps and slices should trigger updates. - ch.Action = deployplan.ActionTypeSkipString + ch.Action = deployplan.Skip ch.Reason = deployplan.ReasonServerSideDefault } else if structdiff.IsEqual(ch.Remote, ch.New) { - ch.Action = deployplan.ActionTypeSkipString + ch.Action = deployplan.Skip ch.Reason = deployplan.ReasonRemoteAlreadySet } else if action, ok := fieldTriggers[pathString]; ok { // TODO: should we check prefixes instead? - ch.Action = action.String() + ch.Action = action ch.Reason = deployplan.ReasonFieldTriggers } else { - ch.Action = deployplan.ActionTypeUpdateString + ch.Action = deployplan.Update } err = adapter.OverrideChangeDesc(ctx, path, ch, remoteState) @@ -414,8 +414,8 @@ func (b *DeploymentBundle) LookupReferenceLocal(ctx context.Context, path *struc defer b.Plan.ReadUnlockEntry(targetResourceKey) - targetAction := deployplan.ActionTypeFromString(targetEntry.Action) - if targetAction == deployplan.ActionTypeUndefined { + targetAction := targetEntry.Action + if targetAction == deployplan.Undefined { return nil, fmt.Errorf("internal error: %s: missing action in the plan", targetResourceKey) } @@ -476,7 +476,7 @@ func (b *DeploymentBundle) LookupReferenceLocal(ctx context.Context, path *struc if configValidErr != nil && remoteValidErr == nil { // The field is only present in remote state schema. - if targetAction != deployplan.ActionTypeSkip { + if targetAction != deployplan.Skip { // The resource is going to be updated, so remoteState can change return nil, errDelayed } @@ -495,7 +495,7 @@ func (b *DeploymentBundle) LookupReferenceLocal(ctx context.Context, path *struc return value, nil } - if targetAction == deployplan.ActionTypeSkip { + if targetAction == deployplan.Skip { remoteState, ok := b.RemoteStateCache.Load(targetResourceKey) if ok { return structaccess.Get(remoteState, fieldPath) @@ -755,7 +755,7 @@ func (b *DeploymentBundle) makePlan(ctx context.Context, configRoot *config.Root } p.Plan[n] = &deployplan.PlanEntry{ - Action: deployplan.ActionTypeDelete.String(), + Action: deployplan.Delete, DependsOn: entry.DependsOn, } } diff --git a/bundle/direct/dresources/adapter.go b/bundle/direct/dresources/adapter.go index 6e3c213c56..3ddeefc37e 100644 --- a/bundle/direct/dresources/adapter.go +++ b/bundle/direct/dresources/adapter.go @@ -48,7 +48,7 @@ type IResource interface { // [Optional] FieldTriggers returns actions to trigger when given fields are changed. // Keys are field paths (e.g., "name", "catalog_name"). Values are actions. - // Unspecified changed fields default to ActionTypeUpdate. + // Unspecified changed fields default to Update. // // Note: these functions are called once per resource implementation initialization, // not once per resource. @@ -363,7 +363,7 @@ func (a *Adapter) validate() error { if a.overrideChangeDesc == nil { hasUpdateWithIDTrigger := false for _, action := range a.fieldTriggers { - if action == deployplan.ActionTypeUpdateWithID { + if action == deployplan.UpdateWithID { hasUpdateWithIDTrigger = true } } diff --git a/bundle/direct/dresources/all_test.go b/bundle/direct/dresources/all_test.go index e1ba1a7fbf..001dd7af46 100644 --- a/bundle/direct/dresources/all_test.go +++ b/bundle/direct/dresources/all_test.go @@ -672,7 +672,7 @@ func TestFieldTriggersNoUpdateWhenNotImplemented(t *testing.T) { t.Run(resourceName+"_local", func(t *testing.T) { for field, action := range adapter.FieldTriggers() { - assert.NotEqual(t, deployplan.ActionTypeUpdate, action, + assert.NotEqual(t, deployplan.Update, action, "resource %s does not implement DoUpdate but field %s triggers update action", resourceName, field) } }) diff --git a/bundle/direct/dresources/app.go b/bundle/direct/dresources/app.go index 8bc2580870..1cb5d2cccf 100644 --- a/bundle/direct/dresources/app.go +++ b/bundle/direct/dresources/app.go @@ -93,7 +93,7 @@ func (r *ResourceApp) DoDelete(ctx context.Context, id string) error { func (*ResourceApp) FieldTriggers() map[string]deployplan.ActionType { return map[string]deployplan.ActionType{ - "name": deployplan.ActionTypeRecreate, + "name": deployplan.Recreate, } } diff --git a/bundle/direct/dresources/cluster.go b/bundle/direct/dresources/cluster.go index f099d5d0df..40c275cec5 100644 --- a/bundle/direct/dresources/cluster.go +++ b/bundle/direct/dresources/cluster.go @@ -126,19 +126,19 @@ func (r *ResourceCluster) OverrideChangeDesc(ctx context.Context, p *structpath. // We do change skip here in the same way TF provider does suppress diff if the alias is used. // https://github.com/databricks/terraform-provider-databricks/blob/main/clusters/resource_cluster.go#L109-L117 if change.New == compute.DataSecurityModeDataSecurityModeStandard && change.Remote == compute.DataSecurityModeUserIsolation && change.New == change.Old { - change.Action = deployplan.ActionTypeSkipString + change.Action = deployplan.Skip change.Reason = deployplan.ReasonAlias } else if change.New == compute.DataSecurityModeDataSecurityModeDedicated && change.Remote == compute.DataSecurityModeSingleUser && change.New == change.Old { - change.Action = deployplan.ActionTypeSkipString + change.Action = deployplan.Skip change.Reason = deployplan.ReasonAlias } else if change.New == compute.DataSecurityModeDataSecurityModeAuto && (change.Remote == compute.DataSecurityModeSingleUser || change.Remote == compute.DataSecurityModeUserIsolation) && change.New == change.Old { - change.Action = deployplan.ActionTypeSkipString + change.Action = deployplan.Skip change.Reason = deployplan.ReasonAlias } case "num_workers", "autoscale": if remoteState.State == compute.StateRunning { - change.Action = deployplan.ActionTypeResizeString + change.Action = deployplan.Resize } } return nil diff --git a/bundle/direct/dresources/dashboard.go b/bundle/direct/dresources/dashboard.go index b74c643445..a1366996a2 100644 --- a/bundle/direct/dresources/dashboard.go +++ b/bundle/direct/dresources/dashboard.go @@ -308,13 +308,13 @@ func (r *ResourceDashboard) OverrideChangeDesc(_ context.Context, path *structpa // change.New is always nil for etag because it's not present in the config // We compare stored etag with remote one. if change.Old == change.Remote { - change.Action = deployplan.ActionTypeSkipString + change.Action = deployplan.Skip } else { - change.Action = deployplan.ActionTypeUpdateString + change.Action = deployplan.Update } case "parent_path": - if change.Action == deployplan.ActionTypeUpdateString { - change.Action = deployplan.ActionTypeRecreateString + if change.Action == deployplan.Update { + change.Action = deployplan.Recreate } case "serialized_dashboard", "dataset_catalog", "dataset_schema": // "serialized_dashboard" locally and remotely will have different diffs. @@ -324,7 +324,7 @@ func (r *ResourceDashboard) OverrideChangeDesc(_ context.Context, path *structpa // They will always differ between local config (which has values) and remote state (which has empty strings), // so we skip them for remote diff computation to avoid false positives. if change.Old == change.New { - change.Action = deployplan.ActionTypeSkipString + change.Action = deployplan.Skip } } diff --git a/bundle/direct/dresources/experiment.go b/bundle/direct/dresources/experiment.go index 1cce7d31a8..0ee0edcd8c 100644 --- a/bundle/direct/dresources/experiment.go +++ b/bundle/direct/dresources/experiment.go @@ -75,10 +75,10 @@ func (r *ResourceExperiment) DoDelete(ctx context.Context, id string) error { func (*ResourceExperiment) FieldTriggers() map[string]deployplan.ActionType { // TF implementation: https://github.com/databricks/terraform-provider-databricks/blob/6c106e8e7052bb2726148d66309fd460ed444236/mlflow/resource_mlflow_experiment.go#L22 return map[string]deployplan.ActionType{ - "name": deployplan.ActionTypeUpdate, - "artifact_location": deployplan.ActionTypeRecreate, + "name": deployplan.Update, + "artifact_location": deployplan.Recreate, // Tags updates are not supported by TF. This mirrors that behaviour. - "tags": deployplan.ActionTypeSkip, + "tags": deployplan.Skip, } } diff --git a/bundle/direct/dresources/model.go b/bundle/direct/dresources/model.go index 2b290d79c5..de6b057bd5 100644 --- a/bundle/direct/dresources/model.go +++ b/bundle/direct/dresources/model.go @@ -115,7 +115,7 @@ func (*ResourceMlflowModel) FieldTriggers() map[string]deployplan.ActionType { // the [ml.RenameModel] needs to be called instead of [ml.UpdateModel]. // // We might reasonably choose to never fix this because this is a legacy resource. - "name": deployplan.ActionTypeRecreate, + "name": deployplan.Recreate, // Allowing updates for tags requires dynamic selection of the method since // tags can only be updated by calling [ml.SetModelTag] or [ml.DeleteModelTag] methods. @@ -123,6 +123,6 @@ func (*ResourceMlflowModel) FieldTriggers() map[string]deployplan.ActionType { // Skip annotation matches the current behavior of Terraform where tags changes are showed // in plan but are just ignored / not applied. Since this is a legacy resource we might // reasonably choose to not fix it here as well. - "tags": deployplan.ActionTypeSkip, + "tags": deployplan.Skip, } } diff --git a/bundle/direct/dresources/model_serving_endpoint.go b/bundle/direct/dresources/model_serving_endpoint.go index dbf7af4e00..e8899dc678 100644 --- a/bundle/direct/dresources/model_serving_endpoint.go +++ b/bundle/direct/dresources/model_serving_endpoint.go @@ -320,11 +320,11 @@ func (r *ResourceModelServingEndpoint) DoDelete(ctx context.Context, id string) func (*ResourceModelServingEndpoint) FieldTriggers() map[string]deployplan.ActionType { // TF implementation: https://github.com/databricks/terraform-provider-databricks/blob/6c106e8e7052bb2726148d66309fd460ed444236/mlflow/resource_mlflow_experiment.go#L22 return map[string]deployplan.ActionType{ - "name": deployplan.ActionTypeRecreate, - "description": deployplan.ActionTypeRecreate, // description is immutable, can't be updated via API - "config.auto_capture_config.catalog_name": deployplan.ActionTypeRecreate, - "config.auto_capture_config.schema_name": deployplan.ActionTypeRecreate, - "config.auto_capture_config.table_name_prefix": deployplan.ActionTypeRecreate, - "route_optimized": deployplan.ActionTypeRecreate, + "name": deployplan.Recreate, + "description": deployplan.Recreate, // description is immutable, can't be updated via API + "config.auto_capture_config.catalog_name": deployplan.Recreate, + "config.auto_capture_config.schema_name": deployplan.Recreate, + "config.auto_capture_config.table_name_prefix": deployplan.Recreate, + "route_optimized": deployplan.Recreate, } } diff --git a/bundle/direct/dresources/pipeline.go b/bundle/direct/dresources/pipeline.go index 5355a607c3..5ca6405b49 100644 --- a/bundle/direct/dresources/pipeline.go +++ b/bundle/direct/dresources/pipeline.go @@ -124,9 +124,9 @@ func (r *ResourcePipeline) DoDelete(ctx context.Context, id string) error { func (*ResourcePipeline) FieldTriggers() map[string]deployplan.ActionType { result := map[string]deployplan.ActionType{ - "storage": deployplan.ActionTypeRecreate, - "ingestion_definition.connection_name": deployplan.ActionTypeRecreate, - "ingestion_definition.ingestion_gateway_id": deployplan.ActionTypeRecreate, + "storage": deployplan.Recreate, + "ingestion_definition.connection_name": deployplan.Recreate, + "ingestion_definition.ingestion_gateway_id": deployplan.Recreate, } return result @@ -135,7 +135,7 @@ func (*ResourcePipeline) FieldTriggers() map[string]deployplan.ActionType { func (*ResourcePipeline) OverrideChangeDesc(ctx context.Context, path *structpath.PathNode, ch *ChangeDesc, _ *pipelines.GetPipelineResponse) error { if path.String() == "run_as" { if structdiff.IsEqual(ch.Old, ch.New) { - ch.Action = deployplan.ActionTypeSkipString + ch.Action = deployplan.Skip ch.Reason = "override" } } diff --git a/bundle/direct/dresources/registered_model.go b/bundle/direct/dresources/registered_model.go index cd2feaf696..458dafe873 100644 --- a/bundle/direct/dresources/registered_model.go +++ b/bundle/direct/dresources/registered_model.go @@ -107,10 +107,10 @@ func (*ResourceRegisteredModel) FieldTriggers() map[string]deployplan.ActionType return map[string]deployplan.ActionType{ // The name can technically be updated without recreated. We recreate for now though // to match TF implementation. - "name": deployplan.ActionTypeRecreate, + "name": deployplan.Recreate, - "catalog_name": deployplan.ActionTypeRecreate, - "schema_name": deployplan.ActionTypeRecreate, - "storage_location": deployplan.ActionTypeRecreate, + "catalog_name": deployplan.Recreate, + "schema_name": deployplan.Recreate, + "storage_location": deployplan.Recreate, } } diff --git a/bundle/direct/dresources/schema.go b/bundle/direct/dresources/schema.go index 1c09817617..4ed682566f 100644 --- a/bundle/direct/dresources/schema.go +++ b/bundle/direct/dresources/schema.go @@ -80,8 +80,8 @@ func (r *ResourceSchema) DoDelete(ctx context.Context, id string) error { func (*ResourceSchema) FieldTriggers() map[string]deployplan.ActionType { return map[string]deployplan.ActionType{ - "name": deployplan.ActionTypeRecreate, - "catalog_name": deployplan.ActionTypeRecreate, - "storage_root": deployplan.ActionTypeRecreate, + "name": deployplan.Recreate, + "catalog_name": deployplan.Recreate, + "storage_root": deployplan.Recreate, } } diff --git a/bundle/direct/dresources/secret_scope.go b/bundle/direct/dresources/secret_scope.go index 6aa960cdc9..34c838b000 100644 --- a/bundle/direct/dresources/secret_scope.go +++ b/bundle/direct/dresources/secret_scope.go @@ -85,9 +85,9 @@ func (r *ResourceSecretScope) DoDelete(ctx context.Context, id string) error { func (r *ResourceSecretScope) FieldTriggers() map[string]deployplan.ActionType { return map[string]deployplan.ActionType{ - "scope": deployplan.ActionTypeRecreate, - "scope_backend_type": deployplan.ActionTypeRecreate, - "backend_azure_keyvault": deployplan.ActionTypeRecreate, - "initial_manage_principal": deployplan.ActionTypeRecreate, + "scope": deployplan.Recreate, + "scope_backend_type": deployplan.Recreate, + "backend_azure_keyvault": deployplan.Recreate, + "initial_manage_principal": deployplan.Recreate, } } diff --git a/bundle/direct/dresources/secret_scope_acls.go b/bundle/direct/dresources/secret_scope_acls.go index 4c110a60f3..e8f201b66a 100644 --- a/bundle/direct/dresources/secret_scope_acls.go +++ b/bundle/direct/dresources/secret_scope_acls.go @@ -119,7 +119,7 @@ func (r *ResourceSecretScopeAcls) FieldTriggers() map[string]deployplan.ActionTy // When scope name changes, we need a DoUpdateWithID trigger. This is necessary so that subsequent // DoRead operations use the correct ID and we do not end up with a persistent drift. return map[string]deployplan.ActionType{ - "scope_name": deployplan.ActionTypeUpdateWithID, + "scope_name": deployplan.UpdateWithID, } } diff --git a/bundle/direct/dresources/volume.go b/bundle/direct/dresources/volume.go index 6c490e5d15..3912f07eb5 100644 --- a/bundle/direct/dresources/volume.go +++ b/bundle/direct/dresources/volume.go @@ -115,11 +115,11 @@ func (r *ResourceVolume) DoDelete(ctx context.Context, id string) error { func (*ResourceVolume) FieldTriggers() map[string]deployplan.ActionType { return map[string]deployplan.ActionType{ - "catalog_name": deployplan.ActionTypeRecreate, - "schema_name": deployplan.ActionTypeRecreate, - "storage_location": deployplan.ActionTypeRecreate, - "volume_type": deployplan.ActionTypeRecreate, - "name": deployplan.ActionTypeUpdateWithID, + "catalog_name": deployplan.Recreate, + "schema_name": deployplan.Recreate, + "storage_location": deployplan.Recreate, + "volume_type": deployplan.Recreate, + "name": deployplan.UpdateWithID, } } diff --git a/bundle/direct/graph.go b/bundle/direct/graph.go index 5770377c90..433eb8dc57 100644 --- a/bundle/direct/graph.go +++ b/bundle/direct/graph.go @@ -23,7 +23,7 @@ func makeGraph(plan *deployplan.Plan) (*dagrun.Graph, error) { continue } - isDelete := entry.Action == deployplan.ActionTypeDelete.String() + isDelete := entry.Action == deployplan.Delete for _, dep := range entry.DependsOn { if _, exists := plan.Plan[dep.Node]; exists { diff --git a/bundle/phases/deploy.go b/bundle/phases/deploy.go index 065e2f46dd..be3f260329 100644 --- a/bundle/phases/deploy.go +++ b/bundle/phases/deploy.go @@ -34,7 +34,7 @@ func approvalForDeploy(ctx context.Context, b *bundle.Bundle, plan *deployplan.P return false, err } - types := []deployplan.ActionType{deployplan.ActionTypeRecreate, deployplan.ActionTypeDelete} + types := []deployplan.ActionType{deployplan.Recreate, deployplan.Delete} schemaActions := filterGroup(actions, "schemas", types...) dltActions := filterGroup(actions, "pipelines", types...) volumeActions := filterGroup(actions, "volumes", types...) @@ -249,7 +249,7 @@ func RunPlan(ctx context.Context, b *bundle.Bundle, engine engine.EngineType) *d resourceKey := "resources." + group.Description.PluralName + "." + rKey if _, ok := plan.Plan[resourceKey]; !ok { plan.Plan[resourceKey] = &deployplan.PlanEntry{ - Action: deployplan.ActionTypeSkip.String(), + Action: deployplan.Skip, } } } diff --git a/bundle/phases/destroy.go b/bundle/phases/destroy.go index e66d2f5e6a..d4e6010cec 100644 --- a/bundle/phases/destroy.go +++ b/bundle/phases/destroy.go @@ -51,9 +51,9 @@ func approvalForDestroy(ctx context.Context, b *bundle.Bundle, plan *deployplan. cmdio.LogString(ctx, "") } - schemaActions := filterGroup(deleteActions, "schemas", deployplan.ActionTypeDelete) - dltActions := filterGroup(deleteActions, "pipelines", deployplan.ActionTypeDelete) - volumeActions := filterGroup(deleteActions, "volumes", deployplan.ActionTypeDelete) + schemaActions := filterGroup(deleteActions, "schemas", deployplan.Delete) + dltActions := filterGroup(deleteActions, "pipelines", deployplan.Delete) + volumeActions := filterGroup(deleteActions, "volumes", deployplan.Delete) if len(schemaActions) > 0 { cmdio.LogString(ctx, deleteSchemaMessage) diff --git a/bundle/phases/plan.go b/bundle/phases/plan.go index a1c85ddf4d..a8926e707f 100644 --- a/bundle/phases/plan.go +++ b/bundle/phases/plan.go @@ -34,7 +34,7 @@ func checkForPreventDestroy(b *bundle.Bundle, actions []deployplan.Action) error root := b.Config.Value() var errs []error for _, action := range actions { - if action.ActionType != deployplan.ActionTypeRecreate && action.ActionType != deployplan.ActionTypeDelete { + if action.ActionType != deployplan.Recreate && action.ActionType != deployplan.Delete { continue } diff --git a/bundle/phases/plan_test.go b/bundle/phases/plan_test.go index e52d6dff7b..c6d0091c09 100644 --- a/bundle/phases/plan_test.go +++ b/bundle/phases/plan_test.go @@ -49,7 +49,7 @@ func TestCheckPreventDestroyForAllResources(t *testing.T) { actions := []deployplan.Action{ { ResourceKey: "resources." + resourceType + ".test_resource", - ActionType: deployplan.ActionTypeRecreate, + ActionType: deployplan.Recreate, }, } @@ -95,11 +95,11 @@ func TestCheckForPreventDestroyWhenFirstHasNoPreventDestroy(t *testing.T) { actions := []deployplan.Action{ { ResourceKey: "resources.jobs.test_job", - ActionType: deployplan.ActionTypeRecreate, + ActionType: deployplan.Recreate, }, { ResourceKey: "resources.apps.test_app", - ActionType: deployplan.ActionTypeRecreate, + ActionType: deployplan.Recreate, }, } diff --git a/cmd/bundle/deployment/migrate.go b/cmd/bundle/deployment/migrate.go index 13d7053430..e147cbde6c 100644 --- a/cmd/bundle/deployment/migrate.go +++ b/cmd/bundle/deployment/migrate.go @@ -232,7 +232,7 @@ To start using direct engine, deploy with DATABRICKS_BUNDLE_ENGINE=direct env va for _, entry := range plan.Plan { // Force all actions to be "update" so that deploym below goes through every resource - entry.Action = deployplan.ActionTypeUpdateString + entry.Action = deployplan.Update } // We need to copy ETag into new state. diff --git a/cmd/bundle/plan.go b/cmd/bundle/plan.go index bee61bd160..e3dd63929e 100644 --- a/cmd/bundle/plan.go +++ b/cmd/bundle/plan.go @@ -75,17 +75,17 @@ It is useful for previewing changes before running 'bundle deploy'.`, for _, change := range plan.GetActions() { switch change.ActionType { - case deployplan.ActionTypeCreate: + case deployplan.Create: createCount++ - case deployplan.ActionTypeUpdate, deployplan.ActionTypeUpdateWithID, deployplan.ActionTypeResize: + case deployplan.Update, deployplan.UpdateWithID, deployplan.Resize: updateCount++ - case deployplan.ActionTypeDelete: + case deployplan.Delete: deleteCount++ - case deployplan.ActionTypeRecreate: + case deployplan.Recreate: // A recreate counts as both a delete and a create deleteCount++ createCount++ - case deployplan.ActionTypeSkip, deployplan.ActionTypeUndefined: + case deployplan.Skip, deployplan.Undefined: unchangedCount++ } } @@ -99,7 +99,7 @@ It is useful for previewing changes before running 'bundle deploy'.`, if totalChanges > 0 { // Print all actions in the order they were processed for _, action := range plan.GetActions() { - if action.ActionType == deployplan.ActionTypeSkip { + if action.ActionType == deployplan.Skip { continue } key := strings.TrimPrefix(action.ResourceKey, "resources.")