diff --git a/ibm/service/power/resource_ibm_pi_network.go b/ibm/service/power/resource_ibm_pi_network.go index f194401393..b90d65222f 100644 --- a/ibm/service/power/resource_ibm_pi_network.go +++ b/ibm/service/power/resource_ibm_pi_network.go @@ -24,6 +24,11 @@ import ( "github.com/IBM-Cloud/terraform-provider-ibm/ibm/validate" ) +const ( + piEndingIPAaddress = "pi_ending_ip_address" + piStartingIPAaddress = "pi_starting_ip_address" +) + func ResourceIBMPINetwork() *schema.Resource { return &schema.Resource{ CreateContext: resourceIBMPINetworkCreate, @@ -65,6 +70,7 @@ func ResourceIBMPINetwork() *schema.Resource { helpers.PINetworkGateway: { Type: schema.TypeString, Optional: true, + Computed: true, Description: "PI network gateway", }, helpers.PINetworkJumbo: { @@ -78,6 +84,26 @@ func ResourceIBMPINetwork() *schema.Resource { Required: true, Description: "PI cloud instance ID", }, + helpers.PINetworkIPAddressRange: { + Type: schema.TypeList, + Optional: true, + Computed: true, + Description: "List of one or more ip address range(s)", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + piEndingIPAaddress: { + Type: schema.TypeString, + Required: true, + Description: "Ending ip address", + }, + piStartingIPAaddress: { + Type: schema.TypeString, + Required: true, + Description: "Starting ip address", + }, + }, + }, + }, //Computed Attributes "network_id": { @@ -102,26 +128,30 @@ func resourceIBMPINetworkCreate(ctx context.Context, d *schema.ResourceData, met cloudInstanceID := d.Get(helpers.PICloudInstanceId).(string) networkname := d.Get(helpers.PINetworkName).(string) networktype := d.Get(helpers.PINetworkType).(string) - networkdns := flex.ExpandStringList((d.Get(helpers.PINetworkDNS).(*schema.Set)).List()) client := st.NewIBMPINetworkClient(ctx, sess, cloudInstanceID) var body = &models.NetworkCreate{ Type: &networktype, Name: networkname, } + if v, ok := d.GetOk(helpers.PINetworkDNS); ok { + networkdns := flex.ExpandStringList((v.(*schema.Set)).List()) + if len(networkdns) > 0 { + body.DNSServers = networkdns + } + } + if v, ok := d.GetOk(helpers.PINetworkJumbo); ok { body.Jumbo = v.(bool) } - if len(networkdns) > 0 { - body.DNSServers = networkdns - } if networktype == "vlan" { var networkcidr string + var ipBodyRanges []*models.IPAddressRange if v, ok := d.GetOk(helpers.PINetworkCidr); ok { networkcidr = v.(string) } else { - diag.Errorf("%s is required when %s is vlan", helpers.PINetworkCidr, helpers.PINetworkType) + return diag.Errorf("%s is required when %s is vlan", helpers.PINetworkCidr, helpers.PINetworkType) } gateway, firstip, lastip, err := generateIPData(networkcidr) @@ -129,8 +159,17 @@ func resourceIBMPINetworkCreate(ctx context.Context, d *schema.ResourceData, met return diag.FromErr(err) } - var ipbody = []*models.IPAddressRange{{EndingIPAddress: &lastip, StartingIPAddress: &firstip}} - body.IPAddressRanges = ipbody + ipBodyRanges = []*models.IPAddressRange{{EndingIPAddress: &lastip, StartingIPAddress: &firstip}} + + if g, ok := d.GetOk(helpers.PINetworkGateway); ok { + gateway = g.(string) + } + + if ips, ok := d.GetOk(helpers.PINetworkIPAddressRange); ok { + ipBodyRanges = getIPAddressRanges(ips.([]interface{})) + } + + body.IPAddressRanges = ipBodyRanges body.Gateway = gateway body.Cidr = networkcidr } @@ -140,11 +179,11 @@ func resourceIBMPINetworkCreate(ctx context.Context, d *schema.ResourceData, met return diag.FromErr(err) } - IBMPINetworkID := *networkResponse.NetworkID + networkID := *networkResponse.NetworkID - d.SetId(fmt.Sprintf("%s/%s", cloudInstanceID, IBMPINetworkID)) + d.SetId(fmt.Sprintf("%s/%s", cloudInstanceID, networkID)) - _, err = isWaitForIBMPINetworkAvailable(ctx, client, IBMPINetworkID, d.Timeout(schema.TimeoutCreate)) + _, err = isWaitForIBMPINetworkAvailable(ctx, client, networkID, d.Timeout(schema.TimeoutCreate)) if err != nil { return diag.FromErr(err) } @@ -176,6 +215,20 @@ func resourceIBMPINetworkRead(ctx context.Context, d *schema.ResourceData, meta d.Set(helpers.PINetworkName, networkdata.Name) d.Set(helpers.PINetworkType, networkdata.Type) d.Set(helpers.PINetworkJumbo, networkdata.Jumbo) + d.Set(helpers.PINetworkGateway, networkdata.Gateway) + ipRangesMap := []map[string]interface{}{} + if networkdata.IPAddressRanges != nil { + for _, n := range networkdata.IPAddressRanges { + if n != nil { + v := map[string]interface{}{ + piEndingIPAaddress: n.EndingIPAddress, + piStartingIPAaddress: n.StartingIPAddress, + } + ipRangesMap = append(ipRangesMap, v) + } + } + } + d.Set(helpers.PINetworkIPAddressRange, ipRangesMap) return nil @@ -192,15 +245,18 @@ func resourceIBMPINetworkUpdate(ctx context.Context, d *schema.ResourceData, met return diag.FromErr(err) } - if d.HasChanges(helpers.PINetworkName, helpers.PINetworkDNS) { + if d.HasChanges(helpers.PINetworkName, helpers.PINetworkDNS, helpers.PINetworkGateway, helpers.PINetworkIPAddressRange) { networkC := st.NewIBMPINetworkClient(ctx, sess, cloudInstanceID) body := &models.NetworkUpdate{ DNSServers: flex.ExpandStringList((d.Get(helpers.PINetworkDNS).(*schema.Set)).List()), } + if d.Get(helpers.PINetworkType).(string) == "vlan" { + body.Gateway = flex.PtrToString(d.Get(helpers.PINetworkGateway).(string)) + body.IPAddressRanges = getIPAddressRanges(d.Get(helpers.PINetworkIPAddressRange).([]interface{})) + } if d.HasChange(helpers.PINetworkName) { - name := d.Get(helpers.PINetworkName).(string) - body.Name = &name + body.Name = flex.PtrToString(d.Get(helpers.PINetworkName).(string)) } _, err = networkC.Update(networkID, body) @@ -308,3 +364,18 @@ func generateIPData(cdir string) (gway, firstip, lastip string, err error) { return gateway.String(), firstusable.String(), lastusable.String(), nil } + +func getIPAddressRanges(ipAddressRanges []interface{}) []*models.IPAddressRange { + ipRanges := make([]*models.IPAddressRange, 0, len(ipAddressRanges)) + for _, v := range ipAddressRanges { + if v != nil { + ipAddressRange := v.(map[string]interface{}) + ipRange := &models.IPAddressRange{ + EndingIPAddress: flex.PtrToString(ipAddressRange[piEndingIPAaddress].(string)), + StartingIPAddress: flex.PtrToString(ipAddressRange[piStartingIPAaddress].(string)), + } + ipRanges = append(ipRanges, ipRange) + } + } + return ipRanges +} diff --git a/ibm/service/power/resource_ibm_pi_network_test.go b/ibm/service/power/resource_ibm_pi_network_test.go index 40f498fe62..517bf87118 100644 --- a/ibm/service/power/resource_ibm_pi_network_test.go +++ b/ibm/service/power/resource_ibm_pi_network_test.go @@ -32,6 +32,9 @@ func TestAccIBMPINetworkbasic(t *testing.T) { testAccCheckIBMPINetworkExists("ibm_pi_network.power_networks"), resource.TestCheckResourceAttr( "ibm_pi_network.power_networks", "pi_network_name", name), + resource.TestCheckResourceAttrSet("ibm_pi_network.power_networks", "id"), + resource.TestCheckResourceAttrSet("ibm_pi_network.power_networks", "pi_gateway"), + resource.TestCheckResourceAttrSet("ibm_pi_network.power_networks", "pi_ipaddress_range.#"), ), }, { @@ -42,6 +45,44 @@ func TestAccIBMPINetworkbasic(t *testing.T) { "ibm_pi_network.power_networks", "pi_network_name", name), resource.TestCheckResourceAttr( "ibm_pi_network.power_networks", "pi_dns.#", "1"), + resource.TestCheckResourceAttrSet("ibm_pi_network.power_networks", "id"), + resource.TestCheckResourceAttrSet("ibm_pi_network.power_networks", "pi_gateway"), + resource.TestCheckResourceAttrSet("ibm_pi_network.power_networks", "pi_ipaddress_range.#"), + ), + }, + }, + }) +} +func TestAccIBMPINetworkGatewaybasic(t *testing.T) { + name := fmt.Sprintf("tf-pi-network-%d", acctest.RandIntRange(10, 100)) + resource.Test(t, resource.TestCase{ + PreCheck: func() { acc.TestAccPreCheck(t) }, + Providers: acc.TestAccProviders, + CheckDestroy: testAccCheckIBMPINetworkDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckIBMPINetworkGatewayConfig(name), + Check: resource.ComposeTestCheckFunc( + testAccCheckIBMPINetworkExists("ibm_pi_network.power_networks"), + resource.TestCheckResourceAttr( + "ibm_pi_network.power_networks", "pi_network_name", name), + resource.TestCheckResourceAttrSet("ibm_pi_network.power_networks", "pi_gateway"), + resource.TestCheckResourceAttrSet("ibm_pi_network.power_networks", "id"), + resource.TestCheckResourceAttrSet("ibm_pi_network.power_networks", "pi_ipaddress_range.#"), + ), + }, + { + Config: testAccCheckIBMPINetworkConfigGatewayUpdateDNS(name), + Check: resource.ComposeTestCheckFunc( + testAccCheckIBMPINetworkExists("ibm_pi_network.power_networks"), + resource.TestCheckResourceAttr( + "ibm_pi_network.power_networks", "pi_network_name", name), + resource.TestCheckResourceAttr( + "ibm_pi_network.power_networks", "pi_gateway", "192.168.17.2"), + resource.TestCheckResourceAttr( + "ibm_pi_network.power_networks", "pi_ipaddress_range.0.pi_ending_ip_address", "192.168.17.254"), + resource.TestCheckResourceAttr( + "ibm_pi_network.power_networks", "pi_ipaddress_range.0.pi_starting_ip_address", "192.168.17.3"), ), }, }, @@ -121,3 +162,31 @@ func testAccCheckIBMPINetworkConfigUpdateDNS(name string) string { } `, acc.Pi_cloud_instance_id, name) } + +func testAccCheckIBMPINetworkGatewayConfig(name string) string { + return fmt.Sprintf(` + resource "ibm_pi_network" "power_networks" { + pi_cloud_instance_id = "%s" + pi_network_name = "%s" + pi_network_type = "vlan" + pi_cidr = "192.168.17.0/24" + } + `, acc.Pi_cloud_instance_id, name) +} + +func testAccCheckIBMPINetworkConfigGatewayUpdateDNS(name string) string { + return fmt.Sprintf(` + resource "ibm_pi_network" "power_networks" { + pi_cloud_instance_id = "%s" + pi_network_name = "%s" + pi_network_type = "vlan" + pi_dns = ["127.0.0.1"] + pi_gateway = "192.168.17.2" + pi_cidr = "192.168.17.0/24" + pi_ipaddress_range { + pi_ending_ip_address = "192.168.17.254" + pi_starting_ip_address = "192.168.17.3" + } + } + `, acc.Pi_cloud_instance_id, name) +} diff --git a/website/docs/r/pi_network.html.markdown b/website/docs/r/pi_network.html.markdown index cd357be1bc..daf86f7edc 100644 --- a/website/docs/r/pi_network.html.markdown +++ b/website/docs/r/pi_network.html.markdown @@ -21,6 +21,11 @@ resource "ibm_pi_network" "power_networks" { pi_network_type = "vlan" pi_cidr = "" pi_dns = [<"DNS Servers">] + pi_gateway = "192.168.0.1" + pi_ipaddress_range { + pi_starting_ip_address = "192.168.0.2" + pi_ending_ip_address = "192.168.0.254" + } } ``` @@ -55,6 +60,11 @@ Review the argument references that you can specify for your resource. - `pi_network_type` - (Required, String) The type of network that you want to create, such as `pub-vlan` or `vlan`. - `pi_dns` - (Optional, Set of String) The DNS Servers for the network. Required for `vlan` network type. - `pi_cidr` - (Optional, String) The network CIDR. Required for `vlan` network type. +- `pi_gateway` - (Optional, String) The gateway ip address. +- `pi_ipaddress_range` - (Optional, List of Map) List of one or more ip address range. The `pi_ipaddress_range` object structure is documented below. + The `pi_ipaddress_range` block supports: + - `pi_ending_ip_address` - (Required, String) The ending ip address. + - `pi_starting_ip_address` - (Required, String) The staring ip address. **Note** if the `pi_gateway` or `pi_ipaddress_range` is not provided, it will calculate the value based on CIDR respectively. - `pi_network_jumbo` - (Optional, Bool) MTU Jumbo option of the network. ## Attribute reference