Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port 4981 terraform fix update resources issue when changing identifier #87

19 changes: 19 additions & 0 deletions internal/cli/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,25 @@ func (c *PortClient) CreateEntity(ctx context.Context, e *Entity, runID string)
return &pb.Entity, nil
}

func (c *PortClient) UpdateEntity(ctx context.Context, id string, blueprint string, e *Entity, runID string) (*Entity, error) {
url := "v1/blueprints/{blueprint}/entities/{identifier}"
pb := &PortBody{}
resp, err := c.Client.R().
SetBody(e).
SetPathParam(("blueprint"), e.Blueprint).
SetPathParam("identifier", id).
SetQueryParam("run_id", runID).
SetResult(&pb).
Put(url)
if err != nil {
return nil, err
}
if !pb.OK {
return nil, fmt.Errorf("failed to update entity, got: %s", resp.Body())
}
return &pb.Entity, nil
}

func (c *PortClient) DeleteEntity(ctx context.Context, id string, blueprint string) error {
url := "v1/blueprints/{blueprint}/entities/{identifier}"
pb := &PortBody{}
Expand Down
11 changes: 10 additions & 1 deletion port/action/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func (r *ActionResource) ImportState(ctx context.Context, req resource.ImportSta

resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("blueprint"), idParts[0])...)
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("identifier"), idParts[1])...)

}

