Marshal contents of 'serialized_dashboard' if not a string

This commit is contained in:
Pieter Noordhuis 2024-10-24 17:10:13 +02:00
parent c4df41c3d6
commit a3e32c0adb
No known key found for this signature in database
GPG Key ID: 12ACCCC104CF2930
2 changed files with 83 additions and 3 deletions

View File

@ -2,6 +2,7 @@ package tfdyn
import ( import (
"context" "context"
"encoding/json"
"fmt" "fmt"
"github.com/databricks/cli/bundle/internal/tf/schema" "github.com/databricks/cli/bundle/internal/tf/schema"
@ -10,6 +11,34 @@ import (
"github.com/databricks/cli/libs/log" "github.com/databricks/cli/libs/log"
) )
const (
filePathFieldName = "file_path"
serializedDashboardFieldName = "serialized_dashboard"
)
// Marshal "serialized_dashboard" as JSON if it is set in the input but not in the output.
func marshalSerializedDashboard(vin dyn.Value, vout dyn.Value) (dyn.Value, error) {
// Skip if the "serialized_dashboard" field is already set.
if v := vout.Get(serializedDashboardFieldName); v.IsValid() {
return vout, nil
}
// Skip if the "serialized_dashboard" field on the input is not set.
v := vin.Get(serializedDashboardFieldName)
if !v.IsValid() {
return vout, nil
}
// Marshal the "serialized_dashboard" field as JSON.
data, err := json.Marshal(v.AsAny())
if err != nil {
return dyn.InvalidValue, fmt.Errorf("failed to marshal serialized_dashboard: %w", err)
}
// Set the "serialized_dashboard" field on the output.
return dyn.Set(vout, serializedDashboardFieldName, dyn.V(string(data)))
}
func convertDashboardResource(ctx context.Context, vin dyn.Value) (dyn.Value, error) { func convertDashboardResource(ctx context.Context, vin dyn.Value) (dyn.Value, error) {
var err error var err error
@ -22,8 +51,8 @@ func convertDashboardResource(ctx context.Context, vin dyn.Value) (dyn.Value, er
// Include "serialized_dashboard" field if "file_path" is set. // Include "serialized_dashboard" field if "file_path" is set.
// Note: the Terraform resource supports "file_path" natively, but its // Note: the Terraform resource supports "file_path" natively, but its
// change detection mechanism doesn't work as expected at the time of writing (Sep 30). // change detection mechanism doesn't work as expected at the time of writing (Sep 30).
if path, ok := vout.Get("file_path").AsString(); ok { if path, ok := vout.Get(filePathFieldName).AsString(); ok {
vout, err = dyn.Set(vout, "serialized_dashboard", dyn.V(fmt.Sprintf("${file(\"%s\")}", path))) vout, err = dyn.Set(vout, serializedDashboardFieldName, dyn.V(fmt.Sprintf("${file(\"%s\")}", path)))
if err != nil { if err != nil {
return dyn.InvalidValue, fmt.Errorf("failed to set serialized_dashboard: %w", err) return dyn.InvalidValue, fmt.Errorf("failed to set serialized_dashboard: %w", err)
} }
@ -33,7 +62,7 @@ func convertDashboardResource(ctx context.Context, vin dyn.Value) (dyn.Value, er
case 0: case 0:
return v, nil return v, nil
case 1: case 1:
if p[0] == dyn.Key("file_path") { if p[0] == dyn.Key(filePathFieldName) {
return v, dyn.ErrDrop return v, dyn.ErrDrop
} }
} }
@ -46,6 +75,12 @@ func convertDashboardResource(ctx context.Context, vin dyn.Value) (dyn.Value, er
} }
} }
// Marshal "serialized_dashboard" as JSON if it is set in the input but not in the output.
vout, err = marshalSerializedDashboard(vin, vout)
if err != nil {
return dyn.InvalidValue, err
}
return vout, nil return vout, nil
} }

View File

@ -82,3 +82,48 @@ func TestConvertDashboardFilePath(t *testing.T) {
"file_path": "some/path", "file_path": "some/path",
}) })
} }
func TestConvertDashboardSerializedDashboardString(t *testing.T) {
var src = resources.Dashboard{
SerializedDashboard: `{ "json": true }`,
}
vin, err := convert.FromTyped(src, dyn.NilValue)
require.NoError(t, err)
ctx := context.Background()
out := schema.NewResources()
err = dashboardConverter{}.Convert(ctx, "my_dashboard", vin, out)
require.NoError(t, err)
// Assert that the "serialized_dashboard" is included.
assert.Subset(t, out.Dashboard["my_dashboard"], map[string]any{
"serialized_dashboard": `{ "json": true }`,
})
}
func TestConvertDashboardSerializedDashboardAny(t *testing.T) {
var src = resources.Dashboard{
SerializedDashboard: map[string]any{
"pages": []map[string]any{
{
"displayName": "New Page",
"layout": []map[string]any{},
},
},
},
}
vin, err := convert.FromTyped(src, dyn.NilValue)
require.NoError(t, err)
ctx := context.Background()
out := schema.NewResources()
err = dashboardConverter{}.Convert(ctx, "my_dashboard", vin, out)
require.NoError(t, err)
// Assert that the "serialized_dashboard" is included.
assert.Subset(t, out.Dashboard["my_dashboard"], map[string]any{
"serialized_dashboard": `{"pages":[{"displayName":"New Page","layout":[]}]}`,
})
}