Skip to content

Commit a372540

Browse files
committed
Enable usage of tags in unleash_feature_v2
1 parent 5ad61d8 commit a372540

File tree

6 files changed

+154
-4
lines changed

6 files changed

+154
-4
lines changed

docs/resources/feature_v2.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ resource "unleash_feature_v2" "with_env_strategies" {
4444
}
4545
}
4646
}
47+
48+
tag {
49+
type = "simple"
50+
value = "foo"
51+
}
52+
53+
tag {
54+
type = "simple"
55+
value = "bar"
56+
}
4757
}
4858
```
4959

@@ -61,6 +71,7 @@ resource "unleash_feature_v2" "with_env_strategies" {
6171
- `archive_on_destroy` (Boolean) Whether to archive the feature toggle on destroy. Default is `true`. When `false`, it will permanently delete the feature toggle.
6272
- `description` (String) Feature description
6373
- `environment` (Block List) Use this to enable a feature in an environment and add strategies (see [below for nested schema](#nestedblock--environment))
74+
- `tag` (Block List) Tag to add to the feature (see [below for nested schema](#nestedblock--tag))
6475
- `variant` (Block List) Feature variant (see [below for nested schema](#nestedblock--variant))
6576

6677
### Read-Only
@@ -77,7 +88,7 @@ Required:
7788
Optional:
7889

7990
- `enabled` (Boolean) Whether the feature is on/off in the environment. Default is `true` (on)
80-
- `strategy` (Block Set) Strategy to add in the environment (see [below for nested schema](#nestedblock--environment--strategy))
91+
- `strategy` (Block List) Strategy to add in the environment (see [below for nested schema](#nestedblock--environment--strategy))
8192

8293
<a id="nestedblock--environment--strategy"></a>
8394
### Nested Schema for `environment.strategy`
@@ -96,6 +107,18 @@ Read-Only:
96107

97108

98109

110+
<a id="nestedblock--tag"></a>
111+
### Nested Schema for `tag`
112+
113+
Required:
114+
115+
- `value` (String) Tag value.
116+
117+
Optional:
118+
119+
- `type` (String) Tag type. Default is `simple`.
120+
121+
99122
<a id="nestedblock--variant"></a>
100123
### Nested Schema for `variant`
101124

examples/resources/unleash_feature_v2/resource.tf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,14 @@ resource "unleash_feature_v2" "with_env_strategies" {
2929
}
3030
}
3131
}
32+
33+
tag {
34+
type = "simple"
35+
value = "foo"
36+
}
37+
38+
tag {
39+
type = "simple"
40+
value = "bar"
41+
}
3242
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.18
55
require (
66
github.com/hashicorp/terraform-plugin-docs v0.14.1
77
github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1
8-
github.com/philips-labs/go-unleash-api v1.0.2
8+
github.com/philips-labs/go-unleash-api v1.0.5
99
)
1010

1111
require (

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,8 @@ github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx
184184
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
185185
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
186186
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
187-
github.com/philips-labs/go-unleash-api v1.0.2 h1:GTbeJ+LfohrpXzj/qg89yyZHupEAPX8Wxq3z4sigzi8=
188-
github.com/philips-labs/go-unleash-api v1.0.2/go.mod h1:7iJbdxlvMu9VlRLpitWFavCifH8IsfYPc7EkDY3PFv4=
187+
github.com/philips-labs/go-unleash-api v1.0.5 h1:eESdVQbH7szoLfe8l0JjCuQWoL7uKVJ4u2Fjt15B0Tw=
188+
github.com/philips-labs/go-unleash-api v1.0.5/go.mod h1:7iJbdxlvMu9VlRLpitWFavCifH8IsfYPc7EkDY3PFv4=
189189
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
190190
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
191191
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=

internal/provider/resource_feature_v2.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,26 @@ func resourceFeatureV2() *schema.Resource {
168168
},
169169
},
170170
},
171+
"tag": {
172+
Description: "Tag to add to the feature",
173+
Type: schema.TypeList,
174+
Optional: true,
175+
Elem: &schema.Resource{
176+
Schema: map[string]*schema.Schema{
177+
"type": {
178+
Description: "Tag type. Default is `simple`.",
179+
Type: schema.TypeString,
180+
Optional: true,
181+
Default: "simple",
182+
},
183+
"value": {
184+
Description: "Tag value.",
185+
Type: schema.TypeString,
186+
Required: true,
187+
},
188+
},
189+
},
190+
},
171191
},
172192
}
173193
}
@@ -228,6 +248,19 @@ func resourceFeatureV2Create(ctx context.Context, d *schema.ResourceData, meta i
228248
}
229249
}
230250
}
251+
if t, ok := d.GetOk("tag"); ok {
252+
tfTags := t.([]interface{})
253+
for _, tfTag := range tfTags {
254+
tag := toFeatureTag(tfTag.(map[string]interface{}))
255+
_, resp, err := client.FeatureTags.CreateFeatureTags(feature.Name, tag)
256+
if resp == nil || err != nil {
257+
client.FeatureToggles.ArchiveFeature(feature.Project, feature.Name)
258+
client.FeatureToggles.DeleteArchivedFeature(feature.Name)
259+
return diag.FromErr(err)
260+
}
261+
}
262+
263+
}
231264

232265
d.SetId(createdFeature.Name)
233266
readDiags := resourceFeatureV2Read(ctx, d, meta)
@@ -273,6 +306,23 @@ func resourceFeatureV2Read(ctx context.Context, d *schema.ResourceData, meta int
273306
_ = d.Set("environment", flattenEnvironments(toSave))
274307
}
275308

309+
if t, ok := d.GetOk("tag"); ok {
310+
featureTags, _, err := client.FeatureTags.GetAllFeatureTags(feature.Name)
311+
if err != nil {
312+
return diag.FromErr(err)
313+
}
314+
toSave := []api.FeatureTag{}
315+
for _, tfTag := range t.([]interface{}) {
316+
for _, tag := range featureTags.Tags {
317+
if tfTag.(map[string]interface{})["value"] == tag.Value {
318+
toSave = append(toSave, tag)
319+
}
320+
}
321+
}
322+
323+
_ = d.Set("tag", flattenTags(toSave))
324+
}
325+
276326
return diags
277327
}
278328

@@ -311,6 +361,34 @@ func resourceFeatureV2Update(ctx context.Context, d *schema.ResourceData, meta i
311361
}
312362
}
313363

364+
if d.HasChange("tag") {
365+
o, a := d.GetChange("tag")
366+
old := o.([]interface{})
367+
new := a.([]interface{})
368+
369+
toAdd := []api.FeatureTag{}
370+
toRemove := []api.FeatureTag{}
371+
372+
for _, newTag := range new {
373+
newFeatureTag := toFeatureTag(newTag.(map[string]interface{}))
374+
if !isTagIn(newFeatureTag, old) {
375+
toAdd = append(toAdd, newFeatureTag)
376+
}
377+
}
378+
379+
for _, oldTag := range old {
380+
oldFeatureTag := toFeatureTag(oldTag.(map[string]interface{}))
381+
if !isTagIn(oldFeatureTag, new) {
382+
toRemove = append(toRemove, oldFeatureTag)
383+
}
384+
}
385+
386+
_, _, err := client.FeatureTags.UpdateFeatureTags(feature.Name, toAdd, toRemove)
387+
if err != nil {
388+
return diag.FromErr(err)
389+
}
390+
}
391+
314392
if d.HasChange("environment") {
315393
o, a := d.GetChange("environment")
316394
old := o.([]interface{})
@@ -429,6 +507,16 @@ func isEnvIn(name string, envs []interface{}) bool {
429507
return false
430508
}
431509

510+
func isTagIn(tag api.FeatureTag, tags []interface{}) bool {
511+
for _, t := range tags {
512+
tfTag := toFeatureTag(t.(map[string]interface{}))
513+
if tfTag.Type == tag.Type && tfTag.Value == tag.Value {
514+
return true
515+
}
516+
}
517+
return false
518+
}
519+
432520
func isStratIn(id string, strats []api.FeatureStrategy) bool {
433521
for _, strat := range strats {
434522
if strat.ID == id {
@@ -529,3 +617,26 @@ func flattenEnvironments(environments []api.Environment) []interface{} {
529617

530618
return tfEnvironments
531619
}
620+
621+
func flattenTags(tags []api.FeatureTag) []interface{} {
622+
if tags == nil {
623+
return []interface{}{}
624+
}
625+
626+
tfTags := []interface{}{}
627+
for _, tag := range tags {
628+
tfTag := map[string]interface{}{}
629+
tfTag["type"] = tag.Type
630+
tfTag["value"] = tag.Value
631+
632+
tfTags = append(tfTags, tfTag)
633+
}
634+
return tfTags
635+
}
636+
637+
func toFeatureTag(tfTag map[string]interface{}) api.FeatureTag {
638+
tag := api.FeatureTag{}
639+
tag.Type = tfTag["type"].(string)
640+
tag.Value = tfTag["value"].(string)
641+
return tag
642+
}

internal/provider/resource_feature_v2_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ func TestAccResourceFeatureV2(t *testing.T) {
3232
resource.TestCheckResourceAttr("unleash_feature_v2.foo", "environment.1.strategy.1.parameters.rollout", "68"),
3333
resource.TestCheckResourceAttr("unleash_feature_v2.foo", "environment.1.strategy.1.parameters.stickiness", "random"),
3434
resource.TestCheckResourceAttr("unleash_feature_v2.foo", "environment.1.strategy.1.parameters.groupId", "toggle"),
35+
resource.TestCheckResourceAttr("unleash_feature_v2.foo", "tag.0.type", "simple"),
36+
resource.TestCheckResourceAttr("unleash_feature_v2.foo", "tag.0.value", "value"),
3537
),
3638
},
3739
},
@@ -70,5 +72,9 @@ resource "unleash_feature_v2" "foo" {
7072
}
7173
}
7274
}
75+
tag {
76+
type = "simple"
77+
value = "value"
78+
}
7379
}
7480
`, utils.RandomString(4))

0 commit comments

Comments
 (0)