diff --git a/docs/resources/metadata.md b/docs/resources/metadata.md index d8329ea9..cbf9d288 100644 --- a/docs/resources/metadata.md +++ b/docs/resources/metadata.md @@ -43,16 +43,19 @@ resource "coder_metadata" "pod_info" { item { key = "description" value = "This description will show up in the Coder dashboard." + order = 1 } item { key = "pod_uid" value = kubernetes_pod.dev[0].uid + order = 2 } item { key = "public_key" value = tls_private_key.example_key_pair.public_key_openssh # The value of this item will be hidden from view by default sensitive = true + order = 3 } } ``` @@ -84,6 +87,7 @@ Required: Optional: +- `order` (Number) The order determines the position of item in the UI presentation. The lowest order is shown first and items with equal order are sorted by key (ascending order). - `sensitive` (Boolean) Set to `true` to for items such as API keys whose values should be hidden from view by default. Note that this does not prevent metadata from being retrieved using the API, so it is not suitable for secrets that should not be exposed to workspace users. - `value` (String) The value of this metadata item. Supports basic Markdown, including hyperlinks. diff --git a/examples/resources/coder_metadata/resource.tf b/examples/resources/coder_metadata/resource.tf index 0491ce57..b73f6427 100644 --- a/examples/resources/coder_metadata/resource.tf +++ b/examples/resources/coder_metadata/resource.tf @@ -25,15 +25,18 @@ resource "coder_metadata" "pod_info" { item { key = "description" value = "This description will show up in the Coder dashboard." + order = 1 } item { key = "pod_uid" value = kubernetes_pod.dev[0].uid + order = 2 } item { key = "public_key" value = tls_private_key.example_key_pair.public_key_openssh # The value of this item will be hidden from view by default sensitive = true + order = 3 } } diff --git a/provider/metadata.go b/provider/metadata.go index 5ed6d478..b70bb451 100644 --- a/provider/metadata.go +++ b/provider/metadata.go @@ -103,6 +103,12 @@ func metadataResource() *schema.Resource { ForceNew: true, Computed: true, }, + "order": { + Type: schema.TypeInt, + Description: "The order determines the position of item in the UI presentation. The lowest order is shown first and items with equal order are sorted by key (ascending order).", + ForceNew: true, + Optional: true, + }, }, }, }, diff --git a/provider/metadata_test.go b/provider/metadata_test.go index 3164e65b..5dbd31e0 100644 --- a/provider/metadata_test.go +++ b/provider/metadata_test.go @@ -35,17 +35,21 @@ func TestMetadata(t *testing.T) { key = "secret" value = "squirrel" sensitive = true + order = 1 } item { key = "implicit_null" + order = 2 } item { key = "explicit_null" value = null + order = 3 } item { key = "empty" value = "" + order = 4 } } `, @@ -66,19 +70,24 @@ func TestMetadata(t *testing.T) { "item.0.key": "foo", "item.0.value": "bar", "item.0.sensitive": "false", + "item.0.order": "0", "item.1.key": "secret", "item.1.value": "squirrel", "item.1.sensitive": "true", + "item.1.order": "1", "item.2.key": "implicit_null", "item.2.is_null": "true", "item.2.sensitive": "false", + "item.2.order": "2", "item.3.key": "explicit_null", "item.3.is_null": "true", "item.3.sensitive": "false", + "item.3.order": "3", "item.4.key": "empty", "item.4.value": "", "item.4.is_null": "false", "item.4.sensitive": "false", + "item.4.order": "4", } { require.Equal(t, expected, metadata.Primary.Attributes[key]) } diff --git a/provider/provider.go b/provider/provider.go index 2b6409ba..bbcfebf9 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/hashicorp/go-cty/cty" + "github.com/hashicorp/go-cty/cty/gocty" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "golang.org/x/xerrors" @@ -99,10 +100,16 @@ func populateIsNull(resourceData *schema.ResourceData) (result interface{}, err var resultItems []interface{} for _, item := range items { key := valueAsString(item.GetAttr("key")) + order, err := valueAsInt(item.GetAttr("order")) + if err != nil { + return nil, xerrors.Errorf("unable to parse order for coder_metadata item %q: %w", key, err) + } + resultItem := map[string]interface{}{ "key": key, "value": valueAsString(item.GetAttr("value")), "sensitive": valueAsBool(item.GetAttr("sensitive")), + "order": order, } if item.GetAttr("value").IsNull() { resultItem["is_null"] = true @@ -132,6 +139,15 @@ func valueAsBool(value cty.Value) interface{} { return value.True() } +func valueAsInt(value cty.Value) (interface{}, error) { + if value.IsNull() { + return nil, nil + } + var valueAsInt int64 + err := gocty.FromCtyValue(value, &valueAsInt) + return valueAsInt, err +} + // errorAsDiagnostic transforms a Go error to a diag.Diagnostics object representing a fatal error. func errorAsDiagnostics(err error) diag.Diagnostics { return []diag.Diagnostic{{