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
6 changes: 5 additions & 1 deletion docs/data-sources/mariadb_credential.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,15 @@ data "stackit_mariadb_credential" "example" {
- `instance_id` (String) ID of the MariaDB instance.
- `project_id` (String) STACKIT project ID to which the instance is associated.

### Optional

- `region` (String) The resource region. If not defined, the provider region is used.

### Read-Only

- `host` (String)
- `hosts` (List of String)
- `id` (String) Terraform's internal data source. identifier. It is structured as "`project_id`,`instance_id`,`credential_id`".
- `id` (String) Terraform's internal data source. identifier. It is structured as "`project_id`,`region`,`instance_id`,`credential_id`".
- `name` (String)
- `password` (String, Sensitive)
- `port` (Number)
Expand Down
6 changes: 5 additions & 1 deletion docs/data-sources/mariadb_instance.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,17 @@ data "stackit_mariadb_instance" "example" {
- `instance_id` (String) ID of the MariaDB instance.
- `project_id` (String) STACKIT Project ID to which the instance is associated.

### Optional

- `region` (String) The resource region. If not defined, the provider region is used.

### Read-Only

- `cf_guid` (String)
- `cf_organization_guid` (String)
- `cf_space_guid` (String)
- `dashboard_url` (String)
- `id` (String) Terraform's internal data source. identifier. It is structured as "`project_id`,`instance_id`".
- `id` (String) Terraform's internal data source. identifier. It is structured as "`project_id`,`region`,`instance_id`".
- `image_url` (String)
- `name` (String) Instance name.
- `parameters` (Attributes) (see [below for nested schema](#nestedatt--parameters))
Expand Down
5 changes: 3 additions & 2 deletions docs/resources/mariadb_credential.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,15 @@ resource "stackit_mariadb_credential" "example_rotate" {

### Optional

- `region` (String) The resource region. If not defined, the provider region is used.
- `rotate_when_changed` (Map of String) A map of arbitrary key/value pairs that will force recreation of the resource when they change, enabling resource rotation based on external conditions such as a rotating timestamp. Changing this forces a new resource to be created.

### Read-Only

- `credential_id` (String) The credential's ID.
- `host` (String)
- `hosts` (List of String)
- `id` (String) Terraform's internal resource identifier. It is structured as "`project_id`,`instance_id`,`credential_id`".
- `id` (String) Terraform's internal resource identifier. It is structured as "`project_id`,`region`,`instance_id`,`credential_id`".
- `name` (String)
- `password` (String, Sensitive)
- `port` (Number)
Expand All @@ -66,6 +67,6 @@ In Terraform v1.5.0 and later, the [` + "`" + `import` + "`" + ` block](https://
# Only use the import statement, if you want to import an existing mariadb credential
import {
to = stackit_mariadb_credential.import-example
id = "${var.project_id},${var.mariadb_instance_id},${var.mariadb_credential_id}"
id = "${var.project_id},${var.region},${var.mariadb_instance_id},${var.mariadb_credential_id}"
}
```
5 changes: 3 additions & 2 deletions docs/resources/mariadb_instance.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,15 @@ resource "stackit_mariadb_instance" "example" {
### Optional

- `parameters` (Attributes) Configuration parameters. Please note that removing a previously configured field from your Terraform configuration won't replace its value in the API. To update a previously configured field, explicitly set a new value for it. (see [below for nested schema](#nestedatt--parameters))
- `region` (String) The resource region. If not defined, the provider region is used.

### Read-Only

- `cf_guid` (String)
- `cf_organization_guid` (String)
- `cf_space_guid` (String)
- `dashboard_url` (String)
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`instance_id`".
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`instance_id`".
- `image_url` (String)
- `instance_id` (String) ID of the MariaDB instance.
- `plan_id` (String) The selected plan ID.
Expand Down Expand Up @@ -73,6 +74,6 @@ In Terraform v1.5.0 and later, the [` + "`" + `import` + "`" + ` block](https://
# Only use the import statement, if you want to import an existing mariadb instance
import {
to = stackit_mariadb_instance.import-example
id = "${var.project_id},${var.mariadb_instance_id}"
id = "${var.project_id},${var.region},${var.mariadb_instance_id}"
}
```
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Only use the import statement, if you want to import an existing mariadb credential
import {
to = stackit_mariadb_credential.import-example
id = "${var.project_id},${var.mariadb_instance_id},${var.mariadb_credential_id}"
id = "${var.project_id},${var.region},${var.mariadb_instance_id},${var.mariadb_credential_id}"
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Only use the import statement, if you want to import an existing mariadb instance
import {
to = stackit_mariadb_instance.import-example
id = "${var.project_id},${var.mariadb_instance_id}"
id = "${var.project_id},${var.region},${var.mariadb_instance_id}"
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ require (
github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v1.15.0
github.com/stackitcloud/stackit-sdk-go/services/logme v1.0.1
github.com/stackitcloud/stackit-sdk-go/services/logs v0.10.0
github.com/stackitcloud/stackit-sdk-go/services/mariadb v1.0.1
github.com/stackitcloud/stackit-sdk-go/services/mariadb v1.1.0
github.com/stackitcloud/stackit-sdk-go/services/modelserving v0.11.0
github.com/stackitcloud/stackit-sdk-go/services/mongodbflex v1.12.0
github.com/stackitcloud/stackit-sdk-go/services/objectstorage v1.9.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -700,8 +700,8 @@ github.com/stackitcloud/stackit-sdk-go/services/logme v1.0.1 h1:iteL61eMMPWT6872
github.com/stackitcloud/stackit-sdk-go/services/logme v1.0.1/go.mod h1:JDOOYaGgcBts2x52nKPRMFgSZe7qqOFmfz1xIXCQgRY=
github.com/stackitcloud/stackit-sdk-go/services/logs v0.10.0 h1:g7zpfQFFq3UhAWrMK9rPaZY6dLMAuMJf5g6+r7VRTXc=
github.com/stackitcloud/stackit-sdk-go/services/logs v0.10.0/go.mod h1:tvRejL8w5KpGBbLFPQ+dXOJURgZ3OMbZmwxlKQrGMuA=
github.com/stackitcloud/stackit-sdk-go/services/mariadb v1.0.1 h1:Ll1erKKms7OnFva3bRXOs9PEYLoWJp5prSg985K0glk=
github.com/stackitcloud/stackit-sdk-go/services/mariadb v1.0.1/go.mod h1:joa89Y1dyn0j22FstRcIKfW2ada3FDxNfttxSvq27uY=
github.com/stackitcloud/stackit-sdk-go/services/mariadb v1.1.0 h1:3IZ3baztlqmkkDxwBfRymYTFeZa3AARVXYlt3hohfPs=
github.com/stackitcloud/stackit-sdk-go/services/mariadb v1.1.0/go.mod h1:joa89Y1dyn0j22FstRcIKfW2ada3FDxNfttxSvq27uY=
github.com/stackitcloud/stackit-sdk-go/services/modelserving v0.11.0 h1:LfcQ++Z8a13jrJ5NOaCY/hwToh/e+QJj0eS6rd6s6k8=
github.com/stackitcloud/stackit-sdk-go/services/modelserving v0.11.0/go.mod h1:u7T85YqoqncJevbPU1ODKthbmxxEh1zw+bVaAO8v0Sg=
github.com/stackitcloud/stackit-sdk-go/services/mongodbflex v1.12.0 h1:SVd3WMmLAE0Jxk2SaRuM85DTOOXHycyMpZGx9vzqNkI=
Expand Down
43 changes: 29 additions & 14 deletions stackit/internal/services/mariadb/credential/datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ import (

"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
mariadb "github.com/stackitcloud/stackit-sdk-go/services/mariadb/v1api"
mariadb "github.com/stackitcloud/stackit-sdk-go/services/mariadb/v2api"
)

// Ensure the implementation satisfies the expected interfaces.
var (
_ datasource.DataSource = &credentialDataSource{}
_ datasource.DataSource = &credentialDataSource{}
_ datasource.DataSourceWithConfigure = &credentialDataSource{}
)

type DataSourceModel struct {
Expand All @@ -38,6 +39,7 @@ type DataSourceModel struct {
Port types.Int32 `tfsdk:"port"`
Uri types.String `tfsdk:"uri"`
Username types.String `tfsdk:"username"`
Region types.String `tfsdk:"region"`
}

// NewCredentialDataSource is a helper function to simplify the provider implementation.
Expand All @@ -47,37 +49,40 @@ func NewCredentialDataSource() datasource.DataSource {

// credentialDataSource is the data source implementation.
type credentialDataSource struct {
client *mariadb.APIClient
client *mariadb.APIClient
providerData core.ProviderData
}

// Metadata returns the data source type name.
func (r *credentialDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
func (d *credentialDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_mariadb_credential"
}

// Configure adds the provider configured client to the data source.
func (r *credentialDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
providerData, ok := conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
func (d *credentialDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
var ok bool
d.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
if !ok {
return
}

apiClient := mariadbUtils.ConfigureClient(ctx, &providerData, &resp.Diagnostics)
apiClient := mariadbUtils.ConfigureClient(ctx, &d.providerData, &resp.Diagnostics)
if resp.Diagnostics.HasError() {
return
}
r.client = apiClient
d.client = apiClient
tflog.Info(ctx, "mariadb credential client configured")
}

// Schema defines the schema for the data source.
func (r *credentialDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
func (d *credentialDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
descriptions := map[string]string{ //nolint:gosec // description for credential id
"main": "MariaDB credential data source schema. Must have a `region` specified in the provider configuration.",
"id": "Terraform's internal data source. identifier. It is structured as \"`project_id`,`instance_id`,`credential_id`\".",
"id": "Terraform's internal data source. identifier. It is structured as \"`project_id`,`region`,`instance_id`,`credential_id`\".",
"credential_id": "The credential's ID.",
"instance_id": "ID of the MariaDB instance.",
"project_id": "STACKIT project ID to which the instance is associated.",
"region": "The resource region. If not defined, the provider region is used.",
}

resp.Schema = schema.Schema{
Expand Down Expand Up @@ -135,12 +140,18 @@ func (r *credentialDataSource) Schema(_ context.Context, _ datasource.SchemaRequ
"username": schema.StringAttribute{
Computed: true,
},
"region": schema.StringAttribute{
Optional: true,
// must be computed to allow for storing the override value from the provider
Computed: true,
Description: descriptions["region"],
},
},
}
}

// Read refreshes the Terraform state with the latest data.
func (r *credentialDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { // nolint:gocritic // function signature required by Terraform
func (d *credentialDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { // nolint:gocritic // function signature required by Terraform
var model DataSourceModel
diags := req.Config.Get(ctx, &model)
resp.Diagnostics.Append(diags...)
Expand All @@ -151,13 +162,15 @@ func (r *credentialDataSource) Read(ctx context.Context, req datasource.ReadRequ
ctx = core.InitProviderContext(ctx)

projectId := model.ProjectId.ValueString()
region := d.providerData.GetRegionWithOverride(model.Region)
instanceId := model.InstanceId.ValueString()
credentialId := model.CredentialId.ValueString()
ctx = tflog.SetField(ctx, "project_id", projectId)
ctx = tflog.SetField(ctx, "region", region)
ctx = tflog.SetField(ctx, "instance_id", instanceId)
ctx = tflog.SetField(ctx, "credential_id", credentialId)

recordSetResp, err := r.client.DefaultAPI.GetCredentials(ctx, projectId, instanceId, credentialId).Execute()
recordSetResp, err := d.client.DefaultAPI.GetCredentials(ctx, projectId, region, instanceId, credentialId).Execute()
if err != nil {
utils.LogError(
ctx,
Expand All @@ -176,7 +189,7 @@ func (r *credentialDataSource) Read(ctx context.Context, req datasource.ReadRequ
ctx = core.LogResponse(ctx)

// Map response body to schema
err = mapDataSourceFields(ctx, recordSetResp, &model)
err = mapDataSourceFields(ctx, recordSetResp, &model, region)
if err != nil {
core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading credential", fmt.Sprintf("Processing API payload: %v", err))
return
Expand All @@ -191,7 +204,7 @@ func (r *credentialDataSource) Read(ctx context.Context, req datasource.ReadRequ
tflog.Info(ctx, "mariadb credential read")
}

func mapDataSourceFields(ctx context.Context, credentialsResp *mariadb.CredentialsResponse, model *DataSourceModel) error {
func mapDataSourceFields(ctx context.Context, credentialsResp *mariadb.CredentialsResponse, model *DataSourceModel, region string) error {
if credentialsResp == nil {
return fmt.Errorf("response input is nil")
}
Expand All @@ -214,9 +227,11 @@ func mapDataSourceFields(ctx context.Context, credentialsResp *mariadb.Credentia

model.Id = utils.BuildInternalTerraformId(
model.ProjectId.ValueString(),
region,
model.InstanceId.ValueString(),
credentialId,
)
model.Region = types.StringValue(region)

modelHosts, err := utils.ListValueToStringSlice(model.Hosts)
if err != nil {
Expand Down
17 changes: 11 additions & 6 deletions stackit/internal/services/mariadb/credential/datasource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ package mariadb

import (
"context"
"fmt"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/types"
mariadb "github.com/stackitcloud/stackit-sdk-go/services/mariadb/v1api"
mariadb "github.com/stackitcloud/stackit-sdk-go/services/mariadb/v2api"
)

func TestMapDataSourceFields(t *testing.T) {
Expand All @@ -29,7 +30,7 @@ func TestMapDataSourceFields(t *testing.T) {
Raw: &mariadb.RawCredentials{},
},
DataSourceModel{
Id: types.StringValue("pid,iid,cid"),
Id: types.StringValue(fmt.Sprintf("pid,%s,iid,cid", testRegion)),
CredentialId: types.StringValue("cid"),
InstanceId: types.StringValue("iid"),
ProjectId: types.StringValue("pid"),
Expand All @@ -40,6 +41,7 @@ func TestMapDataSourceFields(t *testing.T) {
Port: types.Int32Null(),
Uri: types.StringNull(),
Username: types.StringValue(""),
Region: types.StringValue(testRegion),
},
true,
},
Expand Down Expand Up @@ -67,7 +69,7 @@ func TestMapDataSourceFields(t *testing.T) {
},
},
DataSourceModel{
Id: types.StringValue("pid,iid,cid"),
Id: types.StringValue(fmt.Sprintf("pid,%s,iid,cid", testRegion)),
CredentialId: types.StringValue("cid"),
InstanceId: types.StringValue("iid"),
ProjectId: types.StringValue("pid"),
Expand All @@ -81,6 +83,7 @@ func TestMapDataSourceFields(t *testing.T) {
Port: types.Int32Value(1234),
Uri: types.StringValue("uri"),
Username: types.StringValue("username"),
Region: types.StringValue(testRegion),
},
true,
},
Expand Down Expand Up @@ -114,7 +117,7 @@ func TestMapDataSourceFields(t *testing.T) {
},
},
DataSourceModel{
Id: types.StringValue("pid,iid,cid"),
Id: types.StringValue(fmt.Sprintf("pid,%s,iid,cid", testRegion)),
CredentialId: types.StringValue("cid"),
InstanceId: types.StringValue("iid"),
ProjectId: types.StringValue("pid"),
Expand All @@ -129,6 +132,7 @@ func TestMapDataSourceFields(t *testing.T) {
Port: types.Int32Value(1234),
Uri: types.StringValue("uri"),
Username: types.StringValue("username"),
Region: types.StringValue(testRegion),
},
true,
},
Expand All @@ -153,7 +157,7 @@ func TestMapDataSourceFields(t *testing.T) {
},
},
DataSourceModel{
Id: types.StringValue("pid,iid,cid"),
Id: types.StringValue(fmt.Sprintf("pid,%s,iid,cid", testRegion)),
CredentialId: types.StringValue("cid"),
InstanceId: types.StringValue("iid"),
ProjectId: types.StringValue("pid"),
Expand All @@ -164,6 +168,7 @@ func TestMapDataSourceFields(t *testing.T) {
Port: types.Int32Value(2123456789),
Uri: types.StringNull(),
Username: types.StringValue(""),
Region: types.StringValue(testRegion),
},
true,
},
Expand Down Expand Up @@ -202,7 +207,7 @@ func TestMapDataSourceFields(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
err := mapDataSourceFields(context.Background(), tt.input, &tt.state)
err := mapDataSourceFields(context.Background(), tt.input, &tt.state, testRegion)
if !tt.isValid && err == nil {
t.Fatalf("Should have failed")
}
Expand Down
Loading
Loading