Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions stackit/internal/services/edgecloud/instance/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"strings"

"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
Expand Down Expand Up @@ -281,12 +280,17 @@ func (i *instanceResource) Create(ctx context.Context, req resource.CreateReques
core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating instance", "API returned nil Instance ID")
return
}

edgeCloudInstanceId := *createResp.Id
utils.SetAndLogStateFields(ctx, &resp.Diagnostics, &resp.State, map[string]any{
// Write id attributes to state before polling via the wait handler - just in case anything goes wrong during the wait handler
ctx = utils.SetAndLogStateFields(ctx, &resp.Diagnostics, &resp.State, map[string]any{
"project_id": projectId,
"instance_id": edgeCloudInstanceId,
"region": region,
})
if resp.Diagnostics.HasError() {
return
}

waitResp, err := edgewait.CreateOrUpdateInstanceWaitHandler(ctx, i.client, projectId, region, edgeCloudInstanceId).WaitWithContext(ctx)
if err != nil {
Expand Down Expand Up @@ -436,9 +440,12 @@ func (i *instanceResource) ImportState(ctx context.Context, req resource.ImportS
)
return
}
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), idParts[0])...)
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), idParts[1])...)
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), idParts[2])...)
ctx = utils.SetAndLogStateFields(ctx, &resp.Diagnostics, &resp.State, map[string]any{
"project_id": idParts[0],
"region": idParts[1],
"instance_id": idParts[2],
})
tflog.Info(ctx, "Edge cloud Instance state imported")
}

// mapFields maps the API response to the Terraform model.
Expand Down
27 changes: 22 additions & 5 deletions stackit/internal/services/logs/instance/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"strings"

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
Expand All @@ -18,7 +17,7 @@ import (
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
logs "github.com/stackitcloud/stackit-sdk-go/services/logs/v1api"
wait "github.com/stackitcloud/stackit-sdk-go/services/logs/v1api/wait"
"github.com/stackitcloud/stackit-sdk-go/services/logs/v1api/wait"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/logs/utils"
Expand Down Expand Up @@ -249,6 +248,21 @@ func (r *logsInstanceResource) Create(ctx context.Context, req resource.CreateRe

ctx = core.LogResponse(ctx)

if createResp == nil || createResp.Id == "" {
core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating Logs Instance", "Create API response: Incomplete response (id missing)")
return
}
instanceId := createResp.Id
// Write id attributes to state before polling via the wait handler - just in case anything goes wrong during the wait handler
ctx = tfutils.SetAndLogStateFields(ctx, &resp.Diagnostics, &resp.State, map[string]any{
"project_id": projectId,
"region": region,
"instance_id": instanceId,
})
if resp.Diagnostics.HasError() {
return
}

waitResp, err := wait.CreateLogsInstanceWaitHandler(ctx, r.client.DefaultAPI, projectId, regionId, createResp.Id).WaitWithContext(ctx)
if err != nil {
core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating Logs Instance", fmt.Sprintf("Waiting for Logs Instance to become active: %v", err))
Expand Down Expand Up @@ -403,9 +417,12 @@ func (r *logsInstanceResource) ImportState(ctx context.Context, req resource.Imp
core.LogAndAddError(ctx, &resp.Diagnostics, "Error importing Logs Instance", fmt.Sprintf("Invalid import ID %q: expected format is `project_id`,`region`,`instance_id`", req.ID))
return
}
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), idParts[0])...)
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), idParts[1])...)
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), idParts[2])...)

ctx = tfutils.SetAndLogStateFields(ctx, &resp.Diagnostics, &resp.State, map[string]any{
"project_id": idParts[0],
"region": idParts[1],
"instance_id": idParts[2],
})
tflog.Info(ctx, "Logs Instance state imported")
}

Expand Down
82 changes: 82 additions & 0 deletions stackit/internal/services/logs/logs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package logs

import (
"fmt"
"net/http"
"regexp"
"testing"

"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
logs "github.com/stackitcloud/stackit-sdk-go/services/logs/v1api"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/testutil"
)

