-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
update to metal-go and add all required fields and validations for De…
…vice Signed-off-by: ocobleseqx <[email protected]>
- Loading branch information
ocobleseqx
committed
Nov 10, 2023
1 parent
bfcf752
commit 16afc28
Showing
3 changed files
with
195 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,26 @@ | ||
# terraform import equinix_metal_device.{{.Hostname}} {{.ID}} | ||
resource "equinix_metal_device" "{{.Hostname}}" { | ||
plan = "{{.Plan.Slug}}" | ||
hostname = "{{.Hostname}}" | ||
billing_cycle = "{{.BillingCycle}}" | ||
metro = "{{.Metro.Code}}" | ||
operating_system = "{{.OS.Slug}}" | ||
project_id = "{{.Project.ID}}" | ||
|
||
tags = {{.Tags}} | ||
# terraform import equinix_metal_device.example {{.Id}} | ||
resource "equinix_metal_device" "example" { | ||
always_pxe = {{.AlwaysPxe}} | ||
billing_cycle = {{.BillingCycle}} | ||
custom_data = {{.Customdata | nullIfNilOrEmpty}} | ||
description = {{.Description | nullIfNilOrEmpty}} | ||
force_detach_volumes = false | ||
{{- if .HardwareReservation }} | ||
hardware_reservation_id = {{.HardwareReservation.Id }} | ||
{{ else }} | ||
hardware_reservation_id = null | ||
{{- end }} | ||
hostname = {{.Hostname}} | ||
ipxe_script_url = {{.IpxeScriptUrl}} | ||
metro = {{.Metro.Code}} | ||
operating_system = {{.OperatingSystem.Slug}} | ||
plan = {{.Plan.Slug}} | ||
project_id = {{ hrefToID .Project.Href}} | ||
project_ssh_key_ids = null | ||
storage = {{.Storage | nullIfNilOrEmpty}} | ||
tags = {{.Tags}} | ||
termination_time = {{.TerminationTime | nullIfNilOrEmpty}} | ||
user_data = {{.Userdata | nullIfNilOrEmpty}} # sensitive | ||
user_ssh_key_ids = null | ||
wait_for_reservation_deprovision = false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
package terraform | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
"time" | ||
) | ||
|
||
func addQuotesToString(v interface{}) { | ||
val := reflect.ValueOf(v) | ||
|
||
switch val.Kind() { | ||
case reflect.Ptr: | ||
val = val.Elem() | ||
if val.Kind() != reflect.Struct { | ||
return | ||
} | ||
|
||
if val.Type() == reflect.TypeOf(new(string)) { | ||
oldValue := val.Elem().String() | ||
newValue := fmt.Sprintf(`"%s"`, oldValue) | ||
val.Elem().SetString(newValue) | ||
return | ||
} | ||
case reflect.String: | ||
oldValue := val.String() | ||
newValue := fmt.Sprintf(`"%s"`, oldValue) | ||
val.SetString(newValue) | ||
return | ||
case reflect.Slice: | ||
for i := 0; i < val.Len(); i++ { | ||
elem := val.Index(i) | ||
if elem.Kind() == reflect.Struct || (elem.Kind() == reflect.Ptr && elem.Elem().Kind() == reflect.Struct) { | ||
addQuotesToString(elem.Interface()) | ||
} | ||
} | ||
return | ||
case reflect.Map: | ||
for _, key := range val.MapKeys() { | ||
elem := val.MapIndex(key) | ||
if elem.Kind() == reflect.Struct || (elem.Kind() == reflect.Ptr && elem.Elem().Kind() == reflect.Struct) { | ||
addQuotesToString(elem.Interface()) | ||
} | ||
} | ||
return | ||
default: | ||
return | ||
} | ||
|
||
for i := 0; i < val.NumField(); i++ { | ||
field := val.Field(i) | ||
|
||
switch field.Kind() { | ||
case reflect.String: | ||
oldValue := field.String() | ||
newValue := fmt.Sprintf(`"%s"`, oldValue) | ||
field.SetString(newValue) | ||
case reflect.Ptr: | ||
if field.IsNil() { | ||
continue | ||
} | ||
// Check if the pointer is to a string | ||
if field.Type().Elem() == reflect.TypeOf("") { | ||
oldValue := field.Elem().String() | ||
newValue := fmt.Sprintf(`"%s"`, oldValue) | ||
field.Elem().SetString(newValue) | ||
} else { | ||
// Exclude *time.Time from recursion | ||
if field.Type() != reflect.TypeOf(&time.Time{}) { | ||
addQuotesToString(field.Interface()) | ||
} | ||
} | ||
case reflect.Struct: | ||
// Exclude time.Time from recursion | ||
if field.Type() != reflect.TypeOf(time.Time{}) { | ||
addQuotesToString(field.Interface()) | ||
} | ||
} | ||
} | ||
} | ||
|
||
func nullIfNilOrEmpty(v interface{}) interface{} { | ||
if v == nil { | ||
return "null" | ||
} | ||
|
||
// Use reflection to check if the value is an empty value (e.g., empty string, empty slice, or empty map) | ||
val := reflect.ValueOf(v) | ||
switch val.Kind() { | ||
case reflect.String: | ||
if val.String() == "\"\"" { | ||
return "null" | ||
} | ||
case reflect.Array, reflect.Slice, reflect.Map: | ||
if val.Len() == 0 { | ||
return "null" | ||
} | ||
case reflect.Ptr: | ||
if val.IsNil() || val.IsZero() { | ||
return "null" | ||
} | ||
|
||
elem := val.Elem() | ||
|
||
// Check if it's a pointer to a string | ||
if elem.Kind() == reflect.String && elem.String() == "\"\"" { | ||
return "null" | ||
} | ||
|
||
switch elem.Kind() { | ||
case reflect.Struct: | ||
if isPointerStructEmpty(elem) { | ||
return "null" | ||
} | ||
case reflect.Array, reflect.Slice: | ||
if elem.Len() == 0 { | ||
return "null" | ||
} | ||
case reflect.Map: | ||
if elem.Len() == 0 { | ||
return "null" | ||
} | ||
} | ||
} | ||
|
||
return v | ||
} | ||
|
||
func isPointerStructEmpty(structVal reflect.Value) bool { | ||
// Iterate through the struct fields | ||
for i := 0; i < structVal.NumField(); i++ { | ||
field := structVal.Field(i) | ||
|
||
// You can define custom logic to determine if a field is empty | ||
// For example, check if a string field is empty, or if a slice/map field is empty | ||
switch field.Kind() { | ||
case reflect.String: | ||
if field.String() != "" { | ||
return false | ||
} | ||
case reflect.Slice, reflect.Map: | ||
if field.Len() > 0 { | ||
return false | ||
} | ||
// Add more cases for other field types as needed | ||
} | ||
} | ||
|
||
// All fields are empty | ||
return true | ||
} |