Skip to content

Commit e653f89

Browse files
authored
PORT-4245-terraform-add-support-for-advance-configuration (#57)
1 parent 2298cf8 commit e653f89

15 files changed

+835
-91
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
@talsabagport @danielsinai @dvirsegev
1+
@talsabagport @danielsinai @dvirsegev @matarpeles

internal/cli/models.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,51 @@ type (
5353
EnumColors map[string]string `json:"enumColors,omitempty"`
5454
}
5555

56+
ActionProperty struct {
57+
Type string `json:"type,omitempty"`
58+
Title *string `json:"title,omitempty"`
59+
Identifier string `json:"identifier,omitempty"`
60+
Items map[string]any `json:"items,omitempty"`
61+
Default interface{} `json:"default,omitempty"`
62+
Icon *string `json:"icon,omitempty"`
63+
Format *string `json:"format,omitempty"`
64+
MaxLength *int `json:"maxLength,omitempty"`
65+
MinLength *int `json:"minLength,omitempty"`
66+
MaxItems *int `json:"maxItems,omitempty"`
67+
MinItems *int `json:"minItems,omitempty"`
68+
Maximum *float64 `json:"maximum,omitempty"`
69+
Minimum *float64 `json:"minimum,omitempty"`
70+
Description *string `json:"description,omitempty"`
71+
Blueprint *string `json:"blueprint,omitempty"`
72+
Pattern *string `json:"pattern,omitempty"`
73+
Enum interface{} `json:"enum,omitempty"`
74+
Spec *string `json:"spec,omitempty"`
75+
SpecAuthentication *SpecAuthentication `json:"specAuthentication,omitempty"`
76+
EnumColors map[string]string `json:"enumColors,omitempty"`
77+
DependsOn []string `json:"dependsOn,omitempty"`
78+
Dataset *Dataset `json:"dataset,omitempty"`
79+
}
80+
5681
SpecAuthentication struct {
5782
ClientId string `json:"clientId,omitempty"`
5883
AuthorizationUrl string `json:"authorizationUrl,omitempty"`
5984
TokenUrl string `json:"tokenUrl,omitempty"`
6085
}
6186

87+
DatasetValue struct {
88+
JqQuery string `json:"jqQuery,omitempty"`
89+
}
90+
DatasetRule struct {
91+
Blueprint *string `json:"blueprint,omitempty"`
92+
Property *string `json:"property,omitempty"`
93+
Operator string `json:"operator,omitempty"`
94+
Value *DatasetValue `json:"value,omitempty"`
95+
}
96+
Dataset struct {
97+
Combinator string `json:"combinator,omitempty"`
98+
Rules []DatasetRule `json:"rules,omitempty"`
99+
}
100+
62101
BlueprintCalculationProperty struct {
63102
Type string `json:"type,omitempty"`
64103
Title *string `json:"title,omitempty"`
@@ -95,6 +134,9 @@ type (
95134
OmitUserInputs *bool `json:"omitUserInputs,omitempty"`
96135
ReportWorkflowStatus *bool `json:"reportWorkflowStatus,omitempty"`
97136
Branch *string `json:"branch,omitempty"`
137+
ProjectName *string `json:"projectName,omitempty"`
138+
GroupName *string `json:"groupName,omitempty"`
139+
DefaultRef *string `json:"defaultRef,omitempty"`
98140
}
99141

100142
ApprovalNotification struct {
@@ -113,7 +155,10 @@ type (
113155
Path string `json:"path,omitempty"`
114156
}
115157

116-
ActionUserInputs = BlueprintSchema
158+
ActionUserInputs = struct {
159+
Properties map[string]ActionProperty `json:"properties"`
160+
Required []string `json:"required,omitempty"`
161+
}
117162

118163
Blueprint struct {
119164
Meta

internal/consts/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ const (
77
Kafka = "KAFKA"
88
AzureDevops = "AZURE-DEVOPS"
99
Github = "GITHUB"
10+
Gitlab = "GITLAB"
1011
)

internal/flex/string.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package flex
22

33
import (
4+
"context"
5+
6+
"github.com/hashicorp/terraform-plugin-framework/attr"
47
"github.com/hashicorp/terraform-plugin-framework/types"
8+
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
59
)
610

711
func GoStringToFramework(v *string) types.String {
@@ -11,3 +15,15 @@ func GoStringToFramework(v *string) types.String {
1115

1216
return types.StringValue(*v)
1317
}
18+
19+
func GoArrayStringToTerraformList(ctx context.Context, array []string) types.List {
20+
if array == nil {
21+
return types.ListNull(types.StringType)
22+
}
23+
attrs := make([]attr.Value, 0, len(array))
24+
for _, value := range array {
25+
attrs = append(attrs, basetypes.NewStringValue(value))
26+
}
27+
list, _ := types.ListValue(types.StringType, attrs)
28+
return list
29+
}

internal/utils/utils.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,13 @@ func GoObjectToTerraformString(v interface{}) (types.String, error) {
8484
value := string(js)
8585
return types.StringValue(value), nil
8686
}
87+
88+
func InterfaceToStringArray(o interface{}) []string {
89+
items := o.([]interface{})
90+
res := make([]string, len(items))
91+
for i, item := range items {
92+
res[i] = item.(string)
93+
}
94+
95+
return res
96+
}

port/action/actionStateToPortBody.go

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,33 @@ import (
77
"github.com/port-labs/terraform-provider-port-labs/internal/consts"
88
)
99

10+
func actionDataSetToPortBody(dataSet *DatasetModel) *cli.Dataset {
11+
cliDateSet := &cli.Dataset{
12+
Combinator: dataSet.Combinator.ValueString(),
13+
}
14+
rules := make([]cli.DatasetRule, 0, len(dataSet.Rules))
15+
for _, rule := range dataSet.Rules {
16+
dataSetRule := cli.DatasetRule{
17+
Operator: rule.Operator.ValueString(),
18+
Value: &cli.DatasetValue{
19+
JqQuery: rule.Value.JqQuery.ValueString(),
20+
},
21+
}
22+
if !rule.Blueprint.IsNull() {
23+
blueprint := rule.Blueprint.ValueString()
24+
dataSetRule.Blueprint = &blueprint
25+
}
26+
if !rule.Property.IsNull() {
27+
rule := rule.Property.ValueString()
28+
dataSetRule.Property = &rule
29+
}
30+
31+
rules = append(rules, dataSetRule)
32+
}
33+
cliDateSet.Rules = rules
34+
return cliDateSet
35+
}
36+
1037
func actionStateToPortBody(ctx context.Context, data *ActionModel, bp *cli.Blueprint) (*cli.Action, error) {
1138
action := &cli.Action{
1239
Identifier: data.Identifier.ValueString(),
@@ -55,15 +82,15 @@ func actionStateToPortBody(ctx context.Context, data *ActionModel, bp *cli.Bluep
5582
return nil, err
5683
}
5784
} else {
58-
action.UserInputs.Properties = make(map[string]cli.BlueprintProperty)
85+
action.UserInputs.Properties = make(map[string]cli.ActionProperty)
5986
}
6087

6188
return action, nil
6289
}
6390

6491
func actionPropertiesToBody(ctx context.Context, action *cli.Action, data *ActionModel) error {
6592
required := []string{}
66-
props := map[string]cli.BlueprintProperty{}
93+
props := map[string]cli.ActionProperty{}
6794
var err error
6895
if data.UserProperties.StringProps != nil {
6996
err = stringPropResourceToBody(ctx, data, props, &required)
@@ -75,11 +102,11 @@ func actionPropertiesToBody(ctx context.Context, action *cli.Action, data *Actio
75102
err = numberPropResourceToBody(ctx, data, props, &required)
76103
}
77104
if data.UserProperties.BooleanProps != nil {
78-
booleanPropResourceToBody(data, props, &required)
105+
err = booleanPropResourceToBody(ctx, data, props, &required)
79106
}
80107

81108
if data.UserProperties.ObjectProps != nil {
82-
err = objectPropResourceToBody(data, props, &required)
109+
err = objectPropResourceToBody(ctx, data, props, &required)
83110
}
84111

85112
if err != nil {
@@ -148,5 +175,38 @@ func invocationMethodToBody(data *ActionModel) *cli.InvocationMethod {
148175
}
149176
return webhookInvocation
150177
}
178+
179+
if data.GitlabMethod != nil {
180+
projectName := data.GitlabMethod.ProjectName.ValueString()
181+
groupName := data.GitlabMethod.GroupName.ValueString()
182+
gitlabInvocation := &cli.InvocationMethod{
183+
Type: consts.Gitlab,
184+
ProjectName: &projectName,
185+
GroupName: &groupName,
186+
}
187+
188+
if !data.GitlabMethod.OmitPayload.IsNull() {
189+
omitPayload := data.GitlabMethod.OmitPayload.ValueBool()
190+
gitlabInvocation.OmitPayload = &omitPayload
191+
}
192+
193+
if !data.GitlabMethod.OmitUserInputs.IsNull() {
194+
omitUserInputs := data.GitlabMethod.OmitUserInputs.ValueBool()
195+
gitlabInvocation.OmitUserInputs = &omitUserInputs
196+
}
197+
198+
if !data.GitlabMethod.DefaultRef.IsNull() {
199+
defaultRef := data.GitlabMethod.DefaultRef.ValueString()
200+
gitlabInvocation.DefaultRef = &defaultRef
201+
}
202+
203+
if !data.GitlabMethod.Agent.IsNull() {
204+
agent := data.GitlabMethod.Agent.ValueBool()
205+
gitlabInvocation.Agent = &agent
206+
}
207+
208+
return gitlabInvocation
209+
}
210+
151211
return nil
152212
}

port/action/array.go

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
"github.com/port-labs/terraform-provider-port-labs/internal/utils"
1313
)
1414

15-
func handleArrayItemsToBody(ctx context.Context, property *cli.BlueprintProperty, prop ArrayPropModel, required *[]string) error {
15+
func handleArrayItemsToBody(ctx context.Context, property *cli.ActionProperty, prop ArrayPropModel, required *[]string) error {
1616
if prop.StringItems != nil {
1717
items := map[string]interface{}{}
1818
items["type"] = "string"
@@ -86,9 +86,9 @@ func handleArrayItemsToBody(ctx context.Context, property *cli.BlueprintProperty
8686
return nil
8787
}
8888

89-
func arrayPropResourceToBody(ctx context.Context, d *ActionModel, props map[string]cli.BlueprintProperty, required *[]string) error {
89+
func arrayPropResourceToBody(ctx context.Context, d *ActionModel, props map[string]cli.ActionProperty, required *[]string) error {
9090
for propIdentifier, prop := range d.UserProperties.ArrayProps {
91-
props[propIdentifier] = cli.BlueprintProperty{
91+
props[propIdentifier] = cli.ActionProperty{
9292
Type: "array",
9393
}
9494

@@ -104,6 +104,14 @@ func arrayPropResourceToBody(ctx context.Context, d *ActionModel, props map[stri
104104
property.Icon = &icon
105105
}
106106

107+
if !prop.DefaultJqQuery.IsNull() {
108+
defaultJqQuery := prop.DefaultJqQuery.ValueString()
109+
jqQueryMap := map[string]string{
110+
"jqQuery": defaultJqQuery,
111+
}
112+
property.Default = jqQueryMap
113+
}
114+
107115
if !prop.Description.IsNull() {
108116
description := prop.Description.ValueString()
109117
property.Description = &description
@@ -118,6 +126,18 @@ func arrayPropResourceToBody(ctx context.Context, d *ActionModel, props map[stri
118126
property.MaxItems = &maxItems
119127
}
120128

129+
if !prop.DependsOn.IsNull() {
130+
dependsOn, err := utils.TerraformListToGoArray(ctx, prop.DependsOn, "string")
131+
if err != nil {
132+
return err
133+
}
134+
property.DependsOn = utils.InterfaceToStringArray(dependsOn)
135+
136+
}
137+
if prop.Dataset != nil {
138+
property.Dataset = actionDataSetToPortBody(prop.Dataset)
139+
}
140+
121141
err := handleArrayItemsToBody(ctx, &property, prop, required)
122142
if err != nil {
123143
return err
@@ -133,12 +153,20 @@ func arrayPropResourceToBody(ctx context.Context, d *ActionModel, props map[stri
133153
return nil
134154
}
135155

136-
func addArrayPropertiesToResource(v *cli.BlueprintProperty) (*ArrayPropModel, error) {
156+
func addArrayPropertiesToResource(v *cli.ActionProperty) (*ArrayPropModel, error) {
137157
arrayProp := &ArrayPropModel{
138158
MinItems: flex.GoInt64ToFramework(v.MinItems),
139159
MaxItems: flex.GoInt64ToFramework(v.MaxItems),
140160
}
141161

162+
if v.Default != nil {
163+
switch v := v.Default.(type) {
164+
// We only test for map[string]interface{} ATM
165+
case map[string]interface{}:
166+
arrayProp.DefaultJqQuery = types.StringValue(v["jqQuery"].(string))
167+
}
168+
}
169+
142170
if v.Items != nil {
143171
if v.Items["type"] != "" {
144172
switch v.Items["type"] {

port/action/boolean.go

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
package action
22

3-
import "github.com/port-labs/terraform-provider-port-labs/internal/cli"
3+
import (
4+
"context"
45

5-
func booleanPropResourceToBody(d *ActionModel, props map[string]cli.BlueprintProperty, required *[]string) {
6+
"github.com/port-labs/terraform-provider-port-labs/internal/cli"
7+
"github.com/port-labs/terraform-provider-port-labs/internal/utils"
8+
)
9+
10+
func booleanPropResourceToBody(ctx context.Context, d *ActionModel, props map[string]cli.ActionProperty, required *[]string) error {
611
for propIdentifier, prop := range d.UserProperties.BooleanProps {
7-
props[propIdentifier] = cli.BlueprintProperty{
12+
props[propIdentifier] = cli.ActionProperty{
813
Type: "boolean",
914
}
1015

@@ -18,6 +23,14 @@ func booleanPropResourceToBody(d *ActionModel, props map[string]cli.BlueprintPro
1823
property.Default = prop.Default.ValueBool()
1924
}
2025

26+
if !prop.DefaultJqQuery.IsNull() {
27+
defaultJqQuery := prop.DefaultJqQuery.ValueString()
28+
jqQueryMap := map[string]string{
29+
"jqQuery": defaultJqQuery,
30+
}
31+
property.Default = jqQueryMap
32+
}
33+
2134
if !prop.Icon.IsNull() {
2235
icon := prop.Icon.ValueString()
2336
property.Icon = &icon
@@ -28,10 +41,23 @@ func booleanPropResourceToBody(d *ActionModel, props map[string]cli.BlueprintPro
2841
property.Description = &description
2942
}
3043

44+
if !prop.DependsOn.IsNull() {
45+
dependsOn, err := utils.TerraformListToGoArray(ctx, prop.DependsOn, "string")
46+
if err != nil {
47+
return err
48+
}
49+
property.DependsOn = utils.InterfaceToStringArray(dependsOn)
50+
51+
}
52+
if prop.Dataset != nil {
53+
property.Dataset = actionDataSetToPortBody(prop.Dataset)
54+
}
55+
3156
props[propIdentifier] = property
3257
}
3358
if prop.Required.ValueBool() {
3459
*required = append(*required, propIdentifier)
3560
}
3661
}
62+
return nil
3763
}

0 commit comments

Comments
 (0)