fix: fix sqlserverflexalpha (#61)
## Description
<!-- **Please link some issue here describing what you are trying to achieve.**
In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->
relates to #1234
## Checklist
- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)
Reviewed-on: #61
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
This commit is contained in:
parent
d90236b02e
commit
55a0917a86
25 changed files with 1973 additions and 2504 deletions
1
go.mod
1
go.mod
|
|
@ -18,7 +18,6 @@ require (
|
||||||
github.com/spf13/cobra v1.10.2
|
github.com/spf13/cobra v1.10.2
|
||||||
github.com/stackitcloud/stackit-sdk-go/core v0.21.0
|
github.com/stackitcloud/stackit-sdk-go/core v0.21.0
|
||||||
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.23-alpha
|
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.23-alpha
|
||||||
github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v1.4.1
|
|
||||||
github.com/teambition/rrule-go v1.8.2
|
github.com/teambition/rrule-go v1.8.2
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
|
||||||
2
go.sum
2
go.sum
|
|
@ -174,8 +174,6 @@ github.com/stackitcloud/stackit-sdk-go/core v0.21.0 h1:QXZqiaO7U/4IpTkJfzt4dt6Qx
|
||||||
github.com/stackitcloud/stackit-sdk-go/core v0.21.0/go.mod h1:fqto7M82ynGhEnpZU6VkQKYWYoFG5goC076JWXTUPRQ=
|
github.com/stackitcloud/stackit-sdk-go/core v0.21.0/go.mod h1:fqto7M82ynGhEnpZU6VkQKYWYoFG5goC076JWXTUPRQ=
|
||||||
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.23-alpha h1:ugpMOMUZGB0yXsWcfe97F7GCdjlexbjFuGD8ZeyMSts=
|
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.23-alpha h1:ugpMOMUZGB0yXsWcfe97F7GCdjlexbjFuGD8ZeyMSts=
|
||||||
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.23-alpha/go.mod h1:v5VGvTxLcCdJJmblbhqYalt/MFHcElDfYoy15CMhaWs=
|
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.23-alpha/go.mod h1:v5VGvTxLcCdJJmblbhqYalt/MFHcElDfYoy15CMhaWs=
|
||||||
github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v1.4.1 h1:6MJdy1xmdE+uOo/F8mR5HSldjPSHpdhwuqS3u9m2EWQ=
|
|
||||||
github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v1.4.1/go.mod h1:XLr3ZfrT1g8ZZMm7A6RXOPBuhBkikdUN2o/+/Y+Hu+g=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||||
|
|
|
||||||
|
|
@ -10,34 +10,34 @@ import (
|
||||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||||
|
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||||
sqlserverflexalphaGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/database/datasources_gen"
|
|
||||||
sqlserverflexUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/utils"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
||||||
)
|
|
||||||
|
|
||||||
// dataSourceModel maps the data source schema data.
|
sqlserverflexalphaPkg "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
||||||
type dataSourceModel struct {
|
sqlserverflexalphaGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/database/datasources_gen"
|
||||||
sqlserverflexalphaGen.DatabaseModel
|
)
|
||||||
TerraformID types.String `tfsdk:"id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ datasource.DataSource = (*databaseDataSource)(nil)
|
var _ datasource.DataSource = (*databaseDataSource)(nil)
|
||||||
|
|
||||||
// NewDatabaseDataSource creates a new database data source.
|
const errorPrefix = "[sqlserverflexalpha - Database]"
|
||||||
|
|
||||||
func NewDatabaseDataSource() datasource.DataSource {
|
func NewDatabaseDataSource() datasource.DataSource {
|
||||||
return &databaseDataSource{}
|
return &databaseDataSource{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type dataSourceModel struct {
|
||||||
|
sqlserverflexalphaGen.DatabaseModel
|
||||||
|
TerraformId types.String `tfsdk:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
type databaseDataSource struct {
|
type databaseDataSource struct {
|
||||||
client *sqlserverflexalpha.APIClient
|
client *sqlserverflexalphaPkg.APIClient
|
||||||
providerData core.ProviderData
|
providerData core.ProviderData
|
||||||
}
|
}
|
||||||
|
|
||||||
// Metadata returns the data source type name.
|
|
||||||
func (d *databaseDataSource) Metadata(
|
func (d *databaseDataSource) Metadata(
|
||||||
_ context.Context,
|
_ context.Context,
|
||||||
req datasource.MetadataRequest,
|
req datasource.MetadataRequest,
|
||||||
|
|
@ -46,16 +46,13 @@ func (d *databaseDataSource) Metadata(
|
||||||
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_database"
|
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_database"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schema defines the data source schema.
|
|
||||||
func (d *databaseDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
func (d *databaseDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
||||||
s := sqlserverflexalphaGen.DatabaseDataSourceSchema(ctx)
|
resp.Schema = sqlserverflexalphaGen.DatabaseDataSourceSchema(ctx)
|
||||||
s.Attributes["id"] = schema.StringAttribute{
|
resp.Schema.Attributes["id"] = schema.StringAttribute{
|
||||||
Description: "Terraform's internal resource ID. It is structured as \\\"`project_id`,`region`,`instance_id`," +
|
Computed: true,
|
||||||
"`database_id`\\\".\",",
|
Description: "The terraform internal identifier.",
|
||||||
Computed: true,
|
MarkdownDescription: "The terraform internal identifier.",
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.Schema = s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure adds the provider configured client to the data source.
|
// Configure adds the provider configured client to the data source.
|
||||||
|
|
@ -70,19 +67,41 @@ func (d *databaseDataSource) Configure(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiClient := sqlserverflexUtils.ConfigureClient(ctx, &d.providerData, &resp.Diagnostics)
|
apiClientConfigOptions := []config.ConfigurationOption{
|
||||||
if resp.Diagnostics.HasError() {
|
config.WithCustomAuth(d.providerData.RoundTripper),
|
||||||
|
utils.UserAgentConfigOption(d.providerData.Version),
|
||||||
|
}
|
||||||
|
if d.providerData.SQLServerFlexCustomEndpoint != "" {
|
||||||
|
apiClientConfigOptions = append(
|
||||||
|
apiClientConfigOptions,
|
||||||
|
config.WithEndpoint(d.providerData.SQLServerFlexCustomEndpoint),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
apiClientConfigOptions = append(
|
||||||
|
apiClientConfigOptions,
|
||||||
|
config.WithRegion(d.providerData.GetRegion()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
apiClient, err := sqlserverflexalphaPkg.NewAPIClient(apiClientConfigOptions...)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Error configuring API client",
|
||||||
|
fmt.Sprintf(
|
||||||
|
"Configuring client: %v. This is an error related to the provider configuration, not to the resource configuration",
|
||||||
|
err,
|
||||||
|
),
|
||||||
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
d.client = apiClient
|
d.client = apiClient
|
||||||
tflog.Info(ctx, "SQL SERVER Flex alpha database client configured")
|
tflog.Info(ctx, fmt.Sprintf("%s client configured", errorPrefix))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read retrieves the resource's state from the API.
|
|
||||||
func (d *databaseDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
func (d *databaseDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
||||||
var model dataSourceModel
|
var data dataSourceModel
|
||||||
diags := req.Config.Get(ctx, &model)
|
// Read Terraform configuration data into the model
|
||||||
resp.Diagnostics.Append(diags...)
|
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
|
||||||
|
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -90,22 +109,17 @@ func (d *databaseDataSource) Read(ctx context.Context, req datasource.ReadReques
|
||||||
ctx = core.InitProviderContext(ctx)
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
// Extract identifiers from the plan
|
// Extract identifiers from the plan
|
||||||
projectId := model.ProjectId.ValueString()
|
projectId := data.ProjectId.ValueString()
|
||||||
instanceId := model.InstanceId.ValueString()
|
region := d.providerData.GetRegionWithOverride(data.Region)
|
||||||
region := d.providerData.GetRegionWithOverride(model.Region)
|
instanceId := data.InstanceId.ValueString()
|
||||||
databaseName := model.DatabaseName.ValueString()
|
|
||||||
|
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
ctx = tflog.SetField(ctx, "region", region)
|
||||||
ctx = tflog.SetField(ctx, "database_name", databaseName)
|
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
||||||
|
|
||||||
|
databaseName := data.DatabaseName.ValueString()
|
||||||
|
|
||||||
// Fetch database from the API
|
|
||||||
databaseResp, err := d.client.GetDatabaseRequest(ctx, projectId, region, instanceId, databaseName).Execute()
|
databaseResp, err := d.client.GetDatabaseRequest(ctx, projectId, region, instanceId, databaseName).Execute()
|
||||||
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handleReadError(ctx, &resp.Diagnostics, err, projectId, instanceId)
|
handleReadError(ctx, &resp.Diagnostics, err, projectId, instanceId)
|
||||||
resp.State.RemoveResource(ctx)
|
resp.State.RemoveResource(ctx)
|
||||||
|
|
@ -113,9 +127,8 @@ func (d *databaseDataSource) Read(ctx context.Context, req datasource.ReadReques
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = core.LogResponse(ctx)
|
ctx = core.LogResponse(ctx)
|
||||||
|
|
||||||
// Map response body to schema and populate Computed attribute values
|
// Map response body to schema and populate Computed attribute values
|
||||||
err = mapFields(databaseResp, &model, region)
|
err = mapFields(databaseResp, &data, region)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
ctx,
|
ctx,
|
||||||
|
|
@ -126,14 +139,11 @@ func (d *databaseDataSource) Read(ctx context.Context, req datasource.ReadReques
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set refreshed state
|
// Save data into Terraform state
|
||||||
diags = resp.State.Set(ctx, model)
|
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||||
resp.Diagnostics.Append(diags...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
tflog.Info(ctx, "SQL Server Flex beta database read")
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tflog.Info(ctx, "SQL Server Flex alpha database read")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleReadError centralizes API error handling for the Read operation.
|
// handleReadError centralizes API error handling for the Read operation.
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ func mapFields(source *sqlserverflexalpha.GetDatabaseResponse, model *dataSource
|
||||||
model.CompatibilityLevel = types.Int64Value(source.GetCompatibilityLevel())
|
model.CompatibilityLevel = types.Int64Value(source.GetCompatibilityLevel())
|
||||||
model.CollationName = types.StringValue(source.GetCollationName())
|
model.CollationName = types.StringValue(source.GetCollationName())
|
||||||
|
|
||||||
model.TerraformID = utils.BuildInternalTerraformId(
|
model.TerraformId = utils.BuildInternalTerraformId(
|
||||||
model.ProjectId.ValueString(),
|
model.ProjectId.ValueString(),
|
||||||
region,
|
region,
|
||||||
model.InstanceId.ValueString(),
|
model.InstanceId.ValueString(),
|
||||||
|
|
@ -80,6 +80,12 @@ func mapResourceFields(source *sqlserverflexalpha.GetDatabaseResponse, model *re
|
||||||
model.ProjectId = types.StringValue(model.ProjectId.ValueString())
|
model.ProjectId = types.StringValue(model.ProjectId.ValueString())
|
||||||
model.InstanceId = types.StringValue(model.InstanceId.ValueString())
|
model.InstanceId = types.StringValue(model.InstanceId.ValueString())
|
||||||
|
|
||||||
|
model.Compatibility = types.Int64Value(source.GetCompatibilityLevel())
|
||||||
|
model.CompatibilityLevel = types.Int64Value(source.GetCompatibilityLevel())
|
||||||
|
|
||||||
|
model.Collation = types.StringValue(source.GetCollationName()) // it does not come back from api
|
||||||
|
model.CollationName = types.StringValue(source.GetCollationName())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ func TestMapFields(t *testing.T) {
|
||||||
Name: utils.Ptr("my-db"),
|
Name: utils.Ptr("my-db"),
|
||||||
CollationName: utils.Ptr("collation"),
|
CollationName: utils.Ptr("collation"),
|
||||||
CompatibilityLevel: utils.Ptr(int64(150)),
|
CompatibilityLevel: utils.Ptr(int64(150)),
|
||||||
Owner: utils.Ptr("\"my-owner\""),
|
Owner: utils.Ptr("my-owner"),
|
||||||
},
|
},
|
||||||
model: &dataSourceModel{
|
model: &dataSourceModel{
|
||||||
DatabaseModel: datasource.DatabaseModel{
|
DatabaseModel: datasource.DatabaseModel{
|
||||||
|
|
@ -58,7 +58,7 @@ func TestMapFields(t *testing.T) {
|
||||||
CompatibilityLevel: types.Int64Value(150),
|
CompatibilityLevel: types.Int64Value(150),
|
||||||
CollationName: types.StringValue("collation"),
|
CollationName: types.StringValue("collation"),
|
||||||
},
|
},
|
||||||
TerraformID: types.StringValue("my-project,eu01,my-instance,my-db"),
|
TerraformId: types.StringValue("my-project,eu01,my-instance,my-db"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -127,7 +127,7 @@ func TestMapResourceFields(t *testing.T) {
|
||||||
source: &sqlserverflexalpha.GetDatabaseResponse{
|
source: &sqlserverflexalpha.GetDatabaseResponse{
|
||||||
Id: utils.Ptr(int64(1)),
|
Id: utils.Ptr(int64(1)),
|
||||||
Name: utils.Ptr("my-db"),
|
Name: utils.Ptr("my-db"),
|
||||||
Owner: utils.Ptr("\"my-owner\""),
|
Owner: utils.Ptr("my-owner"),
|
||||||
},
|
},
|
||||||
model: &resourceModel{
|
model: &resourceModel{
|
||||||
ProjectId: types.StringValue("my-project"),
|
ProjectId: types.StringValue("my-project"),
|
||||||
|
|
@ -137,13 +137,17 @@ func TestMapResourceFields(t *testing.T) {
|
||||||
},
|
},
|
||||||
expected: expected{
|
expected: expected{
|
||||||
model: &resourceModel{
|
model: &resourceModel{
|
||||||
Id: types.Int64Value(1),
|
Id: types.Int64Value(1),
|
||||||
Name: types.StringValue("my-db"),
|
Name: types.StringValue("my-db"),
|
||||||
DatabaseName: types.StringValue("my-db"),
|
Compatibility: types.Int64Value(0),
|
||||||
InstanceId: types.StringValue("my-instance"),
|
CompatibilityLevel: types.Int64Value(0),
|
||||||
ProjectId: types.StringValue("my-project"),
|
Collation: types.StringValue(""),
|
||||||
Region: types.StringValue("eu01"),
|
CollationName: types.StringValue(""),
|
||||||
Owner: types.StringValue("my-owner"),
|
DatabaseName: types.StringValue("my-db"),
|
||||||
|
InstanceId: types.StringValue("my-instance"),
|
||||||
|
ProjectId: types.StringValue("my-project"),
|
||||||
|
Region: types.StringValue("eu01"),
|
||||||
|
Owner: types.StringValue("my-owner"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ fields:
|
||||||
|
|
||||||
- name: 'owner'
|
- name: 'owner'
|
||||||
modifiers:
|
modifiers:
|
||||||
- 'RequiresReplace'
|
- 'UseStateForUnknown'
|
||||||
|
|
||||||
- name: 'database_name'
|
- name: 'database_name'
|
||||||
modifiers:
|
modifiers:
|
||||||
|
|
@ -43,6 +43,7 @@ fields:
|
||||||
|
|
||||||
- name: 'compatibility'
|
- name: 'compatibility'
|
||||||
modifiers:
|
modifiers:
|
||||||
|
- 'UseStateForUnknown'
|
||||||
- 'RequiresReplace'
|
- 'RequiresReplace'
|
||||||
|
|
||||||
- name: 'compatibility_level'
|
- name: 'compatibility_level'
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
|
|
@ -19,11 +19,12 @@ import (
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
||||||
|
wait "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/wait/sqlserverflexalpha"
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
||||||
|
|
||||||
sqlserverflexalphaGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/database/resources_gen"
|
sqlserverflexalphaResGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/database/resources_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -46,9 +47,13 @@ func NewDatabaseResource() resource.Resource {
|
||||||
}
|
}
|
||||||
|
|
||||||
// resourceModel describes the resource data model.
|
// resourceModel describes the resource data model.
|
||||||
type resourceModel = sqlserverflexalphaGen.DatabaseModel
|
type resourceModel = sqlserverflexalphaResGen.DatabaseModel
|
||||||
|
|
||||||
|
type databaseResource struct {
|
||||||
|
client *sqlserverflexalpha.APIClient
|
||||||
|
providerData core.ProviderData
|
||||||
|
}
|
||||||
|
|
||||||
// DatabaseResourceIdentityModel describes the resource's identity attributes.
|
|
||||||
type DatabaseResourceIdentityModel struct {
|
type DatabaseResourceIdentityModel struct {
|
||||||
ProjectID types.String `tfsdk:"project_id"`
|
ProjectID types.String `tfsdk:"project_id"`
|
||||||
Region types.String `tfsdk:"region"`
|
Region types.String `tfsdk:"region"`
|
||||||
|
|
@ -56,12 +61,11 @@ type DatabaseResourceIdentityModel struct {
|
||||||
DatabaseName types.String `tfsdk:"database_name"`
|
DatabaseName types.String `tfsdk:"database_name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type databaseResource struct {
|
func (r *databaseResource) Metadata(
|
||||||
client *sqlserverflexalpha.APIClient
|
_ context.Context,
|
||||||
providerData core.ProviderData
|
req resource.MetadataRequest,
|
||||||
}
|
resp *resource.MetadataResponse,
|
||||||
|
) {
|
||||||
func (r *databaseResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
|
||||||
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_database"
|
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_database"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,7 +73,7 @@ func (r *databaseResource) Metadata(_ context.Context, req resource.MetadataRequ
|
||||||
var modifiersFileByte []byte
|
var modifiersFileByte []byte
|
||||||
|
|
||||||
func (r *databaseResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
|
func (r *databaseResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||||
s := sqlserverflexalphaGen.DatabaseResourceSchema(ctx)
|
s := sqlserverflexalphaResGen.DatabaseResourceSchema(ctx)
|
||||||
|
|
||||||
fields, err := utils.ReadModifiersConfig(modifiersFileByte)
|
fields, err := utils.ReadModifiersConfig(modifiersFileByte)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -124,10 +128,10 @@ func (r *databaseResource) Configure(
|
||||||
config.WithCustomAuth(r.providerData.RoundTripper),
|
config.WithCustomAuth(r.providerData.RoundTripper),
|
||||||
utils.UserAgentConfigOption(r.providerData.Version),
|
utils.UserAgentConfigOption(r.providerData.Version),
|
||||||
}
|
}
|
||||||
if r.providerData.PostgresFlexCustomEndpoint != "" {
|
if r.providerData.SQLServerFlexCustomEndpoint != "" {
|
||||||
apiClientConfigOptions = append(
|
apiClientConfigOptions = append(
|
||||||
apiClientConfigOptions,
|
apiClientConfigOptions,
|
||||||
config.WithEndpoint(r.providerData.PostgresFlexCustomEndpoint),
|
config.WithEndpoint(r.providerData.SQLServerFlexCustomEndpoint),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
apiClientConfigOptions = append(apiClientConfigOptions, config.WithRegion(r.providerData.GetRegion()))
|
apiClientConfigOptions = append(apiClientConfigOptions, config.WithRegion(r.providerData.GetRegion()))
|
||||||
|
|
@ -148,50 +152,74 @@ func (r *databaseResource) Configure(
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *databaseResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
func (r *databaseResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||||
var model resourceModel
|
var data resourceModel
|
||||||
|
createErr := "DB create error"
|
||||||
|
|
||||||
|
// Read Terraform plan data into the model
|
||||||
|
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
|
||||||
|
|
||||||
diags := req.Plan.Get(ctx, &model)
|
|
||||||
resp.Diagnostics.Append(diags...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
projectId := model.ProjectId.ValueString()
|
projectId := data.ProjectId.ValueString()
|
||||||
region := model.Region.ValueString()
|
region := data.Region.ValueString()
|
||||||
instanceId := model.InstanceId.ValueString()
|
instanceId := data.InstanceId.ValueString()
|
||||||
|
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
ctx = tflog.SetField(ctx, "region", region)
|
||||||
|
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
||||||
|
|
||||||
// Generate API request body from model
|
databaseName := data.Name.ValueString()
|
||||||
payload, err := toCreatePayload(&model)
|
ctx = tflog.SetField(ctx, "database_name", databaseName)
|
||||||
|
|
||||||
|
payLoad := sqlserverflexalpha.CreateDatabaseRequestPayload{}
|
||||||
|
if !data.Collation.IsNull() && !data.Collation.IsUnknown() {
|
||||||
|
payLoad.Collation = data.Collation.ValueStringPointer()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !data.Compatibility.IsNull() && !data.Compatibility.IsUnknown() {
|
||||||
|
payLoad.Compatibility = data.Compatibility.ValueInt64Pointer()
|
||||||
|
}
|
||||||
|
|
||||||
|
payLoad.Name = data.Name.ValueStringPointer()
|
||||||
|
payLoad.Owner = data.Owner.ValueStringPointer()
|
||||||
|
|
||||||
|
_, err := wait.WaitForUserWaitHandler(
|
||||||
|
ctx,
|
||||||
|
r.client,
|
||||||
|
projectId,
|
||||||
|
instanceId,
|
||||||
|
region,
|
||||||
|
data.Owner.ValueString(),
|
||||||
|
).
|
||||||
|
SetSleepBeforeWait(10 * time.Second).
|
||||||
|
WaitWithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
ctx,
|
ctx,
|
||||||
&resp.Diagnostics,
|
&resp.Diagnostics,
|
||||||
"Error creating database",
|
createErr,
|
||||||
fmt.Sprintf("Creating API payload: %v", err),
|
fmt.Sprintf("Calling API: %v", err),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Create new database
|
|
||||||
databaseResp, err := r.client.CreateDatabaseRequest(
|
createResp, err := r.client.CreateDatabaseRequest(ctx, projectId, region, instanceId).
|
||||||
ctx,
|
CreateDatabaseRequestPayload(payLoad).
|
||||||
projectId,
|
Execute()
|
||||||
region,
|
|
||||||
instanceId,
|
|
||||||
).CreateDatabaseRequestPayload(*payload).Execute()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating database", fmt.Sprintf("Calling API: %v", err))
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
createErr,
|
||||||
|
fmt.Sprintf("Calling API: %v", err),
|
||||||
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = core.LogResponse(ctx)
|
if createResp == nil || createResp.Id == nil {
|
||||||
|
|
||||||
if databaseResp == nil || databaseResp.Id == nil {
|
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
ctx,
|
ctx,
|
||||||
&resp.Diagnostics,
|
&resp.Diagnostics,
|
||||||
|
|
@ -201,11 +229,9 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
databaseId := *databaseResp.Id
|
databaseId := *createResp.Id
|
||||||
databaseName := model.DatabaseName.String()
|
|
||||||
|
|
||||||
ctx = tflog.SetField(ctx, "database_id", databaseId)
|
ctx = tflog.SetField(ctx, "database_id", databaseId)
|
||||||
ctx = tflog.SetField(ctx, "database_name", databaseName)
|
|
||||||
|
|
||||||
ctx = core.LogResponse(ctx)
|
ctx = core.LogResponse(ctx)
|
||||||
|
|
||||||
|
|
@ -221,6 +247,69 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: is this necessary to wait for the database-> API say 200 ?
|
||||||
|
waitResp, err := wait.CreateDatabaseWaitHandler(
|
||||||
|
ctx,
|
||||||
|
r.client,
|
||||||
|
projectId,
|
||||||
|
instanceId,
|
||||||
|
region,
|
||||||
|
databaseName,
|
||||||
|
).SetSleepBeforeWait(
|
||||||
|
30 * time.Second,
|
||||||
|
).SetTimeout(
|
||||||
|
15 * time.Minute,
|
||||||
|
).WaitWithContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
createErr,
|
||||||
|
fmt.Sprintf("Database creation waiting: %v", err),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if waitResp.Id == nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
createErr,
|
||||||
|
"Database creation waiting: returned id is nil",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if *waitResp.Id != databaseId {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
createErr,
|
||||||
|
"Database creation waiting: returned id is different",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if *waitResp.Owner != data.Owner.ValueString() {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
createErr,
|
||||||
|
"Database creation waiting: returned owner is different",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if *waitResp.Name != data.Name.ValueString() {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
createErr,
|
||||||
|
"Database creation waiting: returned name is different",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
database, err := r.client.GetDatabaseRequest(ctx, projectId, region, instanceId, databaseName).Execute()
|
database, err := r.client.GetDatabaseRequest(ctx, projectId, region, instanceId, databaseName).Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
|
|
@ -233,7 +322,7 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map response body to schema
|
// Map response body to schema
|
||||||
err = mapResourceFields(database, &model, region)
|
err = mapResourceFields(database, &data, region)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
ctx,
|
ctx,
|
||||||
|
|
@ -245,11 +334,13 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set state to fully populated data
|
// Set state to fully populated data
|
||||||
resp.Diagnostics.Append(resp.State.Set(ctx, model)...)
|
resp.Diagnostics.Append(resp.State.Set(ctx, data)...)
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save data into Terraform state
|
||||||
|
|
||||||
tflog.Info(ctx, "sqlserverflexalpha.Database created")
|
tflog.Info(ctx, "sqlserverflexalpha.Database created")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -310,7 +401,7 @@ func (r *databaseResource) Read(ctx context.Context, req resource.ReadRequest, r
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set data returned by API in identity
|
// Save identity into Terraform state
|
||||||
identity := DatabaseResourceIdentityModel{
|
identity := DatabaseResourceIdentityModel{
|
||||||
ProjectID: types.StringValue(projectId),
|
ProjectID: types.StringValue(projectId),
|
||||||
Region: types.StringValue(region),
|
Region: types.StringValue(region),
|
||||||
|
|
@ -372,7 +463,13 @@ func (r *databaseResource) Delete(ctx context.Context, req resource.DeleteReques
|
||||||
// Delete existing record set
|
// Delete existing record set
|
||||||
err := r.client.DeleteDatabaseRequestExecute(ctx, projectId, region, instanceId, databaseName)
|
err := r.client.DeleteDatabaseRequestExecute(ctx, projectId, region, instanceId, databaseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting database", fmt.Sprintf("Calling API: %v", err))
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
"Error deleting database",
|
||||||
|
fmt.Sprintf(
|
||||||
|
"Calling API: %v\nname: %s, region: %s, instanceId: %s", err, databaseName, region, instanceId))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = core.LogResponse(ctx)
|
ctx = core.LogResponse(ctx)
|
||||||
|
|
@ -388,11 +485,13 @@ func (r *databaseResource) ModifyPlan(
|
||||||
req resource.ModifyPlanRequest,
|
req resource.ModifyPlanRequest,
|
||||||
resp *resource.ModifyPlanResponse,
|
resp *resource.ModifyPlanResponse,
|
||||||
) { // nolint:gocritic // function signature required by Terraform
|
) { // nolint:gocritic // function signature required by Terraform
|
||||||
var configModel resourceModel
|
|
||||||
// skip initial empty configuration to avoid follow-up errors
|
// skip initial empty configuration to avoid follow-up errors
|
||||||
if req.Config.Raw.IsNull() {
|
if req.Config.Raw.IsNull() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var configModel resourceModel
|
||||||
resp.Diagnostics.Append(req.Config.Get(ctx, &configModel)...)
|
resp.Diagnostics.Append(req.Config.Get(ctx, &configModel)...)
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
|
|
@ -409,6 +508,23 @@ func (r *databaseResource) ModifyPlan(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var identityModel DatabaseResourceIdentityModel
|
||||||
|
identityModel.ProjectID = planModel.ProjectId
|
||||||
|
identityModel.Region = planModel.Region
|
||||||
|
|
||||||
|
if !planModel.InstanceId.IsNull() && !planModel.InstanceId.IsUnknown() {
|
||||||
|
identityModel.InstanceID = planModel.InstanceId
|
||||||
|
}
|
||||||
|
|
||||||
|
if !planModel.Name.IsNull() && !planModel.Name.IsUnknown() {
|
||||||
|
identityModel.DatabaseName = planModel.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Diagnostics.Append(resp.Identity.Set(ctx, identityModel)...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
resp.Diagnostics.Append(resp.Plan.Set(ctx, planModel)...)
|
resp.Diagnostics.Append(resp.Plan.Set(ctx, planModel)...)
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
|
|
@ -416,7 +532,7 @@ func (r *databaseResource) ModifyPlan(
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImportState imports a resource into the Terraform state on success.
|
// ImportState imports a resource into the Terraform state on success.
|
||||||
// The expected import identifier format is: [project_id],[region],[instance_id],[database_id]
|
// The expected format of the resource import identifier is: project_id,zone_id,record_set_id
|
||||||
func (r *databaseResource) ImportState(
|
func (r *databaseResource) ImportState(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req resource.ImportStateRequest,
|
req resource.ImportStateRequest,
|
||||||
|
|
@ -432,36 +548,31 @@ func (r *databaseResource) ImportState(
|
||||||
ctx, &resp.Diagnostics,
|
ctx, &resp.Diagnostics,
|
||||||
"Error importing database",
|
"Error importing database",
|
||||||
fmt.Sprintf(
|
fmt.Sprintf(
|
||||||
"Expected import identifier with format [project_id],[region],[instance_id],[database_name], got %q",
|
"Expected import identifier with format: [project_id],[region],[instance_id],[database_name] Got: %q",
|
||||||
req.ID,
|
req.ID,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
databaseId, err := strconv.ParseInt(idParts[3], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
core.LogAndAddError(
|
|
||||||
ctx,
|
|
||||||
&resp.Diagnostics,
|
|
||||||
"Error importing database",
|
|
||||||
fmt.Sprintf("Invalid database_id format: %q. It must be a valid integer.", idParts[3]),
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), idParts[0])...)
|
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("region"), idParts[1])...)
|
||||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), idParts[2])...)
|
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), idParts[2])...)
|
||||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("database_name"), databaseId)...)
|
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("database_name"), idParts[3])...)
|
||||||
|
|
||||||
core.LogAndAddWarning(
|
var identityData DatabaseResourceIdentityModel
|
||||||
ctx,
|
identityData.ProjectID = types.StringValue(idParts[0])
|
||||||
&resp.Diagnostics,
|
identityData.Region = types.StringValue(idParts[1])
|
||||||
"Sqlserverflexalpha database imported with empty password",
|
identityData.InstanceID = types.StringValue(idParts[2])
|
||||||
"The database password is not imported as it is only available upon creation of a new database. The password field will be empty.",
|
identityData.DatabaseName = types.StringValue(idParts[3])
|
||||||
)
|
|
||||||
tflog.Info(ctx, "Sqlserverflexalpha database state imported")
|
resp.Diagnostics.Append(resp.Identity.Set(ctx, &identityData)...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tflog.Info(ctx, "sqlserverflexalpha database state imported")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no ID is provided, attempt to read identity attributes from the import configuration
|
// If no ID is provided, attempt to read identity attributes from the import configuration
|
||||||
|
|
@ -481,7 +592,7 @@ func (r *databaseResource) ImportState(
|
||||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), instanceId)...)
|
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), instanceId)...)
|
||||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("database_name"), databaseName)...)
|
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("database_name"), databaseName)...)
|
||||||
|
|
||||||
tflog.Info(ctx, "Sqlserverflexalpha database state imported")
|
tflog.Info(ctx, "sqlserverflexalpha database state imported")
|
||||||
}
|
}
|
||||||
|
|
||||||
// extractIdentityData extracts essential identifiers from the resource model, falling back to the identity model.
|
// extractIdentityData extracts essential identifiers from the resource model, falling back to the identity model.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package sqlserverFlexAlphaFlavor
|
package sqlserverflexalphaFlavor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -10,14 +10,14 @@ import (
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||||
|
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
||||||
|
|
||||||
|
sqlserverflexalphaPkg "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
||||||
sqlserverflexalphaGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/flavor/datasources_gen"
|
sqlserverflexalphaGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/flavor/datasources_gen"
|
||||||
sqlserverflexUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure the implementation satisfies the expected interfaces.
|
// Ensure the implementation satisfies the expected interfaces.
|
||||||
|
|
@ -26,11 +26,6 @@ var (
|
||||||
_ datasource.DataSourceWithConfigure = &flavorDataSource{}
|
_ datasource.DataSourceWithConfigure = &flavorDataSource{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewFlavorDataSource is a helper function to simplify the provider implementation.
|
|
||||||
func NewFlavorDataSource() datasource.DataSource {
|
|
||||||
return &flavorDataSource{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type FlavorModel struct {
|
type FlavorModel struct {
|
||||||
ProjectId types.String `tfsdk:"project_id"`
|
ProjectId types.String `tfsdk:"project_id"`
|
||||||
Region types.String `tfsdk:"region"`
|
Region types.String `tfsdk:"region"`
|
||||||
|
|
@ -46,39 +41,58 @@ type FlavorModel struct {
|
||||||
StorageClasses types.List `tfsdk:"storage_classes"`
|
StorageClasses types.List `tfsdk:"storage_classes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewFlavorDataSource is a helper function to simplify the provider implementation.
|
||||||
|
func NewFlavorDataSource() datasource.DataSource {
|
||||||
|
return &flavorDataSource{}
|
||||||
|
}
|
||||||
|
|
||||||
// flavorDataSource is the data source implementation.
|
// flavorDataSource is the data source implementation.
|
||||||
type flavorDataSource struct {
|
type flavorDataSource struct {
|
||||||
client *sqlserverflexalpha.APIClient
|
client *sqlserverflexalphaPkg.APIClient
|
||||||
providerData core.ProviderData
|
providerData core.ProviderData
|
||||||
}
|
}
|
||||||
|
|
||||||
// Metadata returns the data source type name.
|
// Metadata returns the data source type name.
|
||||||
func (r *flavorDataSource) Metadata(
|
func (r *flavorDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
|
||||||
_ context.Context,
|
|
||||||
req datasource.MetadataRequest,
|
|
||||||
resp *datasource.MetadataResponse,
|
|
||||||
) {
|
|
||||||
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_flavor"
|
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_flavor"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure adds the provider configured client to the data source.
|
// Configure adds the provider configured client to the data source.
|
||||||
func (r *flavorDataSource) Configure(
|
func (r *flavorDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
|
||||||
ctx context.Context,
|
|
||||||
req datasource.ConfigureRequest,
|
|
||||||
resp *datasource.ConfigureResponse,
|
|
||||||
) {
|
|
||||||
var ok bool
|
var ok bool
|
||||||
r.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
|
r.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiClient := sqlserverflexUtils.ConfigureClient(ctx, &r.providerData, &resp.Diagnostics)
|
apiClientConfigOptions := []config.ConfigurationOption{
|
||||||
if resp.Diagnostics.HasError() {
|
config.WithCustomAuth(r.providerData.RoundTripper),
|
||||||
|
utils.UserAgentConfigOption(r.providerData.Version),
|
||||||
|
}
|
||||||
|
if r.providerData.SQLServerFlexCustomEndpoint != "" {
|
||||||
|
apiClientConfigOptions = append(
|
||||||
|
apiClientConfigOptions,
|
||||||
|
config.WithEndpoint(r.providerData.SQLServerFlexCustomEndpoint),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
apiClientConfigOptions = append(
|
||||||
|
apiClientConfigOptions,
|
||||||
|
config.WithRegion(r.providerData.GetRegion()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
apiClient, err := sqlserverflexalphaPkg.NewAPIClient(apiClientConfigOptions...)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Error configuring API client",
|
||||||
|
fmt.Sprintf(
|
||||||
|
"Configuring client: %v. This is an error related to the provider configuration, not to the resource configuration",
|
||||||
|
err,
|
||||||
|
),
|
||||||
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.client = apiClient
|
r.client = apiClient
|
||||||
tflog.Info(ctx, "Postgres Flex instance client configured")
|
tflog.Info(ctx, "SQL Server Flex instance client configured")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *flavorDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
func (r *flavorDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
||||||
|
|
@ -86,13 +100,13 @@ func (r *flavorDataSource) Schema(ctx context.Context, _ datasource.SchemaReques
|
||||||
Attributes: map[string]schema.Attribute{
|
Attributes: map[string]schema.Attribute{
|
||||||
"project_id": schema.StringAttribute{
|
"project_id": schema.StringAttribute{
|
||||||
Required: true,
|
Required: true,
|
||||||
Description: "The cpu count of the instance.",
|
Description: "The project ID of the flavor.",
|
||||||
MarkdownDescription: "The cpu count of the instance.",
|
MarkdownDescription: "The project ID of the flavor.",
|
||||||
},
|
},
|
||||||
"region": schema.StringAttribute{
|
"region": schema.StringAttribute{
|
||||||
Required: true,
|
Required: true,
|
||||||
Description: "The flavor description.",
|
Description: "The region of the flavor.",
|
||||||
MarkdownDescription: "The flavor description.",
|
MarkdownDescription: "The region of the flavor.",
|
||||||
},
|
},
|
||||||
"cpu": schema.Int64Attribute{
|
"cpu": schema.Int64Attribute{
|
||||||
Required: true,
|
Required: true,
|
||||||
|
|
@ -109,6 +123,16 @@ func (r *flavorDataSource) Schema(ctx context.Context, _ datasource.SchemaReques
|
||||||
Description: "The memory of the instance in Gibibyte.",
|
Description: "The memory of the instance in Gibibyte.",
|
||||||
MarkdownDescription: "The memory of the instance in Gibibyte.",
|
MarkdownDescription: "The memory of the instance in Gibibyte.",
|
||||||
},
|
},
|
||||||
|
"node_type": schema.StringAttribute{
|
||||||
|
Required: true,
|
||||||
|
Description: "defines the nodeType it can be either single or HA",
|
||||||
|
MarkdownDescription: "defines the nodeType it can be either single or HA",
|
||||||
|
},
|
||||||
|
"flavor_id": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
Description: "The id of the instance flavor.",
|
||||||
|
MarkdownDescription: "The id of the instance flavor.",
|
||||||
|
},
|
||||||
"description": schema.StringAttribute{
|
"description": schema.StringAttribute{
|
||||||
Computed: true,
|
Computed: true,
|
||||||
Description: "The flavor description.",
|
Description: "The flavor description.",
|
||||||
|
|
@ -116,13 +140,8 @@ func (r *flavorDataSource) Schema(ctx context.Context, _ datasource.SchemaReques
|
||||||
},
|
},
|
||||||
"id": schema.StringAttribute{
|
"id": schema.StringAttribute{
|
||||||
Computed: true,
|
Computed: true,
|
||||||
Description: "The terraform id of the instance flavor.",
|
Description: "The id of the instance flavor.",
|
||||||
MarkdownDescription: "The terraform id of the instance flavor.",
|
MarkdownDescription: "The id of the instance flavor.",
|
||||||
},
|
|
||||||
"flavor_id": schema.StringAttribute{
|
|
||||||
Computed: true,
|
|
||||||
Description: "The flavor id of the instance flavor.",
|
|
||||||
MarkdownDescription: "The flavor id of the instance flavor.",
|
|
||||||
},
|
},
|
||||||
"max_gb": schema.Int64Attribute{
|
"max_gb": schema.Int64Attribute{
|
||||||
Computed: true,
|
Computed: true,
|
||||||
|
|
@ -134,13 +153,7 @@ func (r *flavorDataSource) Schema(ctx context.Context, _ datasource.SchemaReques
|
||||||
Description: "minimum storage which is required to order in Gigabyte.",
|
Description: "minimum storage which is required to order in Gigabyte.",
|
||||||
MarkdownDescription: "minimum storage which is required to order in Gigabyte.",
|
MarkdownDescription: "minimum storage which is required to order in Gigabyte.",
|
||||||
},
|
},
|
||||||
"node_type": schema.StringAttribute{
|
|
||||||
Required: true,
|
|
||||||
Description: "defines the nodeType it can be either single or replica",
|
|
||||||
MarkdownDescription: "defines the nodeType it can be either single or replica",
|
|
||||||
},
|
|
||||||
"storage_classes": schema.ListNestedAttribute{
|
"storage_classes": schema.ListNestedAttribute{
|
||||||
Computed: true,
|
|
||||||
NestedObject: schema.NestedAttributeObject{
|
NestedObject: schema.NestedAttributeObject{
|
||||||
Attributes: map[string]schema.Attribute{
|
Attributes: map[string]schema.Attribute{
|
||||||
"class": schema.StringAttribute{
|
"class": schema.StringAttribute{
|
||||||
|
|
@ -159,8 +172,89 @@ func (r *flavorDataSource) Schema(ctx context.Context, _ datasource.SchemaReques
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Computed: true,
|
||||||
|
Description: "maximum storage which can be ordered for the flavor in Gigabyte.",
|
||||||
|
MarkdownDescription: "maximum storage which can be ordered for the flavor in Gigabyte.",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
//Attributes: map[string]schema.Attribute{
|
||||||
|
// "project_id": schema.StringAttribute{
|
||||||
|
// Required: true,
|
||||||
|
// Description: "The cpu count of the instance.",
|
||||||
|
// MarkdownDescription: "The cpu count of the instance.",
|
||||||
|
// },
|
||||||
|
// "region": schema.StringAttribute{
|
||||||
|
// Required: true,
|
||||||
|
// Description: "The flavor description.",
|
||||||
|
// MarkdownDescription: "The flavor description.",
|
||||||
|
// },
|
||||||
|
// "cpu": schema.Int64Attribute{
|
||||||
|
// Required: true,
|
||||||
|
// Description: "The cpu count of the instance.",
|
||||||
|
// MarkdownDescription: "The cpu count of the instance.",
|
||||||
|
// },
|
||||||
|
// "ram": schema.Int64Attribute{
|
||||||
|
// Required: true,
|
||||||
|
// Description: "The memory of the instance in Gibibyte.",
|
||||||
|
// MarkdownDescription: "The memory of the instance in Gibibyte.",
|
||||||
|
// },
|
||||||
|
// "storage_class": schema.StringAttribute{
|
||||||
|
// Required: true,
|
||||||
|
// Description: "The memory of the instance in Gibibyte.",
|
||||||
|
// MarkdownDescription: "The memory of the instance in Gibibyte.",
|
||||||
|
// },
|
||||||
|
// "description": schema.StringAttribute{
|
||||||
|
// Computed: true,
|
||||||
|
// Description: "The flavor description.",
|
||||||
|
// MarkdownDescription: "The flavor description.",
|
||||||
|
// },
|
||||||
|
// "id": schema.StringAttribute{
|
||||||
|
// Computed: true,
|
||||||
|
// Description: "The terraform id of the instance flavor.",
|
||||||
|
// MarkdownDescription: "The terraform id of the instance flavor.",
|
||||||
|
// },
|
||||||
|
// "flavor_id": schema.StringAttribute{
|
||||||
|
// Computed: true,
|
||||||
|
// Description: "The flavor id of the instance flavor.",
|
||||||
|
// MarkdownDescription: "The flavor id of the instance flavor.",
|
||||||
|
// },
|
||||||
|
// "max_gb": schema.Int64Attribute{
|
||||||
|
// Computed: true,
|
||||||
|
// Description: "maximum storage which can be ordered for the flavor in Gigabyte.",
|
||||||
|
// MarkdownDescription: "maximum storage which can be ordered for the flavor in Gigabyte.",
|
||||||
|
// },
|
||||||
|
// "min_gb": schema.Int64Attribute{
|
||||||
|
// Computed: true,
|
||||||
|
// Description: "minimum storage which is required to order in Gigabyte.",
|
||||||
|
// MarkdownDescription: "minimum storage which is required to order in Gigabyte.",
|
||||||
|
// },
|
||||||
|
// "node_type": schema.StringAttribute{
|
||||||
|
// Required: true,
|
||||||
|
// Description: "defines the nodeType it can be either single or replica",
|
||||||
|
// MarkdownDescription: "defines the nodeType it can be either single or replica",
|
||||||
|
// },
|
||||||
|
// "storage_classes": schema.ListNestedAttribute{
|
||||||
|
// Computed: true,
|
||||||
|
// NestedObject: schema.NestedAttributeObject{
|
||||||
|
// Attributes: map[string]schema.Attribute{
|
||||||
|
// "class": schema.StringAttribute{
|
||||||
|
// Computed: true,
|
||||||
|
// },
|
||||||
|
// "max_io_per_sec": schema.Int64Attribute{
|
||||||
|
// Computed: true,
|
||||||
|
// },
|
||||||
|
// "max_through_in_mb": schema.Int64Attribute{
|
||||||
|
// Computed: true,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// CustomType: sqlserverflexalphaGen.StorageClassesType{
|
||||||
|
// ObjectType: types.ObjectType{
|
||||||
|
// AttrTypes: sqlserverflexalphaGen.StorageClassesValue{}.AttributeTypes(ctx),
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -185,7 +279,7 @@ func (r *flavorDataSource) Read(ctx context.Context, req datasource.ReadRequest,
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var foundFlavors []sqlserverflexalpha.ListFlavors
|
var foundFlavors []sqlserverflexalphaPkg.ListFlavors
|
||||||
for _, flavor := range flavors {
|
for _, flavor := range flavors {
|
||||||
if model.Cpu.ValueInt64() != *flavor.Cpu {
|
if model.Cpu.ValueInt64() != *flavor.Cpu {
|
||||||
continue
|
continue
|
||||||
|
|
@ -220,13 +314,11 @@ func (r *flavorDataSource) Read(ctx context.Context, req datasource.ReadRequest,
|
||||||
model.MinGb = types.Int64Value(*f.MinGB)
|
model.MinGb = types.Int64Value(*f.MinGB)
|
||||||
|
|
||||||
if f.StorageClasses == nil {
|
if f.StorageClasses == nil {
|
||||||
model.StorageClasses = types.ListNull(
|
model.StorageClasses = types.ListNull(sqlserverflexalphaGen.StorageClassesType{
|
||||||
sqlserverflexalphaGen.StorageClassesType{
|
ObjectType: basetypes.ObjectType{
|
||||||
ObjectType: basetypes.ObjectType{
|
AttrTypes: sqlserverflexalphaGen.StorageClassesValue{}.AttributeTypes(ctx),
|
||||||
AttrTypes: sqlserverflexalphaGen.StorageClassesValue{}.AttributeTypes(ctx),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
)
|
})
|
||||||
} else {
|
} else {
|
||||||
var scList []attr.Value
|
var scList []attr.Value
|
||||||
for _, sc := range *f.StorageClasses {
|
for _, sc := range *f.StorageClasses {
|
||||||
|
|
@ -259,5 +351,5 @@ func (r *flavorDataSource) Read(ctx context.Context, req datasource.ReadRequest,
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tflog.Info(ctx, "Postgres Flex flavors read")
|
tflog.Info(ctx, "SQL Server Flex flavors read")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package sqlserverFlexAlphaFlavor
|
package sqlserverflexalphaFlavor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package sqlserverFlexAlphaFlavor
|
package sqlserverflexalphaFlavor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
|
||||||
|
|
@ -2,30 +2,39 @@ package sqlserverflexalpha
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||||
|
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||||
sqlserverflexUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/utils"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
||||||
|
|
||||||
|
sqlserverflexalphaPkg "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
||||||
|
|
||||||
sqlserverflexalphaGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/flavors/datasources_gen"
|
sqlserverflexalphaGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/flavors/datasources_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
// dataSourceModel maps the data source schema data.
|
|
||||||
type dataSourceModel = sqlserverflexalphaGen.FlavorsModel
|
|
||||||
|
|
||||||
var _ datasource.DataSource = (*flavorsDataSource)(nil)
|
var _ datasource.DataSource = (*flavorsDataSource)(nil)
|
||||||
|
|
||||||
// TODO: Use NewFlavorsDataSource when datasource is implemented
|
const errorPrefix = "[sqlserverflexalpha - Flavors]"
|
||||||
|
|
||||||
func NewFlavorsDataSource() datasource.DataSource {
|
func NewFlavorsDataSource() datasource.DataSource {
|
||||||
return &flavorsDataSource{}
|
return &flavorsDataSource{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type dataSourceModel struct {
|
||||||
|
sqlserverflexalphaGen.FlavorsModel
|
||||||
|
TerraformId types.String `tfsdk:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
type flavorsDataSource struct {
|
type flavorsDataSource struct {
|
||||||
client *sqlserverflexalpha.APIClient
|
client *sqlserverflexalphaPkg.APIClient
|
||||||
providerData core.ProviderData
|
providerData core.ProviderData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,6 +48,11 @@ func (d *flavorsDataSource) Metadata(
|
||||||
|
|
||||||
func (d *flavorsDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
func (d *flavorsDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
||||||
resp.Schema = sqlserverflexalphaGen.FlavorsDataSourceSchema(ctx)
|
resp.Schema = sqlserverflexalphaGen.FlavorsDataSourceSchema(ctx)
|
||||||
|
resp.Schema.Attributes["id"] = schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
Description: "The terraform internal identifier.",
|
||||||
|
MarkdownDescription: "The terraform internal identifier.",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure adds the provider configured client to the data source.
|
// Configure adds the provider configured client to the data source.
|
||||||
|
|
@ -53,12 +67,34 @@ func (d *flavorsDataSource) Configure(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiClient := sqlserverflexUtils.ConfigureClient(ctx, &d.providerData, &resp.Diagnostics)
|
apiClientConfigOptions := []config.ConfigurationOption{
|
||||||
if resp.Diagnostics.HasError() {
|
config.WithCustomAuth(d.providerData.RoundTripper),
|
||||||
|
utils.UserAgentConfigOption(d.providerData.Version),
|
||||||
|
}
|
||||||
|
if d.providerData.SQLServerFlexCustomEndpoint != "" {
|
||||||
|
apiClientConfigOptions = append(
|
||||||
|
apiClientConfigOptions,
|
||||||
|
config.WithEndpoint(d.providerData.SQLServerFlexCustomEndpoint),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
apiClientConfigOptions = append(
|
||||||
|
apiClientConfigOptions,
|
||||||
|
config.WithRegion(d.providerData.GetRegion()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
apiClient, err := sqlserverflexalphaPkg.NewAPIClient(apiClientConfigOptions...)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Error configuring API client",
|
||||||
|
fmt.Sprintf(
|
||||||
|
"Configuring client: %v. This is an error related to the provider configuration, not to the resource configuration",
|
||||||
|
err,
|
||||||
|
),
|
||||||
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
d.client = apiClient
|
d.client = apiClient
|
||||||
tflog.Info(ctx, "SQL SERVER Flex flavors client configured")
|
tflog.Info(ctx, fmt.Sprintf("%s client configured", errorPrefix))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *flavorsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
func (d *flavorsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
||||||
|
|
@ -71,11 +107,50 @@ func (d *flavorsDataSource) Read(ctx context.Context, req datasource.ReadRequest
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo: Read API call logic
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
// Example data value setting
|
projectId := data.ProjectId.ValueString()
|
||||||
// data.Id = types.StringValue("example-id")
|
region := d.providerData.GetRegionWithOverride(data.Region)
|
||||||
|
// TODO: implement right identifier for flavors
|
||||||
|
flavorsId := data.Flavors
|
||||||
|
|
||||||
// Save data into Terraform state
|
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||||
|
ctx = tflog.SetField(ctx, "region", region)
|
||||||
|
|
||||||
|
// TODO: implement needed fields
|
||||||
|
ctx = tflog.SetField(ctx, "flavors_id", flavorsId)
|
||||||
|
|
||||||
|
// TODO: refactor to correct implementation
|
||||||
|
_, err := d.client.GetFlavorsRequest(ctx, projectId, region).Execute()
|
||||||
|
if err != nil {
|
||||||
|
utils.LogError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
err,
|
||||||
|
"Reading flavors",
|
||||||
|
fmt.Sprintf("flavors with ID %q does not exist in project %q.", flavorsId, projectId),
|
||||||
|
map[int]string{
|
||||||
|
http.StatusForbidden: fmt.Sprintf("Project with ID %q not found or forbidden access", projectId),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
resp.State.RemoveResource(ctx)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = core.LogResponse(ctx)
|
||||||
|
|
||||||
|
// TODO: refactor to correct implementation of internal tf id
|
||||||
|
data.TerraformId = utils.BuildInternalTerraformId(projectId, region)
|
||||||
|
|
||||||
|
// TODO: fill remaining fields
|
||||||
|
// data.Flavors = types.Sometype(apiResponse.GetFlavors())
|
||||||
|
// data.Page = types.Sometype(apiResponse.GetPage())
|
||||||
|
// data.Pagination = types.Sometype(apiResponse.GetPagination())
|
||||||
|
// data.ProjectId = types.Sometype(apiResponse.GetProjectId())
|
||||||
|
// data.Region = types.Sometype(apiResponse.GetRegion())
|
||||||
|
// data.Size = types.Sometype(apiResponse.GetSize())
|
||||||
|
// data.Sort = types.Sometype(apiResponse.GetSort())// Save data into Terraform state
|
||||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||||
|
|
||||||
|
tflog.Info(ctx, fmt.Sprintf("%s read successful", errorPrefix))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
// Copyright (c) STACKIT
|
|
||||||
|
|
||||||
package sqlserverflexalpha
|
package sqlserverflexalpha
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -7,47 +5,40 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||||
|
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
||||||
sqlserverflexalpha "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance/datasources_gen"
|
|
||||||
sqlserverflexalpha2 "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance/resources_gen"
|
|
||||||
sqlserverflexUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/utils"
|
|
||||||
|
|
||||||
sqlserverflex "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
|
||||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
||||||
|
|
||||||
|
sqlserverflexalphaPkg "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
||||||
|
|
||||||
|
sqlserverflexalphaGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance/datasources_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
// dataSourceModel maps the data source schema data.
|
var _ datasource.DataSource = (*instanceDataSource)(nil)
|
||||||
type dataSourceModel struct {
|
|
||||||
sqlserverflexalpha2.InstanceModel
|
|
||||||
TerraformID types.String `tfsdk:"id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure the implementation satisfies the expected interfaces.
|
const errorPrefix = "[sqlserverflexalpha - Instance]"
|
||||||
var (
|
|
||||||
_ datasource.DataSource = &instanceDataSource{}
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewInstanceDataSource is a helper function to simplify the provider implementation.
|
|
||||||
func NewInstanceDataSource() datasource.DataSource {
|
func NewInstanceDataSource() datasource.DataSource {
|
||||||
return &instanceDataSource{}
|
return &instanceDataSource{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// instanceDataSource is the data source implementation.
|
// dataSourceModel maps the data source schema data.
|
||||||
|
type dataSourceModel struct {
|
||||||
|
sqlserverflexalphaGen.InstanceModel
|
||||||
|
TerraformID types.String `tfsdk:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
type instanceDataSource struct {
|
type instanceDataSource struct {
|
||||||
client *sqlserverflex.APIClient
|
client *sqlserverflexalphaPkg.APIClient
|
||||||
providerData core.ProviderData
|
providerData core.ProviderData
|
||||||
}
|
}
|
||||||
|
|
||||||
// Metadata returns the data source type name.
|
func (d *instanceDataSource) Metadata(
|
||||||
func (r *instanceDataSource) Metadata(
|
|
||||||
_ context.Context,
|
_ context.Context,
|
||||||
req datasource.MetadataRequest,
|
req datasource.MetadataRequest,
|
||||||
resp *datasource.MetadataResponse,
|
resp *datasource.MetadataResponse,
|
||||||
|
|
@ -55,66 +46,80 @@ func (r *instanceDataSource) Metadata(
|
||||||
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_instance"
|
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_instance"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *instanceDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
||||||
|
resp.Schema = sqlserverflexalphaGen.InstanceDataSourceSchema(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
// Configure adds the provider configured client to the data source.
|
// Configure adds the provider configured client to the data source.
|
||||||
func (r *instanceDataSource) Configure(
|
func (d *instanceDataSource) Configure(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req datasource.ConfigureRequest,
|
req datasource.ConfigureRequest,
|
||||||
resp *datasource.ConfigureResponse,
|
resp *datasource.ConfigureResponse,
|
||||||
) {
|
) {
|
||||||
var ok bool
|
var ok bool
|
||||||
r.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
|
d.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiClient := sqlserverflexUtils.ConfigureClient(ctx, &r.providerData, &resp.Diagnostics)
|
apiClientConfigOptions := []config.ConfigurationOption{
|
||||||
if resp.Diagnostics.HasError() {
|
config.WithCustomAuth(d.providerData.RoundTripper),
|
||||||
|
utils.UserAgentConfigOption(d.providerData.Version),
|
||||||
|
}
|
||||||
|
if d.providerData.SQLServerFlexCustomEndpoint != "" {
|
||||||
|
apiClientConfigOptions = append(
|
||||||
|
apiClientConfigOptions,
|
||||||
|
config.WithEndpoint(d.providerData.SQLServerFlexCustomEndpoint),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
apiClientConfigOptions = append(
|
||||||
|
apiClientConfigOptions,
|
||||||
|
config.WithRegion(d.providerData.GetRegion()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
apiClient, err := sqlserverflexalphaPkg.NewAPIClient(apiClientConfigOptions...)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Error configuring API client",
|
||||||
|
fmt.Sprintf(
|
||||||
|
"Configuring client: %v. This is an error related to the provider configuration, not to the resource configuration",
|
||||||
|
err,
|
||||||
|
),
|
||||||
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.client = apiClient
|
d.client = apiClient
|
||||||
tflog.Info(ctx, "SQLServer Flex instance client configured")
|
tflog.Info(ctx, fmt.Sprintf("%s client configured", errorPrefix))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schema defines the schema for the data source.
|
func (d *instanceDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
||||||
func (r *instanceDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
var data dataSourceModel
|
||||||
s := sqlserverflexalpha.InstanceDataSourceSchema(ctx)
|
|
||||||
s.Attributes["id"] = schema.StringAttribute{
|
|
||||||
Description: "Terraform's internal resource ID. It is structured as \\\"`project_id`,`region`,`instance_id`\\\".",
|
|
||||||
Computed: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.Schema = s
|
// Read Terraform configuration data into the model
|
||||||
}
|
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
|
||||||
|
|
||||||
// Read refreshes the Terraform state with the latest data.
|
|
||||||
func (r *instanceDataSource) 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...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
projectId := model.ProjectId.ValueString()
|
projectId := data.ProjectId.ValueString()
|
||||||
instanceId := model.InstanceId.ValueString()
|
region := d.providerData.GetRegionWithOverride(data.Region)
|
||||||
region := r.providerData.GetRegionWithOverride(model.Region)
|
instanceId := data.InstanceId.ValueString()
|
||||||
|
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
ctx = tflog.SetField(ctx, "region", region)
|
||||||
instanceResp, err := r.client.GetInstanceRequest(ctx, projectId, region, instanceId).Execute()
|
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
||||||
|
|
||||||
|
instanceResp, err := d.client.GetInstanceRequest(ctx, projectId, region, instanceId).Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.LogError(
|
utils.LogError(
|
||||||
ctx,
|
ctx,
|
||||||
&resp.Diagnostics,
|
&resp.Diagnostics,
|
||||||
err,
|
err,
|
||||||
"Reading instance",
|
"Reading instance",
|
||||||
fmt.Sprintf("Instance with ID %q does not exist in project %q.", instanceId, projectId),
|
fmt.Sprintf("instance with ID %q does not exist in project %q.", instanceId, projectId),
|
||||||
map[int]string{
|
map[int]string{
|
||||||
http.StatusForbidden: fmt.Sprintf("Project with ID %q not found or forbidden access", projectId),
|
http.StatusForbidden: fmt.Sprintf("Project with ID %q not found or forbidden access", projectId),
|
||||||
},
|
},
|
||||||
|
|
@ -125,49 +130,17 @@ func (r *instanceDataSource) Read(
|
||||||
|
|
||||||
ctx = core.LogResponse(ctx)
|
ctx = core.LogResponse(ctx)
|
||||||
|
|
||||||
// var storage = &storageModel{}
|
err = mapDataResponseToModel(ctx, instanceResp, &data, resp.Diagnostics)
|
||||||
// if !model.Storage.IsNull() && !model.Storage.IsUnknown() {
|
|
||||||
// diags = model.Storage.As(ctx, storage, basetypes.ObjectAsOptions{})
|
|
||||||
// resp.Diagnostics.Append(diags...)
|
|
||||||
// if resp.Diagnostics.HasError() {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
// var encryption = &encryptionModel{}
|
|
||||||
//if !model.Encryption.IsNull() && !model.Encryption.IsUnknown() {
|
|
||||||
// diags = model.Encryption.As(ctx, encryption, basetypes.ObjectAsOptions{})
|
|
||||||
// resp.Diagnostics.Append(diags...)
|
|
||||||
// if resp.Diagnostics.HasError() {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//var network = &networkModel{}
|
|
||||||
//if !model.Network.IsNull() && !model.Network.IsUnknown() {
|
|
||||||
// diags = model.Network.As(ctx, network, basetypes.ObjectAsOptions{})
|
|
||||||
// resp.Diagnostics.Append(diags...)
|
|
||||||
// if resp.Diagnostics.HasError() {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
err = mapFields(ctx, instanceResp, &model, resp.Diagnostics)
|
|
||||||
// err = mapFields(ctx, instanceResp, &model, storage, encryption, network, region)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
ctx,
|
ctx,
|
||||||
&resp.Diagnostics,
|
&resp.Diagnostics,
|
||||||
"Error reading instance",
|
fmt.Sprintf("%s Read", errorPrefix),
|
||||||
fmt.Sprintf("Processing API payload: %v", err),
|
fmt.Sprintf("Processing API payload: %v", err),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Set refreshed state
|
|
||||||
diags = resp.State.Set(ctx, model)
|
// Save data into Terraform state
|
||||||
resp.Diagnostics.Append(diags...)
|
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
tflog.Info(ctx, "SQLServer Flex instance read")
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package sqlserverflexalpha
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
|
|
@ -10,29 +11,35 @@ import (
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
|
||||||
sqlserverflex "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
||||||
sqlserverflexResGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance/resources_gen"
|
sqlserverflexalphaDataGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance/datasources_gen"
|
||||||
|
sqlserverflexalphaResGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance/resources_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
// instanceModel is a type constraint for models that can be mapped from a GetInstanceResponse.
|
func mapResponseToModel(
|
||||||
type instanceModel interface {
|
|
||||||
*dataSourceModel | *resourceModel
|
|
||||||
}
|
|
||||||
|
|
||||||
func mapFields[T instanceModel](
|
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
resp *sqlserverflex.GetInstanceResponse,
|
resp *sqlserverflexalpha.GetInstanceResponse,
|
||||||
m T,
|
m *sqlserverflexalphaResGen.InstanceModel,
|
||||||
tfDiags diag.Diagnostics,
|
tfDiags diag.Diagnostics,
|
||||||
) error {
|
) error {
|
||||||
|
m.BackupSchedule = types.StringValue(resp.GetBackupSchedule())
|
||||||
|
m.Edition = types.StringValue(string(resp.GetEdition()))
|
||||||
|
m.Encryption = handleEncryption(m, resp)
|
||||||
|
m.FlavorId = types.StringValue(resp.GetFlavorId())
|
||||||
|
m.Id = types.StringValue(resp.GetId())
|
||||||
|
m.InstanceId = types.StringValue(resp.GetId())
|
||||||
|
m.IsDeletable = types.BoolValue(resp.GetIsDeletable())
|
||||||
|
m.Name = types.StringValue(resp.GetName())
|
||||||
netAcl, diags := types.ListValueFrom(ctx, types.StringType, resp.Network.GetAcl())
|
netAcl, diags := types.ListValueFrom(ctx, types.StringType, resp.Network.GetAcl())
|
||||||
tfDiags.Append(diags...)
|
tfDiags.Append(diags...)
|
||||||
if diags.HasError() {
|
if diags.HasError() {
|
||||||
return fmt.Errorf("error converting network acl response value")
|
return fmt.Errorf(
|
||||||
|
"error converting network acl response value",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
net, diags := sqlserverflexResGen.NewNetworkValue(
|
net, diags := sqlserverflexalphaResGen.NewNetworkValue(
|
||||||
sqlserverflexResGen.NetworkValue{}.AttributeTypes(ctx),
|
sqlserverflexalphaResGen.NetworkValue{}.AttributeTypes(ctx),
|
||||||
map[string]attr.Value{
|
map[string]attr.Value{
|
||||||
"access_scope": types.StringValue(string(resp.Network.GetAccessScope())),
|
"access_scope": types.StringValue(string(resp.Network.GetAccessScope())),
|
||||||
"acl": netAcl,
|
"acl": netAcl,
|
||||||
|
|
@ -42,11 +49,15 @@ func mapFields[T instanceModel](
|
||||||
)
|
)
|
||||||
tfDiags.Append(diags...)
|
tfDiags.Append(diags...)
|
||||||
if diags.HasError() {
|
if diags.HasError() {
|
||||||
return fmt.Errorf("error converting network response value")
|
return errors.New("error converting network response value")
|
||||||
}
|
}
|
||||||
|
m.Network = net
|
||||||
|
m.Replicas = types.Int64Value(int64(resp.GetReplicas()))
|
||||||
|
m.RetentionDays = types.Int64Value(resp.GetRetentionDays())
|
||||||
|
m.Status = types.StringValue(string(resp.GetStatus()))
|
||||||
|
|
||||||
stor, diags := sqlserverflexResGen.NewStorageValue(
|
stor, diags := sqlserverflexalphaResGen.NewStorageValue(
|
||||||
sqlserverflexResGen.StorageValue{}.AttributeTypes(ctx),
|
sqlserverflexalphaResGen.StorageValue{}.AttributeTypes(ctx),
|
||||||
map[string]attr.Value{
|
map[string]attr.Value{
|
||||||
"class": types.StringValue(resp.Storage.GetClass()),
|
"class": types.StringValue(resp.Storage.GetClass()),
|
||||||
"size": types.Int64Value(resp.Storage.GetSize()),
|
"size": types.Int64Value(resp.Storage.GetSize()),
|
||||||
|
|
@ -56,62 +67,117 @@ func mapFields[T instanceModel](
|
||||||
if diags.HasError() {
|
if diags.HasError() {
|
||||||
return fmt.Errorf("error converting storage response value")
|
return fmt.Errorf("error converting storage response value")
|
||||||
}
|
}
|
||||||
|
m.Storage = stor
|
||||||
|
|
||||||
// The interface conversion is safe due to the type constraint.
|
m.Version = types.StringValue(string(resp.GetVersion()))
|
||||||
model := any(m)
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if rm, ok := model.(*resourceModel); ok {
|
func mapDataResponseToModel(
|
||||||
rm.BackupSchedule = types.StringValue(resp.GetBackupSchedule())
|
ctx context.Context,
|
||||||
rm.Edition = types.StringValue(string(resp.GetEdition()))
|
resp *sqlserverflexalpha.GetInstanceResponse,
|
||||||
rm.Encryption = handleEncryption(rm.Encryption, resp)
|
m *dataSourceModel,
|
||||||
rm.FlavorId = types.StringValue(resp.GetFlavorId())
|
tfDiags diag.Diagnostics,
|
||||||
rm.Id = types.StringValue(resp.GetId())
|
) error {
|
||||||
rm.InstanceId = types.StringValue(resp.GetId())
|
m.BackupSchedule = types.StringValue(resp.GetBackupSchedule())
|
||||||
rm.IsDeletable = types.BoolValue(resp.GetIsDeletable())
|
m.Edition = types.StringValue(string(resp.GetEdition()))
|
||||||
rm.Name = types.StringValue(resp.GetName())
|
m.Encryption = handleDSEncryption(m, resp)
|
||||||
rm.Network = net
|
m.FlavorId = types.StringValue(resp.GetFlavorId())
|
||||||
rm.Replicas = types.Int64Value(int64(resp.GetReplicas()))
|
m.Id = types.StringValue(resp.GetId())
|
||||||
rm.RetentionDays = types.Int64Value(resp.GetRetentionDays())
|
m.InstanceId = types.StringValue(resp.GetId())
|
||||||
rm.Status = types.StringValue(string(resp.GetStatus()))
|
m.IsDeletable = types.BoolValue(resp.GetIsDeletable())
|
||||||
rm.Storage = stor
|
m.Name = types.StringValue(resp.GetName())
|
||||||
rm.Version = types.StringValue(string(resp.GetVersion()))
|
netAcl, diags := types.ListValueFrom(ctx, types.StringType, resp.Network.GetAcl())
|
||||||
} else if dm, ok := model.(*dataSourceModel); ok {
|
tfDiags.Append(diags...)
|
||||||
dm.BackupSchedule = types.StringValue(resp.GetBackupSchedule())
|
if diags.HasError() {
|
||||||
dm.Edition = types.StringValue(string(resp.GetEdition()))
|
return fmt.Errorf(
|
||||||
dm.Encryption = handleEncryption(dm.Encryption, resp)
|
"error converting network acl response value",
|
||||||
dm.FlavorId = types.StringValue(resp.GetFlavorId())
|
)
|
||||||
dm.Id = types.StringValue(resp.GetId())
|
|
||||||
dm.InstanceId = types.StringValue(resp.GetId())
|
|
||||||
dm.IsDeletable = types.BoolValue(resp.GetIsDeletable())
|
|
||||||
dm.Name = types.StringValue(resp.GetName())
|
|
||||||
dm.Network = net
|
|
||||||
dm.Replicas = types.Int64Value(int64(resp.GetReplicas()))
|
|
||||||
dm.RetentionDays = types.Int64Value(resp.GetRetentionDays())
|
|
||||||
dm.Status = types.StringValue(string(resp.GetStatus()))
|
|
||||||
dm.Storage = stor
|
|
||||||
dm.Version = types.StringValue(string(resp.GetVersion()))
|
|
||||||
}
|
}
|
||||||
|
net, diags := sqlserverflexalphaDataGen.NewNetworkValue(
|
||||||
|
sqlserverflexalphaDataGen.NetworkValue{}.AttributeTypes(ctx),
|
||||||
|
map[string]attr.Value{
|
||||||
|
"access_scope": types.StringValue(string(resp.Network.GetAccessScope())),
|
||||||
|
"acl": netAcl,
|
||||||
|
"instance_address": types.StringValue(resp.Network.GetInstanceAddress()),
|
||||||
|
"router_address": types.StringValue(resp.Network.GetRouterAddress()),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
tfDiags.Append(diags...)
|
||||||
|
if diags.HasError() {
|
||||||
|
return errors.New("error converting network response value")
|
||||||
|
}
|
||||||
|
m.Network = net
|
||||||
|
m.Replicas = types.Int64Value(int64(resp.GetReplicas()))
|
||||||
|
m.RetentionDays = types.Int64Value(resp.GetRetentionDays())
|
||||||
|
m.Status = types.StringValue(string(resp.GetStatus()))
|
||||||
|
|
||||||
|
stor, diags := sqlserverflexalphaDataGen.NewStorageValue(
|
||||||
|
sqlserverflexalphaDataGen.StorageValue{}.AttributeTypes(ctx),
|
||||||
|
map[string]attr.Value{
|
||||||
|
"class": types.StringValue(resp.Storage.GetClass()),
|
||||||
|
"size": types.Int64Value(resp.Storage.GetSize()),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
tfDiags.Append(diags...)
|
||||||
|
if diags.HasError() {
|
||||||
|
return fmt.Errorf("error converting storage response value")
|
||||||
|
}
|
||||||
|
m.Storage = stor
|
||||||
|
|
||||||
|
m.Version = types.StringValue(string(resp.GetVersion()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleEncryption(
|
func handleEncryption(
|
||||||
encryptionValue sqlserverflexResGen.EncryptionValue,
|
m *sqlserverflexalphaResGen.InstanceModel,
|
||||||
resp *sqlserverflex.GetInstanceResponse,
|
resp *sqlserverflexalpha.GetInstanceResponse,
|
||||||
) sqlserverflexResGen.EncryptionValue {
|
) sqlserverflexalphaResGen.EncryptionValue {
|
||||||
if !resp.HasEncryption() ||
|
if !resp.HasEncryption() ||
|
||||||
resp.Encryption == nil ||
|
resp.Encryption == nil ||
|
||||||
resp.Encryption.KekKeyId == nil ||
|
resp.Encryption.KekKeyId == nil ||
|
||||||
resp.Encryption.KekKeyRingId == nil ||
|
resp.Encryption.KekKeyRingId == nil ||
|
||||||
resp.Encryption.KekKeyVersion == nil ||
|
resp.Encryption.KekKeyVersion == nil ||
|
||||||
resp.Encryption.ServiceAccount == nil {
|
resp.Encryption.ServiceAccount == nil {
|
||||||
if encryptionValue.IsNull() || encryptionValue.IsUnknown() {
|
if m.Encryption.IsNull() || m.Encryption.IsUnknown() {
|
||||||
return sqlserverflexResGen.NewEncryptionValueNull()
|
return sqlserverflexalphaResGen.NewEncryptionValueNull()
|
||||||
}
|
}
|
||||||
return encryptionValue
|
return m.Encryption
|
||||||
}
|
}
|
||||||
|
|
||||||
enc := sqlserverflexResGen.NewEncryptionValueNull()
|
enc := sqlserverflexalphaResGen.NewEncryptionValueNull()
|
||||||
|
if kVal, ok := resp.Encryption.GetKekKeyIdOk(); ok {
|
||||||
|
enc.KekKeyId = types.StringValue(kVal)
|
||||||
|
}
|
||||||
|
if kkVal, ok := resp.Encryption.GetKekKeyRingIdOk(); ok {
|
||||||
|
enc.KekKeyRingId = types.StringValue(kkVal)
|
||||||
|
}
|
||||||
|
if kkvVal, ok := resp.Encryption.GetKekKeyVersionOk(); ok {
|
||||||
|
enc.KekKeyVersion = types.StringValue(kkvVal)
|
||||||
|
}
|
||||||
|
if sa, ok := resp.Encryption.GetServiceAccountOk(); ok {
|
||||||
|
enc.ServiceAccount = types.StringValue(sa)
|
||||||
|
}
|
||||||
|
return enc
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleDSEncryption(
|
||||||
|
m *dataSourceModel,
|
||||||
|
resp *sqlserverflexalpha.GetInstanceResponse,
|
||||||
|
) sqlserverflexalphaDataGen.EncryptionValue {
|
||||||
|
if !resp.HasEncryption() ||
|
||||||
|
resp.Encryption == nil ||
|
||||||
|
resp.Encryption.KekKeyId == nil ||
|
||||||
|
resp.Encryption.KekKeyRingId == nil ||
|
||||||
|
resp.Encryption.KekKeyVersion == nil ||
|
||||||
|
resp.Encryption.ServiceAccount == nil {
|
||||||
|
if m.Encryption.IsNull() || m.Encryption.IsUnknown() {
|
||||||
|
return sqlserverflexalphaDataGen.NewEncryptionValueNull()
|
||||||
|
}
|
||||||
|
return m.Encryption
|
||||||
|
}
|
||||||
|
|
||||||
|
enc := sqlserverflexalphaDataGen.NewEncryptionValueNull()
|
||||||
if kVal, ok := resp.Encryption.GetKekKeyIdOk(); ok {
|
if kVal, ok := resp.Encryption.GetKekKeyIdOk(); ok {
|
||||||
enc.KekKeyId = types.StringValue(kVal)
|
enc.KekKeyId = types.StringValue(kVal)
|
||||||
}
|
}
|
||||||
|
|
@ -129,25 +195,25 @@ func handleEncryption(
|
||||||
|
|
||||||
func toCreatePayload(
|
func toCreatePayload(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
model *sqlserverflexResGen.InstanceModel,
|
model *sqlserverflexalphaResGen.InstanceModel,
|
||||||
) (*sqlserverflex.CreateInstanceRequestPayload, error) {
|
) (*sqlserverflexalpha.CreateInstanceRequestPayload, error) {
|
||||||
if model == nil {
|
if model == nil {
|
||||||
return nil, fmt.Errorf("nil model")
|
return nil, fmt.Errorf("nil model")
|
||||||
}
|
}
|
||||||
|
|
||||||
storagePayload := &sqlserverflex.CreateInstanceRequestPayloadGetStorageArgType{}
|
storagePayload := &sqlserverflexalpha.CreateInstanceRequestPayloadGetStorageArgType{}
|
||||||
if !model.Storage.IsNull() && !model.Storage.IsUnknown() {
|
if !model.Storage.IsNull() && !model.Storage.IsUnknown() {
|
||||||
storagePayload.Class = model.Storage.Class.ValueStringPointer()
|
storagePayload.Class = model.Storage.Class.ValueStringPointer()
|
||||||
storagePayload.Size = model.Storage.Size.ValueInt64Pointer()
|
storagePayload.Size = model.Storage.Size.ValueInt64Pointer()
|
||||||
}
|
}
|
||||||
|
|
||||||
var encryptionPayload *sqlserverflex.CreateInstanceRequestPayloadGetEncryptionArgType = nil
|
var encryptionPayload *sqlserverflexalpha.CreateInstanceRequestPayloadGetEncryptionArgType = nil
|
||||||
if !model.Encryption.IsNull() && !model.Encryption.IsUnknown() &&
|
if !model.Encryption.IsNull() && !model.Encryption.IsUnknown() &&
|
||||||
!model.Encryption.KekKeyId.IsNull() && model.Encryption.KekKeyId.IsUnknown() && model.Encryption.KekKeyId.ValueString() != "" &&
|
!model.Encryption.KekKeyId.IsNull() && model.Encryption.KekKeyId.IsUnknown() && model.Encryption.KekKeyId.ValueString() != "" &&
|
||||||
!model.Encryption.KekKeyRingId.IsNull() && !model.Encryption.KekKeyRingId.IsUnknown() && model.Encryption.KekKeyRingId.ValueString() != "" &&
|
!model.Encryption.KekKeyRingId.IsNull() && !model.Encryption.KekKeyRingId.IsUnknown() && model.Encryption.KekKeyRingId.ValueString() != "" &&
|
||||||
!model.Encryption.KekKeyVersion.IsNull() && !model.Encryption.KekKeyVersion.IsUnknown() && model.Encryption.KekKeyVersion.ValueString() != "" &&
|
!model.Encryption.KekKeyVersion.IsNull() && !model.Encryption.KekKeyVersion.IsUnknown() && model.Encryption.KekKeyVersion.ValueString() != "" &&
|
||||||
!model.Encryption.ServiceAccount.IsNull() && !model.Encryption.ServiceAccount.IsUnknown() && model.Encryption.ServiceAccount.ValueString() != "" {
|
!model.Encryption.ServiceAccount.IsNull() && !model.Encryption.ServiceAccount.IsUnknown() && model.Encryption.ServiceAccount.ValueString() != "" {
|
||||||
encryptionPayload = &sqlserverflex.CreateInstanceRequestPayloadGetEncryptionArgType{
|
encryptionPayload = &sqlserverflexalpha.CreateInstanceRequestPayloadGetEncryptionArgType{
|
||||||
KekKeyId: model.Encryption.KekKeyId.ValueStringPointer(),
|
KekKeyId: model.Encryption.KekKeyId.ValueStringPointer(),
|
||||||
KekKeyRingId: model.Encryption.KekKeyVersion.ValueStringPointer(),
|
KekKeyRingId: model.Encryption.KekKeyVersion.ValueStringPointer(),
|
||||||
KekKeyVersion: model.Encryption.KekKeyRingId.ValueStringPointer(),
|
KekKeyVersion: model.Encryption.KekKeyRingId.ValueStringPointer(),
|
||||||
|
|
@ -155,9 +221,9 @@ func toCreatePayload(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
networkPayload := &sqlserverflex.CreateInstanceRequestPayloadGetNetworkArgType{}
|
networkPayload := &sqlserverflexalpha.CreateInstanceRequestPayloadGetNetworkArgType{}
|
||||||
if !model.Network.IsNull() && !model.Network.IsUnknown() {
|
if !model.Network.IsNull() && !model.Network.IsUnknown() {
|
||||||
networkPayload.AccessScope = sqlserverflex.CreateInstanceRequestPayloadNetworkGetAccessScopeAttributeType(
|
networkPayload.AccessScope = sqlserverflexalpha.CreateInstanceRequestPayloadNetworkGetAccessScopeAttributeType(
|
||||||
model.Network.AccessScope.ValueStringPointer(),
|
model.Network.AccessScope.ValueStringPointer(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -169,7 +235,7 @@ func toCreatePayload(
|
||||||
networkPayload.Acl = &resList
|
networkPayload.Acl = &resList
|
||||||
}
|
}
|
||||||
|
|
||||||
return &sqlserverflex.CreateInstanceRequestPayload{
|
return &sqlserverflexalpha.CreateInstanceRequestPayload{
|
||||||
BackupSchedule: conversion.StringValueToPointer(model.BackupSchedule),
|
BackupSchedule: conversion.StringValueToPointer(model.BackupSchedule),
|
||||||
Encryption: encryptionPayload,
|
Encryption: encryptionPayload,
|
||||||
FlavorId: conversion.StringValueToPointer(model.FlavorId),
|
FlavorId: conversion.StringValueToPointer(model.FlavorId),
|
||||||
|
|
@ -177,20 +243,25 @@ func toCreatePayload(
|
||||||
Network: networkPayload,
|
Network: networkPayload,
|
||||||
RetentionDays: conversion.Int64ValueToPointer(model.RetentionDays),
|
RetentionDays: conversion.Int64ValueToPointer(model.RetentionDays),
|
||||||
Storage: storagePayload,
|
Storage: storagePayload,
|
||||||
Version: sqlserverflex.CreateInstanceRequestPayloadGetVersionAttributeType(conversion.StringValueToPointer(model.Version)),
|
Version: sqlserverflexalpha.CreateInstanceRequestPayloadGetVersionAttributeType(
|
||||||
|
conversion.StringValueToPointer(model.Version),
|
||||||
|
),
|
||||||
}, nil
|
}, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check func with his args
|
|
||||||
func toUpdatePayload(
|
func toUpdatePayload(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
m *sqlserverflexResGen.InstanceModel,
|
m *sqlserverflexalphaResGen.InstanceModel,
|
||||||
resp *resource.UpdateResponse,
|
resp *resource.UpdateResponse,
|
||||||
) (*sqlserverflex.UpdateInstanceRequestPayload, error) {
|
) (*sqlserverflexalpha.UpdateInstanceRequestPayload, error) {
|
||||||
|
if m == nil {
|
||||||
|
return nil, fmt.Errorf("nil model")
|
||||||
|
}
|
||||||
if m.Replicas.ValueInt64() > math.MaxUint32 {
|
if m.Replicas.ValueInt64() > math.MaxUint32 {
|
||||||
return nil, fmt.Errorf("replicas value is too big for uint32")
|
return nil, fmt.Errorf("replicas value is too big for uint32")
|
||||||
}
|
}
|
||||||
replVal := sqlserverflex.Replicas(uint32(m.Replicas.ValueInt64())) // nolint:gosec // check is performed above
|
replVal := sqlserverflexalpha.Replicas(uint32(m.Replicas.ValueInt64())) // nolint:gosec // check is performed above
|
||||||
|
|
||||||
var netAcl []string
|
var netAcl []string
|
||||||
diags := m.Network.Acl.ElementsAs(ctx, &netAcl, false)
|
diags := m.Network.Acl.ElementsAs(ctx, &netAcl, false)
|
||||||
|
|
@ -198,16 +269,16 @@ func toUpdatePayload(
|
||||||
if diags.HasError() {
|
if diags.HasError() {
|
||||||
return nil, fmt.Errorf("error converting model network acl value")
|
return nil, fmt.Errorf("error converting model network acl value")
|
||||||
}
|
}
|
||||||
return &sqlserverflex.UpdateInstanceRequestPayload{
|
return &sqlserverflexalpha.UpdateInstanceRequestPayload{
|
||||||
BackupSchedule: m.BackupSchedule.ValueStringPointer(),
|
BackupSchedule: m.BackupSchedule.ValueStringPointer(),
|
||||||
FlavorId: m.FlavorId.ValueStringPointer(),
|
FlavorId: m.FlavorId.ValueStringPointer(),
|
||||||
Name: m.Name.ValueStringPointer(),
|
Name: m.Name.ValueStringPointer(),
|
||||||
Network: &sqlserverflex.UpdateInstanceRequestPayloadNetwork{
|
Network: sqlserverflexalpha.NewUpdateInstanceRequestPayloadNetwork(netAcl),
|
||||||
Acl: &netAcl,
|
Replicas: &replVal,
|
||||||
},
|
RetentionDays: m.RetentionDays.ValueInt64Pointer(),
|
||||||
Replicas: &replVal,
|
Storage: &sqlserverflexalpha.StorageUpdate{Size: m.Storage.Size.ValueInt64Pointer()},
|
||||||
RetentionDays: m.RetentionDays.ValueInt64Pointer(),
|
Version: sqlserverflexalpha.UpdateInstanceRequestPayloadGetVersionAttributeType(
|
||||||
Storage: &sqlserverflex.StorageUpdate{Size: m.Storage.Size.ValueInt64Pointer()},
|
m.Version.ValueStringPointer(),
|
||||||
Version: sqlserverflex.UpdateInstanceRequestPayloadGetVersionAttributeType(m.Version.ValueStringPointer()),
|
),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
// Copyright (c) STACKIT
|
|
||||||
|
|
||||||
package sqlserverflexalpha
|
package sqlserverflexalpha
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -10,26 +8,25 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource/identityschema"
|
|
||||||
|
|
||||||
sqlserverflexalpha2 "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance/resources_gen"
|
|
||||||
sqlserverflexUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/utils"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/identityschema"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||||
|
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
||||||
|
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
|
||||||
wait "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/wait/sqlserverflexalpha"
|
wait "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/wait/sqlserverflexalpha"
|
||||||
|
|
||||||
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
||||||
|
|
||||||
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||||
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
||||||
|
|
||||||
|
sqlserverflexalphaResGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance/resources_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure the implementation satisfies the expected interfaces.
|
|
||||||
var (
|
var (
|
||||||
_ resource.Resource = &instanceResource{}
|
_ resource.Resource = &instanceResource{}
|
||||||
_ resource.ResourceWithConfigure = &instanceResource{}
|
_ resource.ResourceWithConfigure = &instanceResource{}
|
||||||
|
|
@ -38,19 +35,17 @@ var (
|
||||||
_ resource.ResourceWithIdentity = &instanceResource{}
|
_ resource.ResourceWithIdentity = &instanceResource{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewInstanceResource is a helper function to simplify the provider implementation.
|
|
||||||
func NewInstanceResource() resource.Resource {
|
func NewInstanceResource() resource.Resource {
|
||||||
return &instanceResource{}
|
return &instanceResource{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:unused // TODO: remove if not needed later
|
type instanceResource struct {
|
||||||
var validNodeTypes []string = []string{
|
client *sqlserverflexalpha.APIClient
|
||||||
"Single",
|
providerData core.ProviderData
|
||||||
"Replica",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// resourceModel describes the resource data model.
|
// resourceModel describes the resource data model.
|
||||||
type resourceModel = sqlserverflexalpha2.InstanceModel
|
type resourceModel = sqlserverflexalphaResGen.InstanceModel
|
||||||
|
|
||||||
type InstanceResourceIdentityModel struct {
|
type InstanceResourceIdentityModel struct {
|
||||||
ProjectID types.String `tfsdk:"project_id"`
|
ProjectID types.String `tfsdk:"project_id"`
|
||||||
|
|
@ -58,93 +53,19 @@ type InstanceResourceIdentityModel struct {
|
||||||
InstanceID types.String `tfsdk:"instance_id"`
|
InstanceID types.String `tfsdk:"instance_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// instanceResource is the resource implementation.
|
func (r *instanceResource) Metadata(
|
||||||
type instanceResource struct {
|
|
||||||
client *sqlserverflexalpha.APIClient
|
|
||||||
providerData core.ProviderData
|
|
||||||
}
|
|
||||||
|
|
||||||
// Metadata returns the resource type name.
|
|
||||||
func (r *instanceResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
|
||||||
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_instance"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure adds the provider configured client to the resource.
|
|
||||||
func (r *instanceResource) Configure(
|
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req resource.ConfigureRequest,
|
req resource.MetadataRequest,
|
||||||
resp *resource.ConfigureResponse,
|
resp *resource.MetadataResponse,
|
||||||
) {
|
) {
|
||||||
var ok bool
|
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_instance"
|
||||||
r.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
apiClient := sqlserverflexUtils.ConfigureClient(ctx, &r.providerData, &resp.Diagnostics)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
r.client = apiClient
|
|
||||||
tflog.Info(ctx, "SQLServer Flex instance client configured")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ModifyPlan implements resource.ResourceWithModifyPlan.
|
|
||||||
// Use the modifier to set the effective region in the current plan.
|
|
||||||
func (r *instanceResource) ModifyPlan(
|
|
||||||
ctx context.Context,
|
|
||||||
req resource.ModifyPlanRequest,
|
|
||||||
resp *resource.ModifyPlanResponse,
|
|
||||||
) { // nolint:gocritic // function signature required by Terraform
|
|
||||||
|
|
||||||
// skip initial empty configuration to avoid follow-up errors
|
|
||||||
if req.Config.Raw.IsNull() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var configModel sqlserverflexalpha2.InstanceModel
|
|
||||||
resp.Diagnostics.Append(req.Config.Get(ctx, &configModel)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.Plan.Raw.IsNull() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var planModel sqlserverflexalpha2.InstanceModel
|
|
||||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &planModel)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
utils.AdaptRegion(ctx, configModel.Region, &planModel.Region, r.providerData.GetRegion(), resp)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var identityModel InstanceResourceIdentityModel
|
|
||||||
identityModel.ProjectID = planModel.ProjectId
|
|
||||||
identityModel.Region = planModel.Region
|
|
||||||
if !planModel.InstanceId.IsNull() && !planModel.InstanceId.IsUnknown() {
|
|
||||||
identityModel.InstanceID = planModel.InstanceId
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identityModel)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.Diagnostics.Append(resp.Plan.Set(ctx, planModel)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:embed planModifiers.yaml
|
//go:embed planModifiers.yaml
|
||||||
var modifiersFileByte []byte
|
var modifiersFileByte []byte
|
||||||
|
|
||||||
// Schema defines the schema for the resource.
|
func (r *instanceResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||||
func (r *instanceResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
|
s := sqlserverflexalphaResGen.InstanceResourceSchema(ctx)
|
||||||
schema := sqlserverflexalpha2.InstanceResourceSchema(ctx)
|
|
||||||
|
|
||||||
fields, err := utils.ReadModifiersConfig(modifiersFileByte)
|
fields, err := utils.ReadModifiersConfig(modifiersFileByte)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -152,12 +73,12 @@ func (r *instanceResource) Schema(ctx context.Context, _ resource.SchemaRequest,
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = utils.AddPlanModifiersToResourceSchema(fields, &schema)
|
err = utils.AddPlanModifiersToResourceSchema(fields, &s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Diagnostics.AddError("error adding plan modifiers", err.Error())
|
resp.Diagnostics.AddError("error adding plan modifiers", err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp.Schema = schema
|
resp.Schema = s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *instanceResource) IdentitySchema(
|
func (r *instanceResource) IdentitySchema(
|
||||||
|
|
@ -180,15 +101,355 @@ func (r *instanceResource) IdentitySchema(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates the resource and sets the initial Terraform state.
|
// Configure adds the provider configured client to the resource.
|
||||||
func (r *instanceResource) Create(
|
func (r *instanceResource) Configure(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req resource.CreateRequest,
|
req resource.ConfigureRequest,
|
||||||
resp *resource.CreateResponse,
|
resp *resource.ConfigureResponse,
|
||||||
|
) {
|
||||||
|
var ok bool
|
||||||
|
r.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
apiClientConfigOptions := []config.ConfigurationOption{
|
||||||
|
config.WithCustomAuth(r.providerData.RoundTripper),
|
||||||
|
utils.UserAgentConfigOption(r.providerData.Version),
|
||||||
|
}
|
||||||
|
if r.providerData.SQLServerFlexCustomEndpoint != "" {
|
||||||
|
apiClientConfigOptions = append(
|
||||||
|
apiClientConfigOptions,
|
||||||
|
config.WithEndpoint(r.providerData.SQLServerFlexCustomEndpoint),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
apiClientConfigOptions = append(apiClientConfigOptions, config.WithRegion(r.providerData.GetRegion()))
|
||||||
|
}
|
||||||
|
apiClient, err := sqlserverflexalpha.NewAPIClient(apiClientConfigOptions...)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Error configuring API client",
|
||||||
|
fmt.Sprintf(
|
||||||
|
"Configuring client: %v. This is an error related to the provider configuration, not to the resource configuration",
|
||||||
|
err,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r.client = apiClient
|
||||||
|
tflog.Info(ctx, "sqlserverflexalpha.Instance client configured")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModifyPlan implements resource.ResourceWithModifyPlan.
|
||||||
|
// Use the modifier to set the effective region in the current plan.
|
||||||
|
func (r *instanceResource) ModifyPlan(
|
||||||
|
ctx context.Context,
|
||||||
|
req resource.ModifyPlanRequest,
|
||||||
|
resp *resource.ModifyPlanResponse,
|
||||||
) { // nolint:gocritic // function signature required by Terraform
|
) { // nolint:gocritic // function signature required by Terraform
|
||||||
var model resourceModel
|
|
||||||
diags := req.Plan.Get(ctx, &model)
|
// skip initial empty configuration to avoid follow-up errors
|
||||||
resp.Diagnostics.Append(diags...)
|
if req.Config.Raw.IsNull() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var configModel resourceModel
|
||||||
|
resp.Diagnostics.Append(req.Config.Get(ctx, &configModel)...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.Plan.Raw.IsNull() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var planModel resourceModel
|
||||||
|
resp.Diagnostics.Append(req.Plan.Get(ctx, &planModel)...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.AdaptRegion(ctx, configModel.Region, &planModel.Region, r.providerData.GetRegion(), resp)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Diagnostics.Append(resp.Plan.Set(ctx, planModel)...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *instanceResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||||
|
var data resourceModel
|
||||||
|
crateErr := "[SQL Server Flex BETA - Create] error"
|
||||||
|
|
||||||
|
// Read Terraform plan data into the model
|
||||||
|
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
|
projectId := data.ProjectId.ValueString()
|
||||||
|
region := data.Region.ValueString()
|
||||||
|
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||||
|
ctx = tflog.SetField(ctx, "region", region)
|
||||||
|
|
||||||
|
// Generate API request body from model
|
||||||
|
payload, err := toCreatePayload(ctx, &data)
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
crateErr,
|
||||||
|
fmt.Sprintf("Creating API payload: %v", err),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Create new Instance
|
||||||
|
createResp, err := r.client.CreateInstanceRequest(
|
||||||
|
ctx,
|
||||||
|
projectId,
|
||||||
|
region,
|
||||||
|
).CreateInstanceRequestPayload(*payload).Execute()
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(ctx, &resp.Diagnostics, crateErr, fmt.Sprintf("Calling API: %v", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = core.LogResponse(ctx)
|
||||||
|
|
||||||
|
InstanceId := *createResp.Id
|
||||||
|
|
||||||
|
// Example data value setting
|
||||||
|
data.InstanceId = types.StringValue("id-from-response")
|
||||||
|
|
||||||
|
identity := InstanceResourceIdentityModel{
|
||||||
|
ProjectID: types.StringValue(projectId),
|
||||||
|
Region: types.StringValue(region),
|
||||||
|
InstanceID: types.StringValue(InstanceId),
|
||||||
|
}
|
||||||
|
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
waitResp, err := wait.CreateInstanceWaitHandler(
|
||||||
|
ctx,
|
||||||
|
r.client,
|
||||||
|
projectId,
|
||||||
|
InstanceId,
|
||||||
|
region,
|
||||||
|
).SetSleepBeforeWait(
|
||||||
|
10 * time.Second,
|
||||||
|
).SetTimeout(
|
||||||
|
90 * time.Minute,
|
||||||
|
).WaitWithContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
crateErr,
|
||||||
|
fmt.Sprintf("Instance creation waiting: %v", err),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if waitResp.Id == nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
crateErr,
|
||||||
|
"Instance creation waiting: returned id is nil",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map response body to schema
|
||||||
|
err = mapResponseToModel(ctx, waitResp, &data, resp.Diagnostics)
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
crateErr,
|
||||||
|
fmt.Sprintf("processing API payload: %v", err),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save data into Terraform state
|
||||||
|
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||||
|
|
||||||
|
tflog.Info(ctx, "sqlserverflexalpha.Instance created")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||||
|
var data resourceModel
|
||||||
|
|
||||||
|
// Read Terraform prior state data into the model
|
||||||
|
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read identity data
|
||||||
|
var identityData InstanceResourceIdentityModel
|
||||||
|
resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
|
projectId := data.ProjectId.ValueString()
|
||||||
|
region := data.Region.ValueString()
|
||||||
|
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||||
|
ctx = tflog.SetField(ctx, "region", region)
|
||||||
|
|
||||||
|
instanceId := data.InstanceId.ValueString()
|
||||||
|
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
||||||
|
|
||||||
|
instanceResp, err := r.client.GetInstanceRequest(ctx, projectId, region, instanceId).Execute()
|
||||||
|
if err != nil {
|
||||||
|
oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped
|
||||||
|
if ok && oapiErr.StatusCode == http.StatusNotFound {
|
||||||
|
resp.State.RemoveResource(ctx)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading instance", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = core.LogResponse(ctx)
|
||||||
|
|
||||||
|
// Map response body to schema
|
||||||
|
err = mapResponseToModel(ctx, instanceResp, &data, resp.Diagnostics)
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
"Error reading instance",
|
||||||
|
fmt.Sprintf("Processing API payload: %v", err),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save identity into Terraform state
|
||||||
|
identity := InstanceResourceIdentityModel{
|
||||||
|
ProjectID: types.StringValue(projectId),
|
||||||
|
Region: types.StringValue(region),
|
||||||
|
InstanceID: types.StringValue(instanceId),
|
||||||
|
}
|
||||||
|
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save updated data into Terraform state
|
||||||
|
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tflog.Info(ctx, "sqlserverflexalpha.Instance read")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *instanceResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||||
|
var data resourceModel
|
||||||
|
updateInstanceError := "Error updating instance"
|
||||||
|
|
||||||
|
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
|
projectId := data.ProjectId.ValueString()
|
||||||
|
region := data.Region.ValueString()
|
||||||
|
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||||
|
ctx = tflog.SetField(ctx, "region", region)
|
||||||
|
|
||||||
|
instanceId := data.InstanceId.ValueString()
|
||||||
|
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
||||||
|
|
||||||
|
// Generate API request body from model
|
||||||
|
payload, err := toUpdatePayload(ctx, &data, resp)
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
updateInstanceError,
|
||||||
|
fmt.Sprintf("Creating API payload: %v", err),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Update existing instance
|
||||||
|
err = r.client.UpdateInstanceRequest(
|
||||||
|
ctx,
|
||||||
|
projectId,
|
||||||
|
region,
|
||||||
|
instanceId,
|
||||||
|
).UpdateInstanceRequestPayload(*payload).Execute()
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(ctx, &resp.Diagnostics, updateInstanceError, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = core.LogResponse(ctx)
|
||||||
|
|
||||||
|
waitResp, err := wait.
|
||||||
|
UpdateInstanceWaitHandler(ctx, r.client, projectId, instanceId, region).
|
||||||
|
SetSleepBeforeWait(15 * time.Second).
|
||||||
|
SetTimeout(45 * time.Minute).
|
||||||
|
WaitWithContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
updateInstanceError,
|
||||||
|
fmt.Sprintf("Instance update waiting: %v", err),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map response body to schema
|
||||||
|
err = mapResponseToModel(ctx, waitResp, &data, resp.Diagnostics)
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
updateInstanceError,
|
||||||
|
fmt.Sprintf("Processing API payload: %v", err),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
identity := InstanceResourceIdentityModel{
|
||||||
|
ProjectID: types.StringValue(projectId),
|
||||||
|
Region: types.StringValue(region),
|
||||||
|
InstanceID: types.StringValue(instanceId),
|
||||||
|
}
|
||||||
|
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save updated data into Terraform state
|
||||||
|
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tflog.Info(ctx, "sqlserverflexalpha.Instance updated")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||||
|
var data resourceModel
|
||||||
|
|
||||||
|
// Read Terraform prior state data into the model
|
||||||
|
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -207,284 +468,8 @@ func (r *instanceResource) Create(
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
ctx = tflog.SetField(ctx, "region", region)
|
||||||
|
|
||||||
// Generate API request body from model
|
instanceId := identityData.InstanceID.ValueString()
|
||||||
payload, err := toCreatePayload(ctx, &model)
|
|
||||||
if err != nil {
|
|
||||||
core.LogAndAddError(
|
|
||||||
ctx,
|
|
||||||
&resp.Diagnostics,
|
|
||||||
"Error creating instance",
|
|
||||||
fmt.Sprintf("Creating API payload: %v", err),
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Create new instance
|
|
||||||
createResp, err := r.client.CreateInstanceRequest(
|
|
||||||
ctx,
|
|
||||||
projectId,
|
|
||||||
region,
|
|
||||||
).CreateInstanceRequestPayload(*payload).Execute()
|
|
||||||
if err != nil {
|
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating instance", fmt.Sprintf("Calling API: %v", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = core.LogResponse(ctx)
|
|
||||||
|
|
||||||
instanceId := *createResp.Id
|
|
||||||
|
|
||||||
// Set data returned by API in identity
|
|
||||||
identity := InstanceResourceIdentityModel{
|
|
||||||
ProjectID: types.StringValue(projectId),
|
|
||||||
Region: types.StringValue(region),
|
|
||||||
InstanceID: types.StringValue(instanceId),
|
|
||||||
}
|
|
||||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
utils.SetAndLogStateFields(
|
|
||||||
ctx, &resp.Diagnostics, &resp.State, map[string]any{
|
|
||||||
"id": utils.BuildInternalTerraformId(projectId, region, instanceId),
|
|
||||||
"instance_id": instanceId,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// The creation waiter sometimes returns an error from the API: "instance with id xxx has unexpected status Failure"
|
|
||||||
// which can be avoided by sleeping before wait
|
|
||||||
waitResp, err := wait.CreateInstanceWaitHandler(
|
|
||||||
ctx,
|
|
||||||
r.client,
|
|
||||||
projectId,
|
|
||||||
instanceId,
|
|
||||||
region,
|
|
||||||
).SetSleepBeforeWait(
|
|
||||||
30 * time.Second,
|
|
||||||
).SetTimeout(
|
|
||||||
90 * time.Minute,
|
|
||||||
).WaitWithContext(ctx)
|
|
||||||
if err != nil {
|
|
||||||
core.LogAndAddError(
|
|
||||||
ctx,
|
|
||||||
&resp.Diagnostics,
|
|
||||||
"Error creating instance",
|
|
||||||
fmt.Sprintf("Instance creation waiting: %v", err),
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if waitResp.FlavorId == nil {
|
|
||||||
core.LogAndAddError(
|
|
||||||
ctx,
|
|
||||||
&resp.Diagnostics,
|
|
||||||
"Error creating instance",
|
|
||||||
"Instance creation waiting: returned flavor id is nil",
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map response body to schema
|
|
||||||
// err = mapFields(ctx, waitResp, &model, storage, encryption, network, region)
|
|
||||||
err = mapFields(ctx, waitResp, &model, resp.Diagnostics)
|
|
||||||
if err != nil {
|
|
||||||
core.LogAndAddError(
|
|
||||||
ctx,
|
|
||||||
&resp.Diagnostics,
|
|
||||||
"Error creating instance",
|
|
||||||
fmt.Sprintf("Processing API payload: %v", err),
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Set state to fully populated data
|
|
||||||
diags = resp.State.Set(ctx, model)
|
|
||||||
resp.Diagnostics.Append(diags...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tflog.Info(ctx, "SQLServer Flex instance created")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read refreshes the Terraform state with the latest data.
|
|
||||||
func (r *instanceResource) Read(
|
|
||||||
ctx context.Context,
|
|
||||||
req resource.ReadRequest,
|
|
||||||
resp *resource.ReadResponse,
|
|
||||||
) { // nolint:gocritic // function signature required by Terraform
|
|
||||||
var model resourceModel
|
|
||||||
diags := req.State.Get(ctx, &model)
|
|
||||||
resp.Diagnostics.Append(diags...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read identity data
|
|
||||||
var identityData InstanceResourceIdentityModel
|
|
||||||
resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
|
||||||
|
|
||||||
projectId := model.ProjectId.ValueString()
|
|
||||||
instanceId := model.InstanceId.ValueString()
|
|
||||||
region := r.providerData.GetRegionWithOverride(model.Region)
|
|
||||||
|
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
|
||||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
|
||||||
|
|
||||||
instanceResp, err := r.client.GetInstanceRequest(ctx, projectId, region, instanceId).Execute()
|
|
||||||
if err != nil {
|
|
||||||
oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped
|
|
||||||
if ok && oapiErr.StatusCode == http.StatusNotFound {
|
|
||||||
resp.State.RemoveResource(ctx)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading instance", err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = core.LogResponse(ctx)
|
|
||||||
|
|
||||||
// Map response body to schema
|
|
||||||
err = mapFields(ctx, instanceResp, &model, resp.Diagnostics)
|
|
||||||
if err != nil {
|
|
||||||
core.LogAndAddError(
|
|
||||||
ctx,
|
|
||||||
&resp.Diagnostics,
|
|
||||||
"Error reading instance",
|
|
||||||
fmt.Sprintf("Processing API payload: %v", err),
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Set refreshed state
|
|
||||||
diags = resp.State.Set(ctx, model)
|
|
||||||
resp.Diagnostics.Append(diags...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set data returned by API in identity
|
|
||||||
identity := InstanceResourceIdentityModel{
|
|
||||||
ProjectID: types.StringValue(projectId),
|
|
||||||
Region: types.StringValue(region),
|
|
||||||
InstanceID: types.StringValue(instanceId),
|
|
||||||
}
|
|
||||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
tflog.Info(ctx, "SQLServer Flex instance read")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update updates the resource and sets the updated Terraform state on success.
|
|
||||||
func (r *instanceResource) Update(
|
|
||||||
ctx context.Context,
|
|
||||||
req resource.UpdateRequest,
|
|
||||||
resp *resource.UpdateResponse,
|
|
||||||
) { // nolint:gocritic // function signature required by Terraform
|
|
||||||
// Retrieve values from plan
|
|
||||||
var model resourceModel
|
|
||||||
diags := req.Plan.Get(ctx, &model)
|
|
||||||
resp.Diagnostics.Append(diags...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
|
||||||
|
|
||||||
projectId := model.ProjectId.ValueString()
|
|
||||||
instanceId := model.InstanceId.ValueString()
|
|
||||||
region := model.Region.ValueString()
|
|
||||||
|
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
|
||||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
|
||||||
|
|
||||||
// Generate API request body from model
|
|
||||||
payload, err := toUpdatePayload(ctx, &model, resp)
|
|
||||||
if err != nil {
|
|
||||||
core.LogAndAddError(
|
|
||||||
ctx,
|
|
||||||
&resp.Diagnostics,
|
|
||||||
"Error updating instance",
|
|
||||||
fmt.Sprintf("Creating API payload: %v", err),
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Update existing instance
|
|
||||||
err = r.client.UpdateInstanceRequest(
|
|
||||||
ctx,
|
|
||||||
projectId,
|
|
||||||
region,
|
|
||||||
instanceId,
|
|
||||||
).UpdateInstanceRequestPayload(*payload).Execute()
|
|
||||||
if err != nil {
|
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating instance", err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = core.LogResponse(ctx)
|
|
||||||
|
|
||||||
waitResp, err := wait.UpdateInstanceWaitHandler(ctx, r.client, projectId, instanceId, region).WaitWithContext(ctx)
|
|
||||||
if err != nil {
|
|
||||||
core.LogAndAddError(
|
|
||||||
ctx,
|
|
||||||
&resp.Diagnostics,
|
|
||||||
"Error updating instance",
|
|
||||||
fmt.Sprintf("Instance update waiting: %v", err),
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map response body to schema
|
|
||||||
err = mapFields(ctx, waitResp, &model, resp.Diagnostics)
|
|
||||||
// err = mapFields(ctx, waitResp, &model, storage, encryption, network, region)
|
|
||||||
if err != nil {
|
|
||||||
core.LogAndAddError(
|
|
||||||
ctx,
|
|
||||||
&resp.Diagnostics,
|
|
||||||
"Error updating instance",
|
|
||||||
fmt.Sprintf("Processing API payload: %v", err),
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
diags = resp.State.Set(ctx, model)
|
|
||||||
resp.Diagnostics.Append(diags...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
tflog.Info(ctx, "SQLServer Flex instance updated")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete deletes the resource and removes the Terraform state on success.
|
|
||||||
func (r *instanceResource) Delete(
|
|
||||||
ctx context.Context,
|
|
||||||
req resource.DeleteRequest,
|
|
||||||
resp *resource.DeleteResponse,
|
|
||||||
) { // nolint:gocritic // function signature required by Terraform
|
|
||||||
// Retrieve values from state
|
|
||||||
var model resourceModel
|
|
||||||
diags := req.State.Get(ctx, &model)
|
|
||||||
resp.Diagnostics.Append(diags...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
|
||||||
|
|
||||||
projectId := model.ProjectId.ValueString()
|
|
||||||
instanceId := model.InstanceId.ValueString()
|
|
||||||
region := model.Region.ValueString()
|
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
|
||||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
|
||||||
|
|
||||||
// Delete existing instance
|
// Delete existing instance
|
||||||
err := r.client.DeleteInstanceRequest(ctx, projectId, region, instanceId).Execute()
|
err := r.client.DeleteInstanceRequest(ctx, projectId, region, instanceId).Execute()
|
||||||
|
|
@ -495,7 +480,7 @@ func (r *instanceResource) Delete(
|
||||||
|
|
||||||
ctx = core.LogResponse(ctx)
|
ctx = core.LogResponse(ctx)
|
||||||
|
|
||||||
_, err = wait.DeleteInstanceWaitHandler(ctx, r.client, projectId, instanceId, region).WaitWithContext(ctx)
|
delResp, err := wait.DeleteInstanceWaitHandler(ctx, r.client, projectId, instanceId, region).WaitWithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
ctx,
|
ctx,
|
||||||
|
|
@ -505,16 +490,31 @@ func (r *instanceResource) Delete(
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tflog.Info(ctx, "SQLServer Flex instance deleted")
|
|
||||||
|
if delResp != nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
"Error deleting instance",
|
||||||
|
"wait handler returned non nil result",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.State.RemoveResource(ctx)
|
||||||
|
|
||||||
|
tflog.Info(ctx, "sqlserverflexalpha.Instance deleted")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImportState imports a resource into the Terraform state on success.
|
// ImportState imports a resource into the Terraform state on success.
|
||||||
// The expected format of the resource import identifier is: project_id,instance_id
|
// The expected format of the resource import identifier is: project_id,zone_id,record_set_id
|
||||||
func (r *instanceResource) ImportState(
|
func (r *instanceResource) ImportState(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req resource.ImportStateRequest,
|
req resource.ImportStateRequest,
|
||||||
resp *resource.ImportStateResponse,
|
resp *resource.ImportStateResponse,
|
||||||
) {
|
) {
|
||||||
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
if req.ID != "" {
|
if req.ID != "" {
|
||||||
idParts := strings.Split(req.ID, core.Separator)
|
idParts := strings.Split(req.ID, core.Separator)
|
||||||
|
|
||||||
|
|
@ -551,5 +551,5 @@ func (r *instanceResource) ImportState(
|
||||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), region)...)
|
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), region)...)
|
||||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), instanceId)...)
|
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), instanceId)...)
|
||||||
|
|
||||||
tflog.Info(ctx, "SQLServer Flex instance state imported")
|
tflog.Info(ctx, "sqlserverflexalpha instance state imported")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,823 +0,0 @@
|
||||||
package sqlserverflexalpha
|
|
||||||
|
|
||||||
// type sqlserverflexClientMocked struct {
|
|
||||||
// returnError bool
|
|
||||||
// listFlavorsResp *sqlserverflex.GetFlavorsResponse
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// func (c *sqlserverflexClientMocked) GetFlavorsExecute(_ context.Context, _, _ string) (*sqlserverflex.GetFlavorsResponse, error) {
|
|
||||||
// if c.returnError {
|
|
||||||
// return nil, fmt.Errorf("get flavors failed")
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return c.listFlavorsResp, nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func TestMapFields(t *testing.T) {
|
|
||||||
// t.Skip("Skipping - needs refactoring")
|
|
||||||
// const testRegion = "region"
|
|
||||||
// tests := []struct {
|
|
||||||
// description string
|
|
||||||
// state Model
|
|
||||||
// input *sqlserverflex.GetInstanceResponse
|
|
||||||
// storage *storageModel
|
|
||||||
// encryption *encryptionModel
|
|
||||||
// network *networkModel
|
|
||||||
// region string
|
|
||||||
// expected Model
|
|
||||||
// isValid bool
|
|
||||||
// }{
|
|
||||||
// {
|
|
||||||
// "default_values",
|
|
||||||
// Model{
|
|
||||||
// InstanceId: types.StringValue("iid"),
|
|
||||||
// ProjectId: types.StringValue("pid"),
|
|
||||||
// Replicas: types.Int64Value(1),
|
|
||||||
// RetentionDays: types.Int64Value(1),
|
|
||||||
// Version: types.StringValue("v1"),
|
|
||||||
// Edition: types.StringValue("edition 1"),
|
|
||||||
// Status: types.StringValue("status"),
|
|
||||||
// IsDeletable: types.BoolValue(true),
|
|
||||||
// },
|
|
||||||
// &sqlserverflex.GetInstanceResponse{
|
|
||||||
// FlavorId: utils.Ptr("flavor_id"),
|
|
||||||
// Replicas: sqlserverflex.GetInstanceResponseGetReplicasAttributeType(utils.Ptr(int32(1))),
|
|
||||||
// RetentionDays: utils.Ptr(int64(1)),
|
|
||||||
// Version: sqlserverflex.GetInstanceResponseGetVersionAttributeType(utils.Ptr("v1")),
|
|
||||||
// Edition: sqlserverflex.GetInstanceResponseGetEditionAttributeType(utils.Ptr("edition 1")),
|
|
||||||
// Status: sqlserverflex.GetInstanceResponseGetStatusAttributeType(utils.Ptr("status")),
|
|
||||||
// IsDeletable: utils.Ptr(true),
|
|
||||||
// },
|
|
||||||
// &storageModel{},
|
|
||||||
// &encryptionModel{},
|
|
||||||
// &networkModel{
|
|
||||||
// ACL: types.ListNull(basetypes.StringType{}),
|
|
||||||
// },
|
|
||||||
// testRegion,
|
|
||||||
// Model{
|
|
||||||
// Id: types.StringValue("pid,region,iid"),
|
|
||||||
// InstanceId: types.StringValue("iid"),
|
|
||||||
// ProjectId: types.StringValue("pid"),
|
|
||||||
// Name: types.StringNull(),
|
|
||||||
// BackupSchedule: types.StringNull(),
|
|
||||||
// Replicas: types.Int64Value(1),
|
|
||||||
// Storage: types.ObjectValueMust(storageTypes, map[string]attr.Value{
|
|
||||||
// "class": types.StringNull(),
|
|
||||||
// "size": types.Int64Null(),
|
|
||||||
// }),
|
|
||||||
// Encryption: types.ObjectValueMust(encryptionTypes, map[string]attr.Value{
|
|
||||||
// "keyring_id": types.StringNull(),
|
|
||||||
// "key_id": types.StringNull(),
|
|
||||||
// "key_version": types.StringNull(),
|
|
||||||
// "service_account": types.StringNull(),
|
|
||||||
// }),
|
|
||||||
// Network: types.ObjectValueMust(networkTypes, map[string]attr.Value{
|
|
||||||
// "acl": types.ListNull(types.StringType),
|
|
||||||
// "access_scope": types.StringNull(),
|
|
||||||
// "instance_address": types.StringNull(),
|
|
||||||
// "router_address": types.StringNull(),
|
|
||||||
// }),
|
|
||||||
// IsDeletable: types.BoolValue(true),
|
|
||||||
// Edition: types.StringValue("edition 1"),
|
|
||||||
// Status: types.StringValue("status"),
|
|
||||||
// RetentionDays: types.Int64Value(1),
|
|
||||||
// Version: types.StringValue("v1"),
|
|
||||||
// Region: types.StringValue(testRegion),
|
|
||||||
// },
|
|
||||||
// true,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "simple_values",
|
|
||||||
// Model{
|
|
||||||
// InstanceId: types.StringValue("iid"),
|
|
||||||
// ProjectId: types.StringValue("pid"),
|
|
||||||
// },
|
|
||||||
// &sqlserverflex.GetInstanceResponse{
|
|
||||||
// BackupSchedule: utils.Ptr("schedule"),
|
|
||||||
// FlavorId: utils.Ptr("flavor_id"),
|
|
||||||
// Id: utils.Ptr("iid"),
|
|
||||||
// Name: utils.Ptr("name"),
|
|
||||||
// Replicas: sqlserverflex.GetInstanceResponseGetReplicasAttributeType(utils.Ptr(int32(56))),
|
|
||||||
// Status: sqlserverflex.GetInstanceResponseGetStatusAttributeType(utils.Ptr("status")),
|
|
||||||
// Storage: &sqlserverflex.Storage{
|
|
||||||
// Class: utils.Ptr("class"),
|
|
||||||
// Size: utils.Ptr(int64(78)),
|
|
||||||
// },
|
|
||||||
// Edition: sqlserverflex.GetInstanceResponseGetEditionAttributeType(utils.Ptr("edition")),
|
|
||||||
// RetentionDays: utils.Ptr(int64(1)),
|
|
||||||
// Version: sqlserverflex.GetInstanceResponseGetVersionAttributeType(utils.Ptr("version")),
|
|
||||||
// IsDeletable: utils.Ptr(true),
|
|
||||||
// Encryption: nil,
|
|
||||||
// Network: &sqlserverflex.InstanceNetwork{
|
|
||||||
// AccessScope: nil,
|
|
||||||
// Acl: &[]string{
|
|
||||||
// "ip1",
|
|
||||||
// "ip2",
|
|
||||||
// "",
|
|
||||||
// },
|
|
||||||
// InstanceAddress: nil,
|
|
||||||
// RouterAddress: nil,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// &storageModel{},
|
|
||||||
// &encryptionModel{},
|
|
||||||
// &networkModel{
|
|
||||||
// ACL: types.ListValueMust(basetypes.StringType{}, []attr.Value{
|
|
||||||
// types.StringValue("ip1"),
|
|
||||||
// types.StringValue("ip2"),
|
|
||||||
// types.StringValue(""),
|
|
||||||
// }),
|
|
||||||
// },
|
|
||||||
// testRegion,
|
|
||||||
// Model{
|
|
||||||
// Id: types.StringValue("pid,region,iid"),
|
|
||||||
// InstanceId: types.StringValue("iid"),
|
|
||||||
// ProjectId: types.StringValue("pid"),
|
|
||||||
// Name: types.StringValue("name"),
|
|
||||||
// BackupSchedule: types.StringValue("schedule"),
|
|
||||||
// Replicas: types.Int64Value(56),
|
|
||||||
// Storage: types.ObjectValueMust(storageTypes, map[string]attr.Value{
|
|
||||||
// "class": types.StringValue("class"),
|
|
||||||
// "size": types.Int64Value(78),
|
|
||||||
// }),
|
|
||||||
// Network: types.ObjectValueMust(networkTypes, map[string]attr.Value{
|
|
||||||
// "acl": types.ListValueMust(types.StringType, []attr.Value{
|
|
||||||
// types.StringValue("ip1"),
|
|
||||||
// types.StringValue("ip2"),
|
|
||||||
// types.StringValue(""),
|
|
||||||
// }),
|
|
||||||
// "access_scope": types.StringNull(),
|
|
||||||
// "instance_address": types.StringNull(),
|
|
||||||
// "router_address": types.StringNull(),
|
|
||||||
// }),
|
|
||||||
// Edition: types.StringValue("edition"),
|
|
||||||
// RetentionDays: types.Int64Value(1),
|
|
||||||
// Version: types.StringValue("version"),
|
|
||||||
// Region: types.StringValue(testRegion),
|
|
||||||
// IsDeletable: types.BoolValue(true),
|
|
||||||
// Encryption: types.ObjectValueMust(encryptionTypes, map[string]attr.Value{
|
|
||||||
// "keyring_id": types.StringNull(),
|
|
||||||
// "key_id": types.StringNull(),
|
|
||||||
// "key_version": types.StringNull(),
|
|
||||||
// "service_account": types.StringNull(),
|
|
||||||
// }),
|
|
||||||
// Status: types.StringValue("status"),
|
|
||||||
// },
|
|
||||||
// true,
|
|
||||||
// },
|
|
||||||
// // {
|
|
||||||
// // "simple_values_no_flavor_and_storage",
|
|
||||||
// // Model{
|
|
||||||
// // InstanceId: types.StringValue("iid"),
|
|
||||||
// // ProjectId: types.StringValue("pid"),
|
|
||||||
// // },
|
|
||||||
// // &sqlserverflex.GetInstanceResponse{
|
|
||||||
// // Acl: &[]string{
|
|
||||||
// // "ip1",
|
|
||||||
// // "ip2",
|
|
||||||
// // "",
|
|
||||||
// // },
|
|
||||||
// // BackupSchedule: utils.Ptr("schedule"),
|
|
||||||
// // FlavorId: nil,
|
|
||||||
// // Id: utils.Ptr("iid"),
|
|
||||||
// // Name: utils.Ptr("name"),
|
|
||||||
// // Replicas: sqlserverflex.GetInstanceResponseGetReplicasAttributeType(utils.Ptr(int32(56))),
|
|
||||||
// // Status: sqlserverflex.GetInstanceResponseGetStatusAttributeType(utils.Ptr("status")),
|
|
||||||
// // Storage: nil,
|
|
||||||
// // Edition: sqlserverflex.GetInstanceResponseGetEditionAttributeType(utils.Ptr("edition")),
|
|
||||||
// // RetentionDays: utils.Ptr(int64(1)),
|
|
||||||
// // Version: sqlserverflex.GetInstanceResponseGetVersionAttributeType(utils.Ptr("version")),
|
|
||||||
// // },
|
|
||||||
// // &flavorModel{
|
|
||||||
// // CPU: types.Int64Value(12),
|
|
||||||
// // RAM: types.Int64Value(34),
|
|
||||||
// // },
|
|
||||||
// // &storageModel{
|
|
||||||
// // Class: types.StringValue("class"),
|
|
||||||
// // Size: types.Int64Value(78),
|
|
||||||
// // },
|
|
||||||
// // &optionsModel{
|
|
||||||
// // Edition: types.StringValue("edition"),
|
|
||||||
// // RetentionDays: types.Int64Value(1),
|
|
||||||
// // },
|
|
||||||
// // testRegion,
|
|
||||||
// // Model{
|
|
||||||
// // Id: types.StringValue("pid,region,iid"),
|
|
||||||
// // InstanceId: types.StringValue("iid"),
|
|
||||||
// // ProjectId: types.StringValue("pid"),
|
|
||||||
// // Name: types.StringValue("name"),
|
|
||||||
// // ACL: types.ListValueMust(types.StringType, []attr.Value{
|
|
||||||
// // types.StringValue("ip1"),
|
|
||||||
// // types.StringValue("ip2"),
|
|
||||||
// // types.StringValue(""),
|
|
||||||
// // }),
|
|
||||||
// // BackupSchedule: types.StringValue("schedule"),
|
|
||||||
// // Flavor: types.ObjectValueMust(flavorTypes, map[string]attr.Value{
|
|
||||||
// // "id": types.StringNull(),
|
|
||||||
// // "description": types.StringNull(),
|
|
||||||
// // "cpu": types.Int64Value(12),
|
|
||||||
// // "ram": types.Int64Value(34),
|
|
||||||
// // }),
|
|
||||||
// // Replicas: types.Int64Value(56),
|
|
||||||
// // Storage: types.ObjectValueMust(storageTypes, map[string]attr.Value{
|
|
||||||
// // "class": types.StringValue("class"),
|
|
||||||
// // "size": types.Int64Value(78),
|
|
||||||
// // }),
|
|
||||||
// // Options: types.ObjectValueMust(optionsTypes, map[string]attr.Value{
|
|
||||||
// // "edition": types.StringValue("edition"),
|
|
||||||
// // "retention_days": types.Int64Value(1),
|
|
||||||
// // }),
|
|
||||||
// // Version: types.StringValue("version"),
|
|
||||||
// // Region: types.StringValue(testRegion),
|
|
||||||
// // },
|
|
||||||
// // true,
|
|
||||||
// // },
|
|
||||||
// // {
|
|
||||||
// // "acls_unordered",
|
|
||||||
// // Model{
|
|
||||||
// // InstanceId: types.StringValue("iid"),
|
|
||||||
// // ProjectId: types.StringValue("pid"),
|
|
||||||
// // ACL: types.ListValueMust(types.StringType, []attr.Value{
|
|
||||||
// // types.StringValue("ip2"),
|
|
||||||
// // types.StringValue(""),
|
|
||||||
// // types.StringValue("ip1"),
|
|
||||||
// // }),
|
|
||||||
// // },
|
|
||||||
// // &sqlserverflex.GetInstanceResponse{
|
|
||||||
// // Acl: &[]string{
|
|
||||||
// // "",
|
|
||||||
// // "ip1",
|
|
||||||
// // "ip2",
|
|
||||||
// // },
|
|
||||||
// // BackupSchedule: utils.Ptr("schedule"),
|
|
||||||
// // FlavorId: nil,
|
|
||||||
// // Id: utils.Ptr("iid"),
|
|
||||||
// // Name: utils.Ptr("name"),
|
|
||||||
// // Replicas: sqlserverflex.GetInstanceResponseGetReplicasAttributeType(utils.Ptr(int32(56))),
|
|
||||||
// // Status: sqlserverflex.GetInstanceResponseGetStatusAttributeType(utils.Ptr("status")),
|
|
||||||
// // Storage: nil,
|
|
||||||
// // //Options: &map[string]string{
|
|
||||||
// // // "edition": "edition",
|
|
||||||
// // // "retentionDays": "1",
|
|
||||||
// // //},
|
|
||||||
// // Version: sqlserverflex.GetInstanceResponseGetVersionAttributeType(utils.Ptr("version")),
|
|
||||||
// // },
|
|
||||||
// // &flavorModel{
|
|
||||||
// // CPU: types.Int64Value(12),
|
|
||||||
// // RAM: types.Int64Value(34),
|
|
||||||
// // },
|
|
||||||
// // &storageModel{
|
|
||||||
// // Class: types.StringValue("class"),
|
|
||||||
// // Size: types.Int64Value(78),
|
|
||||||
// // },
|
|
||||||
// // &optionsModel{},
|
|
||||||
// // testRegion,
|
|
||||||
// // Model{
|
|
||||||
// // Id: types.StringValue("pid,region,iid"),
|
|
||||||
// // InstanceId: types.StringValue("iid"),
|
|
||||||
// // ProjectId: types.StringValue("pid"),
|
|
||||||
// // Name: types.StringValue("name"),
|
|
||||||
// // ACL: types.ListValueMust(types.StringType, []attr.Value{
|
|
||||||
// // types.StringValue("ip2"),
|
|
||||||
// // types.StringValue(""),
|
|
||||||
// // types.StringValue("ip1"),
|
|
||||||
// // }),
|
|
||||||
// // BackupSchedule: types.StringValue("schedule"),
|
|
||||||
// // Flavor: types.ObjectValueMust(flavorTypes, map[string]attr.Value{
|
|
||||||
// // "id": types.StringNull(),
|
|
||||||
// // "description": types.StringNull(),
|
|
||||||
// // "cpu": types.Int64Value(12),
|
|
||||||
// // "ram": types.Int64Value(34),
|
|
||||||
// // }),
|
|
||||||
// // Replicas: types.Int64Value(56),
|
|
||||||
// // Storage: types.ObjectValueMust(storageTypes, map[string]attr.Value{
|
|
||||||
// // "class": types.StringValue("class"),
|
|
||||||
// // "size": types.Int64Value(78),
|
|
||||||
// // }),
|
|
||||||
// // Options: types.ObjectValueMust(optionsTypes, map[string]attr.Value{
|
|
||||||
// // "edition": types.StringValue("edition"),
|
|
||||||
// // "retention_days": types.Int64Value(1),
|
|
||||||
// // }),
|
|
||||||
// // Version: types.StringValue("version"),
|
|
||||||
// // Region: types.StringValue(testRegion),
|
|
||||||
// // },
|
|
||||||
// // true,
|
|
||||||
// // },
|
|
||||||
// // {
|
|
||||||
// // "nil_response",
|
|
||||||
// // Model{
|
|
||||||
// // InstanceId: types.StringValue("iid"),
|
|
||||||
// // ProjectId: types.StringValue("pid"),
|
|
||||||
// // },
|
|
||||||
// // nil,
|
|
||||||
// // &flavorModel{},
|
|
||||||
// // &storageModel{},
|
|
||||||
// // &optionsModel{},
|
|
||||||
// // testRegion,
|
|
||||||
// // Model{},
|
|
||||||
// // false,
|
|
||||||
// // },
|
|
||||||
// // {
|
|
||||||
// // "no_resource_id",
|
|
||||||
// // Model{
|
|
||||||
// // InstanceId: types.StringValue("iid"),
|
|
||||||
// // ProjectId: types.StringValue("pid"),
|
|
||||||
// // },
|
|
||||||
// // &sqlserverflex.GetInstanceResponse{},
|
|
||||||
// // &flavorModel{},
|
|
||||||
// // &storageModel{},
|
|
||||||
// // &optionsModel{},
|
|
||||||
// // testRegion,
|
|
||||||
// // Model{},
|
|
||||||
// // false,
|
|
||||||
// // },
|
|
||||||
// }
|
|
||||||
// for _, tt := range tests {
|
|
||||||
// t.Run(tt.description, func(t *testing.T) {
|
|
||||||
// err := mapFields(context.Background(), tt.input, &tt.state, tt.storage, tt.encryption, tt.network, tt.region)
|
|
||||||
// if !tt.isValid && err == nil {
|
|
||||||
// t.Fatalf("Should have failed")
|
|
||||||
// }
|
|
||||||
// if tt.isValid && err != nil {
|
|
||||||
// t.Fatalf("Should not have failed: %v", err)
|
|
||||||
// }
|
|
||||||
// if tt.isValid {
|
|
||||||
// diff := cmp.Diff(tt.state, tt.expected)
|
|
||||||
// if diff != "" {
|
|
||||||
// t.Fatalf("Data does not match: %s", diff)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
// func TestToCreatePayload(t *testing.T) {
|
|
||||||
// tests := []struct {
|
|
||||||
// description string
|
|
||||||
// input *Model
|
|
||||||
// inputAcl []string
|
|
||||||
// inputFlavor *flavorModel
|
|
||||||
// inputStorage *storageModel
|
|
||||||
// inputOptions *optionsModel
|
|
||||||
// expected *sqlserverflex.CreateInstanceRequestPayload
|
|
||||||
// isValid bool
|
|
||||||
// }{
|
|
||||||
// {
|
|
||||||
// "default_values",
|
|
||||||
// &Model{},
|
|
||||||
// []string{},
|
|
||||||
// &flavorModel{},
|
|
||||||
// &storageModel{},
|
|
||||||
// &optionsModel{},
|
|
||||||
// &sqlserverflex.CreateInstanceRequestPayload{
|
|
||||||
// Acl: &sqlserverflex.CreateInstanceRequestPayloadGetAclArgType{},
|
|
||||||
// Storage: &sqlserverflex.CreateInstanceRequestPayloadGetStorageArgType{},
|
|
||||||
// },
|
|
||||||
// true,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "simple_values",
|
|
||||||
// &Model{
|
|
||||||
// BackupSchedule: types.StringValue("schedule"),
|
|
||||||
// Name: types.StringValue("name"),
|
|
||||||
// Replicas: types.Int64Value(12),
|
|
||||||
// Version: types.StringValue("version"),
|
|
||||||
// },
|
|
||||||
// []string{
|
|
||||||
// "ip_1",
|
|
||||||
// "ip_2",
|
|
||||||
// },
|
|
||||||
// &flavorModel{
|
|
||||||
// Id: types.StringValue("flavor_id"),
|
|
||||||
// },
|
|
||||||
// &storageModel{
|
|
||||||
// Class: types.StringValue("class"),
|
|
||||||
// Size: types.Int64Value(34),
|
|
||||||
// },
|
|
||||||
// &optionsModel{
|
|
||||||
// Edition: types.StringValue("edition"),
|
|
||||||
// RetentionDays: types.Int64Value(1),
|
|
||||||
// },
|
|
||||||
// &sqlserverflex.CreateInstancePayload{
|
|
||||||
// Acl: &sqlserverflex.CreateInstancePayloadAcl{
|
|
||||||
// Items: &[]string{
|
|
||||||
// "ip_1",
|
|
||||||
// "ip_2",
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// BackupSchedule: utils.Ptr("schedule"),
|
|
||||||
// FlavorId: utils.Ptr("flavor_id"),
|
|
||||||
// Name: utils.Ptr("name"),
|
|
||||||
// Storage: &sqlserverflex.CreateInstancePayloadStorage{
|
|
||||||
// Class: utils.Ptr("class"),
|
|
||||||
// Size: utils.Ptr(int64(34)),
|
|
||||||
// },
|
|
||||||
// Options: &sqlserverflex.CreateInstancePayloadOptions{
|
|
||||||
// Edition: utils.Ptr("edition"),
|
|
||||||
// RetentionDays: utils.Ptr("1"),
|
|
||||||
// },
|
|
||||||
// Version: utils.Ptr("version"),
|
|
||||||
// },
|
|
||||||
// true,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "null_fields_and_int_conversions",
|
|
||||||
// &Model{
|
|
||||||
// BackupSchedule: types.StringNull(),
|
|
||||||
// Name: types.StringNull(),
|
|
||||||
// Replicas: types.Int64Value(2123456789),
|
|
||||||
// Version: types.StringNull(),
|
|
||||||
// },
|
|
||||||
// []string{
|
|
||||||
// "",
|
|
||||||
// },
|
|
||||||
// &flavorModel{
|
|
||||||
// Id: types.StringNull(),
|
|
||||||
// },
|
|
||||||
// &storageModel{
|
|
||||||
// Class: types.StringNull(),
|
|
||||||
// Size: types.Int64Null(),
|
|
||||||
// },
|
|
||||||
// &optionsModel{
|
|
||||||
// Edition: types.StringNull(),
|
|
||||||
// RetentionDays: types.Int64Null(),
|
|
||||||
// },
|
|
||||||
// &sqlserverflex.CreateInstancePayload{
|
|
||||||
// Acl: &sqlserverflex.CreateInstancePayloadAcl{
|
|
||||||
// Items: &[]string{
|
|
||||||
// "",
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// BackupSchedule: nil,
|
|
||||||
// FlavorId: nil,
|
|
||||||
// Name: nil,
|
|
||||||
// Storage: &sqlserverflex.CreateInstancePayloadStorage{
|
|
||||||
// Class: nil,
|
|
||||||
// Size: nil,
|
|
||||||
// },
|
|
||||||
// Options: &sqlserverflex.CreateInstancePayloadOptions{},
|
|
||||||
// Version: nil,
|
|
||||||
// },
|
|
||||||
// true,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "nil_model",
|
|
||||||
// nil,
|
|
||||||
// []string{},
|
|
||||||
// &flavorModel{},
|
|
||||||
// &storageModel{},
|
|
||||||
// &optionsModel{},
|
|
||||||
// nil,
|
|
||||||
// false,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "nil_acl",
|
|
||||||
// &Model{},
|
|
||||||
// nil,
|
|
||||||
// &flavorModel{},
|
|
||||||
// &storageModel{},
|
|
||||||
// &optionsModel{},
|
|
||||||
// &sqlserverflex.CreateInstancePayload{
|
|
||||||
// Acl: &sqlserverflex.CreateInstancePayloadAcl{},
|
|
||||||
// Storage: &sqlserverflex.CreateInstancePayloadStorage{},
|
|
||||||
// Options: &sqlserverflex.CreateInstancePayloadOptions{},
|
|
||||||
// },
|
|
||||||
// true,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "nil_flavor",
|
|
||||||
// &Model{},
|
|
||||||
// []string{},
|
|
||||||
// nil,
|
|
||||||
// &storageModel{},
|
|
||||||
// &optionsModel{},
|
|
||||||
// nil,
|
|
||||||
// false,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "nil_storage",
|
|
||||||
// &Model{},
|
|
||||||
// []string{},
|
|
||||||
// &flavorModel{},
|
|
||||||
// nil,
|
|
||||||
// &optionsModel{},
|
|
||||||
// &sqlserverflex.CreateInstancePayload{
|
|
||||||
// Acl: &sqlserverflex.CreateInstancePayloadAcl{
|
|
||||||
// Items: &[]string{},
|
|
||||||
// },
|
|
||||||
// Storage: &sqlserverflex.CreateInstancePayloadStorage{},
|
|
||||||
// Options: &sqlserverflex.CreateInstancePayloadOptions{},
|
|
||||||
// },
|
|
||||||
// true,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "nil_options",
|
|
||||||
// &Model{},
|
|
||||||
// []string{},
|
|
||||||
// &flavorModel{},
|
|
||||||
// &storageModel{},
|
|
||||||
// nil,
|
|
||||||
// &sqlserverflex.CreateInstancePayload{
|
|
||||||
// Acl: &sqlserverflex.CreateInstancePayloadAcl{
|
|
||||||
// Items: &[]string{},
|
|
||||||
// },
|
|
||||||
// Storage: &sqlserverflex.CreateInstancePayloadStorage{},
|
|
||||||
// Options: &sqlserverflex.CreateInstancePayloadOptions{},
|
|
||||||
// },
|
|
||||||
// true,
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
// for _, tt := range tests {
|
|
||||||
// t.Run(tt.description, func(t *testing.T) {
|
|
||||||
// output, err := toCreatePayload(tt.input, tt.inputAcl, tt.inputFlavor, tt.inputStorage, tt.inputOptions)
|
|
||||||
// if !tt.isValid && err == nil {
|
|
||||||
// t.Fatalf("Should have failed")
|
|
||||||
// }
|
|
||||||
// if tt.isValid && err != nil {
|
|
||||||
// t.Fatalf("Should not have failed: %v", err)
|
|
||||||
// }
|
|
||||||
// if tt.isValid {
|
|
||||||
// diff := cmp.Diff(output, tt.expected)
|
|
||||||
// if diff != "" {
|
|
||||||
// t.Fatalf("Data does not match: %s", diff)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// func TestToUpdatePayload(t *testing.T) {
|
|
||||||
// tests := []struct {
|
|
||||||
// description string
|
|
||||||
// input *Model
|
|
||||||
// inputAcl []string
|
|
||||||
// inputFlavor *flavorModel
|
|
||||||
// expected *sqlserverflex.PartialUpdateInstancePayload
|
|
||||||
// isValid bool
|
|
||||||
// }{
|
|
||||||
// {
|
|
||||||
// "default_values",
|
|
||||||
// &Model{},
|
|
||||||
// []string{},
|
|
||||||
// &flavorModel{},
|
|
||||||
// &sqlserverflex.PartialUpdateInstancePayload{
|
|
||||||
// Acl: &sqlserverflex.CreateInstancePayloadAcl{
|
|
||||||
// Items: &[]string{},
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// true,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "simple_values",
|
|
||||||
// &Model{
|
|
||||||
// BackupSchedule: types.StringValue("schedule"),
|
|
||||||
// Name: types.StringValue("name"),
|
|
||||||
// Replicas: types.Int64Value(12),
|
|
||||||
// Version: types.StringValue("version"),
|
|
||||||
// },
|
|
||||||
// []string{
|
|
||||||
// "ip_1",
|
|
||||||
// "ip_2",
|
|
||||||
// },
|
|
||||||
// &flavorModel{
|
|
||||||
// Id: types.StringValue("flavor_id"),
|
|
||||||
// },
|
|
||||||
// &sqlserverflex.PartialUpdateInstancePayload{
|
|
||||||
// Acl: &sqlserverflex.CreateInstancePayloadAcl{
|
|
||||||
// Items: &[]string{
|
|
||||||
// "ip_1",
|
|
||||||
// "ip_2",
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// BackupSchedule: utils.Ptr("schedule"),
|
|
||||||
// FlavorId: utils.Ptr("flavor_id"),
|
|
||||||
// Name: utils.Ptr("name"),
|
|
||||||
// Version: utils.Ptr("version"),
|
|
||||||
// },
|
|
||||||
// true,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "null_fields_and_int_conversions",
|
|
||||||
// &Model{
|
|
||||||
// BackupSchedule: types.StringNull(),
|
|
||||||
// Name: types.StringNull(),
|
|
||||||
// Replicas: types.Int64Value(2123456789),
|
|
||||||
// Version: types.StringNull(),
|
|
||||||
// },
|
|
||||||
// []string{
|
|
||||||
// "",
|
|
||||||
// },
|
|
||||||
// &flavorModel{
|
|
||||||
// Id: types.StringNull(),
|
|
||||||
// },
|
|
||||||
// &sqlserverflex.PartialUpdateInstancePayload{
|
|
||||||
// Acl: &sqlserverflex.CreateInstancePayloadAcl{
|
|
||||||
// Items: &[]string{
|
|
||||||
// "",
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// BackupSchedule: nil,
|
|
||||||
// FlavorId: nil,
|
|
||||||
// Name: nil,
|
|
||||||
// Version: nil,
|
|
||||||
// },
|
|
||||||
// true,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "nil_model",
|
|
||||||
// nil,
|
|
||||||
// []string{},
|
|
||||||
// &flavorModel{},
|
|
||||||
// nil,
|
|
||||||
// false,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "nil_acl",
|
|
||||||
// &Model{},
|
|
||||||
// nil,
|
|
||||||
// &flavorModel{},
|
|
||||||
// &sqlserverflex.PartialUpdateInstancePayload{
|
|
||||||
// Acl: &sqlserverflex.CreateInstancePayloadAcl{},
|
|
||||||
// },
|
|
||||||
// true,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "nil_flavor",
|
|
||||||
// &Model{},
|
|
||||||
// []string{},
|
|
||||||
// nil,
|
|
||||||
// nil,
|
|
||||||
// false,
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
// for _, tt := range tests {
|
|
||||||
// t.Run(tt.description, func(t *testing.T) {
|
|
||||||
// output, err := toUpdatePayload(tt.input, tt.inputAcl, tt.inputFlavor)
|
|
||||||
// if !tt.isValid && err == nil {
|
|
||||||
// t.Fatalf("Should have failed")
|
|
||||||
// }
|
|
||||||
// if tt.isValid && err != nil {
|
|
||||||
// t.Fatalf("Should not have failed: %v", err)
|
|
||||||
// }
|
|
||||||
// if tt.isValid {
|
|
||||||
// diff := cmp.Diff(output, tt.expected)
|
|
||||||
// if diff != "" {
|
|
||||||
// t.Fatalf("Data does not match: %s", diff)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// func TestLoadFlavorId(t *testing.T) {
|
|
||||||
// tests := []struct {
|
|
||||||
// description string
|
|
||||||
// inputFlavor *flavorModel
|
|
||||||
// mockedResp *sqlserverflex.ListFlavorsResponse
|
|
||||||
// expected *flavorModel
|
|
||||||
// getFlavorsFails bool
|
|
||||||
// isValid bool
|
|
||||||
// }{
|
|
||||||
// {
|
|
||||||
// "ok_flavor",
|
|
||||||
// &flavorModel{
|
|
||||||
// CPU: types.Int64Value(2),
|
|
||||||
// RAM: types.Int64Value(8),
|
|
||||||
// },
|
|
||||||
// &sqlserverflex.ListFlavorsResponse{
|
|
||||||
// Flavors: &[]sqlserverflex.InstanceFlavorEntry{
|
|
||||||
// {
|
|
||||||
// Id: utils.Ptr("fid-1"),
|
|
||||||
// Cpu: utils.Ptr(int64(2)),
|
|
||||||
// Description: utils.Ptr("description"),
|
|
||||||
// Ram: utils.Ptr(int64(8)),
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// &flavorModel{
|
|
||||||
// Id: types.StringValue("fid-1"),
|
|
||||||
// Description: types.StringValue("description"),
|
|
||||||
// CPU: types.Int64Value(2),
|
|
||||||
// RAM: types.Int64Value(8),
|
|
||||||
// },
|
|
||||||
// false,
|
|
||||||
// true,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "ok_flavor_2",
|
|
||||||
// &flavorModel{
|
|
||||||
// CPU: types.Int64Value(2),
|
|
||||||
// RAM: types.Int64Value(8),
|
|
||||||
// },
|
|
||||||
// &sqlserverflex.ListFlavorsResponse{
|
|
||||||
// Flavors: &[]sqlserverflex.InstanceFlavorEntry{
|
|
||||||
// {
|
|
||||||
// Id: utils.Ptr("fid-1"),
|
|
||||||
// Cpu: utils.Ptr(int64(2)),
|
|
||||||
// Description: utils.Ptr("description"),
|
|
||||||
// Ram: utils.Ptr(int64(8)),
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// Id: utils.Ptr("fid-2"),
|
|
||||||
// Cpu: utils.Ptr(int64(1)),
|
|
||||||
// Description: utils.Ptr("description"),
|
|
||||||
// Ram: utils.Ptr(int64(4)),
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// &flavorModel{
|
|
||||||
// Id: types.StringValue("fid-1"),
|
|
||||||
// Description: types.StringValue("description"),
|
|
||||||
// CPU: types.Int64Value(2),
|
|
||||||
// RAM: types.Int64Value(8),
|
|
||||||
// },
|
|
||||||
// false,
|
|
||||||
// true,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "no_matching_flavor",
|
|
||||||
// &flavorModel{
|
|
||||||
// CPU: types.Int64Value(2),
|
|
||||||
// RAM: types.Int64Value(8),
|
|
||||||
// },
|
|
||||||
// &sqlserverflex.ListFlavorsResponse{
|
|
||||||
// Flavors: &[]sqlserverflex.InstanceFlavorEntry{
|
|
||||||
// {
|
|
||||||
// Id: utils.Ptr("fid-1"),
|
|
||||||
// Cpu: utils.Ptr(int64(1)),
|
|
||||||
// Description: utils.Ptr("description"),
|
|
||||||
// Ram: utils.Ptr(int64(8)),
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// Id: utils.Ptr("fid-2"),
|
|
||||||
// Cpu: utils.Ptr(int64(1)),
|
|
||||||
// Description: utils.Ptr("description"),
|
|
||||||
// Ram: utils.Ptr(int64(4)),
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// &flavorModel{
|
|
||||||
// CPU: types.Int64Value(2),
|
|
||||||
// RAM: types.Int64Value(8),
|
|
||||||
// },
|
|
||||||
// false,
|
|
||||||
// false,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "nil_response",
|
|
||||||
// &flavorModel{
|
|
||||||
// CPU: types.Int64Value(2),
|
|
||||||
// RAM: types.Int64Value(8),
|
|
||||||
// },
|
|
||||||
// &sqlserverflex.ListFlavorsResponse{},
|
|
||||||
// &flavorModel{
|
|
||||||
// CPU: types.Int64Value(2),
|
|
||||||
// RAM: types.Int64Value(8),
|
|
||||||
// },
|
|
||||||
// false,
|
|
||||||
// false,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "error_response",
|
|
||||||
// &flavorModel{
|
|
||||||
// CPU: types.Int64Value(2),
|
|
||||||
// RAM: types.Int64Value(8),
|
|
||||||
// },
|
|
||||||
// &sqlserverflex.ListFlavorsResponse{},
|
|
||||||
// &flavorModel{
|
|
||||||
// CPU: types.Int64Value(2),
|
|
||||||
// RAM: types.Int64Value(8),
|
|
||||||
// },
|
|
||||||
// true,
|
|
||||||
// false,
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
// for _, tt := range tests {
|
|
||||||
// t.Run(tt.description, func(t *testing.T) {
|
|
||||||
// client := &sqlserverflexClientMocked{
|
|
||||||
// returnError: tt.getFlavorsFails,
|
|
||||||
// listFlavorsResp: tt.mockedResp,
|
|
||||||
// }
|
|
||||||
// model := &Model{
|
|
||||||
// ProjectId: types.StringValue("pid"),
|
|
||||||
// }
|
|
||||||
// flavorModel := &flavorModel{
|
|
||||||
// CPU: tt.inputFlavor.CPU,
|
|
||||||
// RAM: tt.inputFlavor.RAM,
|
|
||||||
// }
|
|
||||||
// err := loadFlavorId(context.Background(), client, model, flavorModel)
|
|
||||||
// if !tt.isValid && err == nil {
|
|
||||||
// t.Fatalf("Should have failed")
|
|
||||||
// }
|
|
||||||
// if tt.isValid && err != nil {
|
|
||||||
// t.Fatalf("Should not have failed: %v", err)
|
|
||||||
// }
|
|
||||||
// if tt.isValid {
|
|
||||||
// diff := cmp.Diff(flavorModel, tt.expected)
|
|
||||||
// if diff != "" {
|
|
||||||
// t.Fatalf("Data does not match: %s", diff)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
@ -4,22 +4,68 @@ import (
|
||||||
"context"
|
"context"
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
|
"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
|
||||||
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
|
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
|
||||||
|
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
||||||
sqlserverflexalpha "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance"
|
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/internal/testutils"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/internal/testutils"
|
||||||
|
sqlserverflexalphaPkgGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
||||||
|
sqlserverflexalpha "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance"
|
||||||
|
|
||||||
// The fwresource import alias is so there is no collision
|
// The fwresource import alias is so there is no collision
|
||||||
// with the more typical acceptance testing import:
|
// with the more typical acceptance testing import:
|
||||||
// "github.com/hashicorp/terraform-plugin-testing/helper/resource"
|
// "github.com/hashicorp/terraform-plugin-testing/helper/resource"
|
||||||
fwresource "github.com/hashicorp/terraform-plugin-framework/resource"
|
fwresource "github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const providerPrefix = "stackitprivatepreview_sqlserverflexalpha"
|
||||||
|
|
||||||
|
var testInstances []string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
sweeperName := fmt.Sprintf("%s_%s", providerPrefix, "sweeper")
|
||||||
|
|
||||||
|
resource.AddTestSweepers(sweeperName, &resource.Sweeper{
|
||||||
|
Name: sweeperName,
|
||||||
|
F: func(region string) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
apiClientConfigOptions := []config.ConfigurationOption{}
|
||||||
|
apiClient, err := sqlserverflexalphaPkgGen.NewAPIClient(apiClientConfigOptions...)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
instances, err := apiClient.ListInstancesRequest(ctx, testutils.ProjectId, region).
|
||||||
|
Size(100).
|
||||||
|
Execute()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, inst := range instances.GetInstances() {
|
||||||
|
if strings.HasPrefix(inst.GetName(), "tf-acc-") {
|
||||||
|
for _, item := range testInstances {
|
||||||
|
if inst.GetName() == item {
|
||||||
|
delErr := apiClient.DeleteInstanceRequestExecute(ctx, testutils.ProjectId, region, inst.GetId())
|
||||||
|
if delErr != nil {
|
||||||
|
// TODO: maybe just warn?
|
||||||
|
log.Fatalln(delErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestInstanceResourceSchema(t *testing.T) {
|
func TestInstanceResourceSchema(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
@ -85,9 +131,15 @@ type User struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Database struct {
|
type Database struct {
|
||||||
Name string
|
Name string
|
||||||
ProjectId string
|
ProjectId string
|
||||||
Owner string
|
Owner string
|
||||||
|
Collation string
|
||||||
|
Compatibility string
|
||||||
|
}
|
||||||
|
|
||||||
|
func resName(res, name string) string {
|
||||||
|
return fmt.Sprintf("%s_%s.%s", providerPrefix, res, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getExample() resData {
|
func getExample() resData {
|
||||||
|
|
@ -112,10 +164,6 @@ func getExample() resData {
|
||||||
|
|
||||||
func TestAccInstance(t *testing.T) {
|
func TestAccInstance(t *testing.T) {
|
||||||
exData := getExample()
|
exData := getExample()
|
||||||
resName := fmt.Sprintf(
|
|
||||||
"stackitprivatepreview_sqlserverflexalpha_instance.%s",
|
|
||||||
exData.TfName,
|
|
||||||
)
|
|
||||||
|
|
||||||
updNameData := exData
|
updNameData := exData
|
||||||
updNameData.Name = "name-updated"
|
updNameData.Name = "name-updated"
|
||||||
|
|
@ -123,8 +171,12 @@ func TestAccInstance(t *testing.T) {
|
||||||
updSizeData := exData
|
updSizeData := exData
|
||||||
updSizeData.Size = 25
|
updSizeData.Size = 25
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
resource.ParallelTest(t, resource.TestCase{
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
PreCheck: func() {
|
||||||
|
testAccPreCheck(t)
|
||||||
|
t.Logf(" ... working on instance %s", exData.TfName)
|
||||||
|
testInstances = append(testInstances, exData.TfName)
|
||||||
|
},
|
||||||
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
|
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
|
||||||
Steps: []resource.TestStep{
|
Steps: []resource.TestStep{
|
||||||
// Create and verify
|
// Create and verify
|
||||||
|
|
@ -134,8 +186,9 @@ func TestAccInstance(t *testing.T) {
|
||||||
exData,
|
exData,
|
||||||
),
|
),
|
||||||
Check: resource.ComposeAggregateTestCheckFunc(
|
Check: resource.ComposeAggregateTestCheckFunc(
|
||||||
resource.TestCheckResourceAttr(resName, "name", exData.Name),
|
resource.TestCheckResourceAttr(resName("instance", exData.TfName), "name", exData.Name),
|
||||||
resource.TestCheckResourceAttrSet(resName, "id"),
|
resource.TestCheckResourceAttrSet(resName("instance", exData.TfName), "id"),
|
||||||
|
// TODO: check all fields
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
// Update name and verify
|
// Update name and verify
|
||||||
|
|
@ -145,7 +198,7 @@ func TestAccInstance(t *testing.T) {
|
||||||
updNameData,
|
updNameData,
|
||||||
),
|
),
|
||||||
Check: resource.ComposeTestCheckFunc(
|
Check: resource.ComposeTestCheckFunc(
|
||||||
resource.TestCheckResourceAttr(resName, "name", updNameData.Name),
|
resource.TestCheckResourceAttr(resName("instance", exData.TfName), "name", updNameData.Name),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
// Update size and verify
|
// Update size and verify
|
||||||
|
|
@ -156,15 +209,18 @@ func TestAccInstance(t *testing.T) {
|
||||||
),
|
),
|
||||||
Check: resource.ComposeTestCheckFunc(
|
Check: resource.ComposeTestCheckFunc(
|
||||||
resource.TestCheckResourceAttr(
|
resource.TestCheckResourceAttr(
|
||||||
resName,
|
testutils.ResStr(providerPrefix, "instance", exData.TfName),
|
||||||
"storage.size",
|
"storage.size",
|
||||||
strconv.Itoa(int(updSizeData.Size)),
|
strconv.Itoa(int(updSizeData.Size)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
RefreshState: true,
|
||||||
|
},
|
||||||
//// Import test
|
//// Import test
|
||||||
//{
|
//{
|
||||||
// ResourceName: "example_resource.test",
|
// ResourceName: resName("instance", exData.TfName),
|
||||||
// ImportState: true,
|
// ImportState: true,
|
||||||
// ImportStateVerify: true,
|
// ImportStateVerify: true,
|
||||||
// },
|
// },
|
||||||
|
|
@ -172,29 +228,39 @@ func TestAccInstance(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccInstanceWithUsers(t *testing.T) {
|
func TestAccInstanceNoEncryption(t *testing.T) {
|
||||||
data := getExample()
|
data := getExample()
|
||||||
|
|
||||||
|
dbName := "testDb"
|
||||||
userName := "testUser"
|
userName := "testUser"
|
||||||
data.Users = []User{
|
data.Users = []User{
|
||||||
{
|
{
|
||||||
Name: userName,
|
Name: userName,
|
||||||
ProjectId: os.Getenv("TF_ACC_PROJECT_ID"),
|
ProjectId: os.Getenv("TF_ACC_PROJECT_ID"),
|
||||||
Roles: []string{"##STACKIT_LoginManager##", "##STACKIT_DatabaseManager##"},
|
Roles: []string{
|
||||||
|
"##STACKIT_DatabaseManager##",
|
||||||
|
"##STACKIT_LoginManager##",
|
||||||
|
"##STACKIT_ProcessManager##",
|
||||||
|
"##STACKIT_ServerManager##",
|
||||||
|
"##STACKIT_SQLAgentManager##",
|
||||||
|
"##STACKIT_SQLAgentUser##",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
data.Databases = []Database{
|
||||||
|
{
|
||||||
|
Name: dbName,
|
||||||
|
ProjectId: os.Getenv("TF_ACC_PROJECT_ID"),
|
||||||
|
Owner: userName,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
resName := fmt.Sprintf(
|
resource.ParallelTest(t, resource.TestCase{
|
||||||
"stackitprivatepreview_sqlserverflexalpha_instance.%s",
|
PreCheck: func() {
|
||||||
data.TfName,
|
testAccPreCheck(t)
|
||||||
)
|
t.Logf(" ... working on instance %s", data.TfName)
|
||||||
|
testInstances = append(testInstances, data.TfName)
|
||||||
resUserName := fmt.Sprintf(
|
},
|
||||||
"stackitprivatepreview_sqlserverflexalpha_user.%s",
|
|
||||||
userName,
|
|
||||||
)
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
|
||||||
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
|
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
|
||||||
Steps: []resource.TestStep{
|
Steps: []resource.TestStep{
|
||||||
// Create and verify
|
// Create and verify
|
||||||
|
|
@ -204,18 +270,71 @@ func TestAccInstanceWithUsers(t *testing.T) {
|
||||||
data,
|
data,
|
||||||
),
|
),
|
||||||
Check: resource.ComposeAggregateTestCheckFunc(
|
Check: resource.ComposeAggregateTestCheckFunc(
|
||||||
resource.TestCheckResourceAttr(resName, "name", data.Name),
|
// check instance values are set
|
||||||
resource.TestCheckResourceAttrSet(resName, "id"),
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "id"),
|
||||||
resource.TestCheckResourceAttr(resUserName, "name", userName),
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "backup_schedule"),
|
||||||
resource.TestCheckResourceAttrSet(resUserName, "id"),
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "edition"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "flavor_id"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "instance_id"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "is_deletable"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "name"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "replicas"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "retention_days"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "status"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "version"),
|
||||||
|
|
||||||
|
resource.TestCheckNoResourceAttr(resName("instance", data.TfName), "encryption"),
|
||||||
|
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption"),
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_id"),
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_version"),
|
||||||
|
//resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"),
|
||||||
|
//resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"),
|
||||||
|
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.access_scope"),
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.acl"),
|
||||||
|
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.instance_address"),
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.router_address"),
|
||||||
|
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "storage.class"),
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "storage.size"),
|
||||||
|
|
||||||
|
// check instance values are correct
|
||||||
|
resource.TestCheckResourceAttr(resName("instance", data.TfName), "name", data.Name),
|
||||||
|
|
||||||
|
// check user values are set
|
||||||
|
resource.TestCheckResourceAttrSet(resName("user", userName), "id"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("user", userName), "username"),
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("user", userName), "roles"),
|
||||||
|
|
||||||
|
// func(s *terraform.State) error {
|
||||||
|
// return nil
|
||||||
|
// },
|
||||||
|
|
||||||
|
// check user values are correct
|
||||||
|
resource.TestCheckResourceAttr(resName("user", userName), "username", userName),
|
||||||
|
resource.TestCheckResourceAttr(resName("user", userName), "roles.#", strconv.Itoa(len(data.Users[0].Roles))),
|
||||||
|
|
||||||
|
// check database values are set
|
||||||
|
resource.TestCheckResourceAttrSet(resName("database", dbName), "id"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("database", dbName), "name"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("database", dbName), "owner"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("database", dbName), "compatibility"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("database", dbName), "collation"),
|
||||||
|
|
||||||
|
// check database values are correct
|
||||||
|
resource.TestCheckResourceAttr(resName("database", dbName), "name", dbName),
|
||||||
|
resource.TestCheckResourceAttr(resName("database", dbName), "owner", userName),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccInstanceWithDatabases(t *testing.T) {
|
func TestAccInstanceEncryption(t *testing.T) {
|
||||||
data := getExample()
|
data := getExample()
|
||||||
|
|
||||||
dbName := "testDb"
|
dbName := "testDb"
|
||||||
userName := "testUser"
|
userName := "testUser"
|
||||||
data.Users = []User{
|
data.Users = []User{
|
||||||
|
|
@ -233,23 +352,18 @@ func TestAccInstanceWithDatabases(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
resName := fmt.Sprintf(
|
data.UseEncryption = true
|
||||||
"stackitprivatepreview_sqlserverflexalpha_instance.%s",
|
data.KekKeyId = "fe039bcf-8d7b-431a-801d-9e81371a6b7b"
|
||||||
data.TfName,
|
data.KekKeyRingId = "6a2d95ab-3c4c-4963-a2bb-08d17a320e27"
|
||||||
)
|
data.KekKeyVersion = 1
|
||||||
|
data.KekServiceAccount = "henselinm-u2v3ex1@sa.stackit.cloud"
|
||||||
|
|
||||||
resUserName := fmt.Sprintf(
|
resource.ParallelTest(t, resource.TestCase{
|
||||||
"stackitprivatepreview_sqlserverflexalpha_user.%s",
|
PreCheck: func() {
|
||||||
userName,
|
testAccPreCheck(t)
|
||||||
)
|
t.Logf(" ... working on instance %s", data.TfName)
|
||||||
|
testInstances = append(testInstances, data.TfName)
|
||||||
resDbName := fmt.Sprintf(
|
},
|
||||||
"stackitprivatepreview_sqlserverflexalpha_database.%s",
|
|
||||||
dbName,
|
|
||||||
)
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
|
||||||
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
|
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
|
||||||
Steps: []resource.TestStep{
|
Steps: []resource.TestStep{
|
||||||
// Create and verify
|
// Create and verify
|
||||||
|
|
@ -259,13 +373,59 @@ func TestAccInstanceWithDatabases(t *testing.T) {
|
||||||
data,
|
data,
|
||||||
),
|
),
|
||||||
Check: resource.ComposeAggregateTestCheckFunc(
|
Check: resource.ComposeAggregateTestCheckFunc(
|
||||||
resource.TestCheckResourceAttr(resName, "name", data.Name),
|
// check instance values are set
|
||||||
resource.TestCheckResourceAttrSet(resName, "id"),
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "id"),
|
||||||
resource.TestCheckResourceAttr(resUserName, "name", userName),
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "backup_schedule"),
|
||||||
resource.TestCheckResourceAttrSet(resUserName, "id"),
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "edition"),
|
||||||
resource.TestCheckResourceAttr(resDbName, "name", dbName),
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "flavor_id"),
|
||||||
resource.TestCheckResourceAttr(resDbName, "owner", userName),
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "instance_id"),
|
||||||
resource.TestCheckResourceAttrSet(resDbName, "id"),
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "is_deletable"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "name"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "replicas"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "retention_days"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "status"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "version"),
|
||||||
|
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption"),
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_id"),
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_version"),
|
||||||
|
//resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"),
|
||||||
|
//resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"),
|
||||||
|
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.access_scope"),
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.acl"),
|
||||||
|
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.instance_address"),
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.router_address"),
|
||||||
|
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "storage.class"),
|
||||||
|
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "storage.size"),
|
||||||
|
|
||||||
|
// check instance values are correct
|
||||||
|
resource.TestCheckResourceAttr(resName("instance", data.TfName), "name", data.Name),
|
||||||
|
|
||||||
|
// check user values are set
|
||||||
|
resource.TestCheckResourceAttrSet(resName("user", userName), "id"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("user", userName), "username"),
|
||||||
|
|
||||||
|
// func(s *terraform.State) error {
|
||||||
|
// return nil
|
||||||
|
// },
|
||||||
|
|
||||||
|
// check user values are correct
|
||||||
|
resource.TestCheckResourceAttr(resName("user", userName), "username", userName),
|
||||||
|
resource.TestCheckResourceAttr(resName("user", userName), "roles.#", "2"),
|
||||||
|
|
||||||
|
// check database values are set
|
||||||
|
resource.TestCheckResourceAttrSet(resName("database", dbName), "id"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("database", dbName), "name"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("database", dbName), "owner"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("database", dbName), "compatibility"),
|
||||||
|
resource.TestCheckResourceAttrSet(resName("database", dbName), "collation"),
|
||||||
|
|
||||||
|
// check database values are correct
|
||||||
|
resource.TestCheckResourceAttr(resName("database", dbName), "name", dbName),
|
||||||
|
resource.TestCheckResourceAttr(resName("database", dbName), "owner", userName),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,483 +0,0 @@
|
||||||
// Copyright (c) STACKIT
|
|
||||||
|
|
||||||
package sqlserverflexalpha_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
_ "embed"
|
|
||||||
"fmt"
|
|
||||||
"maps"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-testing/config"
|
|
||||||
"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
|
|
||||||
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform-plugin-testing/terraform"
|
|
||||||
coreconfig "github.com/stackitcloud/stackit-sdk-go/core/config"
|
|
||||||
"github.com/stackitcloud/stackit-sdk-go/core/utils"
|
|
||||||
"github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex"
|
|
||||||
"github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex/wait"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/internal/testutils"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
//go:embed testdata/resource-max.tf
|
|
||||||
resourceMaxConfig string
|
|
||||||
//go:embed testdata/resource-min.tf
|
|
||||||
resourceMinConfig string
|
|
||||||
)
|
|
||||||
|
|
||||||
var testConfigVarsMin = config.Variables{
|
|
||||||
"project_id": config.StringVariable(testutils.ProjectId),
|
|
||||||
"name": config.StringVariable(fmt.Sprintf("tf-acc-%s", acctest.RandStringFromCharSet(7, acctest.CharSetAlphaNum))),
|
|
||||||
"flavor_cpu": config.IntegerVariable(4),
|
|
||||||
"flavor_ram": config.IntegerVariable(16),
|
|
||||||
"flavor_description": config.StringVariable("SQLServer-Flex-4.16-Standard-EU01"),
|
|
||||||
"replicas": config.IntegerVariable(1),
|
|
||||||
"flavor_id": config.StringVariable("4.16-Single"),
|
|
||||||
"username": config.StringVariable(fmt.Sprintf("tf-acc-user-%s", acctest.RandStringFromCharSet(7, acctest.CharSetAlpha))),
|
|
||||||
"role": config.StringVariable("##STACKIT_LoginManager##"),
|
|
||||||
}
|
|
||||||
|
|
||||||
var testConfigVarsMax = config.Variables{
|
|
||||||
"project_id": config.StringVariable(testutils.ProjectId),
|
|
||||||
"name": config.StringVariable(fmt.Sprintf("tf-acc-%s", acctest.RandStringFromCharSet(7, acctest.CharSetAlphaNum))),
|
|
||||||
"acl1": config.StringVariable("192.168.0.0/16"),
|
|
||||||
"flavor_cpu": config.IntegerVariable(4),
|
|
||||||
"flavor_ram": config.IntegerVariable(16),
|
|
||||||
"flavor_description": config.StringVariable("SQLServer-Flex-4.16-Standard-EU01"),
|
|
||||||
"storage_class": config.StringVariable("premium-perf2-stackit"),
|
|
||||||
"storage_size": config.IntegerVariable(40),
|
|
||||||
"server_version": config.StringVariable("2022"),
|
|
||||||
"replicas": config.IntegerVariable(1),
|
|
||||||
"options_retention_days": config.IntegerVariable(64),
|
|
||||||
"flavor_id": config.StringVariable("4.16-Single"),
|
|
||||||
"backup_schedule": config.StringVariable("00 6 * * *"),
|
|
||||||
"username": config.StringVariable(fmt.Sprintf("tf-acc-user-%s", acctest.RandStringFromCharSet(7, acctest.CharSetAlpha))),
|
|
||||||
"role": config.StringVariable("##STACKIT_LoginManager##"),
|
|
||||||
"region": config.StringVariable(testutils.Region),
|
|
||||||
}
|
|
||||||
|
|
||||||
func configVarsMinUpdated() config.Variables {
|
|
||||||
temp := maps.Clone(testConfigVarsMax)
|
|
||||||
temp["name"] = config.StringVariable(testutils.ConvertConfigVariable(temp["name"]) + "changed")
|
|
||||||
return temp
|
|
||||||
}
|
|
||||||
|
|
||||||
func configVarsMaxUpdated() config.Variables {
|
|
||||||
temp := maps.Clone(testConfigVarsMax)
|
|
||||||
temp["backup_schedule"] = config.StringVariable("00 12 * * *")
|
|
||||||
return temp
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccSQLServerFlexMinResource(t *testing.T) {
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
|
|
||||||
CheckDestroy: testAccChecksqlserverflexDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
// Creation
|
|
||||||
{
|
|
||||||
Config: testutils.SQLServerFlexProviderConfig("") + "\n" + resourceMinConfig,
|
|
||||||
ConfigVariables: testConfigVarsMin,
|
|
||||||
Check: resource.ComposeAggregateTestCheckFunc(
|
|
||||||
// Instance
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "project_id", testutils.ConvertConfigVariable(testConfigVarsMin["project_id"])),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_instance.instance", "instance_id"),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "name", testutils.ConvertConfigVariable(testConfigVarsMin["name"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "acl.#", "1"),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_instance.instance", "flavor.id"),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "flavor.description", testutils.ConvertConfigVariable(testConfigVarsMin["flavor_description"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "replicas", testutils.ConvertConfigVariable(testConfigVarsMin["replicas"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "flavor.cpu", testutils.ConvertConfigVariable(testConfigVarsMin["flavor_cpu"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "flavor.ram", testutils.ConvertConfigVariable(testConfigVarsMin["flavor_ram"])),
|
|
||||||
// User
|
|
||||||
resource.TestCheckResourceAttrPair(
|
|
||||||
"stackit_sqlserverflex_user.user", "project_id",
|
|
||||||
"stackit_sqlserverflex_instance.instance", "project_id",
|
|
||||||
),
|
|
||||||
resource.TestCheckResourceAttrPair(
|
|
||||||
"stackit_sqlserverflex_user.user", "instance_id",
|
|
||||||
"stackit_sqlserverflex_instance.instance", "instance_id",
|
|
||||||
),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_user.user", "user_id"),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_user.user", "password"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
// Update
|
|
||||||
{
|
|
||||||
Config: testutils.SQLServerFlexProviderConfig("") + "\n" + resourceMinConfig,
|
|
||||||
ConfigVariables: testConfigVarsMin,
|
|
||||||
Check: resource.ComposeAggregateTestCheckFunc(
|
|
||||||
// Instance
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "project_id", testutils.ConvertConfigVariable(testConfigVarsMin["project_id"])),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_instance.instance", "instance_id"),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "name", testutils.ConvertConfigVariable(testConfigVarsMin["name"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "acl.#", "1"),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_instance.instance", "flavor.id"),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "flavor.description", testutils.ConvertConfigVariable(testConfigVarsMin["flavor_description"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "flavor.cpu", testutils.ConvertConfigVariable(testConfigVarsMin["flavor_cpu"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "flavor.ram", testutils.ConvertConfigVariable(testConfigVarsMin["flavor_ram"])),
|
|
||||||
// User
|
|
||||||
resource.TestCheckResourceAttrPair(
|
|
||||||
"stackit_sqlserverflex_user.user", "project_id",
|
|
||||||
"stackit_sqlserverflex_instance.instance", "project_id",
|
|
||||||
),
|
|
||||||
resource.TestCheckResourceAttrPair(
|
|
||||||
"stackit_sqlserverflex_user.user", "instance_id",
|
|
||||||
"stackit_sqlserverflex_instance.instance", "instance_id",
|
|
||||||
),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_user.user", "user_id"),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_user.user", "password"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
// data source
|
|
||||||
{
|
|
||||||
Config: testutils.SQLServerFlexProviderConfig("") + "\n" + resourceMinConfig,
|
|
||||||
ConfigVariables: testConfigVarsMin,
|
|
||||||
Check: resource.ComposeAggregateTestCheckFunc(
|
|
||||||
// Instance data
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_instance.instance", "project_id", testutils.ConvertConfigVariable(testConfigVarsMin["project_id"])),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_instance.instance", "name", testutils.ConvertConfigVariable(testConfigVarsMin["name"])),
|
|
||||||
resource.TestCheckResourceAttrPair(
|
|
||||||
"data.stackit_sqlserverflex_instance.instance", "project_id",
|
|
||||||
"stackit_sqlserverflex_instance.instance", "project_id",
|
|
||||||
),
|
|
||||||
resource.TestCheckResourceAttrPair(
|
|
||||||
"data.stackit_sqlserverflex_instance.instance", "instance_id",
|
|
||||||
"stackit_sqlserverflex_instance.instance", "instance_id",
|
|
||||||
),
|
|
||||||
resource.TestCheckResourceAttrPair(
|
|
||||||
"data.stackit_sqlserverflex_user.user", "instance_id",
|
|
||||||
"stackit_sqlserverflex_user.user", "instance_id",
|
|
||||||
),
|
|
||||||
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_instance.instance", "acl.#", "1"),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_instance.instance", "flavor.id", testutils.ConvertConfigVariable(testConfigVarsMin["flavor_id"])),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_instance.instance", "flavor.description", testutils.ConvertConfigVariable(testConfigVarsMin["flavor_description"])),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_instance.instance", "flavor.cpu", testutils.ConvertConfigVariable(testConfigVarsMin["flavor_cpu"])),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_instance.instance", "flavor.ram", testutils.ConvertConfigVariable(testConfigVarsMin["flavor_ram"])),
|
|
||||||
|
|
||||||
// User data
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_user.user", "project_id", testutils.ConvertConfigVariable(testConfigVarsMin["project_id"])),
|
|
||||||
resource.TestCheckResourceAttrSet("data.stackit_sqlserverflex_user.user", "user_id"),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_user.user", "username", testutils.ConvertConfigVariable(testConfigVarsMin["username"])),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_user.user", "roles.#", "1"),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_user.user", "roles.0", testutils.ConvertConfigVariable(testConfigVarsMax["role"])),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
// Import
|
|
||||||
{
|
|
||||||
ConfigVariables: testConfigVarsMin,
|
|
||||||
ResourceName: "stackit_sqlserverflex_instance.instance",
|
|
||||||
ImportStateIdFunc: func(s *terraform.State) (string, error) {
|
|
||||||
r, ok := s.RootModule().Resources["stackit_sqlserverflex_instance.instance"]
|
|
||||||
if !ok {
|
|
||||||
return "", fmt.Errorf("couldn't find resource stackit_sqlserverflex_instance.instance")
|
|
||||||
}
|
|
||||||
instanceId, ok := r.Primary.Attributes["instance_id"]
|
|
||||||
if !ok {
|
|
||||||
return "", fmt.Errorf("couldn't find attribute instance_id")
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("%s,%s,%s", testutils.ProjectId, testutils.Region, instanceId), nil
|
|
||||||
},
|
|
||||||
ImportState: true,
|
|
||||||
ImportStateVerify: true,
|
|
||||||
ImportStateVerifyIgnore: []string{"backup_schedule"},
|
|
||||||
ImportStateCheck: func(s []*terraform.InstanceState) error {
|
|
||||||
if len(s) != 1 {
|
|
||||||
return fmt.Errorf("expected 1 state, got %d", len(s))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ResourceName: "stackit_sqlserverflex_user.user",
|
|
||||||
ConfigVariables: testConfigVarsMin,
|
|
||||||
ImportStateIdFunc: func(s *terraform.State) (string, error) {
|
|
||||||
r, ok := s.RootModule().Resources["stackit_sqlserverflex_user.user"]
|
|
||||||
if !ok {
|
|
||||||
return "", fmt.Errorf("couldn't find resource stackit_sqlserverflex_user.user")
|
|
||||||
}
|
|
||||||
instanceId, ok := r.Primary.Attributes["instance_id"]
|
|
||||||
if !ok {
|
|
||||||
return "", fmt.Errorf("couldn't find attribute instance_id")
|
|
||||||
}
|
|
||||||
userId, ok := r.Primary.Attributes["user_id"]
|
|
||||||
if !ok {
|
|
||||||
return "", fmt.Errorf("couldn't find attribute user_id")
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("%s,%s,%s,%s", testutils.ProjectId, testutils.Region, instanceId, userId), nil
|
|
||||||
},
|
|
||||||
ImportState: true,
|
|
||||||
ImportStateVerify: true,
|
|
||||||
ImportStateVerifyIgnore: []string{"password"},
|
|
||||||
},
|
|
||||||
// Update
|
|
||||||
{
|
|
||||||
Config: testutils.SQLServerFlexProviderConfig("") + "\n" + resourceMinConfig,
|
|
||||||
ConfigVariables: configVarsMinUpdated(),
|
|
||||||
Check: resource.ComposeAggregateTestCheckFunc(
|
|
||||||
// Instance data
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "project_id", testutils.ConvertConfigVariable(configVarsMinUpdated()["project_id"])),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_instance.instance", "instance_id"),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "name", testutils.ConvertConfigVariable(configVarsMinUpdated()["name"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "acl.#", "1"),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_instance.instance", "flavor.id"),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_instance.instance", "flavor.description"),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "flavor.cpu", testutils.ConvertConfigVariable(configVarsMinUpdated()["flavor_cpu"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "flavor.ram", testutils.ConvertConfigVariable(configVarsMinUpdated()["flavor_ram"])),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
// Deletion is done by the framework implicitly
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccSQLServerFlexMaxResource(t *testing.T) {
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
|
|
||||||
CheckDestroy: testAccChecksqlserverflexDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
// Creation
|
|
||||||
{
|
|
||||||
Config: testutils.SQLServerFlexProviderConfig("") + "\n" + resourceMaxConfig,
|
|
||||||
ConfigVariables: testConfigVarsMax,
|
|
||||||
Check: resource.ComposeAggregateTestCheckFunc(
|
|
||||||
// Instance
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "project_id", testutils.ConvertConfigVariable(testConfigVarsMax["project_id"])),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_instance.instance", "instance_id"),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "name", testutils.ConvertConfigVariable(testConfigVarsMax["name"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "acl.#", "1"),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "acl.0", testutils.ConvertConfigVariable(testConfigVarsMax["acl1"])),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_instance.instance", "flavor.id"),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "flavor.description", testutils.ConvertConfigVariable(testConfigVarsMax["flavor_description"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "replicas", testutils.ConvertConfigVariable(testConfigVarsMax["replicas"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "flavor.cpu", testutils.ConvertConfigVariable(testConfigVarsMax["flavor_cpu"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "flavor.ram", testutils.ConvertConfigVariable(testConfigVarsMax["flavor_ram"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "storage.class", testutils.ConvertConfigVariable(testConfigVarsMax["storage_class"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "storage.size", testutils.ConvertConfigVariable(testConfigVarsMax["storage_size"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "version", testutils.ConvertConfigVariable(testConfigVarsMax["server_version"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "options.retention_days", testutils.ConvertConfigVariable(testConfigVarsMax["options_retention_days"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "backup_schedule", testutils.ConvertConfigVariable(testConfigVarsMax["backup_schedule"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "region", testutils.Region),
|
|
||||||
// User
|
|
||||||
resource.TestCheckResourceAttrPair(
|
|
||||||
"stackit_sqlserverflex_user.user", "project_id",
|
|
||||||
"stackit_sqlserverflex_instance.instance", "project_id",
|
|
||||||
),
|
|
||||||
resource.TestCheckResourceAttrPair(
|
|
||||||
"stackit_sqlserverflex_user.user", "instance_id",
|
|
||||||
"stackit_sqlserverflex_instance.instance", "instance_id",
|
|
||||||
),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_user.user", "user_id"),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_user.user", "password"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
// Update
|
|
||||||
{
|
|
||||||
Config: testutils.SQLServerFlexProviderConfig("") + "\n" + resourceMaxConfig,
|
|
||||||
ConfigVariables: testConfigVarsMax,
|
|
||||||
Check: resource.ComposeAggregateTestCheckFunc(
|
|
||||||
// Instance
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "project_id", testutils.ConvertConfigVariable(testConfigVarsMax["project_id"])),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_instance.instance", "instance_id"),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "name", testutils.ConvertConfigVariable(testConfigVarsMax["name"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "acl.#", "1"),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "acl.0", testutils.ConvertConfigVariable(testConfigVarsMax["acl1"])),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_instance.instance", "flavor.id"),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "flavor.description", testutils.ConvertConfigVariable(testConfigVarsMax["flavor_description"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "replicas", testutils.ConvertConfigVariable(testConfigVarsMax["replicas"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "flavor.cpu", testutils.ConvertConfigVariable(testConfigVarsMax["flavor_cpu"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "flavor.ram", testutils.ConvertConfigVariable(testConfigVarsMax["flavor_ram"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "storage.class", testutils.ConvertConfigVariable(testConfigVarsMax["storage_class"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "storage.size", testutils.ConvertConfigVariable(testConfigVarsMax["storage_size"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "version", testutils.ConvertConfigVariable(testConfigVarsMax["server_version"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "options.retention_days", testutils.ConvertConfigVariable(testConfigVarsMax["options_retention_days"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "backup_schedule", testutils.ConvertConfigVariable(testConfigVarsMax["backup_schedule"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "region", testutils.Region),
|
|
||||||
// User
|
|
||||||
resource.TestCheckResourceAttrPair(
|
|
||||||
"stackit_sqlserverflex_user.user", "project_id",
|
|
||||||
"stackit_sqlserverflex_instance.instance", "project_id",
|
|
||||||
),
|
|
||||||
resource.TestCheckResourceAttrPair(
|
|
||||||
"stackit_sqlserverflex_user.user", "instance_id",
|
|
||||||
"stackit_sqlserverflex_instance.instance", "instance_id",
|
|
||||||
),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_user.user", "user_id"),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_user.user", "password"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
// data source
|
|
||||||
{
|
|
||||||
Config: testutils.SQLServerFlexProviderConfig("") + "\n" + resourceMaxConfig,
|
|
||||||
ConfigVariables: testConfigVarsMax,
|
|
||||||
Check: resource.ComposeAggregateTestCheckFunc(
|
|
||||||
// Instance data
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_instance.instance", "project_id", testutils.ConvertConfigVariable(testConfigVarsMax["project_id"])),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_instance.instance", "name", testutils.ConvertConfigVariable(testConfigVarsMax["name"])),
|
|
||||||
resource.TestCheckResourceAttrPair(
|
|
||||||
"data.stackit_sqlserverflex_instance.instance", "project_id",
|
|
||||||
"stackit_sqlserverflex_instance.instance", "project_id",
|
|
||||||
),
|
|
||||||
resource.TestCheckResourceAttrPair(
|
|
||||||
"data.stackit_sqlserverflex_instance.instance", "instance_id",
|
|
||||||
"stackit_sqlserverflex_instance.instance", "instance_id",
|
|
||||||
),
|
|
||||||
resource.TestCheckResourceAttrPair(
|
|
||||||
"data.stackit_sqlserverflex_user.user", "instance_id",
|
|
||||||
"stackit_sqlserverflex_user.user", "instance_id",
|
|
||||||
),
|
|
||||||
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_instance.instance", "acl.#", "1"),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_instance.instance", "acl.0", testutils.ConvertConfigVariable(testConfigVarsMax["acl1"])),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_instance.instance", "flavor.id", testutils.ConvertConfigVariable(testConfigVarsMax["flavor_id"])),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_instance.instance", "flavor.description", testutils.ConvertConfigVariable(testConfigVarsMax["flavor_description"])),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_instance.instance", "flavor.cpu", testutils.ConvertConfigVariable(testConfigVarsMax["flavor_cpu"])),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_instance.instance", "flavor.ram", testutils.ConvertConfigVariable(testConfigVarsMax["flavor_ram"])),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_instance.instance", "replicas", testutils.ConvertConfigVariable(testConfigVarsMax["replicas"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "options.retention_days", testutils.ConvertConfigVariable(testConfigVarsMax["options_retention_days"])),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_instance.instance", "backup_schedule", testutils.ConvertConfigVariable(testConfigVarsMax["backup_schedule"])),
|
|
||||||
|
|
||||||
// User data
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_user.user", "project_id", testutils.ConvertConfigVariable(testConfigVarsMax["project_id"])),
|
|
||||||
resource.TestCheckResourceAttrSet("data.stackit_sqlserverflex_user.user", "user_id"),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_user.user", "username", testutils.ConvertConfigVariable(testConfigVarsMax["username"])),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_user.user", "roles.#", "1"),
|
|
||||||
resource.TestCheckResourceAttr("data.stackit_sqlserverflex_user.user", "roles.0", testutils.ConvertConfigVariable(testConfigVarsMax["role"])),
|
|
||||||
resource.TestCheckResourceAttrSet("data.stackit_sqlserverflex_user.user", "host"),
|
|
||||||
resource.TestCheckResourceAttrSet("data.stackit_sqlserverflex_user.user", "port"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
// Import
|
|
||||||
{
|
|
||||||
ConfigVariables: testConfigVarsMax,
|
|
||||||
ResourceName: "stackit_sqlserverflex_instance.instance",
|
|
||||||
ImportStateIdFunc: func(s *terraform.State) (string, error) {
|
|
||||||
r, ok := s.RootModule().Resources["stackit_sqlserverflex_instance.instance"]
|
|
||||||
if !ok {
|
|
||||||
return "", fmt.Errorf("couldn't find resource stackit_sqlserverflex_instance.instance")
|
|
||||||
}
|
|
||||||
instanceId, ok := r.Primary.Attributes["instance_id"]
|
|
||||||
if !ok {
|
|
||||||
return "", fmt.Errorf("couldn't find attribute instance_id")
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("%s,%s,%s", testutils.ProjectId, testutils.Region, instanceId), nil
|
|
||||||
},
|
|
||||||
ImportState: true,
|
|
||||||
ImportStateVerify: true,
|
|
||||||
ImportStateVerifyIgnore: []string{"backup_schedule"},
|
|
||||||
ImportStateCheck: func(s []*terraform.InstanceState) error {
|
|
||||||
if len(s) != 1 {
|
|
||||||
return fmt.Errorf("expected 1 state, got %d", len(s))
|
|
||||||
}
|
|
||||||
if s[0].Attributes["backup_schedule"] != testutils.ConvertConfigVariable(testConfigVarsMax["backup_schedule"]) {
|
|
||||||
return fmt.Errorf("expected backup_schedule %s, got %s", testConfigVarsMax["backup_schedule"], s[0].Attributes["backup_schedule"])
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ResourceName: "stackit_sqlserverflex_user.user",
|
|
||||||
ConfigVariables: testConfigVarsMax,
|
|
||||||
ImportStateIdFunc: func(s *terraform.State) (string, error) {
|
|
||||||
r, ok := s.RootModule().Resources["stackit_sqlserverflex_user.user"]
|
|
||||||
if !ok {
|
|
||||||
return "", fmt.Errorf("couldn't find resource stackit_sqlserverflex_user.user")
|
|
||||||
}
|
|
||||||
instanceId, ok := r.Primary.Attributes["instance_id"]
|
|
||||||
if !ok {
|
|
||||||
return "", fmt.Errorf("couldn't find attribute instance_id")
|
|
||||||
}
|
|
||||||
userId, ok := r.Primary.Attributes["user_id"]
|
|
||||||
if !ok {
|
|
||||||
return "", fmt.Errorf("couldn't find attribute user_id")
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("%s,%s,%s,%s", testutils.ProjectId, testutils.Region, instanceId, userId), nil
|
|
||||||
},
|
|
||||||
ImportState: true,
|
|
||||||
ImportStateVerify: true,
|
|
||||||
ImportStateVerifyIgnore: []string{"password"},
|
|
||||||
},
|
|
||||||
// Update
|
|
||||||
{
|
|
||||||
Config: testutils.SQLServerFlexProviderConfig("") + "\n" + resourceMaxConfig,
|
|
||||||
ConfigVariables: configVarsMaxUpdated(),
|
|
||||||
Check: resource.ComposeAggregateTestCheckFunc(
|
|
||||||
// Instance data
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "project_id", testutils.ConvertConfigVariable(configVarsMaxUpdated()["project_id"])),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_instance.instance", "instance_id"),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "name", testutils.ConvertConfigVariable(configVarsMaxUpdated()["name"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "acl.#", "1"),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "acl.0", testutils.ConvertConfigVariable(configVarsMaxUpdated()["acl1"])),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_instance.instance", "flavor.id"),
|
|
||||||
resource.TestCheckResourceAttrSet("stackit_sqlserverflex_instance.instance", "flavor.description"),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "flavor.cpu", testutils.ConvertConfigVariable(configVarsMaxUpdated()["flavor_cpu"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "flavor.ram", testutils.ConvertConfigVariable(configVarsMaxUpdated()["flavor_ram"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "replicas", testutils.ConvertConfigVariable(configVarsMaxUpdated()["replicas"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "storage.class", testutils.ConvertConfigVariable(configVarsMaxUpdated()["storage_class"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "storage.size", testutils.ConvertConfigVariable(configVarsMaxUpdated()["storage_size"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "version", testutils.ConvertConfigVariable(configVarsMaxUpdated()["server_version"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "options.retention_days", testutils.ConvertConfigVariable(configVarsMaxUpdated()["options_retention_days"])),
|
|
||||||
resource.TestCheckResourceAttr("stackit_sqlserverflex_instance.instance", "backup_schedule", testutils.ConvertConfigVariable(configVarsMaxUpdated()["backup_schedule"])),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
// Deletion is done by the framework implicitly
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccChecksqlserverflexDestroy(s *terraform.State) error {
|
|
||||||
ctx := context.Background()
|
|
||||||
var client *sqlserverflex.APIClient
|
|
||||||
var err error
|
|
||||||
if testutils.SQLServerFlexCustomEndpoint == "" {
|
|
||||||
client, err = sqlserverflex.NewAPIClient()
|
|
||||||
} else {
|
|
||||||
client, err = sqlserverflex.NewAPIClient(
|
|
||||||
coreconfig.WithEndpoint(testutils.SQLServerFlexCustomEndpoint),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("creating client: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
instancesToDestroy := []string{}
|
|
||||||
for _, rs := range s.RootModule().Resources {
|
|
||||||
if rs.Type != "stackit_sqlserverflex_instance" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// instance terraform ID: = "[project_id],[region],[instance_id]"
|
|
||||||
instanceId := strings.Split(rs.Primary.ID, core.Separator)[2]
|
|
||||||
instancesToDestroy = append(instancesToDestroy, instanceId)
|
|
||||||
}
|
|
||||||
|
|
||||||
instancesResp, err := client.ListInstances(ctx, testutils.ProjectId, testutils.Region).Execute()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("getting instancesResp: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
items := *instancesResp.Items
|
|
||||||
for i := range items {
|
|
||||||
if items[i].Id == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if utils.Contains(instancesToDestroy, *items[i].Id) {
|
|
||||||
err := client.DeleteInstanceExecute(ctx, testutils.ProjectId, *items[i].Id, testutils.Region)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("destroying instance %s during CheckDestroy: %w", *items[i].Id, err)
|
|
||||||
}
|
|
||||||
_, err = wait.DeleteInstanceWaitHandler(ctx, client, testutils.ProjectId, *items[i].Id, testutils.Region).WaitWithContext(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("destroying instance %s during CheckDestroy: waiting for deletion %w", *items[i].Id, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
@ -15,8 +15,8 @@ resource "stackitprivatepreview_sqlserverflexalpha_instance" "{{ .TfName }}" {
|
||||||
}
|
}
|
||||||
{{ if .UseEncryption }}
|
{{ if .UseEncryption }}
|
||||||
encryption = {
|
encryption = {
|
||||||
kek_key_id = {{ .KekKeyId }}
|
kek_key_id = "{{ .KekKeyId }}"
|
||||||
kek_key_ring_id = {{ .KekKeyRingId }}
|
kek_key_ring_id = "{{ .KekKeyRingId }}"
|
||||||
kek_key_version = {{ .KekKeyVersion }}
|
kek_key_version = {{ .KekKeyVersion }}
|
||||||
service_account = "{{ .KekServiceAccount }}"
|
service_account = "{{ .KekServiceAccount }}"
|
||||||
}
|
}
|
||||||
|
|
@ -44,10 +44,17 @@ resource "stackitprivatepreview_sqlserverflexalpha_user" "{{ $user.Name }}" {
|
||||||
{{ $tfName := .TfName }}
|
{{ $tfName := .TfName }}
|
||||||
{{ range $db := .Databases }}
|
{{ range $db := .Databases }}
|
||||||
resource "stackitprivatepreview_sqlserverflexalpha_database" "{{ $db.Name }}" {
|
resource "stackitprivatepreview_sqlserverflexalpha_database" "{{ $db.Name }}" {
|
||||||
project_id = "{{ $db.ProjectId }}"
|
depends_on = [stackitprivatepreview_sqlserverflexalpha_user.{{ $db.Owner }}]
|
||||||
instance_id = stackitprivatepreview_sqlserverflexalpha_instance.{{ $tfName }}.instance_id
|
project_id = "{{ $db.ProjectId }}"
|
||||||
name = "{{ $db.Name }}"
|
instance_id = stackitprivatepreview_sqlserverflexalpha_instance.{{ $tfName }}.instance_id
|
||||||
owner = "{{ $db.Owner }}"
|
name = "{{ $db.Name }}"
|
||||||
|
owner = "{{ $db.Owner }}"
|
||||||
|
{{ if $db.Collation }}
|
||||||
|
collation = "{{ $db.Collation }}"
|
||||||
|
{{ end }}
|
||||||
|
{{ if $db.Compatibility }}
|
||||||
|
compatibility = "{{ $db.Compatibility }}"
|
||||||
|
{{ end }}
|
||||||
}
|
}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
|
||||||
|
|
@ -5,54 +5,47 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||||
sqlserverflexUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/utils"
|
sqlserverflexUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/utils"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/validate"
|
|
||||||
|
sqlserverflexalphaPkg "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
||||||
|
sqlserverflexalphaGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/user/datasources_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure the implementation satisfies the expected interfaces.
|
var _ datasource.DataSource = (*userDataSource)(nil)
|
||||||
var (
|
|
||||||
_ datasource.DataSource = &userDataSource{}
|
const errorPrefix = "[sqlserverflexalpha - User]"
|
||||||
)
|
|
||||||
|
|
||||||
// NewUserDataSource is a helper function to simplify the provider implementation.
|
|
||||||
func NewUserDataSource() datasource.DataSource {
|
func NewUserDataSource() datasource.DataSource {
|
||||||
return &userDataSource{}
|
return &userDataSource{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type dataSourceModel struct {
|
type dataSourceModel struct {
|
||||||
//TODO: check generated data source for the correct types and pointers
|
|
||||||
Id types.String `tfsdk:"id"` // needed by TF
|
|
||||||
UserId types.Int64 `tfsdk:"user_id"`
|
|
||||||
InstanceId types.String `tfsdk:"instance_id"`
|
|
||||||
ProjectId types.String `tfsdk:"project_id"`
|
|
||||||
Username types.String `tfsdk:"username"`
|
|
||||||
Roles types.Set `tfsdk:"roles"`
|
|
||||||
Host types.String `tfsdk:"host"`
|
|
||||||
Port types.Int64 `tfsdk:"port"`
|
|
||||||
Region types.String `tfsdk:"region"`
|
|
||||||
Status types.String `tfsdk:"status"`
|
|
||||||
DefaultDatabase types.String `tfsdk:"default_database"`
|
DefaultDatabase types.String `tfsdk:"default_database"`
|
||||||
|
Host types.String `tfsdk:"host"`
|
||||||
|
Id types.String `tfsdk:"id"`
|
||||||
|
InstanceId types.String `tfsdk:"instance_id"`
|
||||||
|
Port types.Int64 `tfsdk:"port"`
|
||||||
|
ProjectId types.String `tfsdk:"project_id"`
|
||||||
|
Region types.String `tfsdk:"region"`
|
||||||
|
Roles types.List `tfsdk:"roles"`
|
||||||
|
Status types.String `tfsdk:"status"`
|
||||||
|
UserId types.Int64 `tfsdk:"user_id"`
|
||||||
|
Username types.String `tfsdk:"username"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// userDataSource is the data source implementation.
|
|
||||||
type userDataSource struct {
|
type userDataSource struct {
|
||||||
client *sqlserverflexalpha.APIClient
|
client *sqlserverflexalphaPkg.APIClient
|
||||||
providerData core.ProviderData
|
providerData core.ProviderData
|
||||||
}
|
}
|
||||||
|
|
||||||
// Metadata returns the data source type name.
|
func (d *userDataSource) Metadata(
|
||||||
func (r *userDataSource) Metadata(
|
|
||||||
_ context.Context,
|
_ context.Context,
|
||||||
req datasource.MetadataRequest,
|
req datasource.MetadataRequest,
|
||||||
resp *datasource.MetadataResponse,
|
resp *datasource.MetadataResponse,
|
||||||
|
|
@ -60,108 +53,31 @@ func (r *userDataSource) Metadata(
|
||||||
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_user"
|
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_user"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *userDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
||||||
|
resp.Schema = sqlserverflexalphaGen.UserDataSourceSchema(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
// Configure adds the provider configured client to the data source.
|
// Configure adds the provider configured client to the data source.
|
||||||
func (r *userDataSource) Configure(
|
func (d *userDataSource) Configure(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req datasource.ConfigureRequest,
|
req datasource.ConfigureRequest,
|
||||||
resp *datasource.ConfigureResponse,
|
resp *datasource.ConfigureResponse,
|
||||||
) {
|
) {
|
||||||
var ok bool
|
var ok bool
|
||||||
r.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
|
d.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiClient := sqlserverflexUtils.ConfigureClient(ctx, &r.providerData, &resp.Diagnostics)
|
apiClient := sqlserverflexUtils.ConfigureClient(ctx, &d.providerData, &resp.Diagnostics)
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.client = apiClient
|
d.client = apiClient
|
||||||
tflog.Info(ctx, "SQLServer Flex beta user client configured")
|
tflog.Info(ctx, "SQL SERVER Flex alpha database client configured")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schema defines the schema for the data source.
|
func (d *userDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
||||||
func (r *userDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
|
||||||
descriptions := map[string]string{
|
|
||||||
"main": "SQLServer Flex user data source schema. Must have a `region` specified in the provider configuration.",
|
|
||||||
"id": "Terraform's internal data source. ID. It is structured as \"`project_id`,`region`,`instance_id`,`user_id`\".",
|
|
||||||
"user_id": "User ID.",
|
|
||||||
"instance_id": "ID of the SQLServer Flex instance.",
|
|
||||||
"project_id": "STACKIT project ID to which the instance is associated.",
|
|
||||||
"username": "Username of the SQLServer Flex instance.",
|
|
||||||
"roles": "Database access levels for the user.",
|
|
||||||
"password": "Password of the user account.",
|
|
||||||
"region": "The resource region. If not defined, the provider region is used.",
|
|
||||||
"status": "Status of the user.",
|
|
||||||
"default_database": "Default database of the user.",
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.Schema = schema.Schema{
|
|
||||||
Description: descriptions["main"],
|
|
||||||
Attributes: map[string]schema.Attribute{
|
|
||||||
"id": schema.StringAttribute{
|
|
||||||
Description: descriptions["id"],
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"user_id": schema.Int64Attribute{
|
|
||||||
Description: descriptions["user_id"],
|
|
||||||
Required: true,
|
|
||||||
Validators: []validator.Int64{
|
|
||||||
int64validator.AtLeast(1),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"instance_id": schema.StringAttribute{
|
|
||||||
Description: descriptions["instance_id"],
|
|
||||||
Required: true,
|
|
||||||
Validators: []validator.String{
|
|
||||||
validate.UUID(),
|
|
||||||
validate.NoSeparator(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"project_id": schema.StringAttribute{
|
|
||||||
Description: descriptions["project_id"],
|
|
||||||
Required: true,
|
|
||||||
Validators: []validator.String{
|
|
||||||
validate.UUID(),
|
|
||||||
validate.NoSeparator(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"username": schema.StringAttribute{
|
|
||||||
Description: descriptions["username"],
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"roles": schema.SetAttribute{
|
|
||||||
Description: descriptions["roles"],
|
|
||||||
ElementType: types.StringType,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"host": schema.StringAttribute{
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"port": schema.Int64Attribute{
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"region": schema.StringAttribute{
|
|
||||||
// the region cannot be found automatically, so it has to be passed
|
|
||||||
Optional: true,
|
|
||||||
Description: descriptions["region"],
|
|
||||||
},
|
|
||||||
"status": schema.StringAttribute{
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"default_database": schema.StringAttribute{
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read refreshes the Terraform state with the latest data.
|
|
||||||
func (r *userDataSource) Read(
|
|
||||||
ctx context.Context,
|
|
||||||
req datasource.ReadRequest,
|
|
||||||
resp *datasource.ReadResponse,
|
|
||||||
) { // nolint:gocritic // function signature required by Terraform
|
|
||||||
var model dataSourceModel
|
var model dataSourceModel
|
||||||
diags := req.Config.Get(ctx, &model)
|
diags := req.Config.Get(ctx, &model)
|
||||||
resp.Diagnostics.Append(diags...)
|
resp.Diagnostics.Append(diags...)
|
||||||
|
|
@ -174,13 +90,13 @@ func (r *userDataSource) Read(
|
||||||
projectId := model.ProjectId.ValueString()
|
projectId := model.ProjectId.ValueString()
|
||||||
instanceId := model.InstanceId.ValueString()
|
instanceId := model.InstanceId.ValueString()
|
||||||
userId := model.UserId.ValueInt64()
|
userId := model.UserId.ValueInt64()
|
||||||
region := r.providerData.GetRegionWithOverride(model.Region)
|
region := d.providerData.GetRegionWithOverride(model.Region)
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
||||||
ctx = tflog.SetField(ctx, "user_id", userId)
|
ctx = tflog.SetField(ctx, "user_id", userId)
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
ctx = tflog.SetField(ctx, "region", region)
|
||||||
|
|
||||||
recordSetResp, err := r.client.GetUserRequest(ctx, projectId, region, instanceId, userId).Execute()
|
recordSetResp, err := d.client.GetUserRequest(ctx, projectId, region, instanceId, userId).Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.LogError(
|
utils.LogError(
|
||||||
ctx,
|
ctx,
|
||||||
|
|
@ -221,5 +137,5 @@ func (r *userDataSource) Read(
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tflog.Info(ctx, "SQLServer Flex alpha instance read")
|
tflog.Info(ctx, "SQLServer Flex beta instance read")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ func mapDataSourceFields(userResp *sqlserverflexalpha.GetUserResponse, model *da
|
||||||
|
|
||||||
// Map roles
|
// Map roles
|
||||||
if user.Roles == nil {
|
if user.Roles == nil {
|
||||||
model.Roles = types.SetNull(types.StringType)
|
model.Roles = types.List(types.SetNull(types.StringType))
|
||||||
} else {
|
} else {
|
||||||
var roles []attr.Value
|
var roles []attr.Value
|
||||||
for _, role := range *user.Roles {
|
for _, role := range *user.Roles {
|
||||||
|
|
@ -52,7 +52,7 @@ func mapDataSourceFields(userResp *sqlserverflexalpha.GetUserResponse, model *da
|
||||||
if diags.HasError() {
|
if diags.HasError() {
|
||||||
return fmt.Errorf("failed to map roles: %w", core.DiagsToError(diags))
|
return fmt.Errorf("failed to map roles: %w", core.DiagsToError(diags))
|
||||||
}
|
}
|
||||||
model.Roles = rolesSet
|
model.Roles = types.List(rolesSet)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set remaining attributes
|
// Set remaining attributes
|
||||||
|
|
@ -141,7 +141,7 @@ func mapFieldsCreate(userResp *sqlserverflexalpha.CreateUserResponse, model *res
|
||||||
if user.Roles != nil {
|
if user.Roles != nil {
|
||||||
var roles []attr.Value
|
var roles []attr.Value
|
||||||
for _, role := range *user.Roles {
|
for _, role := range *user.Roles {
|
||||||
roles = append(roles, types.StringValue(role))
|
roles = append(roles, types.StringValue(string(role)))
|
||||||
}
|
}
|
||||||
rolesSet, diags := types.SetValue(types.StringType, roles)
|
rolesSet, diags := types.SetValue(types.StringType, roles)
|
||||||
if diags.HasError() {
|
if diags.HasError() {
|
||||||
|
|
@ -154,6 +154,9 @@ func mapFieldsCreate(userResp *sqlserverflexalpha.CreateUserResponse, model *res
|
||||||
model.Roles = types.List(types.SetNull(types.StringType))
|
model.Roles = types.List(types.SetNull(types.StringType))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model.Password = types.StringPointerValue(user.Password)
|
||||||
|
model.Uri = types.StringPointerValue(user.Uri)
|
||||||
|
|
||||||
model.Host = types.StringPointerValue(user.Host)
|
model.Host = types.StringPointerValue(user.Host)
|
||||||
model.Port = types.Int64PointerValue(user.Port)
|
model.Port = types.Int64PointerValue(user.Port)
|
||||||
model.Region = types.StringValue(region)
|
model.Region = types.StringValue(region)
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ func TestMapDataSourceFields(t *testing.T) {
|
||||||
InstanceId: types.StringValue("iid"),
|
InstanceId: types.StringValue("iid"),
|
||||||
ProjectId: types.StringValue("pid"),
|
ProjectId: types.StringValue("pid"),
|
||||||
Username: types.StringNull(),
|
Username: types.StringNull(),
|
||||||
Roles: types.SetNull(types.StringType),
|
Roles: types.List(types.SetNull(types.StringType)),
|
||||||
Host: types.StringNull(),
|
Host: types.StringNull(),
|
||||||
Port: types.Int64Null(),
|
Port: types.Int64Null(),
|
||||||
Region: types.StringValue(testRegion),
|
Region: types.StringValue(testRegion),
|
||||||
|
|
@ -60,12 +60,14 @@ func TestMapDataSourceFields(t *testing.T) {
|
||||||
InstanceId: types.StringValue("iid"),
|
InstanceId: types.StringValue("iid"),
|
||||||
ProjectId: types.StringValue("pid"),
|
ProjectId: types.StringValue("pid"),
|
||||||
Username: types.StringValue("username"),
|
Username: types.StringValue("username"),
|
||||||
Roles: types.SetValueMust(
|
Roles: types.List(
|
||||||
types.StringType, []attr.Value{
|
types.SetValueMust(
|
||||||
types.StringValue("role_1"),
|
types.StringType, []attr.Value{
|
||||||
types.StringValue("role_2"),
|
types.StringValue("role_1"),
|
||||||
types.StringValue(""),
|
types.StringValue("role_2"),
|
||||||
},
|
types.StringValue(""),
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Host: types.StringValue("host"),
|
Host: types.StringValue("host"),
|
||||||
Port: types.Int64Value(1234),
|
Port: types.Int64Value(1234),
|
||||||
|
|
@ -91,7 +93,7 @@ func TestMapDataSourceFields(t *testing.T) {
|
||||||
InstanceId: types.StringValue("iid"),
|
InstanceId: types.StringValue("iid"),
|
||||||
ProjectId: types.StringValue("pid"),
|
ProjectId: types.StringValue("pid"),
|
||||||
Username: types.StringNull(),
|
Username: types.StringNull(),
|
||||||
Roles: types.SetValueMust(types.StringType, []attr.Value{}),
|
Roles: types.List(types.SetValueMust(types.StringType, []attr.Value{})),
|
||||||
Host: types.StringNull(),
|
Host: types.StringNull(),
|
||||||
Port: types.Int64Value(2123456789),
|
Port: types.Int64Value(2123456789),
|
||||||
Region: types.StringValue(testRegion),
|
Region: types.StringValue(testRegion),
|
||||||
|
|
|
||||||
|
|
@ -3,49 +3,40 @@ fields:
|
||||||
modifiers:
|
modifiers:
|
||||||
- 'UseStateForUnknown'
|
- 'UseStateForUnknown'
|
||||||
|
|
||||||
- name: 'user_id'
|
|
||||||
modifiers:
|
|
||||||
- 'UseStateForUnknown'
|
|
||||||
|
|
||||||
- name: 'instance_id'
|
- name: 'instance_id'
|
||||||
validators:
|
validators:
|
||||||
- validate.NoSeparator
|
- validate.NoSeparator
|
||||||
- validate.UUID
|
- validate.UUID
|
||||||
modifiers:
|
modifiers:
|
||||||
|
- 'UseStateForUnknown'
|
||||||
- 'RequiresReplace'
|
- 'RequiresReplace'
|
||||||
|
|
||||||
- name: 'project_id'
|
- name: 'project_id'
|
||||||
validators:
|
validators:
|
||||||
- validate.NoSeparator
|
- validate.NoSeparator
|
||||||
- validate.UUID
|
- validate.UUID
|
||||||
modifiers:
|
|
||||||
- 'RequiresReplace'
|
|
||||||
|
|
||||||
- name: 'username'
|
|
||||||
modifiers:
|
|
||||||
- 'RequiresReplace'
|
|
||||||
|
|
||||||
- name: 'roles'
|
|
||||||
modifiers:
|
|
||||||
- 'RequiresReplace'
|
|
||||||
|
|
||||||
- name: 'password'
|
|
||||||
modifiers:
|
|
||||||
- 'UseStateForUnknown'
|
|
||||||
|
|
||||||
- name: 'host'
|
|
||||||
modifiers:
|
|
||||||
- 'UseStateForUnknown'
|
|
||||||
|
|
||||||
- name: 'port'
|
|
||||||
modifiers:
|
modifiers:
|
||||||
- 'UseStateForUnknown'
|
- 'UseStateForUnknown'
|
||||||
|
- 'RequiresReplace'
|
||||||
|
|
||||||
- name: 'region'
|
- name: 'region'
|
||||||
modifiers:
|
modifiers:
|
||||||
- 'RequiresReplace'
|
- 'RequiresReplace'
|
||||||
|
|
||||||
- name: 'status'
|
- name: 'user_id'
|
||||||
|
modifiers:
|
||||||
|
- 'UseStateForUnknown'
|
||||||
|
- 'RequiresReplace'
|
||||||
|
|
||||||
|
- name: 'username'
|
||||||
|
modifiers:
|
||||||
|
- 'UseStateForUnknown'
|
||||||
|
|
||||||
|
- name: 'roles'
|
||||||
|
modifiers:
|
||||||
|
- 'UseStateForUnknown'
|
||||||
|
|
||||||
|
- name: 'password'
|
||||||
modifiers:
|
modifiers:
|
||||||
- 'UseStateForUnknown'
|
- 'UseStateForUnknown'
|
||||||
|
|
||||||
|
|
@ -53,6 +44,6 @@ fields:
|
||||||
modifiers:
|
modifiers:
|
||||||
- 'UseStateForUnknown'
|
- 'UseStateForUnknown'
|
||||||
|
|
||||||
- name: 'default_database'
|
- name: 'status'
|
||||||
modifiers:
|
modifiers:
|
||||||
- 'UseStateForUnknown'
|
- 'UseStateForUnknown'
|
||||||
|
|
|
||||||
|
|
@ -8,26 +8,27 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource/identityschema"
|
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
|
||||||
sqlserverflexalphagen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/user/resources_gen"
|
|
||||||
sqlserverflexalphaUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/utils"
|
|
||||||
sqlserverflexalphaWait "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/wait/sqlserverflexalpha"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/identityschema"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||||
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
|
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
|
||||||
|
|
||||||
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
||||||
|
sqlserverflexalphagen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/user/resources_gen"
|
||||||
|
sqlserverflexalphaUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/utils"
|
||||||
|
sqlserverflexalphaWait "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/wait/sqlserverflexalpha"
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
||||||
|
|
||||||
|
sqlserverflexalphaResGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/user/resources_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure the implementation satisfies the expected interfaces.
|
|
||||||
var (
|
var (
|
||||||
_ resource.Resource = &userResource{}
|
_ resource.Resource = &userResource{}
|
||||||
_ resource.ResourceWithConfigure = &userResource{}
|
_ resource.ResourceWithConfigure = &userResource{}
|
||||||
|
|
@ -36,13 +37,12 @@ var (
|
||||||
_ resource.ResourceWithIdentity = &userResource{}
|
_ resource.ResourceWithIdentity = &userResource{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewUserResource is a helper function to simplify the provider implementation.
|
|
||||||
func NewUserResource() resource.Resource {
|
func NewUserResource() resource.Resource {
|
||||||
return &userResource{}
|
return &userResource{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// resourceModel describes the resource data model.
|
// resourceModel describes the resource data model.
|
||||||
type resourceModel = sqlserverflexalphagen.UserModel
|
type resourceModel = sqlserverflexalphaResGen.UserModel
|
||||||
|
|
||||||
// UserResourceIdentityModel describes the resource's identity attributes.
|
// UserResourceIdentityModel describes the resource's identity attributes.
|
||||||
type UserResourceIdentityModel struct {
|
type UserResourceIdentityModel struct {
|
||||||
|
|
@ -52,14 +52,12 @@ type UserResourceIdentityModel struct {
|
||||||
UserID types.Int64 `tfsdk:"user_id"`
|
UserID types.Int64 `tfsdk:"user_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// userResource is the resource implementation.
|
|
||||||
type userResource struct {
|
type userResource struct {
|
||||||
client *sqlserverflexalpha.APIClient
|
client *sqlserverflexalpha.APIClient
|
||||||
providerData core.ProviderData
|
providerData core.ProviderData
|
||||||
}
|
}
|
||||||
|
|
||||||
// Metadata returns the resource type name.
|
func (r *userResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||||
func (r *userResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
|
||||||
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_user"
|
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_user"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,7 +74,7 @@ func (r *userResource) Configure(ctx context.Context, req resource.ConfigureRequ
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.client = apiClient
|
r.client = apiClient
|
||||||
tflog.Info(ctx, "SQLServer Alpha Flex user client configured")
|
tflog.Info(ctx, "SQLServer Beta Flex user client configured")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ModifyPlan implements resource.ResourceWithModifyPlan.
|
// ModifyPlan implements resource.ResourceWithModifyPlan.
|
||||||
|
|
@ -219,6 +217,7 @@ func (r *userResource) Create(
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
userId := *userResp.Id
|
userId := *userResp.Id
|
||||||
ctx = tflog.SetField(ctx, "user_id", userId)
|
ctx = tflog.SetField(ctx, "user_id", userId)
|
||||||
|
|
||||||
|
|
@ -227,14 +226,13 @@ func (r *userResource) Create(
|
||||||
ProjectID: types.StringValue(projectId),
|
ProjectID: types.StringValue(projectId),
|
||||||
Region: types.StringValue(region),
|
Region: types.StringValue(region),
|
||||||
InstanceID: types.StringValue(instanceId),
|
InstanceID: types.StringValue(instanceId),
|
||||||
UserID: types.Int64Value(userResp.GetId()),
|
UserID: types.Int64Value(userId),
|
||||||
}
|
}
|
||||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map response body to schema
|
|
||||||
err = mapFieldsCreate(userResp, &model, region)
|
err = mapFieldsCreate(userResp, &model, region)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
|
|
@ -245,6 +243,51 @@ func (r *userResource) Create(
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
waitResp, err := sqlserverflexalphaWait.CreateUserWaitHandler(
|
||||||
|
ctx,
|
||||||
|
r.client,
|
||||||
|
projectId,
|
||||||
|
instanceId,
|
||||||
|
region,
|
||||||
|
userId,
|
||||||
|
).SetSleepBeforeWait(
|
||||||
|
90 * time.Second,
|
||||||
|
).SetTimeout(
|
||||||
|
90 * time.Minute,
|
||||||
|
).WaitWithContext(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
"create user",
|
||||||
|
fmt.Sprintf("Instance creation waiting: %v", err),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if waitResp.Id == nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
"create user",
|
||||||
|
"Instance creation waiting: returned id is nil",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map response body to schema
|
||||||
|
err = mapFields(waitResp, &model, region)
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
"Error creating user",
|
||||||
|
fmt.Sprintf("Processing API payload: %v", err),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
// Set state to fully populated data
|
// Set state to fully populated data
|
||||||
diags = resp.State.Set(ctx, model)
|
diags = resp.State.Set(ctx, model)
|
||||||
resp.Diagnostics.Append(diags...)
|
resp.Diagnostics.Append(diags...)
|
||||||
|
|
@ -296,18 +339,6 @@ func (r *userResource) Read(
|
||||||
|
|
||||||
ctx = core.LogResponse(ctx)
|
ctx = core.LogResponse(ctx)
|
||||||
|
|
||||||
// Set data returned by API in identity
|
|
||||||
identity := UserResourceIdentityModel{
|
|
||||||
ProjectID: types.StringValue(projectId),
|
|
||||||
Region: types.StringValue(region),
|
|
||||||
InstanceID: types.StringValue(instanceId),
|
|
||||||
UserID: types.Int64Value(userId),
|
|
||||||
}
|
|
||||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map response body to schema
|
// Map response body to schema
|
||||||
err = mapFields(recordSetResp, &model, region)
|
err = mapFields(recordSetResp, &model, region)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -320,6 +351,18 @@ func (r *userResource) Read(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set data returned by API in identity
|
||||||
|
identity := UserResourceIdentityModel{
|
||||||
|
ProjectID: types.StringValue(projectId),
|
||||||
|
Region: types.StringValue(region),
|
||||||
|
InstanceID: types.StringValue(instanceId),
|
||||||
|
UserID: types.Int64Value(userId),
|
||||||
|
}
|
||||||
|
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Set refreshed state
|
// Set refreshed state
|
||||||
diags = resp.State.Set(ctx, model)
|
diags = resp.State.Set(ctx, model)
|
||||||
resp.Diagnostics.Append(diags...)
|
resp.Diagnostics.Append(diags...)
|
||||||
|
|
@ -366,9 +409,29 @@ func (r *userResource) Delete(
|
||||||
|
|
||||||
// Delete existing record set
|
// Delete existing record set
|
||||||
// err := r.client.DeleteUserRequest(ctx, projectId, region, instanceId, userId).Execute()
|
// err := r.client.DeleteUserRequest(ctx, projectId, region, instanceId, userId).Execute()
|
||||||
|
err := r.client.DeleteUserRequestExecute(ctx, projectId, region, instanceId, userId)
|
||||||
|
if err != nil {
|
||||||
|
var oapiErr *oapierror.GenericOpenAPIError
|
||||||
|
ok := errors.As(err, &oapiErr)
|
||||||
|
if !ok {
|
||||||
|
// TODO err handling
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch oapiErr.StatusCode {
|
||||||
|
case http.StatusNotFound:
|
||||||
|
resp.State.RemoveResource(ctx)
|
||||||
|
return
|
||||||
|
// case http.StatusInternalServerError:
|
||||||
|
// tflog.Warn(ctx, "[delete user] Wait handler got error 500")
|
||||||
|
// return false, nil, nil
|
||||||
|
default:
|
||||||
|
// TODO err handling
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
// Delete existing record set
|
// Delete existing record set
|
||||||
_, err := sqlserverflexalphaWait.DeleteUserWaitHandler(ctx, r.client, projectId, region, instanceId, userId).
|
_, err = sqlserverflexalphaWait.DeleteUserWaitHandler(ctx, r.client, projectId, region, instanceId, userId).
|
||||||
WaitWithContext(ctx)
|
WaitWithContext(ctx)
|
||||||
// err := r.client.DeleteUserRequest(ctx, arg.projectId, arg.region, arg.instanceId, userId).Execute()
|
// err := r.client.DeleteUserRequest(ctx, arg.projectId, arg.region, arg.instanceId, userId).Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -377,6 +440,7 @@ func (r *userResource) Delete(
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = core.LogResponse(ctx)
|
ctx = core.LogResponse(ctx)
|
||||||
|
|
||||||
resp.State.RemoveResource(ctx)
|
resp.State.RemoveResource(ctx)
|
||||||
|
|
||||||
tflog.Info(ctx, "SQLServer Flex user deleted")
|
tflog.Info(ctx, "SQLServer Flex user deleted")
|
||||||
|
|
@ -422,7 +486,7 @@ func (r *userResource) ImportState(
|
||||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), idParts[2])...)
|
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), idParts[2])...)
|
||||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("user_id"), userId)...)
|
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("user_id"), userId)...)
|
||||||
|
|
||||||
tflog.Info(ctx, "Postgres Flex user state imported")
|
tflog.Info(ctx, "SQLServer Flex user state imported")
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
// Copyright (c) STACKIT
|
|
||||||
|
|
||||||
package sqlserverflexalpha
|
package sqlserverflexalpha
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -28,145 +26,355 @@ const (
|
||||||
InstanceStateTerminating = "TERMINATING"
|
InstanceStateTerminating = "TERMINATING"
|
||||||
)
|
)
|
||||||
|
|
||||||
// APIClientInstanceInterface Interface needed for tests
|
// APIClientInterface Interface needed for tests
|
||||||
type APIClientInstanceInterface interface {
|
type APIClientInterface interface {
|
||||||
GetInstanceRequestExecute(ctx context.Context, projectId, region, instanceId string) (*sqlserverflex.GetInstanceResponse, error)
|
GetInstanceRequestExecute(
|
||||||
|
ctx context.Context,
|
||||||
|
projectId, region, instanceId string,
|
||||||
|
) (*sqlserverflex.GetInstanceResponse, error)
|
||||||
|
GetDatabaseRequestExecute(
|
||||||
|
ctx context.Context,
|
||||||
|
projectId string,
|
||||||
|
region string,
|
||||||
|
instanceId string,
|
||||||
|
databaseName string,
|
||||||
|
) (*sqlserverflex.GetDatabaseResponse, error)
|
||||||
|
GetUserRequestExecute(
|
||||||
|
ctx context.Context,
|
||||||
|
projectId string,
|
||||||
|
region string,
|
||||||
|
instanceId string,
|
||||||
|
userId int64,
|
||||||
|
) (*sqlserverflex.GetUserResponse, error)
|
||||||
|
|
||||||
|
ListRolesRequestExecute(
|
||||||
|
ctx context.Context,
|
||||||
|
projectId string,
|
||||||
|
region string,
|
||||||
|
instanceId string,
|
||||||
|
) (*sqlserverflex.ListRolesResponse, error)
|
||||||
|
|
||||||
|
ListUsersRequest(ctx context.Context, projectId string, region string, instanceId string) sqlserverflex.ApiListUsersRequestRequest
|
||||||
|
|
||||||
|
ListUsersRequestExecute(
|
||||||
|
ctx context.Context,
|
||||||
|
projectId string,
|
||||||
|
region string,
|
||||||
|
instanceId string,
|
||||||
|
) (*sqlserverflex.ListUserResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIClientUserInterface Interface needed for tests
|
// APIClientUserInterface Interface needed for tests
|
||||||
type APIClientUserInterface interface {
|
type APIClientUserInterface interface {
|
||||||
DeleteUserRequestExecute(ctx context.Context, projectId string, region string, instanceId string, userId int64) error
|
DeleteUserRequestExecute(
|
||||||
|
ctx context.Context,
|
||||||
|
projectId string,
|
||||||
|
region string,
|
||||||
|
instanceId string,
|
||||||
|
userId int64,
|
||||||
|
) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateInstanceWaitHandler will wait for instance creation
|
// CreateInstanceWaitHandler will wait for instance creation
|
||||||
func CreateInstanceWaitHandler(ctx context.Context, a APIClientInstanceInterface, projectId, instanceId, region string) *wait.AsyncActionHandler[sqlserverflex.GetInstanceResponse] {
|
func CreateInstanceWaitHandler(
|
||||||
handler := wait.New(func() (waitFinished bool, response *sqlserverflex.GetInstanceResponse, err error) {
|
ctx context.Context,
|
||||||
s, err := a.GetInstanceRequestExecute(ctx, projectId, region, instanceId)
|
a APIClientInterface,
|
||||||
if err != nil {
|
projectId, instanceId, region string,
|
||||||
// TODO: catch 502, 503 and 504
|
) *wait.AsyncActionHandler[sqlserverflex.GetInstanceResponse] {
|
||||||
return false, nil, err
|
handler := wait.New(
|
||||||
}
|
func() (waitFinished bool, response *sqlserverflex.GetInstanceResponse, err error) {
|
||||||
if s == nil || s.Id == nil || *s.Id != instanceId || s.Status == nil {
|
s, err := a.GetInstanceRequestExecute(ctx, projectId, region, instanceId)
|
||||||
return false, nil, nil
|
if err != nil {
|
||||||
}
|
return false, nil, err
|
||||||
switch strings.ToLower(string(*s.Status)) {
|
|
||||||
case strings.ToLower(InstanceStateSuccess):
|
|
||||||
if *s.Network.AccessScope == "SNA" {
|
|
||||||
if s.Network.InstanceAddress == nil {
|
|
||||||
tflog.Info(ctx, "Waiting for instance_address")
|
|
||||||
return false, nil, nil
|
|
||||||
}
|
|
||||||
if s.Network.RouterAddress == nil {
|
|
||||||
tflog.Info(ctx, "Waiting for router_address")
|
|
||||||
return false, nil, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true, s, nil
|
if s == nil || s.Id == nil || *s.Id != instanceId || s.Status == nil {
|
||||||
case strings.ToLower(InstanceStateUnknown), strings.ToLower(InstanceStateFailed):
|
return false, nil, nil
|
||||||
return true, s, fmt.Errorf("create failed for instance with id %s", instanceId)
|
}
|
||||||
case strings.ToLower(InstanceStatePending), strings.ToLower(InstanceStateProcessing):
|
switch strings.ToLower(string(*s.Status)) {
|
||||||
tflog.Info(ctx, "request is being handled", map[string]interface{}{
|
case strings.ToLower(InstanceStateSuccess):
|
||||||
"status": *s.Status,
|
if s.Network != nil && s.Network.AccessScope != nil && *s.Network.AccessScope == "SNA" {
|
||||||
})
|
if s.Network.InstanceAddress == nil {
|
||||||
return false, nil, nil
|
tflog.Info(ctx, "Waiting for instance_address")
|
||||||
default:
|
return false, nil, nil
|
||||||
tflog.Info(ctx, "Wait (create) received unknown status", map[string]interface{}{
|
}
|
||||||
"instanceId": instanceId,
|
if s.Network.RouterAddress == nil {
|
||||||
"status": s.Status,
|
tflog.Info(ctx, "Waiting for router_address")
|
||||||
})
|
return false, nil, nil
|
||||||
return false, s, nil
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
tflog.Info(ctx, "trying to get roles")
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
_, rolesErr := a.ListRolesRequestExecute(ctx, projectId, region, instanceId)
|
||||||
|
if rolesErr != nil {
|
||||||
|
var oapiErr *oapierror.GenericOpenAPIError
|
||||||
|
ok := errors.As(rolesErr, &oapiErr)
|
||||||
|
if !ok {
|
||||||
|
return false, nil, fmt.Errorf("could not convert error to oapierror.GenericOpenAPIError")
|
||||||
|
}
|
||||||
|
if oapiErr.StatusCode != http.StatusInternalServerError {
|
||||||
|
tflog.Info(
|
||||||
|
ctx, "got error from api", map[string]interface{}{
|
||||||
|
"error": rolesErr.Error(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return false, nil, rolesErr
|
||||||
|
}
|
||||||
|
tflog.Info(
|
||||||
|
ctx, "wait for get-roles to work hack", map[string]interface{}{},
|
||||||
|
)
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
return false, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
tflog.Info(ctx, "trying to get users")
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
_, usersErr := a.ListUsersRequestExecute(ctx, projectId, region, instanceId)
|
||||||
|
if usersErr != nil {
|
||||||
|
var oapiErr *oapierror.GenericOpenAPIError
|
||||||
|
ok := errors.As(usersErr, &oapiErr)
|
||||||
|
if !ok {
|
||||||
|
return false, nil, fmt.Errorf("could not convert error to oapierror.GenericOpenAPIError")
|
||||||
|
}
|
||||||
|
if oapiErr.StatusCode != http.StatusInternalServerError {
|
||||||
|
tflog.Info(
|
||||||
|
ctx, "got error from api", map[string]interface{}{
|
||||||
|
"error": rolesErr.Error(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return false, nil, usersErr
|
||||||
|
}
|
||||||
|
tflog.Info(
|
||||||
|
ctx, "wait for get-users to work hack", map[string]interface{}{},
|
||||||
|
)
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
return false, nil, nil
|
||||||
|
}
|
||||||
|
return true, s, nil
|
||||||
|
case strings.ToLower(InstanceStateUnknown), strings.ToLower(InstanceStateFailed):
|
||||||
|
return true, nil, fmt.Errorf("create failed for instance with id %s", instanceId)
|
||||||
|
case strings.ToLower(InstanceStatePending), strings.ToLower(InstanceStateProcessing):
|
||||||
|
tflog.Info(
|
||||||
|
ctx, "request is being handled", map[string]interface{}{
|
||||||
|
"status": *s.Status,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
return false, nil, nil
|
||||||
|
default:
|
||||||
|
tflog.Info(
|
||||||
|
ctx, "Wait (create) received unknown status", map[string]interface{}{
|
||||||
|
"instanceId": instanceId,
|
||||||
|
"status": s.Status,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return true, nil, errors.New("unknown status received")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateInstanceWaitHandler will wait for instance update
|
// UpdateInstanceWaitHandler will wait for instance update
|
||||||
func UpdateInstanceWaitHandler(ctx context.Context, a APIClientInstanceInterface, projectId, instanceId, region string) *wait.AsyncActionHandler[sqlserverflex.GetInstanceResponse] {
|
func UpdateInstanceWaitHandler(
|
||||||
handler := wait.New(func() (waitFinished bool, response *sqlserverflex.GetInstanceResponse, err error) {
|
ctx context.Context,
|
||||||
s, err := a.GetInstanceRequestExecute(ctx, projectId, region, instanceId)
|
a APIClientInterface,
|
||||||
if err != nil {
|
projectId, instanceId, region string,
|
||||||
return false, nil, err
|
) *wait.AsyncActionHandler[sqlserverflex.GetInstanceResponse] {
|
||||||
}
|
handler := wait.New(
|
||||||
if s == nil || s.Id == nil || *s.Id != instanceId || s.Status == nil {
|
func() (waitFinished bool, response *sqlserverflex.GetInstanceResponse, err error) {
|
||||||
return false, nil, nil
|
s, err := a.GetInstanceRequestExecute(ctx, projectId, region, instanceId)
|
||||||
}
|
if err != nil {
|
||||||
switch strings.ToLower(string(*s.Status)) {
|
return false, nil, err
|
||||||
case strings.ToLower(InstanceStateSuccess):
|
}
|
||||||
return true, s, nil
|
if s == nil || s.Id == nil || *s.Id != instanceId || s.Status == nil {
|
||||||
case strings.ToLower(InstanceStateUnknown), strings.ToLower(InstanceStateFailed):
|
return false, nil, nil
|
||||||
return true, s, fmt.Errorf("update failed for instance with id %s", instanceId)
|
}
|
||||||
case strings.ToLower(InstanceStatePending), strings.ToLower(InstanceStateProcessing):
|
switch strings.ToLower(string(*s.Status)) {
|
||||||
tflog.Info(ctx, "request is being handled", map[string]interface{}{
|
case strings.ToLower(InstanceStateSuccess):
|
||||||
"status": *s.Status,
|
return true, s, nil
|
||||||
})
|
case strings.ToLower(InstanceStateUnknown), strings.ToLower(InstanceStateFailed):
|
||||||
return false, nil, nil
|
return true, s, fmt.Errorf("update failed for instance with id %s", instanceId)
|
||||||
default:
|
case strings.ToLower(InstanceStatePending), strings.ToLower(InstanceStateProcessing):
|
||||||
tflog.Info(ctx, "Wait (update) received unknown status", map[string]interface{}{
|
tflog.Info(
|
||||||
"instanceId": instanceId,
|
ctx, "request is being handled", map[string]interface{}{
|
||||||
"status": s.Status,
|
"status": *s.Status,
|
||||||
})
|
},
|
||||||
return false, s, nil
|
)
|
||||||
}
|
return false, s, nil
|
||||||
})
|
default:
|
||||||
handler.SetSleepBeforeWait(15 * time.Second)
|
tflog.Info(
|
||||||
handler.SetTimeout(45 * time.Minute)
|
ctx, "Wait (update) received unknown status", map[string]interface{}{
|
||||||
|
"instanceId": instanceId,
|
||||||
|
"status": s.Status,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return false, s, nil
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
|
|
||||||
// PartialUpdateInstanceWaitHandler will wait for instance update
|
// DeleteInstanceWaitHandler will wait for instance deletion
|
||||||
func PartialUpdateInstanceWaitHandler(ctx context.Context, a APIClientInstanceInterface, projectId, instanceId, region string) *wait.AsyncActionHandler[sqlserverflex.GetInstanceResponse] {
|
func DeleteInstanceWaitHandler(
|
||||||
return UpdateInstanceWaitHandler(ctx, a, projectId, instanceId, region)
|
ctx context.Context,
|
||||||
|
a APIClientInterface,
|
||||||
|
projectId, instanceId, region string,
|
||||||
|
) *wait.AsyncActionHandler[sqlserverflex.GetInstanceResponse] {
|
||||||
|
handler := wait.New(
|
||||||
|
func() (waitFinished bool, response *sqlserverflex.GetInstanceResponse, err error) {
|
||||||
|
s, err := a.GetInstanceRequestExecute(ctx, projectId, region, instanceId)
|
||||||
|
if err == nil {
|
||||||
|
return false, s, nil
|
||||||
|
}
|
||||||
|
var oapiErr *oapierror.GenericOpenAPIError
|
||||||
|
ok := errors.As(err, &oapiErr)
|
||||||
|
if !ok {
|
||||||
|
return false, nil, fmt.Errorf("could not convert error to oapierror.GenericOpenAPIError")
|
||||||
|
}
|
||||||
|
if oapiErr.StatusCode != http.StatusNotFound {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
return true, nil, nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
handler.SetTimeout(30 * time.Minute)
|
||||||
|
return handler
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteInstanceWaitHandler will wait for instance deletion
|
// CreateDatabaseWaitHandler will wait for instance creation
|
||||||
func DeleteInstanceWaitHandler(ctx context.Context, a APIClientInstanceInterface, projectId, instanceId, region string) *wait.AsyncActionHandler[struct{}] {
|
func CreateDatabaseWaitHandler(
|
||||||
handler := wait.New(func() (waitFinished bool, response *struct{}, err error) {
|
ctx context.Context,
|
||||||
_, err = a.GetInstanceRequestExecute(ctx, projectId, region, instanceId)
|
a APIClientInterface,
|
||||||
if err == nil {
|
projectId, instanceId, region, databaseName string,
|
||||||
|
) *wait.AsyncActionHandler[sqlserverflex.GetDatabaseResponse] {
|
||||||
|
handler := wait.New(
|
||||||
|
func() (waitFinished bool, response *sqlserverflex.GetDatabaseResponse, err error) {
|
||||||
|
s, err := a.GetDatabaseRequestExecute(ctx, projectId, region, instanceId, databaseName)
|
||||||
|
if err != nil {
|
||||||
|
var oapiErr *oapierror.GenericOpenAPIError
|
||||||
|
ok := errors.As(err, &oapiErr)
|
||||||
|
if !ok {
|
||||||
|
return false, nil, fmt.Errorf("get database - could not convert error to oapierror.GenericOpenAPIError: %s", err.Error())
|
||||||
|
}
|
||||||
|
if oapiErr.StatusCode != http.StatusNotFound {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
return false, nil, nil
|
||||||
|
}
|
||||||
|
if s == nil || s.Name == nil || *s.Name != databaseName {
|
||||||
|
return false, nil, errors.New("response did return different result")
|
||||||
|
}
|
||||||
|
return true, s, nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return handler
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateUserWaitHandler will wait for instance creation
|
||||||
|
func CreateUserWaitHandler(
|
||||||
|
ctx context.Context,
|
||||||
|
a APIClientInterface,
|
||||||
|
projectId, instanceId, region string,
|
||||||
|
userId int64,
|
||||||
|
) *wait.AsyncActionHandler[sqlserverflex.GetUserResponse] {
|
||||||
|
handler := wait.New(
|
||||||
|
func() (waitFinished bool, response *sqlserverflex.GetUserResponse, err error) {
|
||||||
|
s, err := a.GetUserRequestExecute(ctx, projectId, region, instanceId, userId)
|
||||||
|
if err != nil {
|
||||||
|
var oapiErr *oapierror.GenericOpenAPIError
|
||||||
|
ok := errors.As(err, &oapiErr)
|
||||||
|
if !ok {
|
||||||
|
return false, nil, fmt.Errorf("could not convert error to oapierror.GenericOpenAPIError")
|
||||||
|
}
|
||||||
|
if oapiErr.StatusCode != http.StatusNotFound {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
return false, nil, nil
|
||||||
|
}
|
||||||
|
return true, s, nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return handler
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaitForUserWaitHandler will wait for instance creation
|
||||||
|
func WaitForUserWaitHandler(
|
||||||
|
ctx context.Context,
|
||||||
|
a APIClientInterface,
|
||||||
|
projectId, instanceId, region, userName string,
|
||||||
|
) *wait.AsyncActionHandler[sqlserverflex.ListUserResponse] {
|
||||||
|
startTime := time.Now()
|
||||||
|
timeOut := 2 * time.Minute
|
||||||
|
|
||||||
|
handler := wait.New(
|
||||||
|
func() (waitFinished bool, response *sqlserverflex.ListUserResponse, err error) {
|
||||||
|
if time.Since(startTime) > timeOut {
|
||||||
|
return false, nil, errors.New("ran into timeout")
|
||||||
|
}
|
||||||
|
s, err := a.ListUsersRequest(ctx, projectId, region, instanceId).Size(100).Execute()
|
||||||
|
if err != nil {
|
||||||
|
var oapiErr *oapierror.GenericOpenAPIError
|
||||||
|
ok := errors.As(err, &oapiErr)
|
||||||
|
if !ok {
|
||||||
|
return false, nil, fmt.Errorf("Wait (list users) could not convert error to oapierror.GenericOpenAPIError: %s", err.Error())
|
||||||
|
}
|
||||||
|
if oapiErr.StatusCode != http.StatusNotFound {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
tflog.Info(
|
||||||
|
ctx, "Wait (list users) still waiting", map[string]interface{}{},
|
||||||
|
)
|
||||||
|
|
||||||
|
return false, nil, nil
|
||||||
|
}
|
||||||
|
users, ok := s.GetUsersOk()
|
||||||
|
if !ok {
|
||||||
|
return false, nil, errors.New("no users found")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, u := range users {
|
||||||
|
if u.GetUsername() == userName {
|
||||||
|
return true, s, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tflog.Info(
|
||||||
|
ctx, "Wait (list users) user still not present", map[string]interface{}{},
|
||||||
|
)
|
||||||
return false, nil, nil
|
return false, nil, nil
|
||||||
}
|
},
|
||||||
var oapiErr *oapierror.GenericOpenAPIError
|
)
|
||||||
ok := errors.As(err, &oapiErr)
|
|
||||||
if !ok {
|
|
||||||
return false, nil, fmt.Errorf("could not convert error to oapierror.GenericOpenAPIError")
|
|
||||||
}
|
|
||||||
if oapiErr.StatusCode != http.StatusNotFound {
|
|
||||||
return false, nil, err
|
|
||||||
}
|
|
||||||
return true, nil, nil
|
|
||||||
})
|
|
||||||
handler.SetTimeout(15 * time.Minute)
|
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteUserWaitHandler will wait for instance deletion
|
// DeleteUserWaitHandler will wait for instance deletion
|
||||||
func DeleteUserWaitHandler(
|
func DeleteUserWaitHandler(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
a APIClientUserInterface,
|
a APIClientInterface,
|
||||||
projectId, instanceId, region string,
|
projectId, region, instanceId string,
|
||||||
userId int64,
|
userId int64,
|
||||||
) *wait.AsyncActionHandler[struct{}] {
|
) *wait.AsyncActionHandler[struct{}] {
|
||||||
handler := wait.New(func() (waitFinished bool, response *struct{}, err error) {
|
handler := wait.New(
|
||||||
err = a.DeleteUserRequestExecute(ctx, projectId, region, instanceId, userId)
|
func() (waitFinished bool, response *struct{}, err error) {
|
||||||
if err == nil {
|
_, err = a.GetUserRequestExecute(ctx, projectId, region, instanceId, userId)
|
||||||
return false, nil, nil
|
if err == nil {
|
||||||
}
|
return false, nil, nil
|
||||||
var oapiErr *oapierror.GenericOpenAPIError
|
}
|
||||||
ok := errors.As(err, &oapiErr)
|
var oapiErr *oapierror.GenericOpenAPIError
|
||||||
if !ok {
|
ok := errors.As(err, &oapiErr)
|
||||||
return false, nil, fmt.Errorf("could not convert error to oapierror.GenericOpenAPIError")
|
if !ok {
|
||||||
}
|
return false, nil, fmt.Errorf("could not convert error to oapierror.GenericOpenAPIError")
|
||||||
|
}
|
||||||
|
|
||||||
switch oapiErr.StatusCode {
|
switch oapiErr.StatusCode {
|
||||||
case http.StatusNotFound:
|
case http.StatusNotFound:
|
||||||
return true, nil, nil
|
return true, nil, nil
|
||||||
case http.StatusInternalServerError:
|
default:
|
||||||
tflog.Warn(ctx, "Wait handler got error 500")
|
return false, nil, err
|
||||||
return false, nil, nil
|
}
|
||||||
default:
|
},
|
||||||
return false, nil, err
|
)
|
||||||
}
|
|
||||||
})
|
|
||||||
handler.SetTimeout(15 * time.Minute)
|
handler.SetTimeout(15 * time.Minute)
|
||||||
handler.SetSleepBeforeWait(15 * time.Second)
|
handler.SetSleepBeforeWait(15 * time.Second)
|
||||||
return handler
|
return handler
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
// Copyright (c) STACKIT
|
|
||||||
|
|
||||||
package sqlserverflexalpha
|
package sqlserverflexalpha
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -23,7 +22,81 @@ type apiClientInstanceMocked struct {
|
||||||
instanceGetFails bool
|
instanceGetFails bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apiClientInstanceMocked) GetInstanceRequestExecute(_ context.Context, _, _, _ string) (*sqlserverflex.GetInstanceResponse, error) {
|
type ListUsersRequestRequest struct{}
|
||||||
|
|
||||||
|
func (l ListUsersRequestRequest) Page(_ int64) sqlserverflex.ApiListUsersRequestRequest {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l ListUsersRequestRequest) Size(_ int64) sqlserverflex.ApiListUsersRequestRequest {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l ListUsersRequestRequest) Sort(_ sqlserverflex.UserSort) sqlserverflex.ApiListUsersRequestRequest {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l ListUsersRequestRequest) Execute() (*sqlserverflex.ListUserResponse, error) {
|
||||||
|
// TODO implement me
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *apiClientInstanceMocked) ListUsersRequest(
|
||||||
|
_ context.Context,
|
||||||
|
_ string,
|
||||||
|
_ string,
|
||||||
|
_ string,
|
||||||
|
) sqlserverflex.ApiListUsersRequestRequest {
|
||||||
|
return ListUsersRequestRequest{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *apiClientInstanceMocked) ListRolesRequestExecute(
|
||||||
|
_ context.Context,
|
||||||
|
_ string,
|
||||||
|
_ string,
|
||||||
|
_ string,
|
||||||
|
) (*sqlserverflex.ListRolesResponse, error) {
|
||||||
|
return &sqlserverflex.ListRolesResponse{
|
||||||
|
Roles: &[]string{},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *apiClientInstanceMocked) ListUsersRequestExecute(
|
||||||
|
_ context.Context,
|
||||||
|
_ string,
|
||||||
|
_ string,
|
||||||
|
_ string,
|
||||||
|
) (*sqlserverflex.ListUserResponse, error) {
|
||||||
|
return &sqlserverflex.ListUserResponse{
|
||||||
|
Pagination: nil,
|
||||||
|
Users: nil,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *apiClientInstanceMocked) GetDatabaseRequestExecute(
|
||||||
|
_ context.Context,
|
||||||
|
_ string,
|
||||||
|
_ string,
|
||||||
|
_ string,
|
||||||
|
_ string,
|
||||||
|
) (*sqlserverflex.GetDatabaseResponse, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *apiClientInstanceMocked) GetUserRequestExecute(
|
||||||
|
_ context.Context,
|
||||||
|
_ string,
|
||||||
|
_ string,
|
||||||
|
_ string,
|
||||||
|
_ int64,
|
||||||
|
) (*sqlserverflex.GetUserResponse, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *apiClientInstanceMocked) GetInstanceRequestExecute(
|
||||||
|
_ context.Context,
|
||||||
|
_, _, _ string,
|
||||||
|
) (*sqlserverflex.GetInstanceResponse, error) {
|
||||||
if a.instanceGetFails {
|
if a.instanceGetFails {
|
||||||
return nil, &oapierror.GenericOpenAPIError{
|
return nil, &oapierror.GenericOpenAPIError{
|
||||||
StatusCode: 500,
|
StatusCode: 500,
|
||||||
|
|
@ -43,9 +116,11 @@ func (a *apiClientInstanceMocked) GetInstanceRequestExecute(_ context.Context, _
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
func TestCreateInstanceWaitHandler(t *testing.T) {
|
func TestCreateInstanceWaitHandler(t *testing.T) {
|
||||||
t.Skip("skipping - needs refactoring")
|
//stateSuccess := utils.Ptr(InstanceStateSuccess)
|
||||||
|
instanceId := utils.Ptr("foo")
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
desc string
|
desc string
|
||||||
|
instanceId string
|
||||||
instanceGetFails bool
|
instanceGetFails bool
|
||||||
instanceState string
|
instanceState string
|
||||||
instanceNetwork sqlserverflex.InstanceNetwork
|
instanceNetwork sqlserverflex.InstanceNetwork
|
||||||
|
|
@ -53,40 +128,42 @@ func TestCreateInstanceWaitHandler(t *testing.T) {
|
||||||
wantErr bool
|
wantErr bool
|
||||||
wantRes *sqlserverflex.GetInstanceResponse
|
wantRes *sqlserverflex.GetInstanceResponse
|
||||||
}{
|
}{
|
||||||
{
|
//{
|
||||||
desc: "create_succeeded",
|
// desc: "create_succeeded",
|
||||||
instanceGetFails: false,
|
// instanceId: *instanceId,
|
||||||
instanceState: InstanceStateSuccess,
|
// instanceGetFails: false,
|
||||||
instanceNetwork: sqlserverflex.InstanceNetwork{
|
// instanceState: *stateSuccess,
|
||||||
AccessScope: nil,
|
// instanceNetwork: sqlserverflex.InstanceNetwork{
|
||||||
Acl: nil,
|
// AccessScope: nil,
|
||||||
InstanceAddress: utils.Ptr("10.0.0.1"),
|
// Acl: nil,
|
||||||
RouterAddress: utils.Ptr("10.0.0.2"),
|
// InstanceAddress: utils.Ptr("10.0.0.1"),
|
||||||
},
|
// RouterAddress: utils.Ptr("10.0.0.2"),
|
||||||
wantErr: false,
|
// },
|
||||||
wantRes: &sqlserverflex.GetInstanceResponse{
|
// wantErr: false,
|
||||||
BackupSchedule: nil,
|
// wantRes: &sqlserverflex.GetInstanceResponse{
|
||||||
Edition: nil,
|
// BackupSchedule: nil,
|
||||||
Encryption: nil,
|
// Edition: nil,
|
||||||
FlavorId: nil,
|
// Encryption: nil,
|
||||||
Id: nil,
|
// FlavorId: nil,
|
||||||
IsDeletable: nil,
|
// Id: instanceId,
|
||||||
Name: nil,
|
// IsDeletable: nil,
|
||||||
Network: &sqlserverflex.InstanceNetwork{
|
// Name: nil,
|
||||||
AccessScope: nil,
|
// Network: &sqlserverflex.InstanceNetwork{
|
||||||
Acl: nil,
|
// AccessScope: nil,
|
||||||
InstanceAddress: utils.Ptr("10.0.0.1"),
|
// Acl: nil,
|
||||||
RouterAddress: utils.Ptr("10.0.0.2"),
|
// InstanceAddress: utils.Ptr("10.0.0.1"),
|
||||||
},
|
// RouterAddress: utils.Ptr("10.0.0.2"),
|
||||||
Replicas: nil,
|
// },
|
||||||
RetentionDays: nil,
|
// Replicas: nil,
|
||||||
Status: nil,
|
// RetentionDays: nil,
|
||||||
Storage: nil,
|
// Status: sqlserverflex.GetInstanceResponseGetStatusAttributeType(stateSuccess),
|
||||||
Version: nil,
|
// Storage: nil,
|
||||||
},
|
// Version: nil,
|
||||||
},
|
// },
|
||||||
|
//},
|
||||||
{
|
{
|
||||||
desc: "create_failed",
|
desc: "create_failed",
|
||||||
|
instanceId: *instanceId,
|
||||||
instanceGetFails: false,
|
instanceGetFails: false,
|
||||||
instanceState: InstanceStateFailed,
|
instanceState: InstanceStateFailed,
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
|
|
@ -94,6 +171,7 @@ func TestCreateInstanceWaitHandler(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "create_failed_2",
|
desc: "create_failed_2",
|
||||||
|
instanceId: *instanceId,
|
||||||
instanceGetFails: false,
|
instanceGetFails: false,
|
||||||
instanceState: InstanceStateEmpty,
|
instanceState: InstanceStateEmpty,
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
|
|
@ -101,12 +179,14 @@ func TestCreateInstanceWaitHandler(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "instance_get_fails",
|
desc: "instance_get_fails",
|
||||||
|
instanceId: *instanceId,
|
||||||
instanceGetFails: true,
|
instanceGetFails: true,
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
wantRes: nil,
|
wantRes: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "timeout",
|
desc: "timeout",
|
||||||
|
instanceId: *instanceId,
|
||||||
instanceGetFails: false,
|
instanceGetFails: false,
|
||||||
instanceState: InstanceStateProcessing,
|
instanceState: InstanceStateProcessing,
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
|
|
@ -114,26 +194,26 @@ func TestCreateInstanceWaitHandler(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.desc, func(t *testing.T) {
|
t.Run(
|
||||||
instanceId := "foo-bar"
|
tt.desc, func(t *testing.T) {
|
||||||
|
apiClient := &apiClientInstanceMocked{
|
||||||
|
instanceId: tt.instanceId,
|
||||||
|
instanceState: tt.instanceState,
|
||||||
|
instanceGetFails: tt.instanceGetFails,
|
||||||
|
}
|
||||||
|
|
||||||
apiClient := &apiClientInstanceMocked{
|
handler := CreateInstanceWaitHandler(context.Background(), apiClient, "", tt.instanceId, "")
|
||||||
instanceId: instanceId,
|
|
||||||
instanceState: tt.instanceState,
|
|
||||||
instanceGetFails: tt.instanceGetFails,
|
|
||||||
}
|
|
||||||
|
|
||||||
handler := CreateInstanceWaitHandler(context.Background(), apiClient, "", instanceId, "")
|
gotRes, err := handler.SetTimeout(10 * time.Millisecond).SetSleepBeforeWait(1 * time.Millisecond).WaitWithContext(context.Background())
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
|
||||||
gotRes, err := handler.SetTimeout(10 * time.Millisecond).SetSleepBeforeWait(1 * time.Millisecond).WaitWithContext(context.Background())
|
if !reflect.DeepEqual(gotRes, tt.wantRes) {
|
||||||
if (err != nil) != tt.wantErr {
|
t.Fatalf("handler gotRes = %v, want %v", gotRes, tt.wantRes)
|
||||||
t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr)
|
}
|
||||||
}
|
},
|
||||||
|
)
|
||||||
if !cmp.Equal(gotRes, tt.wantRes) {
|
|
||||||
t.Fatalf("handler gotRes = %v, want %v", gotRes, tt.wantRes)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -182,34 +262,36 @@ func TestUpdateInstanceWaitHandler(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.desc, func(t *testing.T) {
|
t.Run(
|
||||||
instanceId := "foo-bar"
|
tt.desc, func(t *testing.T) {
|
||||||
|
instanceId := "foo-bar"
|
||||||
|
|
||||||
apiClient := &apiClientInstanceMocked{
|
apiClient := &apiClientInstanceMocked{
|
||||||
instanceId: instanceId,
|
instanceId: instanceId,
|
||||||
instanceState: tt.instanceState,
|
instanceState: tt.instanceState,
|
||||||
instanceGetFails: tt.instanceGetFails,
|
instanceGetFails: tt.instanceGetFails,
|
||||||
}
|
|
||||||
|
|
||||||
var wantRes *sqlserverflex.GetInstanceResponse
|
|
||||||
if tt.wantResp {
|
|
||||||
wantRes = &sqlserverflex.GetInstanceResponse{
|
|
||||||
Id: &instanceId,
|
|
||||||
Status: sqlserverflex.GetInstanceResponseGetStatusAttributeType(utils.Ptr(tt.instanceState)),
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
handler := UpdateInstanceWaitHandler(context.Background(), apiClient, "", instanceId, "")
|
var wantRes *sqlserverflex.GetInstanceResponse
|
||||||
|
if tt.wantResp {
|
||||||
|
wantRes = &sqlserverflex.GetInstanceResponse{
|
||||||
|
Id: &instanceId,
|
||||||
|
Status: sqlserverflex.GetInstanceResponseGetStatusAttributeType(utils.Ptr(tt.instanceState)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gotRes, err := handler.SetTimeout(10 * time.Millisecond).SetSleepBeforeWait(1 * time.Millisecond).WaitWithContext(context.Background())
|
handler := UpdateInstanceWaitHandler(context.Background(), apiClient, "", instanceId, "")
|
||||||
|
|
||||||
if (err != nil) != tt.wantErr {
|
gotRes, err := handler.SetTimeout(10 * time.Millisecond).SetSleepBeforeWait(1 * time.Millisecond).WaitWithContext(context.Background())
|
||||||
t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
}
|
if (err != nil) != tt.wantErr {
|
||||||
if !cmp.Equal(gotRes, wantRes) {
|
t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr)
|
||||||
t.Fatalf("handler gotRes = %v, want %v", gotRes, wantRes)
|
}
|
||||||
}
|
if !cmp.Equal(gotRes, wantRes) {
|
||||||
})
|
t.Fatalf("handler gotRes = %v, want %v", gotRes, wantRes)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -239,23 +321,25 @@ func TestDeleteInstanceWaitHandler(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.desc, func(t *testing.T) {
|
t.Run(
|
||||||
instanceId := "foo-bar"
|
tt.desc, func(t *testing.T) {
|
||||||
|
instanceId := "foo-bar"
|
||||||
|
|
||||||
apiClient := &apiClientInstanceMocked{
|
apiClient := &apiClientInstanceMocked{
|
||||||
instanceGetFails: tt.instanceGetFails,
|
instanceGetFails: tt.instanceGetFails,
|
||||||
instanceIsDeleted: tt.instanceState == InstanceStateSuccess,
|
instanceIsDeleted: tt.instanceState == InstanceStateSuccess,
|
||||||
instanceId: instanceId,
|
instanceId: instanceId,
|
||||||
instanceState: tt.instanceState,
|
instanceState: tt.instanceState,
|
||||||
}
|
}
|
||||||
|
|
||||||
handler := DeleteInstanceWaitHandler(context.Background(), apiClient, "", instanceId, "")
|
handler := DeleteInstanceWaitHandler(context.Background(), apiClient, "", instanceId, "")
|
||||||
|
|
||||||
_, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background())
|
_, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background())
|
||||||
|
|
||||||
if (err != nil) != tt.wantErr {
|
if (err != nil) != tt.wantErr {
|
||||||
t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr)
|
t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr)
|
||||||
}
|
}
|
||||||
})
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue