Skip to content

Commit

Permalink
Add gateway & ip_address_range attribute for network resource (#3585)
Browse files Browse the repository at this point in the history
* add gateway & ip_address_range attribute for network resource

* feedback resolved

* renamed pi_ipaddress_range params
  • Loading branch information
dhirendersingh19 authored May 4, 2022
1 parent d6e3891 commit d3f2b58
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 13 deletions.
97 changes: 84 additions & 13 deletions ibm/service/power/resource_ibm_pi_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -65,6 +70,7 @@ func ResourceIBMPINetwork() *schema.Resource {
helpers.PINetworkGateway: {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "PI network gateway",
},
helpers.PINetworkJumbo: {
Expand All @@ -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": {
Expand All @@ -102,35 +128,48 @@ 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)
if err != nil {
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
}
Expand All @@ -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)
}
Expand Down Expand Up @@ -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

Expand All @@ -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)
Expand Down Expand Up @@ -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
}
69 changes: 69 additions & 0 deletions ibm/service/power/resource_ibm_pi_network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.#"),
),
},
{
Expand All @@ -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"),
),
},
},
Expand Down Expand Up @@ -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)
}
10 changes: 10 additions & 0 deletions website/docs/r/pi_network.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ resource "ibm_pi_network" "power_networks" {
pi_network_type = "vlan"
pi_cidr = "<Network in CIDR notation (192.168.0.0/24)>"
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"
}
}
```

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit d3f2b58

Please sign in to comment.