From 2a684b27ca57fe3e570dd712f3aa5247a920a10f Mon Sep 17 00:00:00 2001 From: AnuBose Date: Thu, 11 Aug 2022 16:22:14 -0500 Subject: [PATCH] add tags to host and volume resource (#59) * add tags to host volume resource * minor cleanup. ron's comments * neil comments * lint errors * lint error Co-authored-by: Neil Gierman --- .../resources/hpegl_metal_host/resource.tf | 1 + internal/resources/resource_host.go | 21 +++++++++++++++++++ internal/resources/resource_volume.go | 21 +++++++++++++++++++ internal/resources/utils.go | 16 ++++++++++++++ 4 files changed, 59 insertions(+) diff --git a/examples/resources/hpegl_metal_host/resource.tf b/examples/resources/hpegl_metal_host/resource.tf index f1ae44c..04c9b7f 100644 --- a/examples/resources/hpegl_metal_host/resource.tf +++ b/examples/resources/hpegl_metal_host/resource.tf @@ -70,4 +70,5 @@ resource "hpegl_metal_host" "terra_host_new_ssh" { network_route = "Public" location = var.location description = "Hello from Terraform" + labels = { "ServiceType" = "BMaaS" } } diff --git a/internal/resources/resource_host.go b/internal/resources/resource_host.go index e5097b6..bfe8642 100644 --- a/internal/resources/resource_host.go +++ b/internal/resources/resource_host.go @@ -41,6 +41,7 @@ const ( hSubState = "sub_state" hPortalCommOkay = "portal_comm_okay" hPwrState = "power_state" + hLabels = "labels" // allowedImageLength is number of Image related attributes that can be provided in the from of 'image@version'. allowedImageLength = 2 @@ -202,6 +203,11 @@ func hostSchema() map[string]*schema.Schema { Schema: volumeInfoSchema(), }, }, + hLabels: { + Type: schema.TypeMap, + Optional: true, + Description: "map of label name to label value for this host", + }, } } @@ -396,6 +402,11 @@ func resourceMetalHostCreate(d *schema.ResourceData, meta interface{}) (err erro host.PreAllocatedIPs = convertStringArr(ips) } + // add tags + if m, ok := (d.Get(hLabels).(map[string]interface{})); ok { + host.Labels = convertMap(m) + } + // Create it ctx := p.GetContext() @@ -474,6 +485,16 @@ func resourceMetalHostRead(d *schema.ResourceData, meta interface{}) (err error) return err } + tags := make(map[string]string, len(host.Labels)) + + for k, v := range host.Labels { + tags[k] = v + } + + if err := d.Set(hLabels, tags); err != nil { + return fmt.Errorf("set labels: %v", err) + } + return nil } diff --git a/internal/resources/resource_volume.go b/internal/resources/resource_volume.go index dfec7c7..a9b0a7b 100644 --- a/internal/resources/resource_volume.go +++ b/internal/resources/resource_volume.go @@ -25,6 +25,7 @@ const ( vShareable = "shareable" vState = "state" vStatus = "status" + vLabels = "labels" // volume Info constants. vID = "id" @@ -112,6 +113,11 @@ func volumeSchema() map[string]*schema.Schema { Computed: true, Description: "The volume provisioning status.", }, + vLabels: { + Type: schema.TypeMap, + Optional: true, + Description: "volume labels as (name, value) pairs", + }, } } @@ -195,6 +201,11 @@ func resourceMetalVolumeCreate(d *schema.ResourceData, meta interface{}) (err er return fmt.Errorf("location %q not found in %q", targetLocation, locations) } + // add tags + if m, ok := d.Get(vLabels).(map[string]interface{}); ok { + volume.Labels = convertMap(m) + } + ctx := p.GetContext() v, _, err := p.Client.VolumesApi.Add(ctx, volume) if err != nil { @@ -252,6 +263,16 @@ func resourceMetalVolumeRead(d *schema.ResourceData, meta interface{}) (err erro d.Set(vState, volume.State) d.Set(vStatus, volume.Status) + tags := make(map[string]string, len(volume.Labels)) + + for k, v := range volume.Labels { + tags[k] = v + } + + if err := d.Set(vLabels, tags); err != nil { + return fmt.Errorf("set labels: %v", err) + } + return nil } diff --git a/internal/resources/utils.go b/internal/resources/utils.go index 6292c72..78aaff4 100644 --- a/internal/resources/utils.go +++ b/internal/resources/utils.go @@ -153,6 +153,22 @@ func wrapResourceError(err *error, msg string) { *err = fmt.Errorf("%s %w", msg, *err) } +// convertMap returns map of string key to string value. +func convertMap(in map[string]interface{}) map[string]string { + ret := make(map[string]string, len(in)) + if len(in) == 0 { + return ret + } + + for k, v := range in { + if s, ok := v.(string); ok { + ret[k] = s + } + } + + return ret +} + // expandStringList takes []interfaces and returns []strings. func expandStringList(list []interface{}) []string { vs := make([]string, 0, len(list))