Skip to content

Commit 77b4cf8

Browse files
Port 10156 bug terraform blueprint unable to add property of type enum list (#267)
* add dynamic unknown fields to the blueprint property types * use reflaction to get the known fields * use any instead of interface * fix eyal pr comments * add support for array enum properties * add docs * remove redundant lines * remove redundant lines * fix comments
1 parent 4490d4a commit 77b4cf8

File tree

9 files changed

+91
-10
lines changed

9 files changed

+91
-10
lines changed

docs/resources/port_blueprint.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,8 @@ Optional:
405405
Optional:
406406

407407
- `default` (List of String) The default of the items
408+
- `enum` (List of String) The enum of the string array items
409+
- `enum_colors` (Map of String) The enum colors of the string array items
408410
- `format` (String) The format of the items
409411
- `pattern` (String) The pattern of the string array items
410412

docs/resources/port_system_blueprint.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ Optional:
117117
Optional:
118118

119119
- `default` (List of String) The default of the items
120+
- `enum` (List of String) The enum of the string array items
121+
- `enum_colors` (Map of String) The enum colors of the string array items
120122
- `format` (String) The format of the items
121123
- `pattern` (String) The pattern of the string array items
122124

examples/resources/port_blueprint/main.tf

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,19 @@ resource "port_blueprint" "microservice" {
4242
icon = "GPU"
4343
identifier = "hedwig-microservice"
4444
properties = {
45+
array_props = {
46+
enum = {
47+
type = "array"
48+
title = "enum"
49+
string_items = {
50+
enum = ["default", "default2"]
51+
enum_colors = {
52+
default = "red"
53+
default2 = "green"
54+
}
55+
}
56+
}
57+
}
4558
string_props = {
4659
name = {
4760
type = "string"
@@ -113,9 +126,9 @@ resource "port_blueprint" "pull_request_blueprint" {
113126
}
114127
}
115128
relations = {
116-
"repository" = {
117-
title = "Repository"
118-
target = port_blueprint.repository_blueprint.identifier
129+
"self" = {
130+
title = "Self"
131+
target = "pull_request"
119132
}
120133
}
121134
}

port/blueprint/array.go

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package blueprint
22

33
import (
44
"context"
5+
56
"github.com/hashicorp/terraform-plugin-framework/attr"
67
"github.com/hashicorp/terraform-plugin-framework/types"
78
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
@@ -59,6 +60,26 @@ func arrayPropResourceToBody(ctx context.Context, state *PropertiesModel, props
5960

6061
property.Default = defaultList
6162
}
63+
if !prop.StringItems.Enum.IsNull() {
64+
enumList, err := utils.TerraformListToGoArray(ctx, prop.StringItems.Enum, "string")
65+
if err != nil {
66+
return err
67+
}
68+
items["enum"] = enumList
69+
}
70+
if !prop.StringItems.EnumColors.IsNull() {
71+
enumColors := map[string]string{}
72+
for k, v := range prop.StringItems.EnumColors.Elements() {
73+
value, _ := v.ToTerraformValue(ctx)
74+
var keyValue string
75+
err := value.As(&keyValue)
76+
if err != nil {
77+
return err
78+
}
79+
enumColors[k] = keyValue
80+
}
81+
items["enumColors"] = enumColors
82+
}
6283
property.Items = items
6384
}
6485

@@ -112,7 +133,7 @@ func arrayPropResourceToBody(ctx context.Context, state *PropertiesModel, props
112133
return nil
113134
}
114135

115-
func AddArrayPropertiesToState(v *cli.BlueprintProperty, jsonEscapeHTML bool) *ArrayPropModel {
136+
func AddArrayPropertiesToState(ctx context.Context, v *cli.BlueprintProperty, jsonEscapeHTML bool) *ArrayPropModel {
116137
arrayProp := &ArrayPropModel{
117138
MinItems: flex.GoInt64ToFramework(v.MinItems),
118139
MaxItems: flex.GoInt64ToFramework(v.MaxItems),
@@ -142,6 +163,20 @@ func AddArrayPropertiesToState(v *cli.BlueprintProperty, jsonEscapeHTML bool) *A
142163
if value, ok := v.Items["pattern"]; ok && value != nil {
143164
arrayProp.StringItems.Pattern = types.StringValue(v.Items["pattern"].(string))
144165
}
166+
if value, ok := v.Items["enum"]; ok && value != nil {
167+
attrs := make([]attr.Value, 0, len(value.([]interface{})))
168+
for _, enumValue := range value.([]interface{}) {
169+
attrs = append(attrs, basetypes.NewStringValue(enumValue.(string)))
170+
}
171+
arrayProp.StringItems.Enum, _ = types.ListValue(types.StringType, attrs)
172+
} else {
173+
arrayProp.StringItems.Enum = types.ListNull(types.StringType)
174+
}
175+
if value, ok := v.Items["enumColors"]; ok && value != nil {
176+
arrayProp.StringItems.EnumColors, _ = types.MapValueFrom(ctx, types.StringType, value)
177+
} else {
178+
arrayProp.StringItems.EnumColors = types.MapNull(types.StringType)
179+
}
145180
case "number":
146181
arrayProp.NumberItems = &NumberItems{}
147182
if v.Default != nil {

port/blueprint/model.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,11 @@ type BooleanPropModel struct {
6161
}
6262

6363
type StringItems struct {
64-
Format types.String `tfsdk:"format"`
65-
Default types.List `tfsdk:"default"`
66-
Pattern types.String `tfsdk:"pattern"`
64+
Format types.String `tfsdk:"format"`
65+
Default types.List `tfsdk:"default"`
66+
Pattern types.String `tfsdk:"pattern"`
67+
Enum types.List `tfsdk:"enum"`
68+
EnumColors types.Map `tfsdk:"enum_colors"`
6769
}
6870

6971
type NumberItems struct {

port/blueprint/resource_test.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package blueprint_test
33
import (
44
"context"
55
"fmt"
6-
"github.com/stretchr/testify/require"
76
"math/rand"
87
"net/http"
98
"os"
@@ -14,6 +13,8 @@ import (
1413
"text/template"
1514
"time"
1615

16+
"github.com/stretchr/testify/require"
17+
1718
"github.com/port-labs/terraform-provider-port-labs/v2/internal/cli"
1819
"github.com/port-labs/terraform-provider-port-labs/v2/internal/consts"
1920
"github.com/port-labs/terraform-provider-port-labs/v2/version"
@@ -248,6 +249,16 @@ func TestAccPortBlueprintArrayProperty(t *testing.T) {
248249
default = [jsonencode({"a": "b"}), jsonencode({"c": "d"})]
249250
}
250251
}
252+
myEnumArrayIdentifier = {
253+
title = "enum"
254+
string_items = {
255+
enum = ["default", "default2"]
256+
enum_colors = {
257+
default = "red"
258+
default2 = "green"
259+
}
260+
}
261+
}
251262
}
252263
}
253264
}`, identifier)
@@ -279,6 +290,10 @@ func TestAccPortBlueprintArrayProperty(t *testing.T) {
279290
resource.TestCheckResourceAttr("port_blueprint.microservice", "properties.array_props.myBooleanArrayIdentifier.boolean_items.default.1", "true"),
280291
resource.TestCheckResourceAttr("port_blueprint.microservice", "properties.array_props.myObjectArrayIdentifier.object_items.default.0", "{\"a\":\"b\"}"),
281292
resource.TestCheckResourceAttr("port_blueprint.microservice", "properties.array_props.myObjectArrayIdentifier.object_items.default.1", "{\"c\":\"d\"}"),
293+
resource.TestCheckResourceAttr("port_blueprint.microservice", "properties.array_props.myEnumArrayIdentifier.string_items.enum.0", "default"),
294+
resource.TestCheckResourceAttr("port_blueprint.microservice", "properties.array_props.myEnumArrayIdentifier.string_items.enum.1", "default2"),
295+
resource.TestCheckResourceAttr("port_blueprint.microservice", "properties.array_props.myEnumArrayIdentifier.string_items.enum_colors.default", "red"),
296+
resource.TestCheckResourceAttr("port_blueprint.microservice", "properties.array_props.myEnumArrayIdentifier.string_items.enum_colors.default2", "green"),
282297
),
283298
},
284299
},

port/blueprint/schema.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,17 @@ func ArrayPropertySchema() schema.MapNestedAttribute {
213213
stringvalidator.RegexMatches(regexp.MustCompile(`^.*$`), "must be a valid regular expression"),
214214
},
215215
},
216+
"enum": schema.ListAttribute{
217+
MarkdownDescription: "The enum of the string array items",
218+
Optional: true,
219+
ElementType: types.StringType,
220+
Validators: []validator.List{listvalidator.UniqueValues(), listvalidator.SizeAtLeast(1)},
221+
},
222+
"enum_colors": schema.MapAttribute{
223+
MarkdownDescription: "The enum colors of the string array items",
224+
Optional: true,
225+
ElementType: types.StringType,
226+
},
216227
},
217228
},
218229
"number_items": schema.SingleNestedAttribute{

port/blueprint/updatePropertiesToState.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package blueprint
22

33
import (
44
"context"
5+
56
"github.com/port-labs/terraform-provider-port-labs/v2/internal/utils"
67

78
"github.com/hashicorp/terraform-plugin-framework/types"
@@ -113,7 +114,7 @@ func (r *BlueprintResource) updatePropertiesToState(ctx context.Context, b *cli.
113114
properties.ArrayProps = make(map[string]ArrayPropModel)
114115
}
115116

116-
arrayProp := AddArrayPropertiesToState(&v, r.portClient.JSONEscapeHTML)
117+
arrayProp := AddArrayPropertiesToState(ctx, &v, r.portClient.JSONEscapeHTML)
117118

118119
if lo.Contains(b.Schema.Required, k) {
119120
arrayProp.Required = types.BoolValue(true)

port/system_blueprint/updatePropertiesToState.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func (r *Resource) updatePropertiesToState(ctx context.Context, b *cli.Blueprint
6060
properties.ArrayProps = make(map[string]blueprint.ArrayPropModel)
6161
}
6262

63-
arrayProp := blueprint.AddArrayPropertiesToState(&v, r.client.JSONEscapeHTML)
63+
arrayProp := blueprint.AddArrayPropertiesToState(ctx, &v, r.client.JSONEscapeHTML)
6464

6565
if lo.Contains(b.Schema.Required, k) {
6666
arrayProp.Required = types.BoolValue(true)

0 commit comments

Comments
 (0)