From d4f7e2ebd53d0e6935e4478ce9c7cf364d5f6424 Mon Sep 17 00:00:00 2001 From: dhirendersingh19 Date: Mon, 28 Feb 2022 14:51:31 +0530 Subject: [PATCH 1/3] add/update network port attach resource --- .../power/resource_ibm_pi_network_port.go | 1 + .../resource_ibm_pi_network_port_attach.go | 121 ++++++++++++------ ...esource_ibm_pi_network_port_attach_test.go | 95 ++++++++++++-- .../r/pi_network_port_attach.html.markdown | 78 +++++++++++ 4 files changed, 247 insertions(+), 48 deletions(-) create mode 100644 website/docs/r/pi_network_port_attach.html.markdown diff --git a/ibm/service/power/resource_ibm_pi_network_port.go b/ibm/service/power/resource_ibm_pi_network_port.go index 7cfc10ca03..703686eb0b 100644 --- a/ibm/service/power/resource_ibm_pi_network_port.go +++ b/ibm/service/power/resource_ibm_pi_network_port.go @@ -71,6 +71,7 @@ func ResourceIBMPINetworkPort() *schema.Resource { Computed: true, }, }, + DeprecationMessage: "Resource ibm_pi_network_port is deprecated. Use ibm_pi_network_port_attach to create & attach a network port to a pvm instance", } } diff --git a/ibm/service/power/resource_ibm_pi_network_port_attach.go b/ibm/service/power/resource_ibm_pi_network_port_attach.go index 939ca43553..c4ced6395f 100644 --- a/ibm/service/power/resource_ibm_pi_network_port_attach.go +++ b/ibm/service/power/resource_ibm_pi_network_port_attach.go @@ -35,18 +35,14 @@ func ResourceIBMPINetworkPortAttach() *schema.Resource { Update: schema.DefaultTimeout(60 * time.Minute), }, Schema: map[string]*schema.Schema{ - "port_id": { - Type: schema.TypeString, - Required: true, - }, helpers.PICloudInstanceId: { Type: schema.TypeString, Required: true, }, - helpers.PIInstanceName: { + helpers.PIInstanceId: { Type: schema.TypeString, Required: true, - Description: "Instance name to attach the network port to", + Description: "Instance id to attach the network port to", }, helpers.PINetworkName: { Type: schema.TypeString, @@ -59,6 +55,25 @@ func ResourceIBMPINetworkPortAttach() *schema.Resource { Description: "A human readable description for this network Port", Default: "Port Created via Terraform", }, + helpers.PINetworkPortIPAddress: { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + //Computed Attributes + "macaddress": { + Type: schema.TypeString, + Computed: true, + }, + "portid": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, "public_ip": { Type: schema.TypeString, Computed: true, @@ -73,21 +88,27 @@ func resourceIBMPINetworkPortAttachCreate(ctx context.Context, d *schema.Resourc if err != nil { return diag.FromErr(err) } - cloudInstanceID := d.Get(helpers.PICloudInstanceId).(string) networkname := d.Get(helpers.PINetworkName).(string) - portid := d.Get("port_id").(string) - instancename := d.Get(helpers.PIInstanceName).(string) description := d.Get(helpers.PINetworkPortDescription).(string) - client := st.NewIBMPINetworkClient(ctx, sess, cloudInstanceID) - log.Printf("Printing the input to the resource: cloud instance [%s] and network name [%s] and the portid [%s]", cloudInstanceID, networkname, portid) - body := &models.NetworkPortUpdate{ + ipaddress := d.Get(helpers.PINetworkPortIPAddress).(string) + instancename := d.Get(helpers.PIInstanceId).(string) + nwportBody := &models.NetworkPortCreate{Description: description} + + if ipaddress != "" { + log.Printf("IP address provided. ") + nwportBody.IPAddress = ipaddress + } + + nwportattachBody := &models.NetworkPortUpdate{ Description: &description, PvmInstanceID: &instancename, } - networkPortResponse, err := client.UpdatePort(networkname, portid, body) + client := st.NewIBMPINetworkClient(ctx, sess, cloudInstanceID) + + networkPortResponse, err := client.CreatePort(networkname, nwportBody) if err != nil { return diag.FromErr(err) } @@ -96,22 +117,30 @@ func resourceIBMPINetworkPortAttachCreate(ctx context.Context, d *schema.Resourc IBMPINetworkPortID := *networkPortResponse.PortID - d.SetId(fmt.Sprintf("%s/%s/%s", cloudInstanceID, networkname, IBMPINetworkPortID)) + _, err = isWaitForIBMPINetworkPortAvailable(ctx, client, IBMPINetworkPortID, networkname, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return diag.FromErr(err) + } + + networkPortResponse, err = client.UpdatePort(networkname, IBMPINetworkPortID, nwportattachBody) + if err != nil { + return diag.FromErr(err) + } - _, err = isWaitForIBMPINetworkPortAttachAvailable(ctx, client, IBMPINetworkPortID, networkname, d.Timeout(schema.TimeoutCreate)) + _, err = isWaitForIBMPINetworkPortAttachAvailable(ctx, client, IBMPINetworkPortID, networkname, d.Timeout(schema.TimeoutUpdate)) if err != nil { return diag.FromErr(err) } - return resourceIBMPINetworkPortAttachRead(ctx, d, meta) + d.SetId(fmt.Sprintf("%s/%s/%s", cloudInstanceID, networkname, IBMPINetworkPortID)) + + return resourceIBMPINetworkPortRead(ctx, d, meta) } func resourceIBMPINetworkPortAttachRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - log.Printf("Calling ther Network Port Attach Read code") sess, err := meta.(conns.ClientSession).IBMPISession() - if err != nil { - fmt.Printf("failed to get a session from the IBM Cloud Service %v", err) + return diag.FromErr(err) } parts, err := flex.IdParts(d.Id()) @@ -119,37 +148,59 @@ func resourceIBMPINetworkPortAttachRead(ctx context.Context, d *schema.ResourceD return diag.FromErr(err) } cloudInstanceID := parts[0] - networkID := parts[1] + networkname := parts[1] portID := parts[2] networkC := st.NewIBMPINetworkClient(ctx, sess, cloudInstanceID) - networkdata, err := networkC.GetPort(networkID, portID) + networkdata, err := networkC.GetPort(networkname, portID) if err != nil { return diag.FromErr(err) } - d.Set("ipaddress", networkdata.IPAddress) + d.Set(helpers.PINetworkPortIPAddress, networkdata.IPAddress) + d.Set(helpers.PINetworkPortDescription, networkdata.Description) + d.Set(helpers.PIInstanceId, networkdata.PvmInstance.PvmInstanceID) d.Set("macaddress", networkdata.MacAddress) d.Set("status", networkdata.Status) d.Set("portid", networkdata.PortID) - d.Set("pvminstance", networkdata.PvmInstance.Href) d.Set("public_ip", networkdata.ExternalIP) return nil } func resourceIBMPINetworkPortAttachUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - log.Printf("Calling the attach update ") - return nil + sess, err := meta.(conns.ClientSession).IBMPISession() + if err != nil { + return diag.FromErr(err) + } + parts, err := flex.IdParts(d.Id()) + if err != nil { + return diag.FromErr(err) + } + cloudInstanceID, networkname, portID := parts[0], parts[1], parts[2] + + if d.HasChange(helpers.PINetworkPortDescription) { + description := d.Get(helpers.PINetworkPortDescription).(string) + body := &models.NetworkPortUpdate{Description: &description} + client := st.NewIBMPINetworkClient(ctx, sess, cloudInstanceID) + _, err = client.UpdatePort(networkname, portID, body) + if err != nil { + return diag.FromErr(err) + } + _, err = isWaitForIBMPINetworkPortAvailable(ctx, client, portID, networkname, d.Timeout(schema.TimeoutUpdate)) + if err != nil { + return diag.FromErr(err) + } + } + return resourceIBMPINetworkPortRead(ctx, d, meta) } func resourceIBMPINetworkPortAttachDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - log.Printf("Detaching the network port from the Instance ") + log.Printf("Calling the network delete functions. ") sess, err := meta.(conns.ClientSession).IBMPISession() if err != nil { - fmt.Printf("failed to get a session from the IBM Cloud Service %v", err) - + return diag.FromErr(err) } parts, err := flex.IdParts(d.Id()) @@ -157,25 +208,19 @@ func resourceIBMPINetworkPortAttachDelete(ctx context.Context, d *schema.Resourc return diag.FromErr(err) } cloudInstanceID := parts[0] - networkID := parts[1] + networkname := parts[1] portID := parts[2] client := st.NewIBMPINetworkClient(ctx, sess, cloudInstanceID) - log.Printf("Executing network port detach") - emptyPVM := "" - body := &models.NetworkPortUpdate{ - PvmInstanceID: &emptyPVM, - } - networkPort, err := client.UpdatePort(networkID, portID, body) + + log.Printf("Calling the delete with the following params delete with cloud instance (%s) and networkid (%s) and portid (%s) ", cloudInstanceID, networkname, portID) + err = client.DeletePort(networkname, portID) if err != nil { return diag.FromErr(err) } - log.Printf("Printing the networkresponse %+v", &networkPort) - d.SetId("") return nil - } func isWaitForIBMPINetworkPortAttachAvailable(ctx context.Context, client *st.IBMPINetworkClient, id string, networkname string, timeout time.Duration) (interface{}, error) { diff --git a/ibm/service/power/resource_ibm_pi_network_port_attach_test.go b/ibm/service/power/resource_ibm_pi_network_port_attach_test.go index 47291d81c8..273212d6d4 100644 --- a/ibm/service/power/resource_ibm_pi_network_port_attach_test.go +++ b/ibm/service/power/resource_ibm_pi_network_port_attach_test.go @@ -21,7 +21,6 @@ import ( ) func TestAccIBMPINetworkPortAttachbasic(t *testing.T) { - t.Skip() name := fmt.Sprintf("tf-pi-network-port-attach-%d", acctest.RandIntRange(10, 100)) resource.Test(t, resource.TestCase{ PreCheck: func() { acc.TestAccPreCheck(t) }, @@ -34,13 +33,57 @@ func TestAccIBMPINetworkPortAttachbasic(t *testing.T) { testAccCheckIBMPINetworkPortAttachExists("ibm_pi_network_port_attach.power_network_port_attach"), resource.TestCheckResourceAttr( "ibm_pi_network_port_attach.power_network_port_attach", "pi_network_name", name), + resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "id"), + resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "portid"), + resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "public_ip"), + ), + }, + { + Config: testAccCheckIBMPINetworkPortAttachUpdateConfig(name), + Check: resource.ComposeTestCheckFunc( + testAccCheckIBMPINetworkPortAttachExists("ibm_pi_network_port_attach.power_network_port_attach"), + resource.TestCheckResourceAttr( + "ibm_pi_network_port_attach.power_network_port_attach", "pi_network_name", name), + resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "id"), + resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "portid"), + resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "public_ip"), ), }, }, }) } -func testAccCheckIBMPINetworkPortAttachDestroy(s *terraform.State) error { +func TestAccIBMPINetworkPortAttachVlanbasic(t *testing.T) { + name := fmt.Sprintf("tf-pi-network-port-attach-%d", acctest.RandIntRange(10, 100)) + resource.Test(t, resource.TestCase{ + PreCheck: func() { acc.TestAccPreCheck(t) }, + Providers: acc.TestAccProviders, + CheckDestroy: testAccCheckIBMPINetworkPortAttachDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckIBMPINetworkPortAttachVlanConfig(name), + Check: resource.ComposeTestCheckFunc( + testAccCheckIBMPINetworkPortAttachExists("ibm_pi_network_port_attach.power_network_port_attach"), + resource.TestCheckResourceAttr( + "ibm_pi_network_port_attach.power_network_port_attach", "pi_network_name", name), + resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "id"), + resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "portid"), + ), + }, + { + Config: testAccCheckIBMPINetworkPortAttachVlanUpdateConfig(name), + Check: resource.ComposeTestCheckFunc( + testAccCheckIBMPINetworkPortAttachExists("ibm_pi_network_port_attach.power_network_port_attach"), + resource.TestCheckResourceAttr( + "ibm_pi_network_port_attach.power_network_port_attach", "pi_network_name", name), + resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "id"), + resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "portid"), + ), + }, + }, + }) +} +func testAccCheckIBMPINetworkPortAttachDestroy(s *terraform.State) error { sess, err := acc.TestAccProvider.Meta().(conns.ClientSession).IBMPISession() if err != nil { return err @@ -54,10 +97,10 @@ func testAccCheckIBMPINetworkPortAttachDestroy(s *terraform.State) error { return err } cloudInstanceID := parts[0] - networkID := parts[1] + networkname := parts[1] portID := parts[2] networkC := st.NewIBMPINetworkClient(context.Background(), sess, cloudInstanceID) - _, err = networkC.GetPort(networkID, portID) + _, err = networkC.GetPort(networkname, portID) if err == nil { return fmt.Errorf("PI Network Port still exists: %s", rs.Primary.ID) } @@ -87,27 +130,59 @@ func testAccCheckIBMPINetworkPortAttachExists(n string) resource.TestCheckFunc { return err } cloudInstanceID := parts[0] - networkID := parts[1] + networkname := parts[1] portID := parts[2] client := st.NewIBMPINetworkClient(context.Background(), sess, cloudInstanceID) - network, err := client.GetPort(networkID, portID) + _, err = client.GetPort(networkname, portID) if err != nil { return err } - parts[1] = *network.PortID return nil } } func testAccCheckIBMPINetworkPortAttachConfig(name string) string { - return testAccCheckIBMPINetworkPortConfig(name) + fmt.Sprintf(` + return testAccCheckIBMPINetworkConfig(name) + fmt.Sprintf(` resource "ibm_pi_network_port_attach" "power_network_port_attach" { pi_cloud_instance_id = "%s" pi_network_name = ibm_pi_network.power_networks.pi_network_name pi_network_port_description = "IP Reserved for Test UAT" - port_id=ibm_pi_network_port.power_network_port.id + pi_instance_id = "%s" + } + `, acc.Pi_cloud_instance_id, acc.Pi_instance_name) +} + +func testAccCheckIBMPINetworkPortAttachUpdateConfig(name string) string { + return testAccCheckIBMPINetworkConfig(name) + fmt.Sprintf(` + resource "ibm_pi_network_port_attach" "power_network_port_attach" { + pi_cloud_instance_id = "%s" + pi_network_name = ibm_pi_network.power_networks.pi_network_name + pi_network_port_description = "IP Reserved for TF Test" + pi_instance_id = "%s" + } + `, acc.Pi_cloud_instance_id, acc.Pi_instance_name) +} + +func testAccCheckIBMPINetworkPortAttachVlanConfig(name string) string { + return testAccCheckIBMPINetworkGatewayConfig(name) + fmt.Sprintf(` + resource "ibm_pi_network_port_attach" "power_network_port_attach" { + pi_cloud_instance_id = "%s" + pi_network_name = ibm_pi_network.power_networks.pi_network_name + pi_network_port_description = "IP Reserved for Test UAT" + pi_instance_id = "%s" + } + `, acc.Pi_cloud_instance_id, acc.Pi_instance_name) +} + +func testAccCheckIBMPINetworkPortAttachVlanUpdateConfig(name string) string { + return testAccCheckIBMPINetworkGatewayConfig(name) + fmt.Sprintf(` + resource "ibm_pi_network_port_attach" "power_network_port_attach" { + pi_cloud_instance_id = "%s" + pi_network_name = ibm_pi_network.power_networks.pi_network_name + pi_network_port_description = "IP Reserved for TF Test" + pi_instance_id = "%s" } - `, acc.Pi_cloud_instance_id) + `, acc.Pi_cloud_instance_id, acc.Pi_instance_name) } diff --git a/website/docs/r/pi_network_port_attach.html.markdown b/website/docs/r/pi_network_port_attach.html.markdown new file mode 100644 index 0000000000..df838d6e8d --- /dev/null +++ b/website/docs/r/pi_network_port_attach.html.markdown @@ -0,0 +1,78 @@ +--- + +subcategory: "Power Systems" +layout: "ibm" +page_title: "IBM: pi_network_port" +description: |- + Manages an Network Port Attachments in the Power Virtual Server Cloud. A network port is equivalent to reserving an IP in the subnet. + When the port is created the status will be "DOWN". This network port however is not attached to an instance. +--- + +# ibm_pi_network_port +Creates & Attaches network port in the Power Virtual Server Cloud. For more information, about network in IBM power virutal server, see [adding or removing a public network +](https://cloud.ibm.com/docs/power-iaas?topic=power-iaas-modifying-server#adding-removing-network).. + +## Example usage + +In the following example, you can create an network_port & attach it to pvm instance: + +```terraform +resource "ibm_pi_network_port" "test-network-port" { + pi_network_name = "Zone1-CFN" + pi_cloud_instance_id = "51e1879c-bcbe-4ee1-a008-49cdba0eaf60" + pi_instance_id = "" + pi_network_port_description = "IP Reserved for Oracle RAC " +} +``` + +**Note** +* Please find [supported Regions](https://cloud.ibm.com/apidocs/power-cloud#endpoint) for endpoints. +* If a Power cloud instance is provisioned at `lon04`, The provider level attributes should be as follows: + * `region` - `lon` + * `zone` - `lon04` + + Example usage: + + ```terraform + provider "ibm" { + region = "lon" + zone = "lon04" + } + ``` + +## Timeouts + +ibm_pi_network_port provides the following [timeouts](https://www.terraform.io/docs/language/resources/syntax.html) configuration options: + +- **create** - (Default 60 minutes) Used for creating a network_port. +- **update** - (Default 60 minutes) Used for updating a network_port. +- **delete** - (Default 60 minutes) Used for deleting a network_port. + +## Argument reference +Review the argument references that you can specify for your resource. + +- `pi_cloud_instance_id` - (Required, String) The GUID of the service instance associated with an account. +- `pi_instance_id` - (Required, String) The ID of the pvm instance to attach the network port to. +- `pi_network_name` - (Required, String) Network ID or name. +- `pi_network_port_description` - (Optional, String) The description for the Network Port. +- `pi_network_port_ipaddress` - (Optional, String) The requested ip address of this port. + +## Attribute reference +In addition to all argument reference list, you can access the following attribute reference after your resource is created. + +- `id` - (String) The unique identifier of the instance. The ID is composed of `//`. +- `macaddress` - (String) The MAC address of the port. +- `portid` - (String) The ID of the port. +- `public_ip` - (String) The public IP associated with the port. +- `status` - (String) The status of the port. + + +## Import + +The `ibm_pi_network_port` resource can be imported by using `power_instance_id`, `port_id` and `pi_network_name`. + +**Example** + +``` +$ terraform import ibm_pi_network_port.example d7bec597-4726-451f-8a63-e62e6f19c32c/cea6651a-bc0a-4438-9f8a-a0770bbf3ebb/network-name +``` From 28ddf36fc240dc2d9420bbe994c6bf2bf684f52f Mon Sep 17 00:00:00 2001 From: dhirendersingh19 Date: Wed, 2 Mar 2022 15:44:49 +0530 Subject: [PATCH 2/3] feedback resolved --- .../resource_ibm_pi_network_port_attach.go | 107 ++++++++++-------- ...esource_ibm_pi_network_port_attach_test.go | 47 +------- .../r/pi_network_port_attach.html.markdown | 4 +- 3 files changed, 63 insertions(+), 95 deletions(-) diff --git a/ibm/service/power/resource_ibm_pi_network_port_attach.go b/ibm/service/power/resource_ibm_pi_network_port_attach.go index c4ced6395f..b6dd305763 100644 --- a/ibm/service/power/resource_ibm_pi_network_port_attach.go +++ b/ibm/service/power/resource_ibm_pi_network_port_attach.go @@ -25,39 +25,42 @@ func ResourceIBMPINetworkPortAttach() *schema.Resource { CreateContext: resourceIBMPINetworkPortAttachCreate, ReadContext: resourceIBMPINetworkPortAttachRead, - UpdateContext: resourceIBMPINetworkPortAttachUpdate, DeleteContext: resourceIBMPINetworkPortAttachDelete, Importer: &schema.ResourceImporter{}, Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(60 * time.Minute), Delete: schema.DefaultTimeout(60 * time.Minute), - Update: schema.DefaultTimeout(60 * time.Minute), }, Schema: map[string]*schema.Schema{ helpers.PICloudInstanceId: { Type: schema.TypeString, Required: true, + ForceNew: true, }, helpers.PIInstanceId: { Type: schema.TypeString, Required: true, + ForceNew: true, Description: "Instance id to attach the network port to", }, helpers.PINetworkName: { Type: schema.TypeString, Required: true, + ForceNew: true, Description: "Network Name - This is the subnet name in the Cloud instance", }, helpers.PINetworkPortDescription: { Type: schema.TypeString, Optional: true, + ForceNew: true, Description: "A human readable description for this network Port", Default: "Port Created via Terraform", }, helpers.PINetworkPortIPAddress: { Type: schema.TypeString, Optional: true, + ForceNew: true, Computed: true, }, @@ -66,7 +69,12 @@ func ResourceIBMPINetworkPortAttach() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "portid": { + "port_id": { + Type: schema.TypeString, + Computed: true, + Deprecated: "port_id attribute is deprecated, use network_port_id instead.", + }, + "network_port_id": { Type: schema.TypeString, Computed: true, }, @@ -90,20 +98,18 @@ func resourceIBMPINetworkPortAttachCreate(ctx context.Context, d *schema.Resourc } cloudInstanceID := d.Get(helpers.PICloudInstanceId).(string) networkname := d.Get(helpers.PINetworkName).(string) + instanceID := d.Get(helpers.PIInstanceId).(string) description := d.Get(helpers.PINetworkPortDescription).(string) - - ipaddress := d.Get(helpers.PINetworkPortIPAddress).(string) - instancename := d.Get(helpers.PIInstanceId).(string) nwportBody := &models.NetworkPortCreate{Description: description} - if ipaddress != "" { - log.Printf("IP address provided. ") + if v, ok := d.GetOk(helpers.PINetworkPortIPAddress); ok { + ipaddress := v.(string) nwportBody.IPAddress = ipaddress } nwportattachBody := &models.NetworkPortUpdate{ Description: &description, - PvmInstanceID: &instancename, + PvmInstanceID: &instanceID, } client := st.NewIBMPINetworkClient(ctx, sess, cloudInstanceID) @@ -115,26 +121,26 @@ func resourceIBMPINetworkPortAttachCreate(ctx context.Context, d *schema.Resourc log.Printf("Printing the networkresponse %+v", &networkPortResponse) - IBMPINetworkPortID := *networkPortResponse.PortID + networkPortID := *networkPortResponse.PortID - _, err = isWaitForIBMPINetworkPortAvailable(ctx, client, IBMPINetworkPortID, networkname, d.Timeout(schema.TimeoutCreate)) + _, err = isWaitForIBMPINetworkportAvailable(ctx, client, networkPortID, networkname, d.Timeout(schema.TimeoutCreate)) if err != nil { return diag.FromErr(err) } - networkPortResponse, err = client.UpdatePort(networkname, IBMPINetworkPortID, nwportattachBody) + networkPortResponse, err = client.UpdatePort(networkname, networkPortID, nwportattachBody) if err != nil { return diag.FromErr(err) } - _, err = isWaitForIBMPINetworkPortAttachAvailable(ctx, client, IBMPINetworkPortID, networkname, d.Timeout(schema.TimeoutUpdate)) + _, err = isWaitForIBMPINetworkPortAttachAvailable(ctx, client, networkPortID, networkname, instanceID, d.Timeout(schema.TimeoutUpdate)) if err != nil { return diag.FromErr(err) } - d.SetId(fmt.Sprintf("%s/%s/%s", cloudInstanceID, networkname, IBMPINetworkPortID)) + d.SetId(fmt.Sprintf("%s/%s/%s", cloudInstanceID, networkname, networkPortID)) - return resourceIBMPINetworkPortRead(ctx, d, meta) + return resourceIBMPINetworkPortAttachRead(ctx, d, meta) } func resourceIBMPINetworkPortAttachRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { @@ -162,39 +168,13 @@ func resourceIBMPINetworkPortAttachRead(ctx context.Context, d *schema.ResourceD d.Set(helpers.PIInstanceId, networkdata.PvmInstance.PvmInstanceID) d.Set("macaddress", networkdata.MacAddress) d.Set("status", networkdata.Status) - d.Set("portid", networkdata.PortID) + d.Set("network_port_id", networkdata.PortID) + d.Set("port_id", networkdata.PortID) d.Set("public_ip", networkdata.ExternalIP) return nil } -func resourceIBMPINetworkPortAttachUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - sess, err := meta.(conns.ClientSession).IBMPISession() - if err != nil { - return diag.FromErr(err) - } - parts, err := flex.IdParts(d.Id()) - if err != nil { - return diag.FromErr(err) - } - cloudInstanceID, networkname, portID := parts[0], parts[1], parts[2] - - if d.HasChange(helpers.PINetworkPortDescription) { - description := d.Get(helpers.PINetworkPortDescription).(string) - body := &models.NetworkPortUpdate{Description: &description} - client := st.NewIBMPINetworkClient(ctx, sess, cloudInstanceID) - _, err = client.UpdatePort(networkname, portID, body) - if err != nil { - return diag.FromErr(err) - } - _, err = isWaitForIBMPINetworkPortAvailable(ctx, client, portID, networkname, d.Timeout(schema.TimeoutUpdate)) - if err != nil { - return diag.FromErr(err) - } - } - return resourceIBMPINetworkPortRead(ctx, d, meta) -} - func resourceIBMPINetworkPortAttachDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { log.Printf("Calling the network delete functions. ") @@ -223,13 +203,45 @@ func resourceIBMPINetworkPortAttachDelete(ctx context.Context, d *schema.Resourc return nil } -func isWaitForIBMPINetworkPortAttachAvailable(ctx context.Context, client *st.IBMPINetworkClient, id string, networkname string, timeout time.Duration) (interface{}, error) { +func isWaitForIBMPINetworkportAvailable(ctx context.Context, client *st.IBMPINetworkClient, id string, networkname string, timeout time.Duration) (interface{}, error) { + log.Printf("Waiting for Power Network (%s) that was created for Network Zone (%s) to be available.", id, networkname) + + stateConf := &resource.StateChangeConf{ + Pending: []string{"retry", helpers.PINetworkProvisioning}, + Target: []string{"DOWN"}, + Refresh: isIBMPINetworkportRefreshFunc(client, id, networkname), + Timeout: timeout, + Delay: 10 * time.Second, + MinTimeout: 10 * time.Minute, + } + + return stateConf.WaitForStateContext(ctx) +} + +func isIBMPINetworkportRefreshFunc(client *st.IBMPINetworkClient, id, networkname string) resource.StateRefreshFunc { + + log.Printf("Calling the IsIBMPINetwork Refresh Function....with the following id (%s) for network port and following id (%s) for network name and waiting for network to be READY", id, networkname) + return func() (interface{}, string, error) { + network, err := client.GetPort(networkname, id) + if err != nil { + return nil, "", err + } + + if *network.Status == "DOWN" { + log.Printf(" The port has been created with the following ip address and attached to an instance ") + return network, "DOWN", nil + } + + return network, helpers.PINetworkProvisioning, nil + } +} +func isWaitForIBMPINetworkPortAttachAvailable(ctx context.Context, client *st.IBMPINetworkClient, id, networkname, instanceid string, timeout time.Duration) (interface{}, error) { log.Printf("Waiting for Power Network (%s) that was created for Network Zone (%s) to be available.", id, networkname) stateConf := &resource.StateChangeConf{ Pending: []string{"retry", helpers.PINetworkProvisioning}, Target: []string{"ACTIVE"}, - Refresh: isIBMPINetworkPortAttachRefreshFunc(client, id, networkname), + Refresh: isIBMPINetworkPortAttachRefreshFunc(client, id, networkname, instanceid), Timeout: timeout, Delay: 10 * time.Second, MinTimeout: 10 * time.Minute, @@ -238,7 +250,7 @@ func isWaitForIBMPINetworkPortAttachAvailable(ctx context.Context, client *st.IB return stateConf.WaitForStateContext(ctx) } -func isIBMPINetworkPortAttachRefreshFunc(client *st.IBMPINetworkClient, id, networkname string) resource.StateRefreshFunc { +func isIBMPINetworkPortAttachRefreshFunc(client *st.IBMPINetworkClient, id, networkname, instanceid string) resource.StateRefreshFunc { log.Printf("Calling the IsIBMPINetwork Refresh Function....with the following id (%s) for network port and following id (%s) for network name and waiting for network to be READY", id, networkname) return func() (interface{}, string, error) { @@ -247,8 +259,7 @@ func isIBMPINetworkPortAttachRefreshFunc(client *st.IBMPINetworkClient, id, netw return nil, "", err } - if &network.PortID != nil && &network.PvmInstance.PvmInstanceID != nil { - //if network.State == "available" { + if *network.Status == "ACTIVE" && network.PvmInstance.PvmInstanceID == instanceid { log.Printf(" The port has been created with the following ip address and attached to an instance ") return network, "ACTIVE", nil } diff --git a/ibm/service/power/resource_ibm_pi_network_port_attach_test.go b/ibm/service/power/resource_ibm_pi_network_port_attach_test.go index 273212d6d4..7980808608 100644 --- a/ibm/service/power/resource_ibm_pi_network_port_attach_test.go +++ b/ibm/service/power/resource_ibm_pi_network_port_attach_test.go @@ -34,18 +34,7 @@ func TestAccIBMPINetworkPortAttachbasic(t *testing.T) { resource.TestCheckResourceAttr( "ibm_pi_network_port_attach.power_network_port_attach", "pi_network_name", name), resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "id"), - resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "portid"), - resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "public_ip"), - ), - }, - { - Config: testAccCheckIBMPINetworkPortAttachUpdateConfig(name), - Check: resource.ComposeTestCheckFunc( - testAccCheckIBMPINetworkPortAttachExists("ibm_pi_network_port_attach.power_network_port_attach"), - resource.TestCheckResourceAttr( - "ibm_pi_network_port_attach.power_network_port_attach", "pi_network_name", name), - resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "id"), - resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "portid"), + resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "network_port_id"), resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "public_ip"), ), }, @@ -67,17 +56,7 @@ func TestAccIBMPINetworkPortAttachVlanbasic(t *testing.T) { resource.TestCheckResourceAttr( "ibm_pi_network_port_attach.power_network_port_attach", "pi_network_name", name), resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "id"), - resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "portid"), - ), - }, - { - Config: testAccCheckIBMPINetworkPortAttachVlanUpdateConfig(name), - Check: resource.ComposeTestCheckFunc( - testAccCheckIBMPINetworkPortAttachExists("ibm_pi_network_port_attach.power_network_port_attach"), - resource.TestCheckResourceAttr( - "ibm_pi_network_port_attach.power_network_port_attach", "pi_network_name", name), - resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "id"), - resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "portid"), + resource.TestCheckResourceAttrSet("ibm_pi_network_port_attach.power_network_port_attach", "network_port_id"), ), }, }, @@ -154,17 +133,6 @@ func testAccCheckIBMPINetworkPortAttachConfig(name string) string { `, acc.Pi_cloud_instance_id, acc.Pi_instance_name) } -func testAccCheckIBMPINetworkPortAttachUpdateConfig(name string) string { - return testAccCheckIBMPINetworkConfig(name) + fmt.Sprintf(` - resource "ibm_pi_network_port_attach" "power_network_port_attach" { - pi_cloud_instance_id = "%s" - pi_network_name = ibm_pi_network.power_networks.pi_network_name - pi_network_port_description = "IP Reserved for TF Test" - pi_instance_id = "%s" - } - `, acc.Pi_cloud_instance_id, acc.Pi_instance_name) -} - func testAccCheckIBMPINetworkPortAttachVlanConfig(name string) string { return testAccCheckIBMPINetworkGatewayConfig(name) + fmt.Sprintf(` resource "ibm_pi_network_port_attach" "power_network_port_attach" { @@ -175,14 +143,3 @@ func testAccCheckIBMPINetworkPortAttachVlanConfig(name string) string { } `, acc.Pi_cloud_instance_id, acc.Pi_instance_name) } - -func testAccCheckIBMPINetworkPortAttachVlanUpdateConfig(name string) string { - return testAccCheckIBMPINetworkGatewayConfig(name) + fmt.Sprintf(` - resource "ibm_pi_network_port_attach" "power_network_port_attach" { - pi_cloud_instance_id = "%s" - pi_network_name = ibm_pi_network.power_networks.pi_network_name - pi_network_port_description = "IP Reserved for TF Test" - pi_instance_id = "%s" - } - `, acc.Pi_cloud_instance_id, acc.Pi_instance_name) -} diff --git a/website/docs/r/pi_network_port_attach.html.markdown b/website/docs/r/pi_network_port_attach.html.markdown index df838d6e8d..35e7d27ff5 100644 --- a/website/docs/r/pi_network_port_attach.html.markdown +++ b/website/docs/r/pi_network_port_attach.html.markdown @@ -62,14 +62,14 @@ In addition to all argument reference list, you can access the following attribu - `id` - (String) The unique identifier of the instance. The ID is composed of `//`. - `macaddress` - (String) The MAC address of the port. -- `portid` - (String) The ID of the port. +- `network_port_id` - (String) The ID of the port. - `public_ip` - (String) The public IP associated with the port. - `status` - (String) The status of the port. ## Import -The `ibm_pi_network_port` resource can be imported by using `power_instance_id`, `port_id` and `pi_network_name`. +The `ibm_pi_network_port` resource can be imported by using `power_instance_id`, `network_port_id` and `pi_network_name`. **Example** From 0b34ba88ebaba5d7fc6e1d0901e3eac4a611ad88 Mon Sep 17 00:00:00 2001 From: dhirendersingh19 Date: Wed, 4 May 2022 20:18:12 +0530 Subject: [PATCH 3/3] improved network port attach docs --- .../r/pi_network_port_attach.html.markdown | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/website/docs/r/pi_network_port_attach.html.markdown b/website/docs/r/pi_network_port_attach.html.markdown index 35e7d27ff5..de0c14dfa5 100644 --- a/website/docs/r/pi_network_port_attach.html.markdown +++ b/website/docs/r/pi_network_port_attach.html.markdown @@ -2,26 +2,25 @@ subcategory: "Power Systems" layout: "ibm" -page_title: "IBM: pi_network_port" +page_title: "IBM: pi_network_port_attach" description: |- - Manages an Network Port Attachments in the Power Virtual Server Cloud. A network port is equivalent to reserving an IP in the subnet. - When the port is created the status will be "DOWN". This network port however is not attached to an instance. + Manages an Network Port Attachments in the Power Virtual Server Cloud. --- -# ibm_pi_network_port -Creates & Attaches network port in the Power Virtual Server Cloud. For more information, about network in IBM power virutal server, see [adding or removing a public network +# ibm_pi_network_port_attach +Attaches network port in the Power Virtual Server Cloud. For more information, about network in IBM power virutal server, see [adding or removing a public network ](https://cloud.ibm.com/docs/power-iaas?topic=power-iaas-modifying-server#adding-removing-network).. ## Example usage -In the following example, you can create an network_port & attach it to pvm instance: +In the following example, you can create an network_port_attach resource: ```terraform -resource "ibm_pi_network_port" "test-network-port" { - pi_network_name = "Zone1-CFN" - pi_cloud_instance_id = "51e1879c-bcbe-4ee1-a008-49cdba0eaf60" +resource "ibm_pi_network_port_attach" "test-network-port-attach" { + pi_cloud_instance_id = "" pi_instance_id = "" - pi_network_port_description = "IP Reserved for Oracle RAC " + pi_network_name = "" + pi_network_port_description = "" } ``` @@ -42,18 +41,17 @@ resource "ibm_pi_network_port" "test-network-port" { ## Timeouts -ibm_pi_network_port provides the following [timeouts](https://www.terraform.io/docs/language/resources/syntax.html) configuration options: +ibm_pi_network_port_attach provides the following [timeouts](https://www.terraform.io/docs/language/resources/syntax.html) configuration options: -- **create** - (Default 60 minutes) Used for creating a network_port. -- **update** - (Default 60 minutes) Used for updating a network_port. -- **delete** - (Default 60 minutes) Used for deleting a network_port. +- **create** - (Default 60 minutes) Used for attaching a network port. +- **delete** - (Default 60 minutes) Used for detaching a network port. ## Argument reference Review the argument references that you can specify for your resource. - `pi_cloud_instance_id` - (Required, String) The GUID of the service instance associated with an account. -- `pi_instance_id` - (Required, String) The ID of the pvm instance to attach the network port to. -- `pi_network_name` - (Required, String) Network ID or name. +- `pi_instance_id` - (Required, String) The ID of the pvm instance to attach the network port to. +- `pi_network_name` - (Required, String) The network ID or name. - `pi_network_port_description` - (Optional, String) The description for the Network Port. - `pi_network_port_ipaddress` - (Optional, String) The requested ip address of this port. @@ -63,16 +61,17 @@ In addition to all argument reference list, you can access the following attribu - `id` - (String) The unique identifier of the instance. The ID is composed of `//`. - `macaddress` - (String) The MAC address of the port. - `network_port_id` - (String) The ID of the port. +- `portid` - (Deprecated, String) The ID of the port. - `public_ip` - (String) The public IP associated with the port. - `status` - (String) The status of the port. ## Import -The `ibm_pi_network_port` resource can be imported by using `power_instance_id`, `network_port_id` and `pi_network_name`. +The `ibm_pi_network_port` resource can be imported by using `power_instance_id`, `pi_network_name` and `port_id`. **Example** ``` -$ terraform import ibm_pi_network_port.example d7bec597-4726-451f-8a63-e62e6f19c32c/cea6651a-bc0a-4438-9f8a-a0770bbf3ebb/network-name +$ terraform import ibm_pi_network_port_attach.example d7bec597-4726-451f-8a63-e62e6f19c32c/network-name/cea6651a-bc0a-4438-9f8a-a0770bbf3ebb ```