feat: auto generated files and new structure (#4)
## 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: #4
Reviewed-by: Andre_Harms <andre.harms@stackit.cloud>
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
979220be66
commit
9f41c4da7f
1283 changed files with 273211 additions and 4614 deletions
|
|
@ -0,0 +1,67 @@
|
|||
package sqlserverflexalpha
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/pkg/sqlserverflexalpha"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||
sqlserverflexalphaGen "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/database/datasources_gen"
|
||||
sqlserverflexUtils "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/utils"
|
||||
)
|
||||
|
||||
var _ datasource.DataSource = (*databaseDataSource)(nil)
|
||||
|
||||
func NewDatabaseDataSource() datasource.DataSource {
|
||||
return &databaseDataSource{}
|
||||
}
|
||||
|
||||
type databaseDataSource struct {
|
||||
client *sqlserverflexalpha.APIClient
|
||||
providerData core.ProviderData
|
||||
}
|
||||
|
||||
func (d *databaseDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_database"
|
||||
}
|
||||
|
||||
func (d *databaseDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
||||
resp.Schema = sqlserverflexalphaGen.DatabaseDataSourceSchema(ctx)
|
||||
}
|
||||
|
||||
// Configure adds the provider configured client to the data source.
|
||||
func (d *databaseDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
|
||||
var ok bool
|
||||
d.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
apiClient := sqlserverflexUtils.ConfigureClient(ctx, &d.providerData, &resp.Diagnostics)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
d.client = apiClient
|
||||
tflog.Info(ctx, "SQL SERVER Flex database client configured")
|
||||
}
|
||||
|
||||
func (d *databaseDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
||||
var data sqlserverflexalphaGen.DatabaseModel
|
||||
|
||||
// Read Terraform configuration data into the model
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
// Todo: Read API call logic
|
||||
|
||||
// Example data value setting
|
||||
// data.Id = types.StringValue("example-id")
|
||||
|
||||
// Save data into Terraform state
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
// Code generated by terraform-plugin-framework-generator DO NOT EDIT.
|
||||
|
||||
package sqlserverflexalpha
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||
)
|
||||
|
||||
func DatabaseDataSourceSchema(ctx context.Context) schema.Schema {
|
||||
return schema.Schema{
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"collation_name": schema.StringAttribute{
|
||||
Computed: true,
|
||||
Description: "The collation of the database. This database collation should match the *collation_name* of one of the collations given by the **Get database collation list** endpoint.",
|
||||
MarkdownDescription: "The collation of the database. This database collation should match the *collation_name* of one of the collations given by the **Get database collation list** endpoint.",
|
||||
},
|
||||
"compatibility_level": schema.Int64Attribute{
|
||||
Computed: true,
|
||||
Description: "CompatibilityLevel of the Database.",
|
||||
MarkdownDescription: "CompatibilityLevel of the Database.",
|
||||
},
|
||||
"database_name": schema.StringAttribute{
|
||||
Required: true,
|
||||
Description: "The name of the database.",
|
||||
MarkdownDescription: "The name of the database.",
|
||||
},
|
||||
"id": schema.Int64Attribute{
|
||||
Computed: true,
|
||||
Description: "The id of the database.",
|
||||
MarkdownDescription: "The id of the database.",
|
||||
},
|
||||
"instance_id": schema.StringAttribute{
|
||||
Required: true,
|
||||
Description: "The ID of the instance.",
|
||||
MarkdownDescription: "The ID of the instance.",
|
||||
},
|
||||
"name": schema.StringAttribute{
|
||||
Computed: true,
|
||||
Description: "The name of the database.",
|
||||
MarkdownDescription: "The name of the database.",
|
||||
},
|
||||
"owner": schema.StringAttribute{
|
||||
Computed: true,
|
||||
Description: "The owner of the database.",
|
||||
MarkdownDescription: "The owner of the database.",
|
||||
},
|
||||
"project_id": schema.StringAttribute{
|
||||
Required: true,
|
||||
Description: "The STACKIT project ID.",
|
||||
MarkdownDescription: "The STACKIT project ID.",
|
||||
},
|
||||
"region": schema.StringAttribute{
|
||||
Required: true,
|
||||
Description: "The region which should be addressed",
|
||||
MarkdownDescription: "The region which should be addressed",
|
||||
Validators: []validator.String{
|
||||
stringvalidator.OneOf(
|
||||
"eu01",
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type DatabaseModel struct {
|
||||
CollationName types.String `tfsdk:"collation_name"`
|
||||
CompatibilityLevel types.Int64 `tfsdk:"compatibility_level"`
|
||||
DatabaseName types.String `tfsdk:"database_name"`
|
||||
Id types.Int64 `tfsdk:"id"`
|
||||
InstanceId types.String `tfsdk:"instance_id"`
|
||||
Name types.String `tfsdk:"name"`
|
||||
Owner types.String `tfsdk:"owner"`
|
||||
ProjectId types.String `tfsdk:"project_id"`
|
||||
Region types.String `tfsdk:"region"`
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,217 @@
|
|||
package sqlserverflexalpha
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/pkg/sqlserverflexalpha"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
||||
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
||||
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
||||
|
||||
sqlserverflexalphaGen "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/database/resources_gen"
|
||||
)
|
||||
|
||||
var (
|
||||
_ resource.Resource = &databaseResource{}
|
||||
_ resource.ResourceWithConfigure = &databaseResource{}
|
||||
_ resource.ResourceWithImportState = &databaseResource{}
|
||||
_ resource.ResourceWithModifyPlan = &databaseResource{}
|
||||
)
|
||||
|
||||
func NewDatabaseResource() resource.Resource {
|
||||
return &databaseResource{}
|
||||
}
|
||||
|
||||
type databaseResource struct {
|
||||
client *sqlserverflexalpha.APIClient
|
||||
providerData core.ProviderData
|
||||
}
|
||||
|
||||
func (r *databaseResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_database"
|
||||
}
|
||||
|
||||
func (r *databaseResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||
resp.Schema = sqlserverflexalphaGen.DatabaseResourceSchema(ctx)
|
||||
}
|
||||
|
||||
// Configure adds the provider configured client to the resource.
|
||||
func (r *databaseResource) Configure(
|
||||
ctx context.Context,
|
||||
req resource.ConfigureRequest,
|
||||
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.PostgresFlexCustomEndpoint != "" {
|
||||
apiClientConfigOptions = append(apiClientConfigOptions, config.WithEndpoint(r.providerData.PostgresFlexCustomEndpoint))
|
||||
} 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.Database client configured")
|
||||
}
|
||||
|
||||
func (r *databaseResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||
var data sqlserverflexalphaGen.DatabaseModel
|
||||
|
||||
// Read Terraform plan data into the model
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: Create API call logic
|
||||
|
||||
// Example data value setting
|
||||
// data.DatabaseId = types.StringValue("id-from-response")
|
||||
|
||||
// Save data into Terraform state
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||
|
||||
tflog.Info(ctx, "sqlserverflexalpha.Database created")
|
||||
}
|
||||
|
||||
func (r *databaseResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
var data sqlserverflexalphaGen.DatabaseModel
|
||||
|
||||
// Read Terraform prior state data into the model
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
// Todo: Read API call logic
|
||||
|
||||
// Save updated data into Terraform state
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||
|
||||
tflog.Info(ctx, "sqlserverflexalpha.Database read")
|
||||
}
|
||||
|
||||
func (r *databaseResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||
var data sqlserverflexalphaGen.DatabaseModel
|
||||
|
||||
// Read Terraform plan data into the model
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
// Todo: Update API call logic
|
||||
|
||||
// Save updated data into Terraform state
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||
|
||||
tflog.Info(ctx, "sqlserverflexalpha.Database updated")
|
||||
}
|
||||
|
||||
func (r *databaseResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||
var data sqlserverflexalphaGen.DatabaseModel
|
||||
|
||||
// Read Terraform prior state data into the model
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
// Todo: Delete API call logic
|
||||
|
||||
tflog.Info(ctx, "sqlserverflexalpha.Database deleted")
|
||||
}
|
||||
|
||||
// ModifyPlan implements resource.ResourceWithModifyPlan.
|
||||
// Use the modifier to set the effective region in the current plan.
|
||||
func (r *databaseResource) ModifyPlan(
|
||||
ctx context.Context,
|
||||
req resource.ModifyPlanRequest,
|
||||
resp *resource.ModifyPlanResponse,
|
||||
) { // nolint:gocritic // function signature required by Terraform
|
||||
var configModel sqlserverflexalphaGen.DatabaseModel
|
||||
// skip initial empty configuration to avoid follow-up errors
|
||||
if req.Config.Raw.IsNull() {
|
||||
return
|
||||
}
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &configModel)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
var planModel sqlserverflexalphaGen.DatabaseModel
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// ImportState imports a resource into the Terraform state on success.
|
||||
// The expected format of the resource import identifier is: project_id,zone_id,record_set_id
|
||||
func (r *databaseResource) ImportState(
|
||||
ctx context.Context,
|
||||
req resource.ImportStateRequest,
|
||||
resp *resource.ImportStateResponse,
|
||||
) {
|
||||
idParts := strings.Split(req.ID, core.Separator)
|
||||
|
||||
// Todo: Import logic
|
||||
if len(idParts) < 2 || idParts[0] == "" || idParts[1] == "" {
|
||||
core.LogAndAddError(
|
||||
ctx, &resp.Diagnostics,
|
||||
"Error importing database",
|
||||
fmt.Sprintf(
|
||||
"Expected import identifier with format [project_id],[region],..., got %q",
|
||||
req.ID,
|
||||
),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), idParts[0])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), idParts[1])...)
|
||||
// ... more ...
|
||||
|
||||
core.LogAndAddWarning(
|
||||
ctx,
|
||||
&resp.Diagnostics,
|
||||
"Sqlserverflexalpha database imported with empty password",
|
||||
"The database password is not imported as it is only available upon creation of a new database. The password field will be empty.",
|
||||
)
|
||||
tflog.Info(ctx, "Sqlserverflexalpha database state imported")
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
// Code generated by terraform-plugin-framework-generator DO NOT EDIT.
|
||||
|
||||
package sqlserverflexalpha
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||
)
|
||||
|
||||
func DatabaseResourceSchema(ctx context.Context) schema.Schema {
|
||||
return schema.Schema{
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"collation": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "The collation of the database. This database collation should match the *collation_name* of one of the collations given by the **Get database collation list** endpoint.",
|
||||
MarkdownDescription: "The collation of the database. This database collation should match the *collation_name* of one of the collations given by the **Get database collation list** endpoint.",
|
||||
},
|
||||
"collation_name": schema.StringAttribute{
|
||||
Computed: true,
|
||||
Description: "The collation of the database. This database collation should match the *collation_name* of one of the collations given by the **Get database collation list** endpoint.",
|
||||
MarkdownDescription: "The collation of the database. This database collation should match the *collation_name* of one of the collations given by the **Get database collation list** endpoint.",
|
||||
},
|
||||
"compatibility": schema.Int64Attribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "CompatibilityLevel of the Database.",
|
||||
MarkdownDescription: "CompatibilityLevel of the Database.",
|
||||
},
|
||||
"compatibility_level": schema.Int64Attribute{
|
||||
Computed: true,
|
||||
Description: "CompatibilityLevel of the Database.",
|
||||
MarkdownDescription: "CompatibilityLevel of the Database.",
|
||||
},
|
||||
"database_name": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "The name of the database.",
|
||||
MarkdownDescription: "The name of the database.",
|
||||
},
|
||||
"id": schema.Int64Attribute{
|
||||
Computed: true,
|
||||
Description: "The id of the database.",
|
||||
MarkdownDescription: "The id of the database.",
|
||||
},
|
||||
"instance_id": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "The ID of the instance.",
|
||||
MarkdownDescription: "The ID of the instance.",
|
||||
},
|
||||
"name": schema.StringAttribute{
|
||||
Required: true,
|
||||
Description: "The name of the database.",
|
||||
MarkdownDescription: "The name of the database.",
|
||||
},
|
||||
"owner": schema.StringAttribute{
|
||||
Required: true,
|
||||
Description: "The owner of the database.",
|
||||
MarkdownDescription: "The owner of the database.",
|
||||
},
|
||||
"project_id": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "The STACKIT project ID.",
|
||||
MarkdownDescription: "The STACKIT project ID.",
|
||||
},
|
||||
"region": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "The region which should be addressed",
|
||||
MarkdownDescription: "The region which should be addressed",
|
||||
Validators: []validator.String{
|
||||
stringvalidator.OneOf(
|
||||
"eu01",
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type DatabaseModel struct {
|
||||
Collation types.String `tfsdk:"collation"`
|
||||
CollationName types.String `tfsdk:"collation_name"`
|
||||
Compatibility types.Int64 `tfsdk:"compatibility"`
|
||||
CompatibilityLevel types.Int64 `tfsdk:"compatibility_level"`
|
||||
DatabaseName types.String `tfsdk:"database_name"`
|
||||
Id types.Int64 `tfsdk:"id"`
|
||||
InstanceId types.String `tfsdk:"instance_id"`
|
||||
Name types.String `tfsdk:"name"`
|
||||
Owner types.String `tfsdk:"owner"`
|
||||
ProjectId types.String `tfsdk:"project_id"`
|
||||
Region types.String `tfsdk:"region"`
|
||||
}
|
||||
|
|
@ -5,24 +5,25 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||
"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-framework/types/basetypes"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/pkg/sqlserverflexalpha"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
||||
|
||||
sqlserverflex "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha"
|
||||
sqlserverflexalphaGen "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/flavor/datasources_gen"
|
||||
sqlserverflexUtils "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/utils"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||
)
|
||||
|
||||
// Ensure the implementation satisfies the expected interfaces.
|
||||
var (
|
||||
_ datasource.DataSource = &flavorDataSource{}
|
||||
_ datasource.DataSource = &flavorDataSource{}
|
||||
_ datasource.DataSourceWithConfigure = &flavorDataSource{}
|
||||
)
|
||||
|
||||
type FlavorModel struct {
|
||||
|
|
@ -144,9 +145,9 @@ func (r *flavorDataSource) Schema(ctx context.Context, _ datasource.SchemaReques
|
|||
Computed: true,
|
||||
},
|
||||
},
|
||||
CustomType: sqlserverflex.StorageClassesType{
|
||||
CustomType: sqlserverflexalphaGen.StorageClassesType{
|
||||
ObjectType: types.ObjectType{
|
||||
AttrTypes: sqlserverflex.StorageClassesValue{}.AttributeTypes(ctx),
|
||||
AttrTypes: sqlserverflexalphaGen.StorageClassesValue{}.AttributeTypes(ctx),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -211,9 +212,9 @@ func (r *flavorDataSource) Read(ctx context.Context, req datasource.ReadRequest,
|
|||
model.MinGb = types.Int64Value(*f.MinGB)
|
||||
|
||||
if f.StorageClasses == nil {
|
||||
model.StorageClasses = types.ListNull(sqlserverflex.StorageClassesType{
|
||||
model.StorageClasses = types.ListNull(sqlserverflexalphaGen.StorageClassesType{
|
||||
ObjectType: basetypes.ObjectType{
|
||||
AttrTypes: sqlserverflex.StorageClassesValue{}.AttributeTypes(ctx),
|
||||
AttrTypes: sqlserverflexalphaGen.StorageClassesValue{}.AttributeTypes(ctx),
|
||||
},
|
||||
})
|
||||
} else {
|
||||
|
|
@ -221,8 +222,8 @@ func (r *flavorDataSource) Read(ctx context.Context, req datasource.ReadRequest,
|
|||
for _, sc := range *f.StorageClasses {
|
||||
scList = append(
|
||||
scList,
|
||||
sqlserverflex.NewStorageClassesValueMust(
|
||||
sqlserverflex.StorageClassesValue{}.AttributeTypes(ctx),
|
||||
sqlserverflexalphaGen.NewStorageClassesValueMust(
|
||||
sqlserverflexalphaGen.StorageClassesValue{}.AttributeTypes(ctx),
|
||||
map[string]attr.Value{
|
||||
"class": types.StringValue(*sc.Class),
|
||||
"max_io_per_sec": types.Int64Value(*sc.MaxIoPerSec),
|
||||
|
|
@ -232,9 +233,9 @@ func (r *flavorDataSource) Read(ctx context.Context, req datasource.ReadRequest,
|
|||
)
|
||||
}
|
||||
storageClassesList := types.ListValueMust(
|
||||
sqlserverflex.StorageClassesType{
|
||||
sqlserverflexalphaGen.StorageClassesType{
|
||||
ObjectType: basetypes.ObjectType{
|
||||
AttrTypes: sqlserverflex.StorageClassesValue{}.AttributeTypes(ctx),
|
||||
AttrTypes: sqlserverflexalphaGen.StorageClassesValue{}.AttributeTypes(ctx),
|
||||
},
|
||||
},
|
||||
scList,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
// Code generated by terraform-plugin-framework-generator DO NOT EDIT.
|
||||
|
||||
package sqlserverflex
|
||||
package sqlserverflexalpha
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
||||
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
|
|
@ -14,6 +12,7 @@ import (
|
|||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||
"github.com/hashicorp/terraform-plugin-go/tftypes"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||
)
|
||||
|
|
@ -21,35 +20,10 @@ import (
|
|||
func FlavorDataSourceSchema(ctx context.Context) schema.Schema {
|
||||
return schema.Schema{
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"cpu": schema.Int64Attribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
//Description: "The cpu count of the instance.",
|
||||
//MarkdownDescription: "The cpu count of the instance.",
|
||||
},
|
||||
"ram": schema.Int64Attribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
//Description: "The cpu count of the instance.",
|
||||
//MarkdownDescription: "The cpu count of the instance.",
|
||||
},
|
||||
"node_type": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
//Description: "The cpu count of the instance.",
|
||||
//MarkdownDescription: "The cpu count of the instance.",
|
||||
},
|
||||
"storage_class": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
//Description: "The cpu count of the instance.",
|
||||
//MarkdownDescription: "The cpu count of the instance.",
|
||||
},
|
||||
"flavors": schema.ListNestedAttribute{
|
||||
NestedObject: schema.NestedAttributeObject{
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"cpu": schema.Int64Attribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "The cpu count of the instance.",
|
||||
MarkdownDescription: "The cpu count of the instance.",
|
||||
|
|
@ -70,7 +44,6 @@ func FlavorDataSourceSchema(ctx context.Context) schema.Schema {
|
|||
MarkdownDescription: "maximum storage which can be ordered for the flavor in Gigabyte.",
|
||||
},
|
||||
"memory": schema.Int64Attribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "The memory of the instance in Gibibyte.",
|
||||
MarkdownDescription: "The memory of the instance in Gibibyte.",
|
||||
|
|
@ -81,10 +54,9 @@ func FlavorDataSourceSchema(ctx context.Context) schema.Schema {
|
|||
MarkdownDescription: "minimum storage which is required to order in Gigabyte.",
|
||||
},
|
||||
"node_type": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "defines the nodeType it can be either single or replica",
|
||||
MarkdownDescription: "defines the nodeType it can be either single or replica",
|
||||
Description: "defines the nodeType it can be either single or HA",
|
||||
MarkdownDescription: "defines the nodeType it can be either single or HA",
|
||||
},
|
||||
"storage_classes": schema.ListNestedAttribute{
|
||||
NestedObject: schema.NestedAttributeObject{
|
||||
|
|
@ -204,10 +176,7 @@ func FlavorDataSourceSchema(ctx context.Context) schema.Schema {
|
|||
}
|
||||
}
|
||||
|
||||
type FlavorsModel struct {
|
||||
Cpu types.Int64 `tfsdk:"cpu"`
|
||||
Ram types.Int64 `tfsdk:"ram"`
|
||||
NodeType types.String `tfsdk:"node_type"`
|
||||
type FlavorModel struct {
|
||||
Flavors types.List `tfsdk:"flavors"`
|
||||
Page types.Int64 `tfsdk:"page"`
|
||||
Pagination PaginationValue `tfsdk:"pagination"`
|
||||
|
|
@ -4,201 +4,62 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
sqlserverflex "github.com/mhenselin/terraform-provider-stackitprivatepreview/pkg/sqlserverflexalpha"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/pkg/sqlserverflexalpha"
|
||||
)
|
||||
|
||||
type flavorsClient interface {
|
||||
GetFlavorsRequestExecute(
|
||||
type flavorsClientReader interface {
|
||||
GetFlavorsRequest(
|
||||
ctx context.Context,
|
||||
projectId, region string,
|
||||
page, size *int64,
|
||||
sort *sqlserverflex.FlavorSort,
|
||||
) (*sqlserverflex.GetFlavorsResponse, error)
|
||||
) sqlserverflexalpha.ApiGetFlavorsRequestRequest
|
||||
}
|
||||
|
||||
// func loadFlavorId(ctx context.Context, client flavorsClient, model *Model, flavor *flavorModel, storage *storageModel) error {
|
||||
// if model == nil {
|
||||
// return fmt.Errorf("nil model")
|
||||
// }
|
||||
// if flavor == nil {
|
||||
// return fmt.Errorf("nil flavor")
|
||||
// }
|
||||
// cpu := flavor.CPU.ValueInt64()
|
||||
// if cpu == 0 {
|
||||
// return fmt.Errorf("nil CPU")
|
||||
// }
|
||||
// ram := flavor.RAM.ValueInt64()
|
||||
// if ram == 0 {
|
||||
// return fmt.Errorf("nil RAM")
|
||||
// }
|
||||
//
|
||||
// nodeType := flavor.NodeType.ValueString()
|
||||
// if nodeType == "" {
|
||||
// if model.Replicas.IsNull() || model.Replicas.IsUnknown() {
|
||||
// return fmt.Errorf("nil NodeType")
|
||||
// }
|
||||
// switch model.Replicas.ValueInt64() {
|
||||
// case 1:
|
||||
// nodeType = "Single"
|
||||
// case 3:
|
||||
// nodeType = "Replica"
|
||||
// default:
|
||||
// return fmt.Errorf("unknown Replicas value: %d", model.Replicas.ValueInt64())
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// storageClass := conversion.StringValueToPointer(storage.Class)
|
||||
// if storageClass == nil {
|
||||
// return fmt.Errorf("nil StorageClass")
|
||||
// }
|
||||
// storageSize := conversion.Int64ValueToPointer(storage.Size)
|
||||
// if storageSize == nil {
|
||||
// return fmt.Errorf("nil StorageSize")
|
||||
// }
|
||||
//
|
||||
// projectId := model.ProjectId.ValueString()
|
||||
// region := model.Region.ValueString()
|
||||
//
|
||||
// flavorList, err := getAllFlavors(ctx, client, projectId, region)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// avl := ""
|
||||
// foundFlavorCount := 0
|
||||
// var foundFlavors []string
|
||||
// for _, f := range flavorList {
|
||||
// if f.Id == nil || f.Cpu == nil || f.Memory == nil {
|
||||
// continue
|
||||
// }
|
||||
// if !strings.EqualFold(*f.NodeType, nodeType) {
|
||||
// continue
|
||||
// }
|
||||
// if *f.Cpu == cpu && *f.Memory == ram {
|
||||
// var useSc *sqlserverflex.FlavorStorageClassesStorageClass
|
||||
// for _, sc := range *f.StorageClasses {
|
||||
// if *sc.Class != *storageClass {
|
||||
// continue
|
||||
// }
|
||||
// if *storageSize < *f.MinGB || *storageSize > *f.MaxGB {
|
||||
// return fmt.Errorf("storage size %d out of bounds (min: %d - max: %d)", *storageSize, *f.MinGB, *f.MaxGB)
|
||||
// }
|
||||
// useSc = &sc
|
||||
// }
|
||||
// if useSc == nil {
|
||||
// return fmt.Errorf("no storage class found for %s", *storageClass)
|
||||
// }
|
||||
//
|
||||
// flavor.Id = types.StringValue(*f.Id)
|
||||
// flavor.Description = types.StringValue(*f.Description)
|
||||
// foundFlavors = append(foundFlavors, fmt.Sprintf("%s (%d/%d - %s)", *f.Id, *f.Cpu, *f.Memory, *f.NodeType))
|
||||
// foundFlavorCount++
|
||||
// }
|
||||
// for _, cls := range *f.StorageClasses {
|
||||
// avl = fmt.Sprintf("%s\n- %d CPU, %d GB RAM, storage %s (min: %d - max: %d)", avl, *f.Cpu, *f.Memory, *cls.Class, *f.MinGB, *f.MaxGB)
|
||||
// }
|
||||
// }
|
||||
// if foundFlavorCount > 1 {
|
||||
// return fmt.Errorf(
|
||||
// "number of flavors returned: %d\nmultiple flavors found: %d flavors\n %s",
|
||||
// len(flavorList),
|
||||
// foundFlavorCount,
|
||||
// strings.Join(foundFlavors, "\n "),
|
||||
// )
|
||||
// }
|
||||
// if flavor.Id.ValueString() == "" {
|
||||
// return fmt.Errorf("couldn't find flavor, available specs are:%s", avl)
|
||||
// }
|
||||
//
|
||||
// return nil
|
||||
//}
|
||||
|
||||
func getAllFlavors(ctx context.Context, client flavorsClient, projectId, region string) (
|
||||
[]sqlserverflex.ListFlavors,
|
||||
func getAllFlavors(ctx context.Context, client flavorsClientReader, projectId, region string) (
|
||||
[]sqlserverflexalpha.ListFlavors,
|
||||
error,
|
||||
) {
|
||||
if projectId == "" || region == "" {
|
||||
return nil, fmt.Errorf("listing sqlserverflex flavors: projectId and region are required")
|
||||
}
|
||||
var flavorList []sqlserverflex.ListFlavors
|
||||
|
||||
page := int64(1)
|
||||
size := int64(10)
|
||||
sort := sqlserverflex.FLAVORSORT_INDEX_ASC
|
||||
counter := 0
|
||||
for {
|
||||
res, err := client.GetFlavorsRequestExecute(ctx, projectId, region, &page, &size, &sort)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("listing sqlserverflex flavors: %w", err)
|
||||
}
|
||||
if res.Flavors == nil {
|
||||
return nil, fmt.Errorf("finding flavors for project %s", projectId)
|
||||
}
|
||||
pagination := res.GetPagination()
|
||||
flavors := res.GetFlavors()
|
||||
flavorList = append(flavorList, flavors...)
|
||||
|
||||
if *pagination.TotalRows < int64(len(flavorList)) {
|
||||
return nil, fmt.Errorf("total rows is smaller than current accumulated list - that should not happen")
|
||||
}
|
||||
if *pagination.TotalRows == int64(len(flavorList)) {
|
||||
break
|
||||
}
|
||||
page++
|
||||
|
||||
if page > *pagination.TotalPages {
|
||||
break
|
||||
}
|
||||
|
||||
// implement a breakpoint
|
||||
counter++
|
||||
if counter > 1000 {
|
||||
panic("too many pagination results")
|
||||
}
|
||||
getAllFilter := func(_ sqlserverflexalpha.ListFlavors) bool { return true }
|
||||
flavorList, err := getFlavorsByFilter(ctx, client, projectId, region, getAllFilter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return flavorList, nil
|
||||
}
|
||||
|
||||
// func getFlavorModelById(ctx context.Context, client flavorsClient, model *Model, flavor *flavorModel) error {
|
||||
// if model == nil {
|
||||
// return fmt.Errorf("nil model")
|
||||
// }
|
||||
// if flavor == nil {
|
||||
// return fmt.Errorf("nil flavor")
|
||||
// }
|
||||
// id := conversion.StringValueToPointer(flavor.Id)
|
||||
// if id == nil {
|
||||
// return fmt.Errorf("nil flavor ID")
|
||||
// }
|
||||
//
|
||||
// flavor.Id = types.StringValue("")
|
||||
//
|
||||
// projectId := model.ProjectId.ValueString()
|
||||
// region := model.Region.ValueString()
|
||||
//
|
||||
// flavorList, err := getAllFlavors(ctx, client, projectId, region)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// avl := ""
|
||||
// for _, f := range flavorList {
|
||||
// if f.Id == nil || f.Cpu == nil || f.Memory == nil {
|
||||
// continue
|
||||
// }
|
||||
// if *f.Id == *id {
|
||||
// flavor.Id = types.StringValue(*f.Id)
|
||||
// flavor.Description = types.StringValue(*f.Description)
|
||||
// flavor.CPU = types.Int64Value(*f.Cpu)
|
||||
// flavor.RAM = types.Int64Value(*f.Memory)
|
||||
// flavor.NodeType = types.StringValue(*f.NodeType)
|
||||
// break
|
||||
// }
|
||||
// avl = fmt.Sprintf("%s\n- %d CPU, %d GB RAM", avl, *f.Cpu, *f.Memory)
|
||||
// }
|
||||
// if flavor.Id.ValueString() == "" {
|
||||
// return fmt.Errorf("couldn't find flavor, available specs are: %s", avl)
|
||||
// }
|
||||
//
|
||||
// return nil
|
||||
//}
|
||||
// getFlavorsByFilter is a helper function to retrieve flavors using a filtern function.
|
||||
// Hint: The API does not have a GetFlavors endpoint, only ListFlavors
|
||||
func getFlavorsByFilter(
|
||||
ctx context.Context,
|
||||
client flavorsClientReader,
|
||||
projectId, region string,
|
||||
filter func(db sqlserverflexalpha.ListFlavors) bool,
|
||||
) ([]sqlserverflexalpha.ListFlavors, error) {
|
||||
if projectId == "" || region == "" {
|
||||
return nil, fmt.Errorf("listing sqlserverflexalpha flavors: projectId and region are required")
|
||||
}
|
||||
|
||||
const pageSize = 25
|
||||
|
||||
var result = make([]sqlserverflexalpha.ListFlavors, 0)
|
||||
|
||||
for page := int64(1); ; page++ {
|
||||
res, err := client.GetFlavorsRequest(ctx, projectId, region).
|
||||
Page(page).Size(pageSize).Sort(sqlserverflexalpha.FLAVORSORT_INDEX_ASC).Execute()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("requesting flavors list (page %d): %w", page, err)
|
||||
}
|
||||
|
||||
// If the API returns no flavors, we have reached the end of the list.
|
||||
if res.Flavors == nil || len(*res.Flavors) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
for _, flavor := range *res.Flavors {
|
||||
if filter(flavor) {
|
||||
result = append(result, flavor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,134 @@
|
|||
package sqlserverFlexAlphaFlavor
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/pkg/sqlserverflexalpha"
|
||||
"github.com/stackitcloud/stackit-sdk-go/core/utils"
|
||||
)
|
||||
|
||||
type mockRequest struct {
|
||||
executeFunc func() (*sqlserverflexalpha.GetFlavorsResponse, error)
|
||||
}
|
||||
|
||||
func (m *mockRequest) Page(_ int64) sqlserverflexalpha.ApiGetFlavorsRequestRequest { return m }
|
||||
func (m *mockRequest) Size(_ int64) sqlserverflexalpha.ApiGetFlavorsRequestRequest { return m }
|
||||
func (m *mockRequest) Sort(_ sqlserverflexalpha.FlavorSort) sqlserverflexalpha.ApiGetFlavorsRequestRequest {
|
||||
return m
|
||||
}
|
||||
func (m *mockRequest) Execute() (*sqlserverflexalpha.GetFlavorsResponse, error) {
|
||||
return m.executeFunc()
|
||||
}
|
||||
|
||||
type mockFlavorsClient struct {
|
||||
executeRequest func() sqlserverflexalpha.ApiGetFlavorsRequestRequest
|
||||
}
|
||||
|
||||
func (m *mockFlavorsClient) GetFlavorsRequest(_ context.Context, _, _ string) sqlserverflexalpha.ApiGetFlavorsRequestRequest {
|
||||
return m.executeRequest()
|
||||
}
|
||||
|
||||
var mockResp = func(page int64) (*sqlserverflexalpha.GetFlavorsResponse, error) {
|
||||
if page == 1 {
|
||||
return &sqlserverflexalpha.GetFlavorsResponse{
|
||||
Flavors: &[]sqlserverflexalpha.ListFlavors{
|
||||
{Id: utils.Ptr("flavor-1"), Description: utils.Ptr("first")},
|
||||
{Id: utils.Ptr("flavor-2"), Description: utils.Ptr("second")},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
if page == 2 {
|
||||
return &sqlserverflexalpha.GetFlavorsResponse{
|
||||
Flavors: &[]sqlserverflexalpha.ListFlavors{
|
||||
{Id: utils.Ptr("flavor-3"), Description: utils.Ptr("three")},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &sqlserverflexalpha.GetFlavorsResponse{
|
||||
Flavors: &[]sqlserverflexalpha.ListFlavors{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func TestGetFlavorsByFilter(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
projectId string
|
||||
region string
|
||||
mockErr error
|
||||
filter func(sqlserverflexalpha.ListFlavors) bool
|
||||
wantCount int
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
description: "Success - Get all flavors (2 pages)",
|
||||
projectId: "pid", region: "reg",
|
||||
filter: func(_ sqlserverflexalpha.ListFlavors) bool { return true },
|
||||
wantCount: 3,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
description: "Success - Filter flavors by description",
|
||||
projectId: "pid", region: "reg",
|
||||
filter: func(f sqlserverflexalpha.ListFlavors) bool { return *f.Description == "first" },
|
||||
wantCount: 1,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
description: "Error - Missing parameters",
|
||||
projectId: "", region: "reg",
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(
|
||||
tt.description, func(t *testing.T) {
|
||||
var currentPage int64
|
||||
client := &mockFlavorsClient{
|
||||
executeRequest: func() sqlserverflexalpha.ApiGetFlavorsRequestRequest {
|
||||
return &mockRequest{
|
||||
executeFunc: func() (*sqlserverflexalpha.GetFlavorsResponse, error) {
|
||||
currentPage++
|
||||
return mockResp(currentPage)
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
actual, err := getFlavorsByFilter(context.Background(), client, tt.projectId, tt.region, tt.filter)
|
||||
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("getFlavorsByFilter() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
|
||||
if !tt.wantErr && len(actual) != tt.wantCount {
|
||||
t.Errorf("getFlavorsByFilter() got %d flavors, want %d", len(actual), tt.wantCount)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAllFlavors(t *testing.T) {
|
||||
var currentPage int64
|
||||
client := &mockFlavorsClient{
|
||||
executeRequest: func() sqlserverflexalpha.ApiGetFlavorsRequestRequest {
|
||||
return &mockRequest{
|
||||
executeFunc: func() (*sqlserverflexalpha.GetFlavorsResponse, error) {
|
||||
currentPage++
|
||||
return mockResp(currentPage)
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
res, err := getAllFlavors(context.Background(), client, "pid", "reg")
|
||||
if err != nil {
|
||||
t.Errorf("getAllFlavors() unexpected error: %v", err)
|
||||
}
|
||||
if len(res) != 3 {
|
||||
t.Errorf("getAllFlavors() expected 3 flavor, got %d", len(res))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
package postgresFlexAlphaFlavor
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/pkg/postgresflexalpha"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha"
|
||||
postgresflexUtils "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/utils"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||
)
|
||||
|
||||
// Ensure the implementation satisfies the expected interfaces.
|
||||
var (
|
||||
_ datasource.DataSource = &flavorListDataSource{}
|
||||
)
|
||||
|
||||
// NewFlavorListDataSource is a helper function to simplify the provider implementation.
|
||||
func NewFlavorListDataSource() datasource.DataSource {
|
||||
return &flavorListDataSource{}
|
||||
}
|
||||
|
||||
// flavorDataSource is the data source implementation.
|
||||
type flavorListDataSource struct {
|
||||
client *postgresflexalpha.APIClient
|
||||
providerData core.ProviderData
|
||||
}
|
||||
|
||||
// Metadata returns the data source type name.
|
||||
func (r *flavorListDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_postgresflexalpha_flavorlist"
|
||||
}
|
||||
|
||||
// Configure adds the provider configured client to the data source.
|
||||
func (r *flavorListDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
|
||||
var ok bool
|
||||
r.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
apiClient := postgresflexUtils.ConfigureClient(ctx, &r.providerData, &resp.Diagnostics)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
r.client = apiClient
|
||||
tflog.Info(ctx, "Postgres Flex flavors client configured")
|
||||
}
|
||||
|
||||
func (r *flavorListDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
||||
resp.Schema = postgresflex.FlavorDataSourceSchema(ctx)
|
||||
}
|
||||
|
||||
func (r *flavorListDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
||||
var model postgresflex.FlavorModel
|
||||
diags := req.Config.Get(ctx, &model)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
ctx = core.InitProviderContext(ctx)
|
||||
|
||||
projectId := model.ProjectId.ValueString()
|
||||
region := r.providerData.GetRegionWithOverride(model.Region)
|
||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||
ctx = tflog.SetField(ctx, "region", region)
|
||||
|
||||
// Set refreshed state
|
||||
diags = resp.State.Set(ctx, model)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
tflog.Info(ctx, "Postgres Flex flavors read")
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package sqlserverflexalpha
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/pkg/sqlserverflexalpha"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||
sqlserverflexUtils "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/utils"
|
||||
|
||||
sqlserverflexalphaGen "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/flavors/datasources_gen"
|
||||
)
|
||||
|
||||
var _ datasource.DataSource = (*flavorsDataSource)(nil)
|
||||
|
||||
func NewFlavorsDataSource() datasource.DataSource {
|
||||
return &flavorsDataSource{}
|
||||
}
|
||||
|
||||
type flavorsDataSource struct {
|
||||
client *sqlserverflexalpha.APIClient
|
||||
providerData core.ProviderData
|
||||
}
|
||||
|
||||
func (d *flavorsDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_flavors"
|
||||
}
|
||||
|
||||
func (d *flavorsDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
||||
resp.Schema = sqlserverflexalphaGen.FlavorsDataSourceSchema(ctx)
|
||||
}
|
||||
|
||||
// Configure adds the provider configured client to the data source.
|
||||
func (d *flavorsDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
|
||||
var ok bool
|
||||
d.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
apiClient := sqlserverflexUtils.ConfigureClient(ctx, &d.providerData, &resp.Diagnostics)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
d.client = apiClient
|
||||
tflog.Info(ctx, "SQL SERVER Flex flavors client configured")
|
||||
}
|
||||
|
||||
func (d *flavorsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
||||
var data sqlserverflexalphaGen.FlavorsModel
|
||||
|
||||
// Read Terraform configuration data into the model
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
// Todo: Read API call logic
|
||||
|
||||
// Example data value setting
|
||||
// data.Id = types.StringValue("example-id")
|
||||
|
||||
// Save data into Terraform state
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,120 @@
|
|||
fields:
|
||||
- name: 'id'
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
|
||||
- name: 'instance_id'
|
||||
validators:
|
||||
- validate.NoSeparator
|
||||
- validate.UUID
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
|
||||
- name: 'project_id'
|
||||
validators:
|
||||
- validate.NoSeparator
|
||||
- validate.UUID
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
- 'RequiresReplace'
|
||||
|
||||
- name: 'name'
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
- 'RequiresReplace'
|
||||
|
||||
- name: 'backup_schedule'
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
|
||||
- name: 'encryption.kek_key_id'
|
||||
validators:
|
||||
- validate.NoSeparator
|
||||
modifiers:
|
||||
- 'RequiresReplace'
|
||||
|
||||
- name: 'encryption.kek_key_version'
|
||||
validators:
|
||||
- validate.NoSeparator
|
||||
modifiers:
|
||||
- 'RequiresReplace'
|
||||
|
||||
- name: 'encryption.kek_key_ring_id'
|
||||
validators:
|
||||
- validate.NoSeparator
|
||||
modifiers:
|
||||
- 'RequiresReplace'
|
||||
|
||||
- name: 'encryption.service_account'
|
||||
validators:
|
||||
- validate.NoSeparator
|
||||
modifiers:
|
||||
- 'RequiresReplace'
|
||||
|
||||
- name: 'network.access_scope'
|
||||
validators:
|
||||
- validate.NoSeparator
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
- 'RequiresReplace'
|
||||
|
||||
- name: 'network.acl'
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
|
||||
- name: 'network.instance_address'
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
|
||||
- name: 'network.router_address'
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
|
||||
- name: 'status'
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
|
||||
- name: 'region'
|
||||
modifiers:
|
||||
- 'RequiresReplace'
|
||||
|
||||
- name: 'retention_days'
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
|
||||
- name: 'edition'
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
- 'RequiresReplace'
|
||||
|
||||
- name: 'version'
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
- 'RequiresReplace'
|
||||
|
||||
- name: 'replicas'
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
- 'RequiresReplace'
|
||||
|
||||
- name: 'storage'
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
|
||||
- name: 'storage.class'
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
- 'RequiresReplace'
|
||||
|
||||
- name: 'storage.size'
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
|
||||
- name: 'flavor_id'
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
- 'RequiresReplace'
|
||||
|
||||
- name: 'is_deletable'
|
||||
modifiers:
|
||||
- 'UseStateForUnknown'
|
||||
|
|
@ -33,7 +33,8 @@ import (
|
|||
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
sqlserverflex "github.com/mhenselin/terraform-provider-stackitprivatepreview/pkg/sqlserverflexalpha"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/pkg/sqlserverflexalpha/wait"
|
||||
wait "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/wait/sqlserverflexalpha"
|
||||
|
||||
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
|
||||
)
|
||||
|
||||
|
|
@ -338,7 +339,7 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r
|
|||
Description: descriptions["status"],
|
||||
},
|
||||
"encryption": schema.SingleNestedAttribute{
|
||||
Required: true,
|
||||
Optional: true,
|
||||
PlanModifiers: []planmodifier.Object{
|
||||
objectplanmodifier.RequiresReplace(),
|
||||
objectplanmodifier.UseStateForUnknown(),
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
1
stackit/internal/services/sqlserverflexalpha/main.go
Normal file
1
stackit/internal/services/sqlserverflexalpha/main.go
Normal file
|
|
@ -0,0 +1 @@
|
|||
package sqlserverflexalpha
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright (c) STACKIT
|
||||
|
||||
package sqlserverflex_test
|
||||
package sqlserverflexalpha_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
variable "project_id" {}
|
||||
variable "name" {}
|
||||
variable "acl1" {}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
variable "project_id" {}
|
||||
variable "name" {}
|
||||
variable "flavor_cpu" {}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,111 @@
|
|||
// Code generated by terraform-plugin-framework-generator DO NOT EDIT.
|
||||
|
||||
package sqlserverflexalpha
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||
)
|
||||
|
||||
func UserResourceSchema(ctx context.Context) schema.Schema {
|
||||
return schema.Schema{
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"default_database": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "The default database for a user of the instance.",
|
||||
MarkdownDescription: "The default database for a user of the instance.",
|
||||
},
|
||||
"host": schema.StringAttribute{
|
||||
Computed: true,
|
||||
Description: "The host of the instance in which the user belongs to.",
|
||||
MarkdownDescription: "The host of the instance in which the user belongs to.",
|
||||
},
|
||||
"id": schema.Int64Attribute{
|
||||
Computed: true,
|
||||
Description: "The ID of the user.",
|
||||
MarkdownDescription: "The ID of the user.",
|
||||
},
|
||||
"instance_id": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "The ID of the instance.",
|
||||
MarkdownDescription: "The ID of the instance.",
|
||||
},
|
||||
"password": schema.StringAttribute{
|
||||
Computed: true,
|
||||
Description: "The password for the user.",
|
||||
MarkdownDescription: "The password for the user.",
|
||||
},
|
||||
"port": schema.Int64Attribute{
|
||||
Computed: true,
|
||||
Description: "The port of the instance in which the user belongs to.",
|
||||
MarkdownDescription: "The port of the instance in which the user belongs to.",
|
||||
},
|
||||
"project_id": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "The STACKIT project ID.",
|
||||
MarkdownDescription: "The STACKIT project ID.",
|
||||
},
|
||||
"region": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "The region which should be addressed",
|
||||
MarkdownDescription: "The region which should be addressed",
|
||||
Validators: []validator.String{
|
||||
stringvalidator.OneOf(
|
||||
"eu01",
|
||||
),
|
||||
},
|
||||
},
|
||||
"roles": schema.ListAttribute{
|
||||
ElementType: types.StringType,
|
||||
Required: true,
|
||||
Description: "A list containing the user roles for the instance.",
|
||||
MarkdownDescription: "A list containing the user roles for the instance.",
|
||||
},
|
||||
"status": schema.StringAttribute{
|
||||
Computed: true,
|
||||
Description: "The current status of the user.",
|
||||
MarkdownDescription: "The current status of the user.",
|
||||
},
|
||||
"uri": schema.StringAttribute{
|
||||
Computed: true,
|
||||
Description: "The connection string for the user to the instance.",
|
||||
MarkdownDescription: "The connection string for the user to the instance.",
|
||||
},
|
||||
"user_id": schema.Int64Attribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "The ID of the user.",
|
||||
MarkdownDescription: "The ID of the user.",
|
||||
},
|
||||
"username": schema.StringAttribute{
|
||||
Required: true,
|
||||
Description: "The name of the user.",
|
||||
MarkdownDescription: "The name of the user.",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type UserModel struct {
|
||||
DefaultDatabase types.String `tfsdk:"default_database"`
|
||||
Host types.String `tfsdk:"host"`
|
||||
Id types.Int64 `tfsdk:"id"`
|
||||
InstanceId types.String `tfsdk:"instance_id"`
|
||||
Password types.String `tfsdk:"password"`
|
||||
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"`
|
||||
Uri types.String `tfsdk:"uri"`
|
||||
UserId types.Int64 `tfsdk:"user_id"`
|
||||
Username types.String `tfsdk:"username"`
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
package sqlserverflexalpha
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/pkg/sqlserverflexalpha"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||
sqlserverflexUtils "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/utils"
|
||||
|
||||
sqlserverflexalphaGen "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/version/datasources_gen"
|
||||
)
|
||||
|
||||
var (
|
||||
_ datasource.DataSource = (*versionDataSource)(nil)
|
||||
_ datasource.DataSourceWithConfigure = (*versionDataSource)(nil)
|
||||
)
|
||||
|
||||
func NewVersionDataSource() datasource.DataSource {
|
||||
return &versionDataSource{}
|
||||
}
|
||||
|
||||
type versionDataSource struct {
|
||||
client *sqlserverflexalpha.APIClient
|
||||
providerData core.ProviderData
|
||||
}
|
||||
|
||||
func (d *versionDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_version"
|
||||
}
|
||||
|
||||
func (d *versionDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
||||
resp.Schema = sqlserverflexalphaGen.VersionDataSourceSchema(ctx)
|
||||
}
|
||||
|
||||
// Configure adds the provider configured client to the data source.
|
||||
func (d *versionDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
|
||||
var ok bool
|
||||
d.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
apiClient := sqlserverflexUtils.ConfigureClient(ctx, &d.providerData, &resp.Diagnostics)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
d.client = apiClient
|
||||
tflog.Info(ctx, "SQL SERVER Flex version client configured")
|
||||
}
|
||||
|
||||
func (d *versionDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
||||
var data sqlserverflexalphaGen.VersionModel
|
||||
|
||||
// Read Terraform configuration data into the model
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
// Todo: Read API call logic
|
||||
|
||||
// Example data value setting
|
||||
// data.Id = types.StringValue("example-id")
|
||||
|
||||
// Save data into Terraform state
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||
}
|
||||
|
|
@ -0,0 +1,569 @@
|
|||
// Code generated by terraform-plugin-framework-generator DO NOT EDIT.
|
||||
|
||||
package sqlserverflexalpha
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
||||
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||
"github.com/hashicorp/terraform-plugin-go/tftypes"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||
)
|
||||
|
||||
func VersionDataSourceSchema(ctx context.Context) schema.Schema {
|
||||
return schema.Schema{
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"project_id": schema.StringAttribute{
|
||||
Required: true,
|
||||
Description: "The STACKIT project ID.",
|
||||
MarkdownDescription: "The STACKIT project ID.",
|
||||
},
|
||||
"region": schema.StringAttribute{
|
||||
Required: true,
|
||||
Description: "The region which should be addressed",
|
||||
MarkdownDescription: "The region which should be addressed",
|
||||
Validators: []validator.String{
|
||||
stringvalidator.OneOf(
|
||||
"eu01",
|
||||
),
|
||||
},
|
||||
},
|
||||
"versions": schema.ListNestedAttribute{
|
||||
NestedObject: schema.NestedAttributeObject{
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"beta": schema.BoolAttribute{
|
||||
Computed: true,
|
||||
Description: "Flag if the version is a beta version. If set the version may contain bugs and is not fully tested.",
|
||||
MarkdownDescription: "Flag if the version is a beta version. If set the version may contain bugs and is not fully tested.",
|
||||
},
|
||||
"deprecated": schema.StringAttribute{
|
||||
Computed: true,
|
||||
Description: "Timestamp in RFC3339 format which says when the version will no longer be supported by STACKIT.",
|
||||
MarkdownDescription: "Timestamp in RFC3339 format which says when the version will no longer be supported by STACKIT.",
|
||||
},
|
||||
"recommend": schema.BoolAttribute{
|
||||
Computed: true,
|
||||
Description: "Flag if the version is recommend by the STACKIT Team.",
|
||||
MarkdownDescription: "Flag if the version is recommend by the STACKIT Team.",
|
||||
},
|
||||
"version": schema.StringAttribute{
|
||||
Computed: true,
|
||||
Description: "The sqlserver version used for the instance.",
|
||||
MarkdownDescription: "The sqlserver version used for the instance.",
|
||||
},
|
||||
},
|
||||
CustomType: VersionsType{
|
||||
ObjectType: types.ObjectType{
|
||||
AttrTypes: VersionsValue{}.AttributeTypes(ctx),
|
||||
},
|
||||
},
|
||||
},
|
||||
Computed: true,
|
||||
Description: "A list containing available sqlserver versions.",
|
||||
MarkdownDescription: "A list containing available sqlserver versions.",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type VersionModel struct {
|
||||
ProjectId types.String `tfsdk:"project_id"`
|
||||
Region types.String `tfsdk:"region"`
|
||||
Versions types.List `tfsdk:"versions"`
|
||||
}
|
||||
|
||||
var _ basetypes.ObjectTypable = VersionsType{}
|
||||
|
||||
type VersionsType struct {
|
||||
basetypes.ObjectType
|
||||
}
|
||||
|
||||
func (t VersionsType) Equal(o attr.Type) bool {
|
||||
other, ok := o.(VersionsType)
|
||||
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return t.ObjectType.Equal(other.ObjectType)
|
||||
}
|
||||
|
||||
func (t VersionsType) String() string {
|
||||
return "VersionsType"
|
||||
}
|
||||
|
||||
func (t VersionsType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) {
|
||||
var diags diag.Diagnostics
|
||||
|
||||
attributes := in.Attributes()
|
||||
|
||||
betaAttribute, ok := attributes["beta"]
|
||||
|
||||
if !ok {
|
||||
diags.AddError(
|
||||
"Attribute Missing",
|
||||
`beta is missing from object`)
|
||||
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
betaVal, ok := betaAttribute.(basetypes.BoolValue)
|
||||
|
||||
if !ok {
|
||||
diags.AddError(
|
||||
"Attribute Wrong Type",
|
||||
fmt.Sprintf(`beta expected to be basetypes.BoolValue, was: %T`, betaAttribute))
|
||||
}
|
||||
|
||||
deprecatedAttribute, ok := attributes["deprecated"]
|
||||
|
||||
if !ok {
|
||||
diags.AddError(
|
||||
"Attribute Missing",
|
||||
`deprecated is missing from object`)
|
||||
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
deprecatedVal, ok := deprecatedAttribute.(basetypes.StringValue)
|
||||
|
||||
if !ok {
|
||||
diags.AddError(
|
||||
"Attribute Wrong Type",
|
||||
fmt.Sprintf(`deprecated expected to be basetypes.StringValue, was: %T`, deprecatedAttribute))
|
||||
}
|
||||
|
||||
recommendAttribute, ok := attributes["recommend"]
|
||||
|
||||
if !ok {
|
||||
diags.AddError(
|
||||
"Attribute Missing",
|
||||
`recommend is missing from object`)
|
||||
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
recommendVal, ok := recommendAttribute.(basetypes.BoolValue)
|
||||
|
||||
if !ok {
|
||||
diags.AddError(
|
||||
"Attribute Wrong Type",
|
||||
fmt.Sprintf(`recommend expected to be basetypes.BoolValue, was: %T`, recommendAttribute))
|
||||
}
|
||||
|
||||
versionAttribute, ok := attributes["version"]
|
||||
|
||||
if !ok {
|
||||
diags.AddError(
|
||||
"Attribute Missing",
|
||||
`version is missing from object`)
|
||||
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
versionVal, ok := versionAttribute.(basetypes.StringValue)
|
||||
|
||||
if !ok {
|
||||
diags.AddError(
|
||||
"Attribute Wrong Type",
|
||||
fmt.Sprintf(`version expected to be basetypes.StringValue, was: %T`, versionAttribute))
|
||||
}
|
||||
|
||||
if diags.HasError() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
return VersionsValue{
|
||||
Beta: betaVal,
|
||||
Deprecated: deprecatedVal,
|
||||
Recommend: recommendVal,
|
||||
Version: versionVal,
|
||||
state: attr.ValueStateKnown,
|
||||
}, diags
|
||||
}
|
||||
|
||||
func NewVersionsValueNull() VersionsValue {
|
||||
return VersionsValue{
|
||||
state: attr.ValueStateNull,
|
||||
}
|
||||
}
|
||||
|
||||
func NewVersionsValueUnknown() VersionsValue {
|
||||
return VersionsValue{
|
||||
state: attr.ValueStateUnknown,
|
||||
}
|
||||
}
|
||||
|
||||
func NewVersionsValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (VersionsValue, diag.Diagnostics) {
|
||||
var diags diag.Diagnostics
|
||||
|
||||
// Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521
|
||||
ctx := context.Background()
|
||||
|
||||
for name, attributeType := range attributeTypes {
|
||||
attribute, ok := attributes[name]
|
||||
|
||||
if !ok {
|
||||
diags.AddError(
|
||||
"Missing VersionsValue Attribute Value",
|
||||
"While creating a VersionsValue value, a missing attribute value was detected. "+
|
||||
"A VersionsValue must contain values for all attributes, even if null or unknown. "+
|
||||
"This is always an issue with the provider and should be reported to the provider developers.\n\n"+
|
||||
fmt.Sprintf("VersionsValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()),
|
||||
)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if !attributeType.Equal(attribute.Type(ctx)) {
|
||||
diags.AddError(
|
||||
"Invalid VersionsValue Attribute Type",
|
||||
"While creating a VersionsValue value, an invalid attribute value was detected. "+
|
||||
"A VersionsValue must use a matching attribute type for the value. "+
|
||||
"This is always an issue with the provider and should be reported to the provider developers.\n\n"+
|
||||
fmt.Sprintf("VersionsValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+
|
||||
fmt.Sprintf("VersionsValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
for name := range attributes {
|
||||
_, ok := attributeTypes[name]
|
||||
|
||||
if !ok {
|
||||
diags.AddError(
|
||||
"Extra VersionsValue Attribute Value",
|
||||
"While creating a VersionsValue value, an extra attribute value was detected. "+
|
||||
"A VersionsValue must not contain values beyond the expected attribute types. "+
|
||||
"This is always an issue with the provider and should be reported to the provider developers.\n\n"+
|
||||
fmt.Sprintf("Extra VersionsValue Attribute Name: %s", name),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if diags.HasError() {
|
||||
return NewVersionsValueUnknown(), diags
|
||||
}
|
||||
|
||||
betaAttribute, ok := attributes["beta"]
|
||||
|
||||
if !ok {
|
||||
diags.AddError(
|
||||
"Attribute Missing",
|
||||
`beta is missing from object`)
|
||||
|
||||
return NewVersionsValueUnknown(), diags
|
||||
}
|
||||
|
||||
betaVal, ok := betaAttribute.(basetypes.BoolValue)
|
||||
|
||||
if !ok {
|
||||
diags.AddError(
|
||||
"Attribute Wrong Type",
|
||||
fmt.Sprintf(`beta expected to be basetypes.BoolValue, was: %T`, betaAttribute))
|
||||
}
|
||||
|
||||
deprecatedAttribute, ok := attributes["deprecated"]
|
||||
|
||||
if !ok {
|
||||
diags.AddError(
|
||||
"Attribute Missing",
|
||||
`deprecated is missing from object`)
|
||||
|
||||
return NewVersionsValueUnknown(), diags
|
||||
}
|
||||
|
||||
deprecatedVal, ok := deprecatedAttribute.(basetypes.StringValue)
|
||||
|
||||
if !ok {
|
||||
diags.AddError(
|
||||
"Attribute Wrong Type",
|
||||
fmt.Sprintf(`deprecated expected to be basetypes.StringValue, was: %T`, deprecatedAttribute))
|
||||
}
|
||||
|
||||
recommendAttribute, ok := attributes["recommend"]
|
||||
|
||||
if !ok {
|
||||
diags.AddError(
|
||||
"Attribute Missing",
|
||||
`recommend is missing from object`)
|
||||
|
||||
return NewVersionsValueUnknown(), diags
|
||||
}
|
||||
|
||||
recommendVal, ok := recommendAttribute.(basetypes.BoolValue)
|
||||
|
||||
if !ok {
|
||||
diags.AddError(
|
||||
"Attribute Wrong Type",
|
||||
fmt.Sprintf(`recommend expected to be basetypes.BoolValue, was: %T`, recommendAttribute))
|
||||
}
|
||||
|
||||
versionAttribute, ok := attributes["version"]
|
||||
|
||||
if !ok {
|
||||
diags.AddError(
|
||||
"Attribute Missing",
|
||||
`version is missing from object`)
|
||||
|
||||
return NewVersionsValueUnknown(), diags
|
||||
}
|
||||
|
||||
versionVal, ok := versionAttribute.(basetypes.StringValue)
|
||||
|
||||
if !ok {
|
||||
diags.AddError(
|
||||
"Attribute Wrong Type",
|
||||
fmt.Sprintf(`version expected to be basetypes.StringValue, was: %T`, versionAttribute))
|
||||
}
|
||||
|
||||
if diags.HasError() {
|
||||
return NewVersionsValueUnknown(), diags
|
||||
}
|
||||
|
||||
return VersionsValue{
|
||||
Beta: betaVal,
|
||||
Deprecated: deprecatedVal,
|
||||
Recommend: recommendVal,
|
||||
Version: versionVal,
|
||||
state: attr.ValueStateKnown,
|
||||
}, diags
|
||||
}
|
||||
|
||||
func NewVersionsValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) VersionsValue {
|
||||
object, diags := NewVersionsValue(attributeTypes, attributes)
|
||||
|
||||
if diags.HasError() {
|
||||
// This could potentially be added to the diag package.
|
||||
diagsStrings := make([]string, 0, len(diags))
|
||||
|
||||
for _, diagnostic := range diags {
|
||||
diagsStrings = append(diagsStrings, fmt.Sprintf(
|
||||
"%s | %s | %s",
|
||||
diagnostic.Severity(),
|
||||
diagnostic.Summary(),
|
||||
diagnostic.Detail()))
|
||||
}
|
||||
|
||||
panic("NewVersionsValueMust received error(s): " + strings.Join(diagsStrings, "\n"))
|
||||
}
|
||||
|
||||
return object
|
||||
}
|
||||
|
||||
func (t VersionsType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) {
|
||||
if in.Type() == nil {
|
||||
return NewVersionsValueNull(), nil
|
||||
}
|
||||
|
||||
if !in.Type().Equal(t.TerraformType(ctx)) {
|
||||
return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type())
|
||||
}
|
||||
|
||||
if !in.IsKnown() {
|
||||
return NewVersionsValueUnknown(), nil
|
||||
}
|
||||
|
||||
if in.IsNull() {
|
||||
return NewVersionsValueNull(), nil
|
||||
}
|
||||
|
||||
attributes := map[string]attr.Value{}
|
||||
|
||||
val := map[string]tftypes.Value{}
|
||||
|
||||
err := in.As(&val)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for k, v := range val {
|
||||
a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
attributes[k] = a
|
||||
}
|
||||
|
||||
return NewVersionsValueMust(VersionsValue{}.AttributeTypes(ctx), attributes), nil
|
||||
}
|
||||
|
||||
func (t VersionsType) ValueType(ctx context.Context) attr.Value {
|
||||
return VersionsValue{}
|
||||
}
|
||||
|
||||
var _ basetypes.ObjectValuable = VersionsValue{}
|
||||
|
||||
type VersionsValue struct {
|
||||
Beta basetypes.BoolValue `tfsdk:"beta"`
|
||||
Deprecated basetypes.StringValue `tfsdk:"deprecated"`
|
||||
Recommend basetypes.BoolValue `tfsdk:"recommend"`
|
||||
Version basetypes.StringValue `tfsdk:"version"`
|
||||
state attr.ValueState
|
||||
}
|
||||
|
||||
func (v VersionsValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) {
|
||||
attrTypes := make(map[string]tftypes.Type, 4)
|
||||
|
||||
var val tftypes.Value
|
||||
var err error
|
||||
|
||||
attrTypes["beta"] = basetypes.BoolType{}.TerraformType(ctx)
|
||||
attrTypes["deprecated"] = basetypes.StringType{}.TerraformType(ctx)
|
||||
attrTypes["recommend"] = basetypes.BoolType{}.TerraformType(ctx)
|
||||
attrTypes["version"] = basetypes.StringType{}.TerraformType(ctx)
|
||||
|
||||
objectType := tftypes.Object{AttributeTypes: attrTypes}
|
||||
|
||||
switch v.state {
|
||||
case attr.ValueStateKnown:
|
||||
vals := make(map[string]tftypes.Value, 4)
|
||||
|
||||
val, err = v.Beta.ToTerraformValue(ctx)
|
||||
|
||||
if err != nil {
|
||||
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
|
||||
}
|
||||
|
||||
vals["beta"] = val
|
||||
|
||||
val, err = v.Deprecated.ToTerraformValue(ctx)
|
||||
|
||||
if err != nil {
|
||||
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
|
||||
}
|
||||
|
||||
vals["deprecated"] = val
|
||||
|
||||
val, err = v.Recommend.ToTerraformValue(ctx)
|
||||
|
||||
if err != nil {
|
||||
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
|
||||
}
|
||||
|
||||
vals["recommend"] = val
|
||||
|
||||
val, err = v.Version.ToTerraformValue(ctx)
|
||||
|
||||
if err != nil {
|
||||
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
|
||||
}
|
||||
|
||||
vals["version"] = val
|
||||
|
||||
if err := tftypes.ValidateValue(objectType, vals); err != nil {
|
||||
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
|
||||
}
|
||||
|
||||
return tftypes.NewValue(objectType, vals), nil
|
||||
case attr.ValueStateNull:
|
||||
return tftypes.NewValue(objectType, nil), nil
|
||||
case attr.ValueStateUnknown:
|
||||
return tftypes.NewValue(objectType, tftypes.UnknownValue), nil
|
||||
default:
|
||||
panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state))
|
||||
}
|
||||
}
|
||||
|
||||
func (v VersionsValue) IsNull() bool {
|
||||
return v.state == attr.ValueStateNull
|
||||
}
|
||||
|
||||
func (v VersionsValue) IsUnknown() bool {
|
||||
return v.state == attr.ValueStateUnknown
|
||||
}
|
||||
|
||||
func (v VersionsValue) String() string {
|
||||
return "VersionsValue"
|
||||
}
|
||||
|
||||
func (v VersionsValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) {
|
||||
var diags diag.Diagnostics
|
||||
|
||||
attributeTypes := map[string]attr.Type{
|
||||
"beta": basetypes.BoolType{},
|
||||
"deprecated": basetypes.StringType{},
|
||||
"recommend": basetypes.BoolType{},
|
||||
"version": basetypes.StringType{},
|
||||
}
|
||||
|
||||
if v.IsNull() {
|
||||
return types.ObjectNull(attributeTypes), diags
|
||||
}
|
||||
|
||||
if v.IsUnknown() {
|
||||
return types.ObjectUnknown(attributeTypes), diags
|
||||
}
|
||||
|
||||
objVal, diags := types.ObjectValue(
|
||||
attributeTypes,
|
||||
map[string]attr.Value{
|
||||
"beta": v.Beta,
|
||||
"deprecated": v.Deprecated,
|
||||
"recommend": v.Recommend,
|
||||
"version": v.Version,
|
||||
})
|
||||
|
||||
return objVal, diags
|
||||
}
|
||||
|
||||
func (v VersionsValue) Equal(o attr.Value) bool {
|
||||
other, ok := o.(VersionsValue)
|
||||
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
if v.state != other.state {
|
||||
return false
|
||||
}
|
||||
|
||||
if v.state != attr.ValueStateKnown {
|
||||
return true
|
||||
}
|
||||
|
||||
if !v.Beta.Equal(other.Beta) {
|
||||
return false
|
||||
}
|
||||
|
||||
if !v.Deprecated.Equal(other.Deprecated) {
|
||||
return false
|
||||
}
|
||||
|
||||
if !v.Recommend.Equal(other.Recommend) {
|
||||
return false
|
||||
}
|
||||
|
||||
if !v.Version.Equal(other.Version) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (v VersionsValue) Type(ctx context.Context) attr.Type {
|
||||
return VersionsType{
|
||||
basetypes.ObjectType{
|
||||
AttrTypes: v.AttributeTypes(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (v VersionsValue) AttributeTypes(ctx context.Context) map[string]attr.Type {
|
||||
return map[string]attr.Type{
|
||||
"beta": basetypes.BoolType{},
|
||||
"deprecated": basetypes.StringType{},
|
||||
"recommend": basetypes.BoolType{},
|
||||
"version": basetypes.StringType{},
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue