Skip to content

Commit 34f61be

Browse files
danielsinairoot
and
root
authored
added calculated properties (#24)
* added calculated properties * fixed tests * added support for team array * fixed issues with teams state --------- Co-authored-by: root <[email protected]>
1 parent 8b6765d commit 34f61be

6 files changed

+281
-23
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@talsabagport @danielsinai @dvirsegev

port/cli/models.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,19 @@ type (
4242
EnumColors map[string]string `json:"enumColors,omitempty"`
4343
}
4444

45+
BlueprintCalculationProperty struct {
46+
Type string `json:"type,omitempty"`
47+
Title string `json:"title,omitempty"`
48+
Identifier string `json:"identifier,omitempty"`
49+
Calculation string `json:"calculation,omitempty"`
50+
Default interface{} `json:"default,omitempty"`
51+
Icon string `json:"icon,omitempty"`
52+
Format string `json:"format,omitempty"`
53+
Description string `json:"description,omitempty"`
54+
Colorized bool `json:"colorized,omitempty"`
55+
Colors map[string]string `json:"colors,omitempty"`
56+
}
57+
4558
BlueprintMirrorProperty struct {
4659
Identifier string `json:"identifier,omitempty"`
4760
Title string `json:"title,omitempty"`
@@ -74,14 +87,15 @@ type (
7487

7588
Blueprint struct {
7689
Meta
77-
Identifier string `json:"identifier,omitempty"`
78-
Title string `json:"title"`
79-
Icon string `json:"icon"`
80-
Description string `json:"description"`
81-
Schema BlueprintSchema `json:"schema"`
82-
MirrorProperties map[string]BlueprintMirrorProperty `json:"mirrorProperties"`
83-
ChangelogDestination *ChangelogDestination `json:"changelogDestination,omitempty"`
84-
Relations map[string]Relation `json:"relations"`
90+
Identifier string `json:"identifier,omitempty"`
91+
Title string `json:"title"`
92+
Icon string `json:"icon"`
93+
Description string `json:"description"`
94+
Schema BlueprintSchema `json:"schema"`
95+
MirrorProperties map[string]BlueprintMirrorProperty `json:"mirrorProperties"`
96+
CalculationProperties map[string]BlueprintCalculationProperty `json:"calculationProperties"`
97+
ChangelogDestination *ChangelogDestination `json:"changelogDestination,omitempty"`
98+
Relations map[string]Relation `json:"relations"`
8599
}
86100

87101
Action struct {

port/resource_port_blueprint.go

Lines changed: 126 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func newBlueprintResource() *schema.Resource {
4343
Type: schema.TypeString,
4444
Description: "The icon of the blueprint",
4545
ValidateFunc: validation.StringInSlice(ICONS, false),
46-
Required: true,
46+
Optional: true,
4747
},
4848
"description": {
4949
Type: schema.TypeString,
@@ -182,6 +182,64 @@ func newBlueprintResource() *schema.Resource {
182182
},
183183
Optional: true,
184184
},
185+
"calculation_properties": {
186+
Type: schema.TypeSet,
187+
Description: "A set of properties that are calculated upon Entitys regular properties.",
188+
Elem: &schema.Resource{
189+
Schema: map[string]*schema.Schema{
190+
"identifier": {
191+
Type: schema.TypeString,
192+
Required: true,
193+
Description: "The identifier of the property",
194+
},
195+
"title": {
196+
Type: schema.TypeString,
197+
Optional: true,
198+
Description: "The name of this property",
199+
},
200+
"calculation": {
201+
Type: schema.TypeString,
202+
Required: true,
203+
Description: "A jq expression that calculates the value of the property, for instance \"'https://grafana.' + .identifier\"",
204+
},
205+
"icon": {
206+
Type: schema.TypeString,
207+
ValidateFunc: validation.StringInSlice(ICONS, false),
208+
Optional: true,
209+
Description: "The icon of the property",
210+
},
211+
"type": {
212+
Type: schema.TypeString,
213+
Required: true,
214+
Description: "The type of the property",
215+
},
216+
"description": {
217+
Type: schema.TypeString,
218+
Optional: true,
219+
Description: "The description of the property",
220+
},
221+
"format": {
222+
Type: schema.TypeString,
223+
Optional: true,
224+
Description: "The format of the Property",
225+
},
226+
"colorized": {
227+
Type: schema.TypeBool,
228+
Optional: true,
229+
Description: "Whether or not the property is colorized",
230+
},
231+
"colors": {
232+
Type: schema.TypeMap,
233+
Elem: &schema.Schema{
234+
Type: schema.TypeString,
235+
},
236+
Optional: true,
237+
Description: "A map of colors for the property",
238+
},
239+
},
240+
},
241+
Optional: true,
242+
},
185243
"changelog_destination": {
186244
Type: schema.TypeList,
187245
MinItems: 1,
@@ -256,7 +314,12 @@ func writeBlueprintFieldsToResource(d *schema.ResourceData, b *cli.Blueprint) {
256314
return schema.HashString(id)
257315
}}
258316

259-
mirror_properties := schema.Set{F: func(i interface{}) int {
317+
mirrorPoperties := schema.Set{F: func(i interface{}) int {
318+
id := (i.(map[string]interface{}))["identifier"].(string)
319+
return schema.HashString(id)
320+
}}
321+
322+
calculationProperties := schema.Set{F: func(i interface{}) int {
260323
id := (i.(map[string]interface{}))["identifier"].(string)
261324
return schema.HashString(id)
262325
}}
@@ -304,11 +367,27 @@ func writeBlueprintFieldsToResource(d *schema.ResourceData, b *cli.Blueprint) {
304367
p["identifier"] = k
305368
p["title"] = v.Title
306369
p["path"] = v.Path
307-
mirror_properties.Add(p)
370+
mirrorPoperties.Add(p)
371+
}
372+
373+
for k, v := range b.CalculationProperties {
374+
p := map[string]interface{}{}
375+
p["identifier"] = k
376+
p["title"] = v.Title
377+
p["description"] = v.Description
378+
p["icon"] = v.Icon
379+
p["calculation"] = v.Calculation
380+
p["type"] = v.Type
381+
p["format"] = v.Format
382+
p["colorized"] = v.Colorized
383+
p["colors"] = v.Colors
384+
385+
calculationProperties.Add(p)
308386
}
309387

310388
d.Set("properties", &properties)
311-
d.Set("mirror_properties", &mirror_properties)
389+
d.Set("mirror_properties", &mirrorPoperties)
390+
d.Set("calculation_properties", &calculationProperties)
312391
}
313392

314393
func blueprintResourceToBody(d *schema.ResourceData) (*cli.Blueprint, error) {
@@ -325,7 +404,8 @@ func blueprintResourceToBody(d *schema.ResourceData) (*cli.Blueprint, error) {
325404
b.Icon = d.Get("icon").(string)
326405
b.Description = d.Get("description").(string)
327406
props := d.Get("properties").(*schema.Set)
328-
mirror_props := d.Get("mirror_properties").(*schema.Set)
407+
mirrorProps := d.Get("mirror_properties").(*schema.Set)
408+
calcProps := d.Get("calculation_properties").(*schema.Set)
329409

330410
if changelogDestination, ok := d.GetOk("changelog_destination"); ok {
331411
if b.ChangelogDestination == nil {
@@ -411,8 +491,8 @@ func blueprintResourceToBody(d *schema.ResourceData) (*cli.Blueprint, error) {
411491
}
412492
}
413493

414-
mirror_properties := make(map[string]cli.BlueprintMirrorProperty, mirror_props.Len())
415-
for _, prop := range mirror_props.List() {
494+
mirrorProperties := make(map[string]cli.BlueprintMirrorProperty, mirrorProps.Len())
495+
for _, prop := range mirrorProps.List() {
416496
p := prop.(map[string]interface{})
417497
propFields := cli.BlueprintMirrorProperty{}
418498
if t, ok := p["title"]; ok && t != "" {
@@ -421,7 +501,43 @@ func blueprintResourceToBody(d *schema.ResourceData) (*cli.Blueprint, error) {
421501
if p, ok := p["path"]; ok && p != "" {
422502
propFields.Path = p.(string)
423503
}
424-
mirror_properties[p["identifier"].(string)] = propFields
504+
mirrorProperties[p["identifier"].(string)] = propFields
505+
}
506+
507+
calculationProperties := make(map[string]cli.BlueprintCalculationProperty, calcProps.Len())
508+
for _, prop := range calcProps.List() {
509+
p := prop.(map[string]interface{})
510+
calcFields := cli.BlueprintCalculationProperty{}
511+
if t, ok := p["type"]; ok && t != "" {
512+
calcFields.Type = t.(string)
513+
}
514+
if t, ok := p["title"]; ok && t != "" {
515+
calcFields.Title = t.(string)
516+
}
517+
if d, ok := p["description"]; ok && d != "" {
518+
calcFields.Description = d.(string)
519+
}
520+
if f, ok := p["format"]; ok && f != "" {
521+
calcFields.Format = f.(string)
522+
}
523+
if i, ok := p["icon"]; ok && i != "" {
524+
calcFields.Icon = i.(string)
525+
}
526+
if r, ok := p["colorized"]; ok && r.(bool) {
527+
calcFields.Colorized = r.(bool)
528+
}
529+
if e, ok := p["colors"]; ok && e != nil {
530+
colors := make(map[string]string)
531+
for key, value := range e.(map[string]interface{}) {
532+
colors[key] = value.(string)
533+
}
534+
calcFields.Colors = colors
535+
}
536+
calcFields.Calculation = p["calculation"].(string)
537+
// TODO: remove the if statement when this issues is solved, https://github.com/hashicorp/terraform-plugin-sdk/pull/1042/files
538+
if p["identifier"] != "" {
539+
calculationProperties[p["identifier"].(string)] = calcFields
540+
}
425541
}
426542

427543
rels := d.Get("relations").(*schema.Set)
@@ -447,7 +563,8 @@ func blueprintResourceToBody(d *schema.ResourceData) (*cli.Blueprint, error) {
447563

448564
b.Schema = cli.BlueprintSchema{Properties: properties, Required: required}
449565
b.Relations = relations
450-
b.MirrorProperties = mirror_properties
566+
b.MirrorProperties = mirrorProperties
567+
b.CalculationProperties = calculationProperties
451568
return b, nil
452569
}
453570

port/resource_port_blueprint_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,18 @@ func TestAccPortBlueprintUpdate(t *testing.T) {
181181
b = "blue"
182182
}
183183
}
184+
calculation_properties {
185+
identifier = "calc"
186+
type = "number"
187+
icon = "Terraform"
188+
title = "calc"
189+
calculation = "2"
190+
colorized = true
191+
colors = {
192+
0 = "red"
193+
1 = "blue"
194+
}
195+
}
184196
}
185197
`, identifier)
186198
var testAccActionConfigUpdate = fmt.Sprintf(`
@@ -225,6 +237,12 @@ func TestAccPortBlueprintUpdate(t *testing.T) {
225237
resource.TestCheckResourceAttr("port-labs_blueprint.microservice1", "properties.0.title", "text"),
226238
resource.TestCheckResourceAttr("port-labs_blueprint.microservice1", "properties.0.required", "true"),
227239
resource.TestCheckResourceAttr("port-labs_blueprint.microservice1", "properties.0.icon", "Terraform"),
240+
resource.TestCheckResourceAttr("port-labs_blueprint.microservice1", "calculation_properties.0.identifier", "calc"),
241+
resource.TestCheckResourceAttr("port-labs_blueprint.microservice1", "calculation_properties.0.icon", "Terraform"),
242+
resource.TestCheckResourceAttr("port-labs_blueprint.microservice1", "calculation_properties.0.type", "number"),
243+
resource.TestCheckResourceAttr("port-labs_blueprint.microservice1", "calculation_properties.0.colorized", "true"),
244+
resource.TestCheckResourceAttr("port-labs_blueprint.microservice1", "calculation_properties.0.colors.0", "red"),
245+
resource.TestCheckResourceAttr("port-labs_blueprint.microservice1", "calculation_properties.0.colors.1", "blue"),
228246
),
229247
},
230248
{

port/resource_port_entity.go

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,19 @@ func newEntityResource() *schema.Resource {
3636
Optional: true,
3737
},
3838
"team": {
39-
Type: schema.TypeString,
40-
Description: "The team related to the entity",
41-
Optional: true,
39+
Type: schema.TypeString,
40+
Description: "The team related to the entity",
41+
Optional: true,
42+
ConflictsWith: []string{"teams"},
43+
},
44+
"teams": {
45+
Type: schema.TypeSet,
46+
Description: "The teams related to the entity",
47+
Elem: &schema.Schema{
48+
Type: schema.TypeString,
49+
},
50+
Optional: true,
51+
ConflictsWith: []string{"team"},
4252
},
4353
"blueprint": {
4454
Type: schema.TypeString,
@@ -164,10 +174,21 @@ func entityResourceToBody(d *schema.ResourceData, bp *cli.Blueprint) (*cli.Entit
164174
}
165175
e.Title = d.Get("title").(string)
166176
e.Blueprint = d.Get("blueprint").(string)
177+
178+
teams := []string{}
179+
167180
if team, ok := d.GetOk("team"); ok {
168-
teams := []string{team.(string)}
169-
e.Team = teams
181+
teams = append(teams, team.(string))
182+
183+
}
184+
185+
if resourceTeams, ok := d.Get("teams").(*schema.Set); ok {
186+
for _, team := range resourceTeams.List() {
187+
teams = append(teams, team.(string))
188+
}
170189
}
190+
e.Team = teams
191+
171192
rels := d.Get("relations").(*schema.Set)
172193
relations := make(map[string]string)
173194
for _, rel := range rels.List() {
@@ -200,9 +221,19 @@ func writeEntityComputedFieldsToResource(d *schema.ResourceData, e *cli.Entity)
200221
func writeEntityFieldsToResource(d *schema.ResourceData, e *cli.Entity) {
201222
d.SetId(e.Identifier)
202223
d.Set("title", e.Title)
203-
if len(e.Team) > 0 {
224+
225+
team := d.Get("team")
226+
227+
if team != "" {
204228
d.Set("team", e.Team[0])
205229
}
230+
231+
teams := d.Get("teams").(*schema.Set)
232+
233+
if len(teams.List()) > 0 {
234+
d.Set("teams", e.Team)
235+
}
236+
206237
d.Set("created_at", e.CreatedAt.String())
207238
d.Set("created_by", e.CreatedBy)
208239
d.Set("updated_at", e.UpdatedAt.String())

0 commit comments

Comments
 (0)