Skip to content

Commit

Permalink
Merge pull request #5648 from powervs-ibm/workspace-details-dep
Browse files Browse the repository at this point in the history
[Resource] Add user tags to workspace resource
  • Loading branch information
yussufsh authored Oct 4, 2024
2 parents 74e151f + 94692da commit 5e34140
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 19 deletions.
64 changes: 56 additions & 8 deletions ibm/service/power/resource_ibm_pi_workspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ import (
func ResourceIBMPIWorkspace() *schema.Resource {
return &schema.Resource{
CreateContext: resourceIBMPIWorkspaceCreate,
ReadContext: resourceIBMPIWorkspaceRead,
DeleteContext: resourceIBMPIWorkspaceDelete,
ReadContext: resourceIBMPIWorkspaceRead,
UpdateContext: resourceIBMPIWorkspaceUpdate,
Importer: &schema.ResourceImporter{},

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(30 * time.Minute),
Delete: schema.DefaultTimeout(30 * time.Minute),
Update: schema.DefaultTimeout(10 * time.Minute),
},

Schema: map[string]*schema.Schema{
Expand Down Expand Up @@ -59,10 +61,23 @@ func ResourceIBMPIWorkspace() *schema.Resource {
Type: schema.TypeString,
ValidateFunc: validation.NoZeroValues,
},
Arg_UserTags: {
Description: "List of user tags attached to the resource.",
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
Set: schema.HashString,
Type: schema.TypeSet,
},

// Attributes
Attr_CRN: {
Computed: true,
Description: "The Workspace crn.",
Type: schema.TypeString,
},
Attr_WorkspaceDetails: {
Computed: true,
Deprecated: "This field is deprecated, use crn instead.",
Description: "Workspace information.",
Type: schema.TypeMap,
},
Expand All @@ -89,16 +104,28 @@ func resourceIBMPIWorkspaceCreate(ctx context.Context, d *schema.ResourceData, m
return diag.FromErr(err)
}

d.SetId(*controller.GUID)
_, err = waitForResourceInstanceCreate(ctx, client, *controller.GUID, d.Timeout(schema.TimeoutCreate))
cloudInstanceID := *controller.GUID
d.SetId(cloudInstanceID)

_, err = waitForResourceWorkspaceCreate(ctx, client, cloudInstanceID, d.Timeout(schema.TimeoutCreate))
if err != nil {
return diag.FromErr(err)
}

// Add user tags for newly created workspace
if tags, ok := d.GetOk(Arg_UserTags); ok {
if len(flex.FlattenSet(tags.(*schema.Set))) > 0 {
oldList, newList := d.GetChange(Arg_UserTags)
err := flex.UpdateGlobalTagsUsingCRN(oldList, newList, meta, *controller.CRN, "", UserTagType)
if err != nil {
log.Printf("Error on creation of workspace (%s) pi_user_tags: %s", *controller.CRN, err)
}
}
}
return resourceIBMPIWorkspaceRead(ctx, d, meta)
}

func waitForResourceInstanceCreate(ctx context.Context, client *instance.IBMPIWorkspacesClient, id string, timeout time.Duration) (interface{}, error) {
func waitForResourceWorkspaceCreate(ctx context.Context, client *instance.IBMPIWorkspacesClient, id string, timeout time.Duration) (interface{}, error) {
stateConf := &retry.StateChangeConf{
Pending: []string{State_InProgress, State_Inactive, State_Provisioning},
Target: []string{State_Active},
Expand Down Expand Up @@ -137,11 +164,19 @@ func resourceIBMPIWorkspaceRead(ctx context.Context, d *schema.ResourceData, met
return diag.FromErr(err)
}
d.Set(Arg_Name, controller.Name)
tags, err := flex.GetGlobalTagsUsingCRN(meta, *controller.CRN, "", UserTagType)
if err != nil {
log.Printf("Error on get of workspace (%s) pi_user_tags: %s", cloudInstanceID, err)
}
d.Set(Arg_UserTags, tags)

d.Set(Attr_CRN, controller.CRN)

// Deprecated Workspace Details Set
wsDetails := map[string]interface{}{
Attr_CreationDate: controller.CreatedAt,
Attr_CRN: controller.TargetCRN,
Attr_CRN: controller.CRN,
}

d.Set(Attr_WorkspaceDetails, flex.Flatten(wsDetails))

return nil
Expand All @@ -159,7 +194,7 @@ func resourceIBMPIWorkspaceDelete(ctx context.Context, d *schema.ResourceData, m
if err != nil && response != nil && response.StatusCode == 410 {
return nil
}
_, err = waitForResourceInstanceDelete(ctx, client, cloudInstanceID, d.Timeout(schema.TimeoutDelete))
_, err = waitForResourceWorkspaceDelete(ctx, client, cloudInstanceID, d.Timeout(schema.TimeoutDelete))
if err != nil {
return diag.FromErr(err)
}
Expand All @@ -168,7 +203,7 @@ func resourceIBMPIWorkspaceDelete(ctx context.Context, d *schema.ResourceData, m
return nil
}

func waitForResourceInstanceDelete(ctx context.Context, client *instance.IBMPIWorkspacesClient, id string, timeout time.Duration) (interface{}, error) {
func waitForResourceWorkspaceDelete(ctx context.Context, client *instance.IBMPIWorkspacesClient, id string, timeout time.Duration) (interface{}, error) {
stateConf := &retry.StateChangeConf{
Pending: []string{State_InProgress, State_Inactive, State_Active},
Target: []string{State_Removed, State_PendingReclamation},
Expand Down Expand Up @@ -199,3 +234,16 @@ func isIBMPIResourceDeleteRefreshFunc(client *instance.IBMPIWorkspacesClient, id
}
}
}

func resourceIBMPIWorkspaceUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
if d.HasChange(Arg_UserTags) {
if crn, ok := d.GetOk(Attr_CRN); ok {
oldList, newList := d.GetChange(Arg_UserTags)
err := flex.UpdateGlobalTagsUsingCRN(oldList, newList, meta, crn.(string), "", UserTagType)
if err != nil {
log.Printf("Error on update of workspace (%s) pi_user_tags: %s", crn, err)
}
}
}
return resourceIBMPIWorkspaceRead(ctx, d, meta)
}
50 changes: 40 additions & 10 deletions ibm/service/power/resource_ibm_pi_workspace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import (
"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/power-go-client/clients/instance"
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns"
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/service/power"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
Expand All @@ -34,14 +35,44 @@ func TestAccIBMPIWorkspaceBasic(t *testing.T) {
})
}

func TestAccIBMPIWorkspaceUserTags(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: testAccCheckIBMPIWorkspaceUserTagConfig(name),
Check: resource.ComposeTestCheckFunc(
testAccCheckIBMPIWorkspaceExists("ibm_pi_workspace.powervs_service_instance"),
resource.TestCheckResourceAttrSet("ibm_pi_workspace.powervs_service_instance", "id"),
resource.TestCheckResourceAttr("ibm_pi_workspace.powervs_service_instance", "pi_user_tags.#", "2"),
resource.TestCheckTypeSetElemAttr("ibm_pi_workspace.powervs_service_instance", "pi_user_tags.*", "env:dev"),
resource.TestCheckTypeSetElemAttr("ibm_pi_workspace.powervs_service_instance", "pi_user_tags.*", "dataresidency:france"),
),
},
},
})
}

func testAccCheckIBMPIWorkspaceConfig(name string) string {
return fmt.Sprintf(`
resource "ibm_pi_workspace" "powervs_service_instance" {
pi_name = "%[1]s"
pi_datacenter = "dal12"
pi_resource_group_id = "%[2]s"
}
`, name, acc.Pi_resource_group_id)
resource "ibm_pi_workspace" "powervs_service_instance" {
pi_name = "%[1]s"
pi_datacenter = "dal12"
pi_resource_group_id = "%[2]s"
}`, name, acc.Pi_resource_group_id)
}

func testAccCheckIBMPIWorkspaceUserTagConfig(name string) string {
return fmt.Sprintf(`
resource "ibm_pi_workspace" "powervs_service_instance" {
pi_name = "%[1]s"
pi_datacenter = "dal12"
pi_resource_group_id = "%[2]s"
pi_user_tags = ["env:dev", "dataresidency:france"]
}`, name, acc.Pi_resource_group_id)
}

func testAccIBMPIWorkspaceDestroy(s *terraform.State) error {
Expand All @@ -54,7 +85,7 @@ func testAccIBMPIWorkspaceDestroy(s *terraform.State) error {
continue
}
cloudInstanceID := rs.Primary.ID
client := st.NewIBMPIWorkspacesClient(context.Background(), sess, cloudInstanceID)
client := instance.NewIBMPIWorkspacesClient(context.Background(), sess, cloudInstanceID)
workspace, resp, err := client.GetRC(cloudInstanceID)
if err == nil {
if *workspace.State == power.State_Active {
Expand All @@ -71,7 +102,6 @@ func testAccIBMPIWorkspaceDestroy(s *terraform.State) error {

func testAccCheckIBMPIWorkspaceExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {

rs, ok := s.RootModule().Resources[n]

if !ok {
Expand All @@ -88,7 +118,7 @@ func testAccCheckIBMPIWorkspaceExists(n string) resource.TestCheckFunc {
}

cloudInstanceID := rs.Primary.ID
client := st.NewIBMPIWorkspacesClient(context.Background(), sess, cloudInstanceID)
client := instance.NewIBMPIWorkspacesClient(context.Background(), sess, cloudInstanceID)
_, _, err = client.GetRC(cloudInstanceID)
if err != nil {
return err
Expand Down
4 changes: 3 additions & 1 deletion website/docs/r/pi_workspace.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,15 @@ Review the argument references that you can specify for your resource.
- `pi_name` - (Required, String) A descriptive name used to identify the workspace.
- `pi_plan` - (Optional, String) Plan associated with the offering; Valid values are `public` or `private`. The default value is `public`.
- `pi_resource_group_id` - (Required, String) The ID of the resource group where you want to create the workspace. You can retrieve the value from data source `ibm_resource_group`.
- `pi_user_tags` - (Optional, List) List of user tags attached to the resource.

## Attribute reference

In addition to all argument reference listed, you can access the following attribute references after your resource source is created.

- `id` - (String) Workspace ID.
- `workspace_details` - (Map) Workspace information.
- `crn` - (String) Workspace crn.
- `workspace_details` - (Deprecated, Map) Workspace information.

Nested schema for `workspace_details`:
- `creation_date` - (String) Date of workspace creation.
Expand Down

0 comments on commit 5e34140

Please sign in to comment.