@@ -7,22 +7,30 @@ import (
7
7
"context"
8
8
"fmt"
9
9
"log"
10
+ "os"
10
11
"strings"
11
12
"time"
12
13
13
14
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
15
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
14
16
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
15
17
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
16
18
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
17
19
18
20
"github.com/IBM-Cloud/power-go-client/clients/instance"
19
21
"github.com/IBM-Cloud/power-go-client/power/models"
20
22
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns"
23
+ "github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex"
21
24
"github.com/IBM/go-sdk-core/v5/core"
22
25
)
23
26
24
27
func ResourceIBMPIHost () * schema.Resource {
25
28
return & schema.Resource {
29
+ CustomizeDiff : customdiff .Sequence (
30
+ func (_ context.Context , diff * schema.ResourceDiff , v interface {}) error {
31
+ return customizeUserTagsPIHostDiff (diff )
32
+ },
33
+ ),
26
34
CreateContext : resourceIBMPIHostCreate ,
27
35
ReadContext : resourceIBMPIHostRead ,
28
36
UpdateContext : resourceIBMPIHostUpdate ,
@@ -55,20 +63,29 @@ func ResourceIBMPIHost() *schema.Resource {
55
63
Elem : & schema.Resource {
56
64
Schema : map [string ]* schema.Schema {
57
65
Attr_DisplayName : {
58
- Type : schema .TypeString ,
59
- Required : true ,
60
66
Description : "Name of the host chosen by the user." ,
67
+ Required : true ,
68
+ Type : schema .TypeString ,
61
69
},
62
70
Attr_SysType : {
63
- Type : schema . TypeString ,
71
+ Description : "System type." ,
64
72
ForceNew : true ,
65
73
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 ,
67
83
},
68
84
},
69
85
},
86
+ MaxItems : 1 ,
70
87
Required : true ,
71
- Type : schema .TypeSet ,
88
+ Type : schema .TypeList ,
72
89
},
73
90
// Attributes
74
91
Attr_Capacity : {
@@ -119,6 +136,11 @@ func ResourceIBMPIHost() *schema.Resource {
119
136
},
120
137
Type : schema .TypeList ,
121
138
},
139
+ Attr_CRN : {
140
+ Computed : true ,
141
+ Description : "The CRN of this resource." ,
142
+ Type : schema .TypeString ,
143
+ },
122
144
Attr_DisplayName : {
123
145
Computed : true ,
124
146
Description : "Name of the host (chosen by the user)." ,
@@ -149,6 +171,12 @@ func ResourceIBMPIHost() *schema.Resource {
149
171
Description : "System type." ,
150
172
Type : schema .TypeString ,
151
173
},
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
+ },
152
180
},
153
181
}
154
182
}
@@ -160,7 +188,7 @@ func resourceIBMPIHostCreate(ctx context.Context, d *schema.ResourceData, meta i
160
188
}
161
189
cloudInstanceID := d .Get (Arg_CloudInstanceID ).(string )
162
190
client := instance .NewIBMPIHostGroupsClient (ctx , sess , cloudInstanceID )
163
- hosts := d .Get (Arg_Host ).(* schema. Set ). List ( )
191
+ hosts := d .Get (Arg_Host ).([] interface {} )
164
192
hostGroupID := d .Get (Arg_HostGroupID ).(string )
165
193
body := models.HostCreate {}
166
194
hostBody := make ([]* models.AddHost , 0 , len (hosts ))
@@ -169,6 +197,7 @@ func resourceIBMPIHostCreate(ctx context.Context, d *schema.ResourceData, meta i
169
197
hs := models.AddHost {
170
198
DisplayName : core .StringPtr (host [Attr_DisplayName ].(string )),
171
199
SysType : core .StringPtr (host [Attr_SysType ].(string )),
200
+ UserTags : flex .FlattenSet (host [Attr_UserTags ].(* schema.Set )),
172
201
}
173
202
hostBody = append (hostBody , & hs )
174
203
}
@@ -186,6 +215,17 @@ func resourceIBMPIHostCreate(ctx context.Context, d *schema.ResourceData, meta i
186
215
if err != nil {
187
216
return diag .FromErr (err )
188
217
}
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
+
189
229
return resourceIBMPIHostRead (ctx , d , meta )
190
230
}
191
231
@@ -207,11 +247,25 @@ func resourceIBMPIHostRead(ctx context.Context, d *schema.ResourceData, meta int
207
247
}
208
248
return diag .FromErr (err )
209
249
}
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 )
210
256
d .Set (Attr_HostID , host .ID )
211
257
212
258
if host .Capacity != nil {
213
259
d .Set (Attr_Capacity , hostCapacityToMap (host .Capacity ))
214
260
}
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
+ }
215
269
if host .DisplayName != "" {
216
270
d .Set (Attr_DisplayName , host .DisplayName )
217
271
}
@@ -227,6 +281,7 @@ func resourceIBMPIHostRead(ctx context.Context, d *schema.ResourceData, meta int
227
281
if host .SysType != "" {
228
282
d .Set (Attr_SysType , host .SysType )
229
283
}
284
+ d .Set (Arg_Host , flattenHostArgumentToList (d , meta ))
230
285
231
286
return nil
232
287
}
@@ -240,18 +295,36 @@ func resourceIBMPIHostUpdate(ctx context.Context, d *schema.ResourceData, meta i
240
295
if err != nil {
241
296
return diag .FromErr (err )
242
297
}
243
- displayName := d .Get (Arg_Host + ".0" ).(map [string ]interface {})[Attr_DisplayName ].(string )
244
298
client := instance .NewIBMPIHostGroupsClient (ctx , sess , cloudInstanceID )
245
299
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 )
246
304
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
+ }
249
313
}
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
+ }
253
324
}
325
+
254
326
}
327
+
255
328
return resourceIBMPIHostRead (ctx , d , meta )
256
329
}
257
330
@@ -372,3 +445,40 @@ func isIBMPIHostRefreshFunc(client *instance.IBMPIHostGroupsClient, id string) r
372
445
return host , State_Down , nil
373
446
}
374
447
}
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