Skip to content

Commit a76ad7b

Browse files
authored
Merge pull request #315 from port-labs/fix/dataSetTypes
fix: support simple values in dataset rules for action imports
2 parents 712843b + eb4a885 commit a76ad7b

File tree

2 files changed

+243
-0
lines changed

2 files changed

+243
-0
lines changed

internal/cli/models.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,74 @@ type (
131131
Combinator string `json:"combinator,omitempty"`
132132
Rules []DatasetRule `json:"rules,omitempty"`
133133
}
134+
)
135+
136+
// Custom UnmarshalJSON for DatasetValue to handle both simple values and jqQuery objects
137+
func (dv *DatasetValue) UnmarshalJSON(data []byte) error {
138+
type Alias DatasetValue
139+
aux := &struct {
140+
*Alias
141+
}{
142+
Alias: (*Alias)(dv),
143+
}
144+
145+
if err := json.Unmarshal(data, aux); err == nil && dv.JqQuery != "" {
146+
return nil
147+
}
148+
149+
var rawValue any
150+
if err := json.Unmarshal(data, &rawValue); err != nil {
151+
return err
152+
}
153+
154+
switch v := rawValue.(type) {
155+
case string:
156+
dv.JqQuery = v
157+
case float64:
158+
dv.JqQuery = json.Number(data).String()
159+
case bool:
160+
if v {
161+
dv.JqQuery = "true"
162+
} else {
163+
dv.JqQuery = "false"
164+
}
165+
case nil:
166+
dv.JqQuery = ""
167+
default:
168+
jsonBytes, err := json.Marshal(v)
169+
if err != nil {
170+
return err
171+
}
172+
dv.JqQuery = string(jsonBytes)
173+
}
134174

175+
return nil
176+
}
177+
178+
// Custom MarshalJSON for DatasetValue to preserve the original format when possible
179+
func (dv DatasetValue) MarshalJSON() ([]byte, error) {
180+
181+
if dv.JqQuery == "" {
182+
return []byte("null"), nil
183+
}
184+
185+
if dv.JqQuery == "true" || dv.JqQuery == "false" {
186+
return []byte(dv.JqQuery), nil
187+
}
188+
189+
var numTest float64
190+
if err := json.Unmarshal([]byte(dv.JqQuery), &numTest); err == nil {
191+
return []byte(dv.JqQuery), nil
192+
}
193+
194+
if len(dv.JqQuery) >= 2 && dv.JqQuery[0] == '"' && dv.JqQuery[len(dv.JqQuery)-1] == '"' {
195+
return []byte(dv.JqQuery), nil
196+
}
197+
198+
return json.Marshal(dv.JqQuery)
199+
}
200+
201+
type (
135202
BlueprintCalculationProperty struct {
136203
Type string `json:"type,omitempty"`
137204
Title *string `json:"title,omitempty"`

port/action/resource_test.go

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,6 +1349,182 @@ func TestAccPortActionEnum(t *testing.T) {
13491349
})
13501350
}
13511351

