Skip to content

Commit

Permalink
Marshal contents of 'serialized_dashboard' if not a string
Browse files Browse the repository at this point in the history
  • Loading branch information
pietern committed Oct 24, 2024
1 parent c4df41c commit a3e32c0
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 3 deletions.
41 changes: 38 additions & 3 deletions bundle/deploy/terraform/tfdyn/convert_dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package tfdyn

import (
"context"
"encoding/json"
"fmt"

"github.com/databricks/cli/bundle/internal/tf/schema"
Expand All @@ -10,6 +11,34 @@ import (
"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) {
var err error

Expand All @@ -22,8 +51,8 @@ func convertDashboardResource(ctx context.Context, vin dyn.Value) (dyn.Value, er
// Include "serialized_dashboard" field if "file_path" is set.
// 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).
if path, ok := vout.Get("file_path").AsString(); ok {
vout, err = dyn.Set(vout, "serialized_dashboard", dyn.V(fmt.Sprintf("${file(\"%s\")}", path)))
if path, ok := vout.Get(filePathFieldName).AsString(); ok {
vout, err = dyn.Set(vout, serializedDashboardFieldName, dyn.V(fmt.Sprintf("${file(\"%s\")}", path)))
if err != nil {
return dyn.InvalidValue, fmt.Errorf("failed to set serialized_dashboard: %w", err)
}
Expand All @@ -33,7 +62,7 @@ func convertDashboardResource(ctx context.Context, vin dyn.Value) (dyn.Value, er
case 0:
return v, nil
case 1:
if p[0] == dyn.Key("file_path") {
if p[0] == dyn.Key(filePathFieldName) {
return v, dyn.ErrDrop
}
}
Expand All @@ -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
}

Expand Down
45 changes: 45 additions & 0 deletions bundle/deploy/terraform/tfdyn/convert_dashboard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,48 @@ func TestConvertDashboardFilePath(t *testing.T) {
"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":[]}]}`,
})
}

0 comments on commit a3e32c0

Please sign in to comment.