func (r *ActionResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
Expand Down Expand Up @@ -126,7 +127,10 @@ func (r *ActionResource) Create(ctx context.Context, req resource.CreateRequest,

func (r *ActionResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var state *ActionModel
var previousState *ActionModel

resp.Diagnostics.Append(req.Plan.Get(ctx, &state)...)
resp.Diagnostics.Append(req.State.Get(ctx, &previousState)...)

if resp.Diagnostics.HasError() {
return
Expand All @@ -144,7 +148,12 @@ func (r *ActionResource) Update(ctx context.Context, req resource.UpdateRequest,
return
}

a, err := r.portClient.UpdateAction(ctx, bp.Identifier, action.Identifier, action)
var a *cli.Action
if previousState.Identifier.IsNull() {
a, err = r.portClient.CreateAction(ctx, bp.Identifier, action)
} else {
a, err = r.portClient.UpdateAction(ctx, bp.Identifier, previousState.Identifier.ValueString(), action)
dvirsegev marked this conversation as resolved.
Show resolved Hide resolved
}
if err != nil {
resp.Diagnostics.AddError("failed to create action", err.Error())
return
Expand Down
79 changes: 79 additions & 0 deletions port/action/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -854,3 +854,82 @@ func TestAccPortActionEncryption(t *testing.T) {
},
})
}

func TestAccPortActionUpdateIdentifier(t *testing.T) {
identifier := utils.GenID()
actionIdentifier := utils.GenID()
actionUpdatedIdentifier := utils.GenID()
var testAccActionConfigCreate = testAccCreateBlueprintConfig(identifier) + fmt.Sprintf(`
resource "port_action" "create_microservice" {
title = "TF Provider Test"
identifier = "%s"
icon = "Terraform"
blueprint = port_blueprint.microservice.id
trigger = "DAY-2"
webhook_method = {
url = "https://getport.io"
}
user_properties = {
"string_props" = {
"myStringIdentifier" = {
"title" = "My String Identifier"
"required" = true
}
}
}
}`, actionIdentifier)

var testAccActionConfigUpdate = testAccCreateBlueprintConfig(identifier) + fmt.Sprintf(`
resource "port_action" "create_microservice" {
title = "TF Provider Test"
identifier = "%s"
icon = "Terraform"
blueprint = port_blueprint.microservice.id
trigger = "DAY-2"
webhook_method = {
url = "https://getport.io"
}
user_properties = {
"string_props" = {
"myStringIdentifier" = {
"title" = "My String Identifier"
"required" = true
}
}
}
}`, actionUpdatedIdentifier)

resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.TestAccPreCheck(t) },
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,

Steps: []resource.TestStep{
{
Config: acctest.ProviderConfig + testAccActionConfigCreate,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("port_action.create_microservice", "title", "TF Provider Test"),
resource.TestCheckResourceAttr("port_action.create_microservice", "identifier", actionIdentifier),
resource.TestCheckResourceAttr("port_action.create_microservice", "icon", "Terraform"),
resource.TestCheckResourceAttr("port_action.create_microservice", "blueprint", identifier),
resource.TestCheckResourceAttr("port_action.create_microservice", "trigger", "DAY-2"),
resource.TestCheckResourceAttr("port_action.create_microservice", "webhook_method.url", "https://getport.io"),
resource.TestCheckResourceAttr("port_action.create_microservice", "user_properties.string_props.myStringIdentifier.title", "My String Identifier"),
resource.TestCheckResourceAttr("port_action.create_microservice", "user_properties.string_props.myStringIdentifier.required", "true"),
),
},
{
Config: acctest.ProviderConfig + testAccActionConfigUpdate,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("port_action.create_microservice", "title", "TF Provider Test"),
resource.TestCheckResourceAttr("port_action.create_microservice", "identifier", actionUpdatedIdentifier),
resource.TestCheckResourceAttr("port_action.create_microservice", "icon", "Terraform"),
resource.TestCheckResourceAttr("port_action.create_microservice", "blueprint", identifier),
resource.TestCheckResourceAttr("port_action.create_microservice", "trigger", "DAY-2"),
resource.TestCheckResourceAttr("port_action.create_microservice", "webhook_method.url", "https://getport.io"),
resource.TestCheckResourceAttr("port_action.create_microservice", "user_properties.string_props.myStringIdentifier.title", "My String Identifier"),
resource.TestCheckResourceAttr("port_action.create_microservice", "user_properties.string_props.myStringIdentifier.required", "true"),
),
},
},
})
}
11 changes: 9 additions & 2 deletions port/blueprint/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,10 @@ func writeBlueprintComputedFieldsToState(state *BlueprintModel, bp *cli.Blueprin

func (r *BlueprintResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var state *BlueprintModel
var previousState *BlueprintModel

resp.Diagnostics.Append(req.Plan.Get(ctx, &state)...)
resp.Diagnostics.Append(req.State.Get(ctx, &previousState)...)

if resp.Diagnostics.HasError() {
return
Expand All @@ -164,10 +167,10 @@ func (r *BlueprintResource) Update(ctx context.Context, req resource.UpdateReque

var bp *cli.Blueprint

if state.Identifier.IsNull() {
if previousState.Identifier.IsNull() {
bp, err = r.portClient.CreateBlueprint(ctx, b)
} else {
bp, err = r.portClient.UpdateBlueprint(ctx, b, state.Identifier.ValueString())
bp, err = r.portClient.UpdateBlueprint(ctx, b, previousState.ID.ValueString())
}

if err != nil {
Expand Down Expand Up @@ -207,6 +210,10 @@ func (r *BlueprintResource) ImportState(ctx context.Context, req resource.Import
resp.Diagnostics.Append(resp.State.SetAttribute(
ctx, path.Root("identifier"), req.ID,
)...)

resp.Diagnostics.Append(resp.State.SetAttribute(
ctx, path.Root("id"), req.ID,
)...)
}

func blueprintResourceToPortRequest(ctx context.Context, state *BlueprintModel) (*cli.Blueprint, error) {
Expand Down
45 changes: 45 additions & 0 deletions port/blueprint/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -678,3 +678,48 @@ func TestAccPortBlueprintWithCalculationProperty(t *testing.T) {
},
})
}

func TestAccPortUpdateBlueprintIdentifier(t *testing.T) {
identifier := utils.GenID()
updatedIdentifier := utils.GenID()
var testAccActionConfigCreate = fmt.Sprintf(`
resource "port_blueprint" "microservice" {
title = "TF Provider Test"
icon = "Terraform"
identifier = "%s"
description = ""
}
`, identifier)

var testAccActionConfigUpdate = fmt.Sprintf(`
resource "port_blueprint" "microservice" {
title = "TF Provider Test"
icon = "Terraform"
identifier = "%s"
description = ""
}
`, updatedIdentifier)

resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.TestAccPreCheck(t) },
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: acctest.ProviderConfig + testAccActionConfigCreate,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("port_blueprint.microservice", "title", "TF Provider Test"),
resource.TestCheckResourceAttr("port_blueprint.microservice", "identifier", identifier),
resource.TestCheckResourceAttr("port_blueprint.microservice", "icon", "Terraform"),
),
},
{
Config: acctest.ProviderConfig + testAccActionConfigUpdate,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("port_blueprint.microservice", "title", "TF Provider Test"),
resource.TestCheckResourceAttr("port_blueprint.microservice", "identifier", updatedIdentifier),
resource.TestCheckResourceAttr("port_blueprint.microservice", "icon", "Terraform"),
),
},
},
})
}
12 changes: 11 additions & 1 deletion port/entity/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,10 @@ func writeEntityComputedFieldsToState(state *EntityModel, e *cli.Entity) {

func (r *EntityResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var state *EntityModel
var previousState *EntityModel

resp.Diagnostics.Append(req.Plan.Get(ctx, &state)...)
resp.Diagnostics.Append(req.State.Get(ctx, &previousState)...)

if resp.Diagnostics.HasError() {
return
Expand All @@ -138,7 +141,14 @@ func (r *EntityResource) Update(ctx context.Context, req resource.UpdateRequest,
runID = state.RunID.ValueString()
}

en, err := r.portClient.CreateEntity(ctx, e, runID)
var en *cli.Entity

if previousState.Identifier.IsNull() {
en, err = r.portClient.CreateEntity(ctx, e, runID)
} else {
en, err = r.portClient.UpdateEntity(ctx, previousState.Identifier.ValueString(), previousState.Blueprint.ValueString(), e, runID)
}

if err != nil {
resp.Diagnostics.AddError("failed to create entity", err.Error())
return
Expand Down
80 changes: 80 additions & 0 deletions port/entity/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -419,3 +419,83 @@ func TestAccPortEntityUpdateProp(t *testing.T) {
},
})
}

func TestAccPortEntityUpdateIdentifier(t *testing.T) {
blueprintIdentifier := utils.GenID()
entityIdentifier := utils.GenID()
entityUpdatedIdentifier := utils.GenID()
var testAccActionConfigCreate = fmt.Sprintf(`
resource "port_blueprint" "microservice" {
title = "TF Provider Test BP0"
icon = "Terraform"
identifier = "%s"
properties = {
"string_props" = {
"myStringIdentifier" = {
"title" = "My String Identifier"
}
}
}
}
resource "port_entity" "microservice" {
title = "TF Provider Test Entity0"
blueprint = port_blueprint.microservice.identifier
identifier = "%s"
properties = {
"string_props" = {
"myStringIdentifier" = "My String Value"
}
}
}`, blueprintIdentifier, entityIdentifier)

var testAccActionConfigUpdate = fmt.Sprintf(`
resource "port_blueprint" "microservice" {
title = "TF Provider Test BP0"
icon = "Terraform"
identifier = "%s"
properties = {
"string_props" = {
"myStringIdentifier" = {
"title" = "My String Identifier"
}
}
}
}
resource "port_entity" "microservice" {
title = "TF Provider Test Entity0"
blueprint = port_blueprint.microservice.identifier
identifier = "%s"
properties = {
"string_props" = {
"myStringIdentifier" = "My String Value2"
}
}
}`, blueprintIdentifier, entityUpdatedIdentifier)

resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.TestAccPreCheck(t) },
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,

Steps: []resource.TestStep{
{
Config: acctest.ProviderConfig + testAccActionConfigCreate,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("port_entity.microservice", "identifier", entityIdentifier),
resource.TestCheckResourceAttr("port_entity.microservice", "title", "TF Provider Test Entity0"),
resource.TestCheckResourceAttr("port_entity.microservice", "blueprint", blueprintIdentifier),
resource.TestCheckResourceAttr("port_entity.microservice", "properties.string_props.myStringIdentifier", "My String Value"),
),
},
{
Config: acctest.ProviderConfig + testAccActionConfigUpdate,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("port_entity.microservice", "identifier", entityUpdatedIdentifier),
resource.TestCheckResourceAttr("port_entity.microservice", "title", "TF Provider Test Entity0"),
resource.TestCheckResourceAttr("port_entity.microservice", "blueprint", blueprintIdentifier),
resource.TestCheckResourceAttr("port_entity.microservice", "properties.string_props.myStringIdentifier", "My String Value2"),
),
},
},
})

}
12 changes: 11 additions & 1 deletion port/scorecard/resouce.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,10 @@ func writeScorecardComputedFieldsToState(state *ScorecardModel, wp *cli.Scorecar

func (r *ScorecardResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var state *ScorecardModel
var previousState *ScorecardModel

resp.Diagnostics.Append(req.Plan.Get(ctx, &state)...)
resp.Diagnostics.Append(req.State.Get(ctx, &previousState)...)

if resp.Diagnostics.HasError() {
return
Expand All @@ -109,7 +112,14 @@ func (r *ScorecardResource) Update(ctx context.Context, req resource.UpdateReque
return
}

sp, err := r.portClient.UpdateScorecard(ctx, state.Blueprint.ValueString(), state.Identifier.ValueString(), s)
var sp *cli.Scorecard

if previousState.Identifier.IsNull() {
sp, err = r.portClient.CreateScorecard(ctx, state.Blueprint.ValueString(), s)
} else {
sp, err = r.portClient.UpdateScorecard(ctx, state.Blueprint.ValueString(), previousState.Identifier.ValueString(), s)
dvirsegev marked this conversation as resolved.
Show resolved Hide resolved
}

if err != nil {
resp.Diagnostics.AddError("failed to update the scorecard", err.Error())
return
Expand Down
Loading
Loading