Skip to content

Commit

Permalink
Granular CRN for power dedicated hosts
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander-Kita committed Jan 7, 2025
1 parent 542efba commit e1dcd2e
Show file tree
Hide file tree
Showing 11 changed files with 297 additions and 57 deletions.
22 changes: 22 additions & 0 deletions ibm/service/power/data_source_ibm_pi_host.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ package power

import (
"context"
"log"

"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"

"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"
)

func DataSourceIBMPIHost() *schema.Resource {
Expand Down Expand Up @@ -84,6 +86,11 @@ func DataSourceIBMPIHost() *schema.Resource {
},
Type: schema.TypeList,
},
Attr_CRN: {
Computed: true,
Description: "The CRN of this resource.",
Type: schema.TypeString,
},
Attr_DisplayName: {
Computed: true,
Description: "Name of the host (chosen by the user).",
Expand Down Expand Up @@ -114,6 +121,13 @@ func DataSourceIBMPIHost() *schema.Resource {
Description: "System type.",
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,
},
},
}
}
Expand All @@ -136,6 +150,14 @@ func dataSourceIBMPIHostRead(ctx context.Context, d *schema.ResourceData, meta i
if host.Capacity != nil {
d.Set(Attr_Capacity, hostCapacityToMap(host.Capacity))
}
if host.Crn != "" {
d.Set(Attr_CRN, host.Crn)
tags, err := flex.GetGlobalTagsUsingCRN(meta, string(host.Crn), "", UserTagType)
if err != nil {
log.Printf("Error on get of pi host (%s) user_tags: %s", hostID, err)
}
d.Set(Attr_UserTags, tags)
}
if host.DisplayName != "" {
d.Set(Attr_DisplayName, host.DisplayName)
}
Expand Down
3 changes: 2 additions & 1 deletion ibm/service/power/data_source_ibm_pi_host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ import (
)

func TestAccIBMPIHostDataSourceBasic(t *testing.T) {
hostResData := "data.ibm_pi_host.pi_host_instance"
resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
Steps: []resource.TestStep{
{
Config: testAccCheckIBMPIHostDataSourceConfigBasic(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.ibm_pi_host.pi_host_instance", "id"),
resource.TestCheckResourceAttrSet(hostResData, "id"),
),
},
},
Expand Down
22 changes: 22 additions & 0 deletions ibm/service/power/data_source_ibm_pi_hosts.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package power

import (
"context"
"log"

"github.com/hashicorp/go-uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
Expand All @@ -13,6 +14,7 @@ import (

"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"
)

func DataSourceIBMPIHosts() *schema.Resource {
Expand Down Expand Up @@ -82,6 +84,11 @@ func DataSourceIBMPIHosts() *schema.Resource {
},
Type: schema.TypeList,
},
Attr_CRN: {
Computed: true,
Description: "The CRN of this resource.",
Type: schema.TypeString,
},
Attr_DisplayName: {
Computed: true,
Description: "Name of the host (chosen by the user).",
Expand Down Expand Up @@ -117,6 +124,13 @@ func DataSourceIBMPIHosts() *schema.Resource {
Description: "System type.",
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,
},
},
},
Type: schema.TypeList,
Expand Down Expand Up @@ -147,6 +161,14 @@ func dataSourceIBMPIHostsRead(ctx context.Context, d *schema.ResourceData, meta
if host.Capacity != nil {
hs[Attr_Capacity] = hostCapacityToMap(host.Capacity)
}
if host.Crn != "" {
hs[Attr_CRN] = host.Crn
tags, err := flex.GetTagsUsingCRN(meta, string(host.Crn))
if err != nil {
log.Printf("Error on get of pi host (%s) user_tags: %s", host.ID, err)
}
hs[Attr_UserTags] = tags
}
if host.DisplayName != "" {
hs[Attr_DisplayName] = host.DisplayName
}
Expand Down
3 changes: 2 additions & 1 deletion ibm/service/power/data_source_ibm_pi_hosts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ import (
)

func TestAccIBMPIHostsDataSourceBasic(t *testing.T) {
hostsResData := "data.ibm_pi_hosts.pi_hosts_instance"
resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
Steps: []resource.TestStep{
{
Config: testAccCheckIBMPIHostsDataSourceConfigBasic(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.ibm_pi_hosts.pi_hosts_instance", "id"),
resource.TestCheckResourceAttrSet(hostsResData, "id"),
),
},
},
Expand Down
134 changes: 122 additions & 12 deletions ibm/service/power/resource_ibm_pi_host.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,30 @@ import (
"context"
"fmt"
"log"
"os"
"strings"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"

"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/IBM/go-sdk-core/v5/core"
)

func ResourceIBMPIHost() *schema.Resource {
return &schema.Resource{
CustomizeDiff: customdiff.Sequence(
func(_ context.Context, diff *schema.ResourceDiff, v interface{}) error {
return customizeUserTagsPIHostDiff(diff)
},
),
CreateContext: resourceIBMPIHostCreate,
ReadContext: resourceIBMPIHostRead,
UpdateContext: resourceIBMPIHostUpdate,
Expand Down Expand Up @@ -55,20 +63,29 @@ func ResourceIBMPIHost() *schema.Resource {
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
Attr_DisplayName: {
Type: schema.TypeString,
Required: true,
Description: "Name of the host chosen by the user.",
Required: true,
Type: schema.TypeString,
},
Attr_SysType: {
Type: schema.TypeString,
Description: "System type.",
ForceNew: true,
Required: true,
Description: "System type.",
Type: schema.TypeString,
},
Attr_UserTags: {
Computed: true,
Description: "List of user tags attached to the resource.",
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
Set: schema.HashString,
Type: schema.TypeSet,
},
},
},
MaxItems: 1,
Required: true,
Type: schema.TypeSet,
Type: schema.TypeList,
},
// Attributes
Attr_Capacity: {
Expand Down Expand Up @@ -119,6 +136,11 @@ func ResourceIBMPIHost() *schema.Resource {
},
Type: schema.TypeList,
},
Attr_CRN: {
Computed: true,
Description: "The CRN of this resource.",
Type: schema.TypeString,
},
Attr_DisplayName: {
Computed: true,
Description: "Name of the host (chosen by the user).",
Expand Down Expand Up @@ -149,6 +171,12 @@ func ResourceIBMPIHost() *schema.Resource {
Description: "System type.",
Type: schema.TypeString,
},
Attr_UserTags: {
Computed: true,
Description: "List of user tags attached to resource.",
Elem: &schema.Schema{Type: schema.TypeString},
Type: schema.TypeList,
},
},
}
}
Expand All @@ -160,7 +188,7 @@ func resourceIBMPIHostCreate(ctx context.Context, d *schema.ResourceData, meta i
}
cloudInstanceID := d.Get(Arg_CloudInstanceID).(string)
client := instance.NewIBMPIHostGroupsClient(ctx, sess, cloudInstanceID)
hosts := d.Get(Arg_Host).(*schema.Set).List()
hosts := d.Get(Arg_Host).([]interface{})
hostGroupID := d.Get(Arg_HostGroupID).(string)
body := models.HostCreate{}
hostBody := make([]*models.AddHost, 0, len(hosts))
Expand All @@ -169,6 +197,7 @@ func resourceIBMPIHostCreate(ctx context.Context, d *schema.ResourceData, meta i
hs := models.AddHost{
DisplayName: core.StringPtr(host[Attr_DisplayName].(string)),
SysType: core.StringPtr(host[Attr_SysType].(string)),
UserTags: flex.FlattenSet(host[Attr_UserTags].(*schema.Set)),
}
hostBody = append(hostBody, &hs)
}
Expand All @@ -186,6 +215,17 @@ func resourceIBMPIHostCreate(ctx context.Context, d *schema.ResourceData, meta i
if err != nil {
return diag.FromErr(err)
}

host := hosts[0].(map[string]interface{})
tags := flex.FlattenSet(host[Attr_UserTags].(*schema.Set))
if hostResponse[0].Crn != "" && len(tags) > 0 {
oldList, newList := d.GetChange(Arg_Host + ".0." + Attr_UserTags)
err := flex.UpdateGlobalTagsUsingCRN(oldList, newList, meta, string(hostResponse[0].Crn), "", UserTagType)
if err != nil {
log.Printf("Error on update of pi host (%s) user_tags during creation: %s", hostResponse[0].ID, err)
}
}

return resourceIBMPIHostRead(ctx, d, meta)
}

Expand All @@ -207,11 +247,25 @@ func resourceIBMPIHostRead(ctx context.Context, d *schema.ResourceData, meta int
}
return diag.FromErr(err)
}
d.Set(Arg_CloudInstanceID, cloudInstanceID)
hostGroupID, err := getLastPart(host.HostGroup.Href)
if err != nil {
return diag.FromErr(err)
}
d.Set(Arg_HostGroupID, hostGroupID)
d.Set(Attr_HostID, host.ID)

if host.Capacity != nil {
d.Set(Attr_Capacity, hostCapacityToMap(host.Capacity))
}
if host.Crn != "" {
d.Set(Attr_CRN, host.Crn)
tags, err := flex.GetGlobalTagsUsingCRN(meta, string(host.Crn), "", UserTagType)
if err != nil {
log.Printf("Error on get of pi host (%s) user_tags: %s", host.ID, err)
}
d.Set(Attr_UserTags, tags.List())
}
if host.DisplayName != "" {
d.Set(Attr_DisplayName, host.DisplayName)
}
Expand All @@ -227,6 +281,7 @@ func resourceIBMPIHostRead(ctx context.Context, d *schema.ResourceData, meta int
if host.SysType != "" {
d.Set(Attr_SysType, host.SysType)
}
d.Set(Arg_Host, flattenHostArgumentToList(d, meta))

return nil
}
Expand All @@ -240,18 +295,36 @@ func resourceIBMPIHostUpdate(ctx context.Context, d *schema.ResourceData, meta i
if err != nil {
return diag.FromErr(err)
}
displayName := d.Get(Arg_Host + ".0").(map[string]interface{})[Attr_DisplayName].(string)
client := instance.NewIBMPIHostGroupsClient(ctx, sess, cloudInstanceID)
if d.HasChange(Arg_Host) {
oldHost, newHost := d.GetChange(Arg_Host + ".0")

displayNameOld := oldHost.(map[string]interface{})[Attr_DisplayName].(string)
displayNameNew := newHost.(map[string]interface{})[Attr_DisplayName].(string)

hostBody := models.HostPut{
DisplayName: &displayName,
if displayNameNew != displayNameOld {
hostBody := models.HostPut{
DisplayName: &displayNameNew,
}
_, err := client.UpdateHost(&hostBody, hostID)
if err != nil {
return diag.FromErr(err)
}
}
_, err := client.UpdateHost(&hostBody, hostID)
if err != nil {
return diag.FromErr(err)

if crn, ok := d.GetOk(Attr_CRN); ok {
userTagsOld := oldHost.(map[string]interface{})[Attr_UserTags].(*schema.Set)
userTagsNew := newHost.(map[string]interface{})[Attr_UserTags].(*schema.Set)
if !userTagsNew.Equal(userTagsOld) {
err = flex.UpdateGlobalTagsUsingCRN(userTagsOld, userTagsNew, meta, crn.(string), "", UserTagType)
if err != nil {
log.Printf("Error on update of pi host (%s) pi_host user_tags: %s", d.Get(Attr_HostID), err)
}
}
}

}

return resourceIBMPIHostRead(ctx, d, meta)
}

Expand Down Expand Up @@ -372,3 +445,40 @@ func isIBMPIHostRefreshFunc(client *instance.IBMPIHostGroupsClient, id string) r
return host, State_Down, nil
}
}

func flattenHostArgumentToList(d *schema.ResourceData, meta interface{}) []map[string]interface{} {
hostListType := make([]map[string]interface{}, 0)
h := map[string]interface{}{}
if v, ok := d.GetOk(Attr_DisplayName); ok {
displayName := v.(string)
h[Attr_DisplayName] = displayName
}
if v, ok := d.GetOk(Attr_SysType); ok {
sysType := v.(string)
h[Attr_SysType] = sysType
}
if v, ok := d.GetOk(Attr_UserTags); ok {
tags := v.([]interface{})
h[Attr_UserTags] = tags
}
hostListType = append(hostListType, h)
return hostListType
}

func customizeUserTagsPIHostDiff(diff *schema.ResourceDiff) error {
if diff.Id() != "" && diff.HasChange(Arg_Host+".0."+Attr_UserTags) {
o, n := diff.GetChange(Arg_Host + ".0." + Attr_UserTags)
oldSet := o.(*schema.Set)
newSet := n.(*schema.Set)
removeInt := oldSet.Difference(newSet).List()
addInt := newSet.Difference(oldSet).List()
if v := os.Getenv("IC_ENV_TAGS"); v != "" {
s := strings.Split(v, ",")
if len(removeInt) == len(s) && len(addInt) == 0 {
fmt.Println("Suppresing the TAG diff ")
return diff.Clear(Arg_Host + ".0." + Attr_UserTags)
}
}
}
return nil
}
Loading

0 comments on commit e1dcd2e

Please sign in to comment.