Skip to content

Commit

Permalink
Granular CRN for instance resources
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander-Kita authored and kavya498 committed Oct 11, 2024
1 parent fef11ba commit 405900d
Show file tree
Hide file tree
Showing 14 changed files with 320 additions and 9 deletions.
19 changes: 17 additions & 2 deletions ibm/service/power/data_source_ibm_pi_cloud_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ package power

import (
"context"
"log"

"github.com/IBM-Cloud/power-go-client/clients/instance"
"github.com/IBM-Cloud/power-go-client/power/models"
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns"
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
Expand Down Expand Up @@ -48,6 +50,11 @@ func DataSourceIBMPICloudInstance() *schema.Resource {
Description: "Date of PVM instance creation.",
Type: schema.TypeString,
},
Attr_CRN: {
Computed: true,
Description: "The CRN of this resource.",
Type: schema.TypeString,
},
Attr_Href: {
Computed: true,
Description: "Link to Cloud Instance resource.",
Expand Down Expand Up @@ -134,7 +141,7 @@ func dataSourceIBMPICloudInstanceRead(ctx context.Context, d *schema.ResourceDat

d.Set(Attr_Capabilities, cloud_instance_data.Capabilities)
d.Set(Attr_Enabled, cloud_instance_data.Enabled)
d.Set(Attr_PVMInstances, flattenpvminstances(cloud_instance_data.PvmInstances))
d.Set(Attr_PVMInstances, flattenpvminstances(cloud_instance_data.PvmInstances, meta))
d.Set(Attr_Region, cloud_instance_data.Region)
d.Set(Attr_TenantID, (cloud_instance_data.TenantID))
d.Set(Attr_TotalInstances, cloud_instance_data.Usage.Instances)
Expand All @@ -146,7 +153,7 @@ func dataSourceIBMPICloudInstanceRead(ctx context.Context, d *schema.ResourceDat
return nil
}

func flattenpvminstances(list []*models.PVMInstanceReference) []map[string]interface{} {
func flattenpvminstances(list []*models.PVMInstanceReference, meta interface{}) []map[string]interface{} {
pvms := make([]map[string]interface{}, 0)
for _, lpars := range list {
l := map[string]interface{}{
Expand All @@ -157,6 +164,14 @@ func flattenpvminstances(list []*models.PVMInstanceReference) []map[string]inter
Attr_Status: *lpars.Status,
Attr_Systype: lpars.SysType,
}
if lpars.Crn != "" {
l[Attr_CRN] = lpars.Crn
tags, err := flex.GetGlobalTagsUsingCRN(meta, string(lpars.Crn), "", UserTagType)
if err != nil {
log.Printf("Error on get of pi instance (%s) user_tags: %s", *lpars.PvmInstanceID, err)
}
l[Attr_UserTags] = tags
}
pvms = append(pvms, l)
}
return pvms
Expand Down
22 changes: 22 additions & 0 deletions ibm/service/power/data_source_ibm_pi_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ package power

import (
"context"
"log"

"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/flex"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
Expand All @@ -32,6 +34,11 @@ func DataSourceIBMPIInstance() *schema.Resource {
},

// Attributes
Attr_CRN: {
Computed: true,
Description: "The CRN of this resource.",
Type: schema.TypeString,
},
Attr_DeploymentType: {
Computed: true,
Description: "The custom deployment type.",
Expand Down Expand Up @@ -208,6 +215,13 @@ func DataSourceIBMPIInstance() *schema.Resource {
Description: "The storage type where server is deployed.",
Type: schema.TypeString,
},
Attr_UserTags: {
Computed: true,
Description: "List of user tags attached to the resource.",
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
Type: schema.TypeSet,
},
Attr_VirtualCoresAssigned: {
Computed: true,
Description: "The virtual cores that are assigned to the instance.",
Expand Down Expand Up @@ -239,6 +253,14 @@ func dataSourceIBMPIInstancesRead(ctx context.Context, d *schema.ResourceData, m

pvminstanceid := *powervmdata.PvmInstanceID
d.SetId(pvminstanceid)
if powervmdata.Crn != "" {
d.Set(Attr_CRN, powervmdata.Crn)
tags, err := flex.GetGlobalTagsUsingCRN(meta, string(powervmdata.Crn), "", UserTagType)
if err != nil {
log.Printf("Error on get of pi instance (%s) user_tags: %s", *powervmdata.PvmInstanceID, err)
}
d.Set(Attr_UserTags, tags)
}
d.Set(Attr_DeploymentType, powervmdata.DeploymentType)
d.Set(Attr_LicenseRepositoryCapacity, powervmdata.LicenseRepositoryCapacity)
d.Set(Attr_MaxMem, powervmdata.Maxmem)
Expand Down
3 changes: 2 additions & 1 deletion ibm/service/power/data_source_ibm_pi_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ import (
)

func TestAccIBMPIInstanceDataSource_basic(t *testing.T) {
instanceResData := "data.ibm_pi_instance.testacc_ds_instance"
resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
Steps: []resource.TestStep{
{
Config: testAccCheckIBMPIInstanceDataSourceConfig(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.ibm_pi_instance.testacc_ds_instance", "id"),
resource.TestCheckResourceAttrSet(instanceResData, "id"),
),
},
},
Expand Down
27 changes: 25 additions & 2 deletions ibm/service/power/data_source_ibm_pi_instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ package power

import (
"context"
"log"
"strconv"

"github.com/IBM-Cloud/power-go-client/clients/instance"
"github.com/IBM-Cloud/power-go-client/power/models"
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns"
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
Expand All @@ -34,6 +36,11 @@ func DataSourceIBMPIInstances() *schema.Resource {
Description: "List of power virtual server instances for the respective cloud instance.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
Attr_CRN: {
Computed: true,
Description: "The CRN of this resource.",
Type: schema.TypeString,
},
Attr_Fault: {
Computed: true,
Description: "Fault information.",
Expand Down Expand Up @@ -189,6 +196,13 @@ func DataSourceIBMPIInstances() *schema.Resource {
Description: "The storage type where server is deployed.",
Type: schema.TypeString,
},
Attr_UserTags: {
Computed: true,
Description: "List of user tags attached to the resource.",
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
Type: schema.TypeSet,
},
Attr_VirtualCoresAssigned: {
Computed: true,
Description: "The virtual cores that are assigned to the instance.",
Expand Down Expand Up @@ -220,12 +234,12 @@ func dataSourceIBMPIInstancesAllRead(ctx context.Context, d *schema.ResourceData

var clientgenU, _ = uuid.GenerateUUID()
d.SetId(clientgenU)
d.Set(Attr_PVMInstances, flattenPvmInstances(powervmdata.PvmInstances))
d.Set(Attr_PVMInstances, flattenPvmInstances(powervmdata.PvmInstances, meta))

return nil
}

func flattenPvmInstances(list []*models.PVMInstanceReference) []map[string]interface{} {
func flattenPvmInstances(list []*models.PVMInstanceReference, meta interface{}) []map[string]interface{} {
result := make([]map[string]interface{}, 0, len(list))
for _, i := range list {
l := map[string]interface{}{
Expand Down Expand Up @@ -253,6 +267,15 @@ func flattenPvmInstances(list []*models.PVMInstanceReference) []map[string]inter
Attr_VirtualCoresAssigned: i.VirtualCores.Assigned,
}

if i.Crn != "" {
l[Attr_CRN] = i.Crn
tags, err := flex.GetGlobalTagsUsingCRN(meta, string(i.Crn), "", UserTagType)
if err != nil {
log.Printf("Error on get of pi instance (%s) user_tags: %s", *i.PvmInstanceID, err)
}
l[Attr_UserTags] = tags
}

if i.Health != nil {
l[Attr_HealthStatus] = i.Health.Status
}
Expand Down
3 changes: 2 additions & 1 deletion ibm/service/power/data_source_ibm_pi_instances_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ import (
)

func TestAccIBMPIInstancesDataSource_basic(t *testing.T) {
instancesResData := "data.ibm_pi_instances.testacc_ds_instance"
resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
Steps: []resource.TestStep{
{
Config: testAccCheckIBMPIInstancesDataSourceConfig(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.ibm_pi_instances.testacc_ds_instance", "id"),
resource.TestCheckResourceAttrSet(instancesResData, "id"),
),
},
},
Expand Down
65 changes: 64 additions & 1 deletion ibm/service/power/resource_ibm_pi_capture.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ func ResourceIBMPICapture() *schema.Resource {
CreateContext: resourceIBMPICaptureCreate,
ReadContext: resourceIBMPICaptureRead,
DeleteContext: resourceIBMPICaptureDelete,
UpdateContext: resourceIBMPICaptureUpdate,
Importer: &schema.ResourceImporter{},

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(75 * time.Minute),
Delete: schema.DefaultTimeout(50 * time.Minute),
Update: schema.DefaultTimeout(60 * time.Minute),
},

Schema: map[string]*schema.Schema{
Expand Down Expand Up @@ -104,7 +106,19 @@ func ResourceIBMPICapture() *schema.Resource {
ForceNew: true,
Description: "Cloud Storage Image Path (bucket-name [/folder/../..])",
},
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,
},
// Computed Attribute
Attr_CRN: {
Computed: true,
Description: "The CRN of the resource.",
Type: schema.TypeString,
},
"image_id": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -161,6 +175,10 @@ func resourceIBMPICaptureCreate(ctx context.Context, d *schema.ResourceData, met
}
}

if v, ok := d.GetOk(Arg_UserTags); ok {
captureBody.UserTags = flex.FlattenSet(v.(*schema.Set))
}

captureResponse, err := client.CaptureInstanceToImageCatalogV2(name, captureBody)

if err != nil {
Expand All @@ -173,6 +191,22 @@ func resourceIBMPICaptureCreate(ctx context.Context, d *schema.ResourceData, met
if err != nil {
return diag.FromErr(err)
}

if _, ok := d.GetOk(Arg_UserTags); ok && capturedestination != cloudStorageDestination {
imageClient := st.NewIBMPIImageClient(ctx, sess, cloudInstanceID)
imagedata, err := imageClient.Get(capturename)
if err != nil {
log.Printf("Error on get of ibm pi capture (%s) while applying pi_user_tags: %s", capturename, err)
}
if imagedata.Crn != "" {
oldList, newList := d.GetChange(Arg_UserTags)
err = flex.UpdateGlobalTagsUsingCRN(oldList, newList, meta, string(imagedata.Crn), "", UserTagType)
if err != nil {
log.Printf("Error on update of pi capture (%s) pi_user_tags during creation: %s", *imagedata.ImageID, err)
}
}
}

return resourceIBMPICaptureRead(ctx, d, meta)
}

Expand All @@ -197,12 +231,20 @@ func resourceIBMPICaptureRead(ctx context.Context, d *schema.ResourceData, meta
case *p_cloud_images.PcloudCloudinstancesImagesGetNotFound:
log.Printf("[DEBUG] image does not exist %v", err)
d.SetId("")
return nil
return diag.Errorf("image does not exist %v", err)
}
log.Printf("[DEBUG] get image failed %v", err)
return diag.FromErr(err)
}
imageid := *imagedata.ImageID
if imagedata.Crn != "" {
d.Set(Attr_CRN, imagedata.Crn)
tags, err := flex.GetGlobalTagsUsingCRN(meta, string(imagedata.Crn), "", UserTagType)
if err != nil {
log.Printf("Error on get of ibm pi capture (%s) pi_user_tags: %s", *imagedata.ImageID, err)
}
d.Set(Arg_UserTags, tags)
}
d.Set("image_id", imageid)
}
d.Set(helpers.PICloudInstanceId, cloudInstanceID)
Expand Down Expand Up @@ -239,3 +281,24 @@ func resourceIBMPICaptureDelete(ctx context.Context, d *schema.ResourceData, met
d.SetId("")
return nil
}

func resourceIBMPICaptureUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
parts, err := flex.IdParts(d.Id())
if err != nil {
return diag.FromErr(err)
}
captureID := parts[1]
capturedestination := parts[2]

if capturedestination != cloudStorageDestination && 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 pi capture (%s) pi_user_tags: %s", captureID, err)
}
}
}

return resourceIBMPICaptureRead(ctx, d, meta)
}
50 changes: 49 additions & 1 deletion ibm/service/power/resource_ibm_pi_capture_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,43 @@ func TestAccIBMPICaptureWithVolume(t *testing.T) {
resource.TestCheckResourceAttr(captureRes, "pi_capture_name", name),
resource.TestCheckResourceAttrSet(captureRes, "image_id"),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func TestAccIBMPICaptureUserTags(t *testing.T) {
captureRes := "ibm_pi_capture.capture_instance"
name := fmt.Sprintf("tf-pi-capture-%d", acctest.RandIntRange(10, 100))
userTagsString := `["env:dev", "test_tag"]`
userTagsStringUpdated := `["env:dev", "test_tag","test_tag2"]`
resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
CheckDestroy: testAccCheckIBMPICaptureDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckIBMPICaptureUserTagsConfig(name, userTagsString),
Check: resource.ComposeTestCheckFunc(
testAccCheckIBMPICaptureExists(captureRes),
resource.TestCheckResourceAttr(captureRes, "pi_capture_name", name),
resource.TestCheckResourceAttrSet(captureRes, "image_id"),
resource.TestCheckResourceAttr(captureRes, "pi_user_tags.#", "2"),
resource.TestCheckTypeSetElemAttr(captureRes, "pi_user_tags.*", "env:dev"),
resource.TestCheckTypeSetElemAttr(captureRes, "pi_user_tags.*", "test_tag"),
),
},
{
Config: testAccCheckIBMPICaptureUserTagsConfig(name, userTagsStringUpdated),
Check: resource.ComposeTestCheckFunc(
testAccCheckIBMPICaptureExists(captureRes),
resource.TestCheckResourceAttr(captureRes, "pi_capture_name", name),
resource.TestCheckResourceAttrSet(captureRes, "image_id"),
resource.TestCheckResourceAttr(captureRes, "pi_user_tags.#", "3"),
resource.TestCheckTypeSetElemAttr(captureRes, "pi_user_tags.*", "env:dev"),
resource.TestCheckTypeSetElemAttr(captureRes, "pi_user_tags.*", "test_tag"),
resource.TestCheckTypeSetElemAttr(captureRes, "pi_user_tags.*", "test_tag2"),
),
},
},
})
Expand Down Expand Up @@ -177,6 +213,18 @@ func testAccCheckIBMPICaptureConfigBasic(name string) string {
`, acc.Pi_cloud_instance_id, name, acc.Pi_instance_name)
}

func testAccCheckIBMPICaptureUserTagsConfig(name string, userTagsString string) string {
return fmt.Sprintf(`
resource "ibm_pi_capture" "capture_instance" {
pi_cloud_instance_id="%[1]s"
pi_capture_name = "%s"
pi_instance_name = "%s"
pi_capture_destination = "image-catalog"
pi_user_tags = %s
}
`, acc.Pi_cloud_instance_id, name, acc.Pi_instance_name, userTagsString)
}

func testAccCheckIBMPICaptureCloudStorageConfig(name string) string {
return fmt.Sprintf(`
resource "ibm_pi_capture" "capture_instance" {
Expand Down
Loading

0 comments on commit 405900d

Please sign in to comment.