-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathmetadata.go
142 lines (135 loc) · 4.42 KB
/
metadata.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package provider
import (
"context"
"net/url"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"golang.org/x/xerrors"
)
func metadataResource() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Description: "Use this resource to attach metadata to a resource. They will be " +
"displayed in the Coder dashboard alongside the resource. " +
"The resource containing the agent, and it's metadata, will be shown by default. " + "\n\n" +
"Alternatively, to attach metadata to the agent, use a `metadata` block within a `coder_agent` resource.",
CreateContext: func(c context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics {
resourceData.SetId(uuid.NewString())
items, err := populateIsNull(resourceData)
if err != nil {
return errorAsDiagnostics(err)
}
err = resourceData.Set("item", items)
if err != nil {
return errorAsDiagnostics(err)
}
return nil
},
ReadContext: func(c context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics {
return nil
},
DeleteContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics {
return nil
},
Schema: map[string]*schema.Schema{
"resource_id": {
Type: schema.TypeString,
Description: "The `id` property of another resource that metadata should be attached to.",
ForceNew: true,
Required: true,
},
"hide": {
Type: schema.TypeBool,
Description: "Hide the resource from the UI.",
ForceNew: true,
Optional: true,
},
"icon": {
Type: schema.TypeString,
Description: "A URL to an icon that will display in the dashboard. View built-in " +
"icons [here](https://github.com/coder/coder/tree/main/site/static/icon). Use a " +
"built-in icon with `\"${data.coder_workspace.me.access_url}/icon/<path>\"`.",
ForceNew: true,
Optional: true,
ValidateFunc: func(i interface{}, s string) ([]string, []error) {
_, err := url.Parse(s)
if err != nil {
return nil, []error{err}
}
return nil, nil
},
},
"daily_cost": {
Type: schema.TypeInt,
Description: "(Enterprise) The cost of this resource every 24 hours." +
" Use the smallest denomination of your preferred currency." +
" For example, if you work in USD, use cents.",
ForceNew: true,
Optional: true,
},
"item": {
Type: schema.TypeList,
Description: "Each `item` block defines a single metadata item consisting of a key/value pair.",
ForceNew: true,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"key": {
Type: schema.TypeString,
Description: "The key of this metadata item.",
ForceNew: true,
Required: true,
},
"value": {
Type: schema.TypeString,
Description: "The value of this metadata item. Supports basic Markdown, including hyperlinks.",
ForceNew: true,
Optional: true,
},
"sensitive": {
Type: schema.TypeBool,
Description: "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.",
ForceNew: true,
Optional: true,
Default: false,
},
"is_null": {
Type: schema.TypeBool,
ForceNew: true,
Computed: true,
},
},
},
},
},
CustomizeDiff: func(ctx context.Context, rd *schema.ResourceDiff, i interface{}) error {
if !rd.HasChange("item") {
return nil
}
keys := map[string]bool{}
metadata, ok := rd.Get("item").([]any)
if !ok {
return xerrors.Errorf("unexpected type %T for items, expected []any", rd.Get("metadata"))
}
for _, t := range metadata {
obj, ok := t.(map[string]any)
if !ok {
return xerrors.Errorf("unexpected type %T for item, expected map[string]any", t)
}
key, ok := obj["key"].(string)
if !ok {
return xerrors.Errorf("unexpected type %T for items 'key' attribute, expected string", obj["key"])
}
if keys[key] {
return xerrors.Errorf("duplicate resource metadata key %q", key)
}
keys[key] = true
}
return nil
},
}
}