1352+
func TestAccPortActionImportNonJqFields(t *testing.T) {
1353+
blueprintIdentifier := utils.GenID()
1354+
actionIdentifier := utils.GenID()
1355+
var testAccActionConfig = testAccCreateBlueprintConfig(blueprintIdentifier) + fmt.Sprintf(`
1356+
resource "port_action" "create_microservice" {
1357+
title = "TF Provider Test - Import Non-JQ Fields"
1358+
identifier = "%s"
1359+
icon = "Terraform"
1360+
self_service_trigger = {
1361+
operation = "DAY-2"
1362+
blueprint_identifier = port_blueprint.microservice.identifier
1363+
user_properties = {
1364+
string_props = {
1365+
environment = {
1366+
title = "Environment"
1367+
required = true
1368+
enum = ["dev", "staging", "prod"]
1369+
default = "dev"
1370+
enum_colors = {
1371+
"dev" = "blue"
1372+
"staging" = "yellow"
1373+
"prod" = "red"
1374+
}
1375+
}
1376+
region = {
1377+
title = "Region"
1378+
pattern = "^[a-z]{2}-[a-z]+-[0-9]$"
1379+
description = "AWS region pattern"
1380+
}
1381+
serviceName = {
1382+
title = "Service Name"
1383+
min_length = 3
1384+
max_length = 50
1385+
}
1386+
}
1387+
number_props = {
1388+
replicas = {
1389+
title = "Replicas"
1390+
minimum = 1
1391+
maximum = 10
1392+
default = 3
1393+
enum = [1, 3, 5, 10]
1394+
}
1395+
port = {
1396+
title = "Port"
1397+
minimum = 1024
1398+
maximum = 65535
1399+
}
1400+
}
1401+
boolean_props = {
1402+
enabled = {
1403+
title = "Enabled"
1404+
default = true
1405+
}
1406+
autoScale = {
1407+
title = "Auto Scale"
1408+
}
1409+
}
1410+
array_props = {
1411+
tags = {
1412+
title = "Tags"
1413+
min_items = 1
1414+
max_items = 5
1415+
string_items = {
1416+
format = "user"
1417+
enum = ["tag1", "tag2", "tag3"]
1418+
}
1419+
}
1420+
ports = {
1421+
title = "Ports"
1422+
min_items = 1
1423+
max_items = 10
1424+
number_items = {
1425+
enum = [80, 443, 8080, 3000]
1426+
}
1427+
}
1428+
}
1429+
}
1430+
}
1431+
webhook_method = {
1432+
url = "https://example.com/webhook"
1433+
}
1434+
}`, actionIdentifier)
1435+
1436+
resource.Test(t, resource.TestCase{
1437+
PreCheck: func() { acctest.TestAccPreCheck(t) },
1438+
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
1439+
Steps: []resource.TestStep{
1440+
{
1441+
Config: acctest.ProviderConfig + testAccActionConfig,
1442+
Check: resource.ComposeTestCheckFunc(
1443+
// Basic action attributes
1444+
resource.TestCheckResourceAttr("port_action.create_microservice", "identifier", actionIdentifier),
1445+
resource.TestCheckResourceAttr("port_action.create_microservice", "title", "TF Provider Test - Import Non-JQ Fields"),
1446+
resource.TestCheckResourceAttr("port_action.create_microservice", "icon", "Terraform"),
1447+
1448+
// String property: environment - with enum, default, and enum_colors
1449+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.environment.title", "Environment"),
1450+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.environment.required", "true"),
1451+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.environment.default", "dev"),
1452+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.environment.enum.#", "3"),
1453+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.environment.enum.0", "dev"),
1454+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.environment.enum.1", "staging"),
1455+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.environment.enum.2", "prod"),
1456+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.environment.enum_colors.dev", "blue"),
1457+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.environment.enum_colors.staging", "yellow"),
1458+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.environment.enum_colors.prod", "red"),
1459+
resource.TestCheckNoResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.environment.enum_jq_query"),
1460+
resource.TestCheckNoResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.environment.default_jq_query"),
1461+
1462+
// String property: region - with pattern and description
1463+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.region.title", "Region"),
1464+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.region.pattern", "^[a-z]{2}-[a-z]+-[0-9]$"),
1465+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.region.description", "AWS region pattern"),
1466+
resource.TestCheckNoResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.region.pattern_jq_query"),
1467+
1468+
// String property: serviceName - with min_length and max_length
1469+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.serviceName.title", "Service Name"),
1470+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.serviceName.min_length", "3"),
1471+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.string_props.serviceName.max_length", "50"),
1472+
1473+
// Number property: replicas - with minimum, maximum, default, and enum
1474+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.number_props.replicas.title", "Replicas"),
1475+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.number_props.replicas.minimum", "1"),
1476+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.number_props.replicas.maximum", "10"),
1477+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.number_props.replicas.default", "3"),
1478+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.number_props.replicas.enum.#", "4"),
1479+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.number_props.replicas.enum.0", "1"),
1480+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.number_props.replicas.enum.3", "10"),
1481+
resource.TestCheckNoResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.number_props.replicas.enum_jq_query"),
1482+
1483+
// Number property: port - with minimum and maximum
1484+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.number_props.port.title", "Port"),
1485+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.number_props.port.minimum", "1024"),
1486+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.number_props.port.maximum", "65535"),
1487+
1488+
// Boolean property: enabled - with default
1489+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.boolean_props.enabled.title", "Enabled"),
1490+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.boolean_props.enabled.default", "true"),
1491+
resource.TestCheckNoResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.boolean_props.enabled.default_jq_query"),
1492+
1493+
// Boolean property: autoScale - without default
1494+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.boolean_props.autoScale.title", "Auto Scale"),
1495+
1496+
// Array property: tags - with min_items, max_items, and string_items
1497+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.array_props.tags.title", "Tags"),
1498+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.array_props.tags.min_items", "1"),
1499+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.array_props.tags.max_items", "5"),
1500+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.array_props.tags.string_items.format", "user"),
1501+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.array_props.tags.string_items.enum.#", "3"),
1502+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.array_props.tags.string_items.enum.0", "tag1"),
1503+
resource.TestCheckNoResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.array_props.tags.min_items_jq_query"),
1504+
resource.TestCheckNoResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.array_props.tags.max_items_jq_query"),
1505+
resource.TestCheckNoResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.array_props.tags.string_items.enum_jq_query"),
1506+
1507+
// Array property: ports - with number_items
1508+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.array_props.ports.title", "Ports"),
1509+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.array_props.ports.min_items", "1"),
1510+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.array_props.ports.max_items", "10"),
1511+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.array_props.ports.number_items.enum.#", "4"),
1512+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.array_props.ports.number_items.enum.0", "80"),
1513+
resource.TestCheckResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.array_props.ports.number_items.enum.1", "443"),
1514+
resource.TestCheckNoResourceAttr("port_action.create_microservice", "self_service_trigger.user_properties.array_props.ports.number_items.enum_jq_query"),
1515+
),
1516+
},
1517+
{
1518+
// Import step - verifies all non-JQ fields are correctly imported
1519+
ResourceName: "port_action.create_microservice",
1520+
ImportState: true,
1521+
ImportStateVerify: true,
1522+
ImportStateId: actionIdentifier,
1523+
},
1524+
},
1525+
})
1526+
}
1527+
13521528
func TestAccPortActionPatternJqQuery(t *testing.T) {
13531529
identifier := utils.GenID()
13541530
actionIdentifier := utils.GenID()

0 commit comments

Comments
 (0)