-
Notifications
You must be signed in to change notification settings - Fork 672
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add workspace create workspace delete resource to terraform provider (#…
…4935) * Add workspace-create workspace-delete terraform provider Add waiting to code to finish wait creating workspace Fix workspace delete Add workspace documentation Increase workspace create timeout Update workspace description Remove extra quotes Update dependencies Update dependencies temp * Update workspace documentation --------- Co-authored-by: michaelkad <[email protected]> Co-authored-by: HARINI KANTAREDDY <[email protected]>
- Loading branch information
1 parent
ea5cc69
commit a45c8ab
Showing
10 changed files
with
351 additions
and
11 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
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
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
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,179 @@ | ||
package power | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"log" | ||
"time" | ||
|
||
st "github.com/IBM-Cloud/power-go-client/clients/instance" | ||
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
) | ||
|
||
func ResourceIBMPIWorkspace() *schema.Resource { | ||
return &schema.Resource{ | ||
CreateContext: resourceIBMPIWorkspaceCreate, | ||
ReadContext: resourceIBMPIWorkspaceRead, | ||
DeleteContext: resourceIBMPIWorkspaceDelete, | ||
Importer: &schema.ResourceImporter{}, | ||
|
||
Timeouts: &schema.ResourceTimeout{ | ||
Create: schema.DefaultTimeout(30 * time.Minute), | ||
Delete: schema.DefaultTimeout(30 * time.Minute), | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
PIWorkspaceName: { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
Description: "A descriptive name used to identify the workspace.", | ||
}, | ||
PIWorkspaceDatacenter: { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
Description: "Target location or environment to create the resource instance.", | ||
}, | ||
PIWorkspaceResourceGroup: { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
Description: "The ID of the resource group where you want to create the workspace. You can retrieve the value from data source ibm_resource_group.", | ||
}, | ||
PIWorkspacePlan: { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
Description: "Plan associated with the offering; Valid values are public or private.", | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceIBMPIWorkspaceCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
sess, err := meta.(conns.ClientSession).IBMPISession() | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
name := d.Get(PIWorkspaceName).(string) | ||
datacenter := d.Get(PIWorkspaceDatacenter).(string) | ||
resourceGroup := d.Get(PIWorkspaceResourceGroup).(string) | ||
plan := d.Get(PIWorkspacePlan).(string) | ||
|
||
// No need for cloudInstanceID because we are creating a workspace | ||
client := st.NewIBMPIWorkspacesClient(ctx, sess, "") | ||
controller, _, err := client.Create(name, datacenter, resourceGroup, plan) | ||
if err != nil { | ||
log.Printf("[DEBUG] create workspace failed %v", err) | ||
return diag.FromErr(err) | ||
} | ||
|
||
d.SetId(*controller.GUID) | ||
_, err = waitForResourceInstanceCreate(ctx, client, *controller.GUID, d.Timeout(schema.TimeoutCreate)) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
return resourceIBMPIWorkspaceRead(ctx, d, meta) | ||
} | ||
|
||
func waitForResourceInstanceCreate(ctx context.Context, client *st.IBMPIWorkspacesClient, id string, timeout time.Duration) (interface{}, error) { | ||
stateConf := &resource.StateChangeConf{ | ||
Pending: []string{"in progress", "inactive", "provisioning"}, | ||
Target: []string{"active"}, | ||
Refresh: isIBMPIWorkspaceCreateRefreshFunc(client, id), | ||
Delay: 10 * time.Second, | ||
MinTimeout: 1 * time.Minute, | ||
Timeout: timeout, | ||
} | ||
return stateConf.WaitForStateContext(ctx) | ||
} | ||
|
||
func isIBMPIWorkspaceCreateRefreshFunc(client *st.IBMPIWorkspacesClient, id string) resource.StateRefreshFunc { | ||
return func() (interface{}, string, error) { | ||
controller, _, err := client.GetRC(id) | ||
if err != nil { | ||
return nil, "", err | ||
} | ||
if *controller.State == "failed" { | ||
return controller, *controller.State, fmt.Errorf("[ERROR] The resource instance %s failed to create", id) | ||
} | ||
return controller, *controller.State, nil | ||
} | ||
} | ||
|
||
func resourceIBMPIWorkspaceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
// session | ||
sess, err := meta.(conns.ClientSession).IBMPISession() | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
cloudInstanceID := d.Id() | ||
client := st.NewIBMPIWorkspacesClient(ctx, sess, cloudInstanceID) | ||
controller, _, err := client.GetRC(cloudInstanceID) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
d.Set(PIWorkspaceName, controller.Name) | ||
|
||
return nil | ||
} | ||
|
||
func resourceIBMPIWorkspaceDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
sess, err := meta.(conns.ClientSession).IBMPISession() | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
cloudInstanceID := d.Id() | ||
client := st.NewIBMPIWorkspacesClient(ctx, sess, cloudInstanceID) | ||
response, err := client.Delete(cloudInstanceID) | ||
if err != nil && response != nil && response.StatusCode == 410 { | ||
return nil | ||
} | ||
_, err = waitForResourceInstanceDelete(ctx, client, cloudInstanceID, d.Timeout(schema.TimeoutDelete)) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
d.SetId("") | ||
|
||
return nil | ||
} | ||
|
||
func waitForResourceInstanceDelete(ctx context.Context, client *st.IBMPIWorkspacesClient, id string, timeout time.Duration) (interface{}, error) { | ||
stateConf := &resource.StateChangeConf{ | ||
Pending: []string{"in progress", "inactive", "active"}, | ||
Target: []string{"removed", "pending_reclamation"}, | ||
Refresh: isIBMPIResourceDeleteRefreshFunc(client, id), | ||
Delay: 10 * time.Second, | ||
MinTimeout: 1 * time.Second, | ||
Timeout: timeout, | ||
} | ||
return stateConf.WaitForStateContext(ctx) | ||
} | ||
|
||
func isIBMPIResourceDeleteRefreshFunc(client *st.IBMPIWorkspacesClient, id string) resource.StateRefreshFunc { | ||
return func() (interface{}, string, error) { | ||
controller, response, err := client.GetRC(id) | ||
if err != nil { | ||
if response != nil && response.StatusCode == 404 { | ||
return controller, "active", nil | ||
} | ||
return nil, "", err | ||
} | ||
if controller == nil { | ||
return controller, "removed", nil | ||
} else { | ||
if *controller.State == "failed" { | ||
return controller, *controller.State, fmt.Errorf("[ERROR] The resource instance %s failed to delete", id) | ||
} | ||
return controller, *controller.State, nil | ||
} | ||
} | ||
} |
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,98 @@ | ||
package power_test | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"strings" | ||
"testing" | ||
|
||
st "github.com/IBM-Cloud/power-go-client/clients/instance" | ||
acc "github.com/IBM-Cloud/terraform-provider-ibm/ibm/acctest" | ||
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform" | ||
) | ||
|
||
func TestAccIBMPIWorkspaceBasic(t *testing.T) { | ||
name := fmt.Sprintf("tf-pi-workspace-%d", acctest.RandIntRange(10, 100)) | ||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { acc.TestAccPreCheck(t) }, | ||
Providers: acc.TestAccProviders, | ||
CheckDestroy: testAccIBMPIWorkspaceDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccCheckIBMPIWorkspaceConfig(name), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckIBMPIWorkspaceExists("ibm_pi_workspace.powervs_service_instance"), | ||
resource.TestCheckResourceAttrSet("ibm_pi_workspace.powervs_service_instance", "id"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckIBMPIWorkspaceConfig(name string) string { | ||
return fmt.Sprintf(` | ||
resource "ibm_pi_workspace" "powervs_service_instance" { | ||
pi_name = "%[1]s" | ||
pi_datacenter = "dal" | ||
pi_resource_group_id = "%[2]s" | ||
pi_plan = "public" | ||
} | ||
`, name, acc.Pi_resource_group_id) | ||
} | ||
|
||
func testAccIBMPIWorkspaceDestroy(s *terraform.State) error { | ||
sess, err := acc.TestAccProvider.Meta().(conns.ClientSession).IBMPISession() | ||
if err != nil { | ||
return err | ||
} | ||
for _, rs := range s.RootModule().Resources { | ||
if rs.Type != "ibm_pi_workspace" { | ||
continue | ||
} | ||
cloudInstanceID := rs.Primary.ID | ||
client := st.NewIBMPIWorkspacesClient(context.Background(), sess, cloudInstanceID) | ||
workspace, resp, err := client.GetRC(cloudInstanceID) | ||
if err == nil { | ||
if *workspace.State == "active" { | ||
return fmt.Errorf("Resource Instance still exists: %s", rs.Primary.ID) | ||
} | ||
} else { | ||
if !strings.Contains(err.Error(), "404") { | ||
return fmt.Errorf("[ERROR] Error checking if Resource Instance (%s) has been destroyed: %s with resp code: %s", rs.Primary.ID, err, resp) | ||
} | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func testAccCheckIBMPIWorkspaceExists(n string) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
|
||
rs, ok := s.RootModule().Resources[n] | ||
|
||
if !ok { | ||
return fmt.Errorf("Not found: %s", n) | ||
} | ||
|
||
if rs.Primary.ID == "" { | ||
return errors.New("No Record ID is set") | ||
} | ||
|
||
sess, err := acc.TestAccProvider.Meta().(conns.ClientSession).IBMPISession() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
cloudInstanceID := rs.Primary.ID | ||
client := st.NewIBMPIWorkspacesClient(context.Background(), sess, cloudInstanceID) | ||
_, _, err = client.GetRC(cloudInstanceID) | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
} |
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
Oops, something went wrong.