Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,16 @@ read_state.py secrets secret1 name expire_time
title "Remove expire_time and re-deploy"
trace update_file.py databricks.yml ' expire_time: "2030-01-01T00:00:00Z"' ""
trace $CLI bundle plan --var secret_value=secret-value
trace $CLI bundle plan --var secret_value=secret-value -o json | nostamp | jq '.plan."resources.secrets.secret1" | {action, changes}' > out.plan.$DATABRICKS_BUNDLE_ENGINE.json
# Project to expire_time (the field this test is about): the full changes set now carries
# output-only fields whose remote values differ between the testserver and a real workspace
# (metastore_id, comment, timestamps), which is noise here and breaks the Cloud run.
trace $CLI bundle plan --var secret_value=secret-value -o json | nostamp | jq '.plan."resources.secrets.secret1" | {action, changes: (.changes | {expire_time, owner, value})}' > out.plan.$DATABRICKS_BUNDLE_ENGINE.json
trace $CLI bundle deploy --var secret_value=secret-value
trace print_requests.py //unity-catalog
read_state.py secrets secret1 name expire_time

title "Plan again to record any drift the removal leaves behind"
trace $CLI bundle plan --var secret_value=secret-value
trace $CLI bundle plan --var secret_value=secret-value -o json | nostamp | jq '.plan."resources.secrets.secret1" | {action, changes}' > out.plan.drift.$DATABRICKS_BUNDLE_ENGINE.json
trace $CLI bundle plan --var secret_value=secret-value -o json | nostamp | jq '.plan."resources.secrets.secret1" | {action, changes: (.changes | {expire_time, owner, value})}' > out.plan.drift.$DATABRICKS_BUNDLE_ENGINE.json

rm -f "$OUT_REQUESTS"
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ read_state.py secrets secret1 name expire_time
title "Change expire_time and re-deploy"
trace update_file.py databricks.yml "2030-01-01T00:00:00Z" "2031-06-15T12:00:00Z"
trace $CLI bundle plan --var secret_value=secret-value
trace $CLI bundle plan --var secret_value=secret-value -o json | nostamp | jq '.plan."resources.secrets.secret1" | {action, changes}' > out.plan.$DATABRICKS_BUNDLE_ENGINE.json
# Project to expire_time (the field this test is about): the full changes set now carries
# output-only fields whose remote values differ between the testserver and a real workspace
# (metastore_id, comment, timestamps), which is noise here and breaks the Cloud run.
trace $CLI bundle plan --var secret_value=secret-value -o json | nostamp | jq '.plan."resources.secrets.secret1" | {action, changes: (.changes | {expire_time, owner, value})}' > out.plan.$DATABRICKS_BUNDLE_ENGINE.json
trace $CLI bundle deploy --var secret_value=secret-value
trace print_requests.py //unity-catalog
read_state.py secrets secret1 name expire_time
Expand Down
40 changes: 40 additions & 0 deletions acceptance/bundle/resources/secrets/update-value/output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,51 @@ secrets secret1 catalog_name='main' schema_name='default' name='test_secret' com
"value": "[redacted]"
},
"changes": {
"create_time": {
"action": "skip",
"reason": "spec:output_only",
"remote": "[TIMESTAMP]"
},
"created_by": {
"action": "skip",
"reason": "spec:output_only",
"remote": "[USERNAME]"
},
"effective_owner": {
"action": "skip",
"reason": "spec:output_only",
"remote": "[USERNAME]"
},
"effective_value": {
"action": "skip",
"reason": "spec:output_only",
"remote": "[redacted]"
},
"full_name": {
"action": "skip",
"reason": "spec:output_only",
"remote": "main.default.test_secret"
},
"metastore_id": {
"action": "skip",
"reason": "spec:output_only",
"remote": "test-metastore-id"
},
"owner": {
"action": "skip",
"reason": "spec:input_only",
"remote": "[USERNAME]"
},
"update_time": {
"action": "skip",
"reason": "spec:output_only",
"remote": "[TIMESTAMP]"
},
"updated_by": {
"action": "skip",
"reason": "spec:output_only",
"remote": "[USERNAME]"
},
"value": {
"action": "update",
"old": "",
Expand Down
41 changes: 18 additions & 23 deletions bundle/direct/dresources/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,35 +45,30 @@ func (*ResourceSecret) PrepareState(input *resources.Secret) *catalog.Secret {
}
}

func (*ResourceSecret) RemapState(remote *catalog.Secret) *catalog.Secret {
return &catalog.Secret{
CatalogName: remote.CatalogName,
SchemaName: remote.SchemaName,
Name: remote.Name,
Value: remote.EffectiveValue,
Comment: remote.Comment,
ExpireTime: remote.ExpireTime,
Owner: remote.EffectiveOwner,
CreateTime: nil,
CreatedBy: "",
EffectiveOwner: "",
EffectiveValue: "",
FullName: "",
MetastoreId: "",
UpdateTime: nil,
UpdatedBy: "",
ForceSendFields: utils.FilterFields[catalog.Secret](nil),
}
// remapSecretRemote surfaces the resolved value and owner (the API returns them under
// effective_value/effective_owner) under value/owner so remote state matches the config
// shape — without this, the persisted value is empty and every plan re-reports an update.
// The rest of the secret, including the output-only metadata, is left intact and handled
// by ignore_remote_changes, so no information is discarded. It runs wherever remote state
// is produced (DoRead/DoCreate/DoUpdate), so no RemapState hook is needed.
func remapSecretRemote(remote *catalog.Secret) *catalog.Secret {
remote.Value = remote.EffectiveValue
remote.Owner = remote.EffectiveOwner
return remote
}

// DoRead fetches the secret by full name. IncludeValue is set so RemapState can
// DoRead fetches the secret by full name. IncludeValue is set so remapSecretRemote can
// recover the stored value from EffectiveValue.
func (r *ResourceSecret) DoRead(ctx context.Context, id string) (*catalog.Secret, error) {
return r.client.SecretsUc.GetSecret(ctx, catalog.GetSecretRequest{
remote, err := r.client.SecretsUc.GetSecret(ctx, catalog.GetSecretRequest{
FullName: id,
IncludeValue: true,
ForceSendFields: nil,
})
if err != nil {
return nil, err
}
return remapSecretRemote(remote), nil
}

// DoCreate creates a new UC secret.
Expand All @@ -84,7 +79,7 @@ func (r *ResourceSecret) DoCreate(ctx context.Context, state *catalog.Secret) (s
if err != nil || response == nil {
return "", nil, err
}
return response.FullName, response, nil
return response.FullName, remapSecretRemote(response), nil
}

// comment is force-sent on update so that clearing it in config clears it on the secret. The
Expand All @@ -106,7 +101,7 @@ func (r *ResourceSecret) DoUpdate(ctx context.Context, id string, state *catalog
if err != nil {
return nil, err
}
return response, nil
return remapSecretRemote(response), nil
}

// DoDelete deletes the secret.
Expand Down
Loading