/
datasource_vcd_cse_kubernetes_cluster.go
349 lines (340 loc) · 11.1 KB
/
datasource_vcd_cse_kubernetes_cluster.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
package vcd
import (
"context"
_ "embed"
semver "github.com/hashicorp/go-version"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/vmware/go-vcloud-director/v2/govcd"
)
func datasourceVcdCseKubernetesCluster() *schema.Resource {
return &schema.Resource{
ReadContext: datasourceVcdCseKubernetesRead,
Schema: map[string]*schema.Schema{
"cluster_id": {
Type: schema.TypeString,
Optional: true,
ExactlyOneOf: []string{"cluster_id", "name"},
Description: "The unique ID of the Kubernetes cluster to read",
},
"name": {
Type: schema.TypeString,
Optional: true,
ExactlyOneOf: []string{"cluster_id", "name"},
RequiredWith: []string{"cse_version", "org_id"},
Description: "The name of the Kubernetes cluster to read. If there is more than one Kubernetes cluster with the same name, searching by name will fail",
},
"org_id": {
Type: schema.TypeString,
Optional: true,
RequiredWith: []string{"cse_version", "name"},
Description: "The ID of organization that owns the Kubernetes cluster, only required if 'name' is set",
},
"cse_version": {
Type: schema.TypeString,
Optional: true,
RequiredWith: []string{"name", "org_id"},
Description: "The CSE version used by the cluster, only required if 'name' is set",
},
"runtime": {
Type: schema.TypeString,
Computed: true,
Description: "The Kubernetes runtime used by the cluster",
},
"kubernetes_template_id": {
Type: schema.TypeString,
Computed: true,
Description: "The ID of the vApp Template that corresponds to a Kubernetes template OVA",
},
"vdc_id": {
Type: schema.TypeString,
Computed: true,
Description: "The ID of the VDC that hosts the Kubernetes cluster",
},
"network_id": {
Type: schema.TypeString,
Computed: true,
Description: "The ID of the network that the Kubernetes cluster uses",
},
"owner": {
Type: schema.TypeString,
Computed: true,
Description: "The user that created the cluster",
},
"ssh_public_key": {
Type: schema.TypeString,
Computed: true,
Description: "The SSH public key used to login into the cluster nodes",
},
"control_plane": {
Type: schema.TypeList,
Computed: true,
Description: "Defines the control plane for the cluster",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"machine_count": {
Type: schema.TypeInt,
Computed: true,
Description: "The number of nodes that the control plane has",
},
"disk_size_gi": {
Type: schema.TypeInt,
Computed: true,
Description: "Disk size, in Gibibytes (Gi), of the control plane nodes",
},
"sizing_policy_id": {
Type: schema.TypeString,
Computed: true,
Description: "VM Sizing policy of the control plane nodes",
},
"placement_policy_id": {
Type: schema.TypeString,
Computed: true,
Description: "VM Placement policy of the control plane nodes",
},
"storage_profile_id": {
Type: schema.TypeString,
Computed: true,
Description: "Storage profile of the control plane nodes",
},
"ip": {
Type: schema.TypeString,
Computed: true,
Description: "IP of the control plane",
},
},
},
},
"worker_pool": {
Type: schema.TypeList,
Computed: true,
Description: "Defines a node pool for the cluster",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Computed: true,
Description: "The name of this node pool",
},
"machine_count": {
Type: schema.TypeInt,
Computed: true,
Description: "The number of nodes that this node pool has",
},
"disk_size_gi": {
Type: schema.TypeInt,
Computed: true,
Description: "Disk size, in Gibibytes (Gi), of the control plane nodes",
},
"sizing_policy_id": {
Type: schema.TypeString,
Computed: true,
Description: "VM Sizing policy of the control plane nodes",
},
"placement_policy_id": {
Type: schema.TypeString,
Computed: true,
Description: "VM Placement policy of the control plane nodes",
},
"vgpu_policy_id": {
Type: schema.TypeString,
Computed: true,
Description: "vGPU policy of the control plane nodes",
},
"storage_profile_id": {
Type: schema.TypeString,
Computed: true,
Description: "Storage profile of the control plane nodes",
},
},
},
},
"default_storage_class": {
Type: schema.TypeList,
Computed: true,
Description: "The default storage class of the cluster, if any",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"storage_profile_id": {
Computed: true,
Type: schema.TypeString,
Description: "ID of the storage profile used by the storage class",
},
"name": {
Computed: true,
Type: schema.TypeString,
Description: "Name of the storage class",
},
"reclaim_policy": {
Computed: true,
Type: schema.TypeString,
Description: "'delete' deletes the volume when the PersistentVolumeClaim is deleted. 'retain' does not, and the volume can be manually reclaimed",
},
"filesystem": {
Computed: true,
Type: schema.TypeString,
Description: "Filesystem of the storage class, can be either 'ext4' or 'xfs'",
},
},
},
},
"pods_cidr": {
Type: schema.TypeString,
Computed: true,
Description: "CIDR that the Kubernetes pods use",
},
"services_cidr": {
Type: schema.TypeString,
Computed: true,
Description: "CIDR that the Kubernetes services use",
},
"virtual_ip_subnet": {
Type: schema.TypeString,
Computed: true,
Description: "Virtual IP subnet of the cluster",
},
"auto_repair_on_errors": {
Type: schema.TypeBool,
Computed: true,
Description: "If errors occur before the Kubernetes cluster becomes available, and this argument is 'true', CSE Server will automatically attempt to repair the cluster",
},
"node_health_check": {
Type: schema.TypeBool,
Computed: true,
Description: "After the Kubernetes cluster becomes available, nodes that become unhealthy will be remediated according to unhealthy node conditions and remediation rules",
},
"kubernetes_version": {
Type: schema.TypeString,
Computed: true,
Description: "The version of Kubernetes installed in this cluster",
},
"tkg_product_version": {
Type: schema.TypeString,
Computed: true,
Description: "The version of TKG installed in this cluster",
},
"capvcd_version": {
Type: schema.TypeString,
Computed: true,
Description: "The version of CAPVCD used by this cluster",
},
"cluster_resource_set_bindings": {
Type: schema.TypeSet,
Computed: true,
Description: "The cluster resource set bindings of this cluster",
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"cpi_version": {
Type: schema.TypeString,
Computed: true,
Description: "The version of the Cloud Provider Interface used by this cluster",
},
"csi_version": {
Type: schema.TypeString,
Computed: true,
Description: "The version of the Container Storage Interface used by this cluster",
},
"state": {
Type: schema.TypeString,
Computed: true,
Description: "The state of the cluster, can be 'provisioning', 'provisioned', 'deleting' or 'error'. Useful to check whether the Kubernetes cluster is in a stable status",
},
"kubeconfig": {
Type: schema.TypeString,
Computed: true,
Description: "The contents of the kubeconfig of the Kubernetes cluster, only available when 'state=provisioned'",
},
"supported_upgrades": {
Type: schema.TypeSet,
Computed: true,
Description: "A set of vApp Template names that could be used to upgrade the existing cluster",
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"events": {
Type: schema.TypeList, // Order matters here, as they're ordered by date
Computed: true,
Description: "A set of events that happened during the Kubernetes cluster lifecycle",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Computed: true,
Type: schema.TypeString,
Description: "Name of the event",
},
"resource_id": {
Computed: true,
Type: schema.TypeString,
Description: "ID of the resource that caused the event",
},
"type": {
Computed: true,
Type: schema.TypeString,
Description: "Type of the event, either 'event' or 'error'",
},
"occurred_at": {
Computed: true,
Type: schema.TypeString,
Description: "When the event happened",
},
"details": {
Computed: true,
Type: schema.TypeString,
Description: "Details of the event",
},
},
},
},
},
}
}
func datasourceVcdCseKubernetesRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
vcdClient := meta.(*VCDClient)
var cluster *govcd.CseKubernetesCluster
var err error
if id, ok := d.GetOk("cluster_id"); ok {
cluster, err = vcdClient.CseGetKubernetesClusterById(id.(string))
if err != nil {
return diag.FromErr(err)
}
} else if name, ok := d.GetOk("name"); ok {
cseVersion, err := semver.NewVersion(d.Get("cse_version").(string))
if err != nil {
return diag.Errorf("could not parse cse_version='%s': %s", cseVersion, err)
}
orgId := d.Get("org_id").(string)
org, err := vcdClient.GetOrgById(orgId)
if err != nil {
return diag.Errorf("could not find an Organization with ID '%s': %s", orgId, err)
}
clusters, err := org.CseGetKubernetesClustersByName(*cseVersion, name.(string))
if err != nil {
return diag.FromErr(err)
}
if len(clusters) != 1 {
return diag.Errorf("expected one Kubernetes cluster with name '%s', got %d. Try to use 'cluster_id' instead of 'name'", name, len(clusters))
}
cluster = clusters[0]
}
// These fields are specific to the data source
dSet(d, "org_id", cluster.OrganizationId)
dSet(d, "cluster_id", cluster.ID)
warns, err := saveClusterDataToState(d, vcdClient, cluster, "datasource")
if err != nil {
return diag.Errorf("could not save Kubernetes cluster data into Terraform state: %s", err)
}
for _, warning := range warns {
diags = append(diags, diag.Diagnostic{
Severity: diag.Warning,
Summary: warning.Error(),
})
}
if len(diags) > 0 {
return diags
}
return nil
}