func TestLogsInstanceSavesIDsOnError(t *testing.T) {
projectId := uuid.NewString()
instanceId := uuid.NewString()
const (
region = "eu01"
)
s := testutil.NewMockServer(t)
defer s.Server.Close()
tfConfig := fmt.Sprintf(`
provider "stackit" {
default_region = "%s"
logs_custom_endpoint = "%s"
service_account_token = "mock-server-needs-no-auth"
}
resource "stackit_logs_instance" "logs" {
project_id = "%s"
display_name = "logs-instance-example"
retention_days = 30
}
`, region, s.Server.URL, projectId)

resource.UnitTest(t, resource.TestCase{
ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
PreConfig: func() {
s.Reset(
testutil.MockResponse{
Description: "create instance",
ToJsonBody: logs.LogsInstance{
Id: instanceId,
},
},
testutil.MockResponse{
Description: "failing waiter",
StatusCode: http.StatusInternalServerError,
},
)
},
Config: tfConfig,
ExpectError: regexp.MustCompile("Error creating Logs Instance.*"),
},
{
PreConfig: func() {
s.Reset(
testutil.MockResponse{
Description: "refresh",
Handler: func(w http.ResponseWriter, req *http.Request) {
expected := fmt.Sprintf("/v1/projects/%s/regions/%s/instances/%s", projectId, region, instanceId)
if req.URL.Path != expected {
t.Errorf("expected request to %s, got %s", expected, req.URL.Path)
}
w.WriteHeader(http.StatusInternalServerError)
},
},
testutil.MockResponse{Description: "delete", StatusCode: http.StatusAccepted},
testutil.MockResponse{
Description: "delete waiter",
StatusCode: http.StatusNotFound,
},
)
},
RefreshState: true,
ExpectError: regexp.MustCompile("Error reading logs instance.*"),
},
},
})
}
19 changes: 14 additions & 5 deletions stackit/internal/services/mariadb/credential/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/validate"

"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
Expand Down Expand Up @@ -190,7 +189,15 @@ func (r *credentialResource) Create(ctx context.Context, req resource.CreateRequ
return
}
credentialId := *credentialsResp.Id
ctx = tflog.SetField(ctx, "credential_id", credentialId)
// Write id attributes to state before polling via the wait handler - just in case anything goes wrong during the wait handler
ctx = utils.SetAndLogStateFields(ctx, &resp.Diagnostics, &resp.State, map[string]any{
"project_id": projectId,
"instance_id": instanceId,
"credential_id": credentialId,
})
if resp.Diagnostics.HasError() {
return
}

waitResp, err := wait.CreateCredentialsWaitHandler(ctx, r.client, projectId, instanceId, credentialId).WaitWithContext(ctx)
if err != nil {
Expand Down Expand Up @@ -311,9 +318,11 @@ func (r *credentialResource) ImportState(ctx context.Context, req resource.Impor
return
}

resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), idParts[0])...)
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), idParts[1])...)
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("credential_id"), idParts[2])...)
ctx = utils.SetAndLogStateFields(ctx, &resp.Diagnostics, &resp.State, map[string]any{
"project_id": idParts[0],
"instance_id": idParts[1],
"credential_id": idParts[2],
})
tflog.Info(ctx, "MariaDB credential state imported")
}

Expand Down
21 changes: 18 additions & 3 deletions stackit/internal/services/mariadb/instance/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/validate"

"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
Expand Down Expand Up @@ -319,7 +318,21 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques

ctx = core.LogResponse(ctx)

if createResp == nil || createResp.InstanceId == nil {
core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating instance", "Create API response: Incomplete response (id missing)")
return
}

instanceId := *createResp.InstanceId
// Write id attributes to state before polling via the wait handler - just in case anything goes wrong during the wait handler
ctx = utils.SetAndLogStateFields(ctx, &resp.Diagnostics, &resp.State, map[string]any{
"project_id": projectId,
"instance_id": instanceId,
})
if resp.Diagnostics.HasError() {
return
}

ctx = tflog.SetField(ctx, "instance_id", instanceId)
waitResp, err := wait.CreateInstanceWaitHandler(ctx, r.client, projectId, instanceId).WaitWithContext(ctx)
if err != nil {
Expand Down Expand Up @@ -510,8 +523,10 @@ func (r *instanceResource) ImportState(ctx context.Context, req resource.ImportS
return
}

resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), idParts[0])...)
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), idParts[1])...)
ctx = utils.SetAndLogStateFields(ctx, &resp.Diagnostics, &resp.State, map[string]any{
"project_id": idParts[0],
"instance_id": idParts[1],
})
tflog.Info(ctx, "MariaDB instance state imported")
}

Expand Down
Loading
Loading