diff --git a/bundle/direct/apply.go b/bundle/direct/apply.go index b10df8ceb4..42d80efab3 100644 --- a/bundle/direct/apply.go +++ b/bundle/direct/apply.go @@ -14,17 +14,13 @@ import ( ) func (d *DeploymentUnit) Destroy(ctx context.Context, db *dstate.DeploymentState) error { - entry, hasEntry := db.GetResourceEntry(d.ResourceKey) - if !hasEntry { + id := db.GetResourceID(d.ResourceKey) + if id == "" { log.Infof(ctx, "Cannot delete %s: missing from state", d.ResourceKey) return nil } - if entry.ID == "" { - return errors.New("invalid state: empty id") - } - - return d.Delete(ctx, db, entry.ID) + return d.Delete(ctx, db, id) } func (d *DeploymentUnit) Deploy(ctx context.Context, db *dstate.DeploymentState, newState any, actionType deployplan.ActionType, planEntry *deployplan.PlanEntry) error { @@ -32,14 +28,9 @@ func (d *DeploymentUnit) Deploy(ctx context.Context, db *dstate.DeploymentState, return d.Create(ctx, db, newState) } - entry, hasEntry := db.GetResourceEntry(d.ResourceKey) - if !hasEntry { - return errors.New("state entry not found") - } - - oldID := entry.ID + oldID := db.GetResourceID(d.ResourceKey) if oldID == "" { - return errors.New("invalid state: empty id") + return errors.New("state entry not found") } switch actionType { diff --git a/bundle/direct/bind.go b/bundle/direct/bind.go index b476319ed7..d01484af13 100644 --- a/bundle/direct/bind.go +++ b/bundle/direct/bind.go @@ -63,10 +63,10 @@ func (b *DeploymentBundle) Bind(ctx context.Context, client *databricks.Workspac // Check if the resource is already managed (bound to a different ID) var checkStateDB dstate.DeploymentState if err := checkStateDB.Open(statePath); err == nil { - if existing, ok := checkStateDB.GetResourceEntry(resourceKey); ok { + if existingID := checkStateDB.GetResourceID(resourceKey); existingID != "" { return nil, ErrResourceAlreadyBound{ ResourceKey: resourceKey, - ExistingID: existing.ID, + ExistingID: existingID, NewID: resourceID, } } diff --git a/bundle/direct/bundle_apply.go b/bundle/direct/bundle_apply.go index ea3f615f7f..af1cadfaf2 100644 --- a/bundle/direct/bundle_apply.go +++ b/bundle/direct/bundle_apply.go @@ -113,12 +113,12 @@ func (b *DeploymentBundle) Apply(ctx context.Context, client *databricks.Workspa if migrateMode { // In migration mode we're reading resources in DAG order so that we have fully resolved config snapshots stored - dbentry, hasEntry := b.StateDB.GetResourceEntry(resourceKey) - if !hasEntry || dbentry.ID == "" { + id := b.StateDB.GetResourceID(resourceKey) + if id == "" { logdiag.LogError(ctx, fmt.Errorf("state entry not found for %q", resourceKey)) return false } - err = b.StateDB.SaveState(resourceKey, dbentry.ID, sv.Value, entry.DependsOn) + err = b.StateDB.SaveState(resourceKey, id, sv.Value, entry.DependsOn) } else { // TODO: redo calcDiff to downgrade planned action if possible (?) err = d.Deploy(ctx, &b.StateDB, sv.Value, action, entry) @@ -135,13 +135,13 @@ func (b *DeploymentBundle) Apply(ctx context.Context, client *databricks.Workspa // already resolved and should not play a role here. needRemoteState := len(g.Adj[resourceKey]) > 0 if needRemoteState { - entry, _ := b.StateDB.GetResourceEntry(d.ResourceKey) - if entry.ID == "" { + id := b.StateDB.GetResourceID(d.ResourceKey) + if id == "" { logdiag.LogError(ctx, fmt.Errorf("%s: internal error: missing entry in state after deploy", errorPrefix)) return false } - err = d.refreshRemoteState(ctx, entry.ID) + err = d.refreshRemoteState(ctx, id) if err != nil { logdiag.LogError(ctx, fmt.Errorf("%s: failed to read remote state: %w", errorPrefix, err)) return false @@ -180,11 +180,11 @@ func (b *DeploymentBundle) LookupReferencePostDeploy(ctx context.Context, path * } if fieldPathS == "id" { - dbentry, hasEntry := b.StateDB.GetResourceEntry(targetResourceKey) - if !hasEntry || dbentry.ID == "" { + id := b.StateDB.GetResourceID(targetResourceKey) + if id == "" { return nil, errors.New("internal error: no db entry") } - return dbentry.ID, nil + return id, nil } remoteState, ok := b.RemoteStateCache.Load(targetResourceKey) diff --git a/bundle/direct/bundle_plan.go b/bundle/direct/bundle_plan.go index 9ee4347450..8bd2b4bfd1 100644 --- a/bundle/direct/bundle_plan.go +++ b/bundle/direct/bundle_plan.go @@ -168,19 +168,19 @@ func (b *DeploymentBundle) CalculatePlan(ctx context.Context, client *databricks } if entry.Action == deployplan.Delete { - dbentry, hasEntry := b.StateDB.GetResourceEntry(resourceKey) - if !hasEntry { + id := b.StateDB.GetResourceID(resourceKey) + if id == "" { logdiag.LogError(ctx, fmt.Errorf("%s: internal error, missing in state", errorPrefix)) return false } - remoteState, err := adapter.DoRead(ctx, dbentry.ID) + remoteState, err := adapter.DoRead(ctx, id) if err != nil { if isResourceGone(err) { // no such resource plan.RemoveEntry(resourceKey) } else { - log.Warnf(ctx, "reading %s id=%q: %s", resourceKey, dbentry.ID, err) + log.Warnf(ctx, "reading %s id=%q: %s", resourceKey, id, err) // This is not an error during deletion, so don't return false here } } @@ -605,12 +605,11 @@ func (b *DeploymentBundle) LookupReferencePreDeploy(ctx context.Context, path *s if fieldPathS == "id" { if targetAction.KeepsID() { - dbentry, hasEntry := b.StateDB.GetResourceEntry(targetResourceKey) - idValue := dbentry.ID - if !hasEntry || idValue == "" { + id := b.StateDB.GetResourceID(targetResourceKey) + if id == "" { return nil, errors.New("internal error: no db entry") } - return idValue, nil + return id, nil } // id may change after deployment, this needs to be done later return nil, errDelayed diff --git a/bundle/direct/dstate/state.go b/bundle/direct/dstate/state.go index e1c776b479..3fb88de9b0 100644 --- a/bundle/direct/dstate/state.go +++ b/bundle/direct/dstate/state.go @@ -84,7 +84,7 @@ func (db *DeploymentState) DeleteState(key string) error { return nil } -func (db *DeploymentState) GetResourceEntry(key string) (ResourceEntry, bool) { +func (db *DeploymentState) getResourceEntry(key string) (ResourceEntry, bool) { db.AssertOpened() db.mu.Lock() defer db.mu.Unlock() @@ -97,6 +97,17 @@ func (db *DeploymentState) GetResourceEntry(key string) (ResourceEntry, bool) { return result, ok } +// GetResourceEntry returns the full resource entry for the given key. +func (db *DeploymentState) GetResourceEntry(key string) (ResourceEntry, bool) { + return db.getResourceEntry(key) +} + +// GetResourceID returns the ID of the resource for the given key, or an empty string if not found. +func (db *DeploymentState) GetResourceID(key string) string { + entry, _ := db.getResourceEntry(key) + return entry.ID +} + func (db *DeploymentState) Open(path string) error { db.mu.Lock() defer db.mu.Unlock()