diff --git a/examples/resources/hpegl_metal_host/README.md b/examples/resources/hpegl_metal_host/README.md index 4e8be69..35b0479 100644 --- a/examples/resources/hpegl_metal_host/README.md +++ b/examples/resources/hpegl_metal_host/README.md @@ -8,20 +8,41 @@ To run the example: * Update `variables.tf` OR provide overrides on the command line * Run with a command similar to ``` -terraform apply \ - -var ="location=USA:Texas:AUSL2" +terraform apply -var "location=USA:Central:V2DCC01" ``` ## Example output ``` +Apply complete! Resources: 6 added, 0 changed, 0 destroyed. + +Outputs: + +gateways = { + "tformed-0" = tomap({ + "Public" = "192.168.50.1" + "Storage-Client" = "10.20.0.1" + }) +} ips = { - "tf-0" = { - "Private" = "10.30.30.3" - "Public" = "192.168.50.151" - "Storage" = "10.20.0.216" - } + "tformed-0" = tomap({ + "Public" = "192.168.50.153" + "Storage-Client" = "10.20.0.2" + }) } +subnets = { + "tformed-0" = tomap({ + "Public" = "192.168.50.0/24" + "Storage-Client" = "10.20.0.0/24" + }) +} +vlans = { + "tformed-0" = tomap({ + "Public" = 100 + "Storage-Client" = 666 + }) +} + ``` ### Argument Reference @@ -56,6 +77,9 @@ In addition to the arguments listed above, the following attributes are exported - `network_route_id` - ID of the network selected for the default route. - `network_untagged_id` - ID of the untagged network. - `connections` - A map of {"network": "ipaddress"} for each connected network. +- `connections_subnet` - A map of {"network": "subnet"} for each connected network. +- `connections_gateway` - A map of {"network": "gateway"} for each connected network. +- `connections_vlan` - A map of {"network": "vlan"} for each connected network. - `chap_user` - The iSCSI CHAP user name of the host. - `chap_secret` - The iSCSI CHAP secret of the host. - `initiator_name` - The iSCSI initator name of the host. diff --git a/examples/resources/hpegl_metal_host/outputs.tf b/examples/resources/hpegl_metal_host/outputs.tf index fe94e13..5825c62 100644 --- a/examples/resources/hpegl_metal_host/outputs.tf +++ b/examples/resources/hpegl_metal_host/outputs.tf @@ -1,4 +1,22 @@ output "ips" { - # Output a map of hostame with all the IP addresses assigned on each network. + # Output a map of hostname with each network's IP address. value = zipmap(hpegl_metal_host.terra_host.*.name, hpegl_metal_host.terra_host.*.connections) } + +output "subnets" { + # Output a map of hostname with each network's subnet address. + value = zipmap(hpegl_metal_host.terra_host.*.name, hpegl_metal_host.terra_host.*.connections_subnet) +} + +output "gateways" { + # Output a map of hostname with each network's gateway address. + value = zipmap(hpegl_metal_host.terra_host.*.name, hpegl_metal_host.terra_host.*.connections_gateway) +} + +output "vlans" { + # Output a map of hostname with each network's vlan. + value = zipmap(hpegl_metal_host.terra_host.*.name, hpegl_metal_host.terra_host.*.connections_vlan) +} + + + diff --git a/internal/resources/resource_host.go b/internal/resources/resource_host.go index b9e43b5..8572073 100644 --- a/internal/resources/resource_host.go +++ b/internal/resources/resource_host.go @@ -33,6 +33,9 @@ const ( hSize = "machine_size" hSizeID = "machine_size_id" hConnections = "connections" + hConnectionsSubnet = "connections_subnet" + hConnectionsGateway = "connections_gateway" + hConnectionsVLAN = "connections_vlan" hUserData = "user_data" hCHAPUser = "chap_user" hCHAPSecret = "chap_secret" @@ -140,7 +143,25 @@ func hostSchema() map[string]*schema.Schema { hConnections: { Type: schema.TypeMap, Computed: true, - Description: "A map of network connections and assigned IP addreses, eg {'Private':'10.83.0.17'}.", + Description: "A map of network connection name to assigned IP addrese, eg {'Private':'10.83.0.17'}.", + }, + hConnectionsSubnet: { + Type: schema.TypeMap, + Computed: true, + Description: "A map of network connection name to subnet IP address.", + }, + hConnectionsGateway: { + Type: schema.TypeMap, + Computed: true, + Description: "A map of network connection name to gateway IP address.", + }, + hConnectionsVLAN: { + Type: schema.TypeMap, + Computed: true, + Description: "A map of network connection name to VLAN ID.", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, }, hCHAPUser: { Type: schema.TypeString, @@ -467,13 +488,11 @@ func resourceMetalHostRead(d *schema.ResourceData, meta interface{}) (err error) } d.Set(hDescription, host.Description) - hCons := make(map[string]interface{}) - for _, con := range host.Connections { - for _, hNet := range con.Networks { - hCons[hNet.Name] = hNet.IP - } + + if err = setConnectionsValues(d, host.Connections); err != nil { + return err } - d.Set(hConnections, hCons) + d.Set(hCHAPUser, host.ISCSIConfig.CHAPUser) d.Set(hCHAPSecret, host.ISCSIConfig.CHAPSecret) d.Set(hInitiatorName, host.ISCSIConfig.InitiatorName) @@ -498,6 +517,42 @@ func resourceMetalHostRead(d *schema.ResourceData, meta interface{}) (err error) return nil } +// setConnectionsValues sets hConnections, hConnectionsSubnet, hConnectionsGateway +// and hConnectionsVLAN from the specified hostConnections. +func setConnectionsValues(d *schema.ResourceData, hostConnections []rest.HostConnection) error { + hConnsIP := make(map[string]string) + hConnsSubnet := make(map[string]string) + hConnsGateway := make(map[string]string) + hConnsVLAN := make(map[string]int32) + + for _, con := range hostConnections { + for _, hNet := range con.Networks { + hConnsIP[hNet.Name] = hNet.IP + hConnsSubnet[hNet.Name] = hNet.Subnet + hConnsGateway[hNet.Name] = hNet.Gateway + hConnsVLAN[hNet.Name] = hNet.VLAN + } + } + + if err := d.Set(hConnections, hConnsIP); err != nil { + return fmt.Errorf("set connections ip map: %v", err) + } + + if err := d.Set(hConnectionsSubnet, hConnsSubnet); err != nil { + return fmt.Errorf("set connections subnet map: %v", err) + } + + if err := d.Set(hConnectionsGateway, hConnsGateway); err != nil { + return fmt.Errorf("set connections gateway map: %v", err) + } + + if err := d.Set(hConnectionsVLAN, hConnsVLAN); err != nil { + return fmt.Errorf("set connections vlan map: %v", err) + } + + return nil +} + func getVAsForHost(hostID string, vas []rest.VolumeAttachment) []rest.VolumeInfo { hostvas := make([]rest.VolumeInfo, 0, len(vas)) diff --git a/internal/resources/resource_host_test.go b/internal/resources/resource_host_test.go new file mode 100644 index 0000000..566d69c --- /dev/null +++ b/internal/resources/resource_host_test.go @@ -0,0 +1,55 @@ +// (C) Copyright 2022 Hewlett Packard Enterprise Development LP + +package resources + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/assert" + + "github.com/hewlettpackard/hpegl-metal-client/v1/pkg/client" +) + +func Test_setConnectionsValues(t *testing.T) { + someName := "someName" + someVlan := int32(22) + someIP := "someip" + someSubnet := "somesubnet" + someGateway := "somegateway" + + conns := []client.HostConnection{ + { + Networks: []client.HostNetworkConnection{ + { + Name: someName, + IP: someIP, + Subnet: someSubnet, + Gateway: someGateway, + VLAN: someVlan, + }, + }, + }, + } + + d := schema.TestResourceDataRaw(t, hostSchema(), map[string]interface{}{}) + + // test + err := setConnectionsValues(d, conns) + assert.Nil(t, err) + + connIPs, ok := d.Get(hConnections).(map[string]interface{}) + assert.True(t, ok, "type assertion failed") + assert.Equal(t, 1, len(connIPs)) + assert.Equal(t, someIP, connIPs[someName]) + + connSubNets, ok := d.Get(hConnectionsSubnet).(map[string]interface{}) + assert.True(t, ok, "type assertion failed") + assert.Equal(t, 1, len(connSubNets)) + assert.Equal(t, someSubnet, connSubNets[someName]) + + connGateways, ok := d.Get(hConnectionsGateway).(map[string]interface{}) + assert.True(t, ok, "type assertion failed") + assert.Equal(t, 1, len(connGateways)) + assert.Equal(t, someGateway, connGateways[someName]) +} diff --git a/version b/version index a34eaa5..6a36bb4 100644 --- a/version +++ b/version @@ -1 +1 @@ -0.1.11 \ No newline at end of file +0.1.12 \ No newline at end of file