Skip to content

Commit e1dcd2e

Browse files
Granular CRN for power dedicated hosts
1 parent 542efba commit e1dcd2e

11 files changed

+297
-57
lines changed

ibm/service/power/data_source_ibm_pi_host.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ package power
55

66
import (
77
"context"
8+
"log"
89

910
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1011
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1112
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
1213

1314
"github.com/IBM-Cloud/power-go-client/clients/instance"
1415
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns"
16+
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex"
1517
)
1618

1719
func DataSourceIBMPIHost() *schema.Resource {
@@ -84,6 +86,11 @@ func DataSourceIBMPIHost() *schema.Resource {
8486
},
8587
Type: schema.TypeList,
8688
},
89+
Attr_CRN: {
90+
Computed: true,
91+
Description: "The CRN of this resource.",
92+
Type: schema.TypeString,
93+
},
8794
Attr_DisplayName: {
8895
Computed: true,
8996
Description: "Name of the host (chosen by the user).",
@@ -114,6 +121,13 @@ func DataSourceIBMPIHost() *schema.Resource {
114121
Description: "System type.",
115122
Type: schema.TypeString,
116123
},
124+
Attr_UserTags: {
125+
Computed: true,
126+
Description: "List of user tags attached to the resource.",
127+
Elem: &schema.Schema{Type: schema.TypeString},
128+
Set: schema.HashString,
129+
Type: schema.TypeSet,
130+
},
117131
},
118132
}
119133
}
@@ -136,6 +150,14 @@ func dataSourceIBMPIHostRead(ctx context.Context, d *schema.ResourceData, meta i
136150
if host.Capacity != nil {
137151
d.Set(Attr_Capacity, hostCapacityToMap(host.Capacity))
138152
}
153+
if host.Crn != "" {
154+
d.Set(Attr_CRN, host.Crn)
155+
tags, err := flex.GetGlobalTagsUsingCRN(meta, string(host.Crn), "", UserTagType)
156+
if err != nil {
157+
log.Printf("Error on get of pi host (%s) user_tags: %s", hostID, err)
158+
}
159+
d.Set(Attr_UserTags, tags)
160+
}
139161
if host.DisplayName != "" {
140162
d.Set(Attr_DisplayName, host.DisplayName)
141163
}

ibm/service/power/data_source_ibm_pi_host_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ import (
1313
)
1414

1515
func TestAccIBMPIHostDataSourceBasic(t *testing.T) {
16+
hostResData := "data.ibm_pi_host.pi_host_instance"
1617
resource.Test(t, resource.TestCase{
1718
PreCheck: func() { acc.TestAccPreCheck(t) },
1819
Providers: acc.TestAccProviders,
1920
Steps: []resource.TestStep{
2021
{
2122
Config: testAccCheckIBMPIHostDataSourceConfigBasic(),
2223
Check: resource.ComposeTestCheckFunc(
23-
resource.TestCheckResourceAttrSet("data.ibm_pi_host.pi_host_instance", "id"),
24+
resource.TestCheckResourceAttrSet(hostResData, "id"),
2425
),
2526
},
2627
},

ibm/service/power/data_source_ibm_pi_hosts.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package power
55

66
import (
77
"context"
8+
"log"
89

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

1415
"github.com/IBM-Cloud/power-go-client/clients/instance"
1516
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns"
17+
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex"
1618
)
1719

1820
func DataSourceIBMPIHosts() *schema.Resource {
@@ -82,6 +84,11 @@ func DataSourceIBMPIHosts() *schema.Resource {
8284
},
8385
Type: schema.TypeList,
8486
},
87+
Attr_CRN: {
88+
Computed: true,
89+
Description: "The CRN of this resource.",
90+
Type: schema.TypeString,
91+
},
8592
Attr_DisplayName: {
8693
Computed: true,
8794
Description: "Name of the host (chosen by the user).",
@@ -117,6 +124,13 @@ func DataSourceIBMPIHosts() *schema.Resource {
117124
Description: "System type.",
118125
Type: schema.TypeString,
119126
},
127+
Attr_UserTags: {
128+
Computed: true,
129+
Description: "List of user tags attached to the resource.",
130+
Elem: &schema.Schema{Type: schema.TypeString},
131+
Set: schema.HashString,
132+
Type: schema.TypeSet,
133+
},
120134
},
121135
},
122136
Type: schema.TypeList,
@@ -147,6 +161,14 @@ func dataSourceIBMPIHostsRead(ctx context.Context, d *schema.ResourceData, meta
147161
if host.Capacity != nil {
148162
hs[Attr_Capacity] = hostCapacityToMap(host.Capacity)
149163
}
164+
if host.Crn != "" {
165+
hs[Attr_CRN] = host.Crn
166+
tags, err := flex.GetTagsUsingCRN(meta, string(host.Crn))
167+
if err != nil {
168+
log.Printf("Error on get of pi host (%s) user_tags: %s", host.ID, err)
169+
}
170+
hs[Attr_UserTags] = tags
171+
}
150172
if host.DisplayName != "" {
151173
hs[Attr_DisplayName] = host.DisplayName
152174
}

ibm/service/power/data_source_ibm_pi_hosts_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ import (
1313
)
1414

1515
func TestAccIBMPIHostsDataSourceBasic(t *testing.T) {
16+
hostsResData := "data.ibm_pi_hosts.pi_hosts_instance"
1617
resource.Test(t, resource.TestCase{
1718
PreCheck: func() { acc.TestAccPreCheck(t) },
1819
Providers: acc.TestAccProviders,
1920
Steps: []resource.TestStep{
2021
{
2122
Config: testAccCheckIBMPIHostsDataSourceConfigBasic(),
2223
Check: resource.ComposeTestCheckFunc(
23-
resource.TestCheckResourceAttrSet("data.ibm_pi_hosts.pi_hosts_instance", "id"),
24+
resource.TestCheckResourceAttrSet(hostsResData, "id"),
2425
),
2526
},
2627
},

ibm/service/power/resource_ibm_pi_host.go

Lines changed: 122 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,30 @@ import (
77
"context"
88
"fmt"
99
"log"
10+
"os"
1011
"strings"
1112
"time"
1213

1314
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
15+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
1416
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
1517
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1618
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
1719

1820
"github.com/IBM-Cloud/power-go-client/clients/instance"
1921
"github.com/IBM-Cloud/power-go-client/power/models"
2022
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns"
23+
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex"
2124
"github.com/IBM/go-sdk-core/v5/core"
2225
)
2326

2427
func ResourceIBMPIHost() *schema.Resource {
2528
return &schema.Resource{
29+
CustomizeDiff: customdiff.Sequence(
30+
func(_ context.Context, diff *schema.ResourceDiff, v interface{}) error {
31+
return customizeUserTagsPIHostDiff(diff)
32+
},
33+
),
2634
CreateContext: resourceIBMPIHostCreate,
2735
ReadContext: resourceIBMPIHostRead,
2836
UpdateContext: resourceIBMPIHostUpdate,
@@ -55,20 +63,29 @@ func ResourceIBMPIHost() *schema.Resource {
5563
Elem: &schema.Resource{
5664
Schema: map[string]*schema.Schema{
5765
Attr_DisplayName: {
58-
Type: schema.TypeString,
59-
Required: true,
6066
Description: "Name of the host chosen by the user.",
67+
Required: true,
68+
Type: schema.TypeString,
6169
},
6270
Attr_SysType: {
63-
Type: schema.TypeString,
71+
Description: "System type.",
6472
ForceNew: true,
6573
Required: true,
66-
Description: "System type.",
74+
Type: schema.TypeString,
75+
},
76+
Attr_UserTags: {
77+
Computed: true,
78+
Description: "List of user tags attached to the resource.",
79+
Elem: &schema.Schema{Type: schema.TypeString},
80+
Optional: true,
81+
Set: schema.HashString,
82+
Type: schema.TypeSet,
6783
},
6884
},
6985
},
86+
MaxItems: 1,
7087
Required: true,
71-
Type: schema.TypeSet,
88+
Type: schema.TypeList,
7289
},
7390
// Attributes
7491
Attr_Capacity: {
@@ -119,6 +136,11 @@ func ResourceIBMPIHost() *schema.Resource {
119136
},
120137
Type: schema.TypeList,
121138
},
139+
Attr_CRN: {
140+
Computed: true,
141+
Description: "The CRN of this resource.",
142+
Type: schema.TypeString,
143+
},
122144
Attr_DisplayName: {
123145
Computed: true,
124146
Description: "Name of the host (chosen by the user).",
@@ -149,6 +171,12 @@ func ResourceIBMPIHost() *schema.Resource {
149171
Description: "System type.",
150172
Type: schema.TypeString,
151173
},
174+
Attr_UserTags: {
175+
Computed: true,
176+
Description: "List of user tags attached to resource.",
177+
Elem: &schema.Schema{Type: schema.TypeString},
178+
Type: schema.TypeList,
179+
},
152180
},
153181
}
154182
}
@@ -160,7 +188,7 @@ func resourceIBMPIHostCreate(ctx context.Context, d *schema.ResourceData, meta i
160188
}
161189
cloudInstanceID := d.Get(Arg_CloudInstanceID).(string)
162190
client := instance.NewIBMPIHostGroupsClient(ctx, sess, cloudInstanceID)
163-
hosts := d.Get(Arg_Host).(*schema.Set).List()
191+
hosts := d.Get(Arg_Host).([]interface{})
164192
hostGroupID := d.Get(Arg_HostGroupID).(string)
165193
body := models.HostCreate{}
166194
hostBody := make([]*models.AddHost, 0, len(hosts))
@@ -169,6 +197,7 @@ func resourceIBMPIHostCreate(ctx context.Context, d *schema.ResourceData, meta i
169197
hs := models.AddHost{
170198
DisplayName: core.StringPtr(host[Attr_DisplayName].(string)),
171199
SysType: core.StringPtr(host[Attr_SysType].(string)),
200+
UserTags: flex.FlattenSet(host[Attr_UserTags].(*schema.Set)),
172201
}
173202
hostBody = append(hostBody, &hs)
174203
}
@@ -186,6 +215,17 @@ func resourceIBMPIHostCreate(ctx context.Context, d *schema.ResourceData, meta i
186215
if err != nil {
187216
return diag.FromErr(err)
188217
}
218+
219+
host := hosts[0].(map[string]interface{})
220+
tags := flex.FlattenSet(host[Attr_UserTags].(*schema.Set))
221+
if hostResponse[0].Crn != "" && len(tags) > 0 {
222+
oldList, newList := d.GetChange(Arg_Host + ".0." + Attr_UserTags)
223+
err := flex.UpdateGlobalTagsUsingCRN(oldList, newList, meta, string(hostResponse[0].Crn), "", UserTagType)
224+
if err != nil {
225+
log.Printf("Error on update of pi host (%s) user_tags during creation: %s", hostResponse[0].ID, err)
226+
}
227+
}
228+
189229
return resourceIBMPIHostRead(ctx, d, meta)
190230
}
191231

@@ -207,11 +247,25 @@ func resourceIBMPIHostRead(ctx context.Context, d *schema.ResourceData, meta int
207247
}
208248
return diag.FromErr(err)
209249
}
250+
d.Set(Arg_CloudInstanceID, cloudInstanceID)
251+
hostGroupID, err := getLastPart(host.HostGroup.Href)
252+
if err != nil {
253+
return diag.FromErr(err)
254+
}
255+
d.Set(Arg_HostGroupID, hostGroupID)
210256
d.Set(Attr_HostID, host.ID)
211257

212258
if host.Capacity != nil {
213259
d.Set(Attr_Capacity, hostCapacityToMap(host.Capacity))
214260
}
261+
if host.Crn != "" {
262+
d.Set(Attr_CRN, host.Crn)
263+
tags, err := flex.GetGlobalTagsUsingCRN(meta, string(host.Crn), "", UserTagType)
264+
if err != nil {
265+
log.Printf("Error on get of pi host (%s) user_tags: %s", host.ID, err)
266+
}
267+
d.Set(Attr_UserTags, tags.List())
268+
}
215269
if host.DisplayName != "" {
216270
d.Set(Attr_DisplayName, host.DisplayName)
217271
}
@@ -227,6 +281,7 @@ func resourceIBMPIHostRead(ctx context.Context, d *schema.ResourceData, meta int
227281
if host.SysType != "" {
228282
d.Set(Attr_SysType, host.SysType)
229283
}
284+
d.Set(Arg_Host, flattenHostArgumentToList(d, meta))
230285

231286
return nil
232287
}
@@ -240,18 +295,36 @@ func resourceIBMPIHostUpdate(ctx context.Context, d *schema.ResourceData, meta i
240295
if err != nil {
241296
return diag.FromErr(err)
242297
}
243-
displayName := d.Get(Arg_Host + ".0").(map[string]interface{})[Attr_DisplayName].(string)
244298
client := instance.NewIBMPIHostGroupsClient(ctx, sess, cloudInstanceID)
245299
if d.HasChange(Arg_Host) {
300+
oldHost, newHost := d.GetChange(Arg_Host + ".0")
301+
302+
displayNameOld := oldHost.(map[string]interface{})[Attr_DisplayName].(string)
303+
displayNameNew := newHost.(map[string]interface{})[Attr_DisplayName].(string)
246304

247-
hostBody := models.HostPut{
248-
DisplayName: &displayName,
305+
if displayNameNew != displayNameOld {
306+
hostBody := models.HostPut{
307+
DisplayName: &displayNameNew,
308+
}
309+
_, err := client.UpdateHost(&hostBody, hostID)
310+
if err != nil {
311+
return diag.FromErr(err)
312+
}
249313
}
250-
_, err := client.UpdateHost(&hostBody, hostID)
251-
if err != nil {
252-
return diag.FromErr(err)
314+
315+
if crn, ok := d.GetOk(Attr_CRN); ok {
316+
userTagsOld := oldHost.(map[string]interface{})[Attr_UserTags].(*schema.Set)
317+
userTagsNew := newHost.(map[string]interface{})[Attr_UserTags].(*schema.Set)
318+
if !userTagsNew.Equal(userTagsOld) {
319+
err = flex.UpdateGlobalTagsUsingCRN(userTagsOld, userTagsNew, meta, crn.(string), "", UserTagType)
320+
if err != nil {
321+
log.Printf("Error on update of pi host (%s) pi_host user_tags: %s", d.Get(Attr_HostID), err)
322+
}
323+
}
253324
}
325+
254326
}
327+
255328
return resourceIBMPIHostRead(ctx, d, meta)
256329
}
257330

@@ -372,3 +445,40 @@ func isIBMPIHostRefreshFunc(client *instance.IBMPIHostGroupsClient, id string) r
372445
return host, State_Down, nil
373446
}
374447
}
448+
449+
func flattenHostArgumentToList(d *schema.ResourceData, meta interface{}) []map[string]interface{} {
450+
hostListType := make([]map[string]interface{}, 0)
451+
h := map[string]interface{}{}
452+
if v, ok := d.GetOk(Attr_DisplayName); ok {
453+
displayName := v.(string)
454+
h[Attr_DisplayName] = displayName
455+
}
456+
if v, ok := d.GetOk(Attr_SysType); ok {
457+
sysType := v.(string)
458+
h[Attr_SysType] = sysType
459+
}
460+
if v, ok := d.GetOk(Attr_UserTags); ok {
461+
tags := v.([]interface{})
462+
h[Attr_UserTags] = tags
463+
}
464+
hostListType = append(hostListType, h)
465+
return hostListType
466+
}
467+
468+
func customizeUserTagsPIHostDiff(diff *schema.ResourceDiff) error {
469+
if diff.Id() != "" && diff.HasChange(Arg_Host+".0."+Attr_UserTags) {
470+
o, n := diff.GetChange(Arg_Host + ".0." + Attr_UserTags)
471+
oldSet := o.(*schema.Set)
472+
newSet := n.(*schema.Set)
473+
removeInt := oldSet.Difference(newSet).List()
474+
addInt := newSet.Difference(oldSet).List()
475+
if v := os.Getenv("IC_ENV_TAGS"); v != "" {
476+
s := strings.Split(v, ",")
477+
if len(removeInt) == len(s) && len(addInt) == 0 {
478+
fmt.Println("Suppresing the TAG diff ")
479+
return diff.Clear(Arg_Host + ".0." + Attr_UserTags)
480+
}
481+
}
482+
}
483+
return nil
484+
}

0 commit comments

Comments
 (0)