chore: updated files - work save

This commit is contained in:
Marcel_Henselin 2026-01-21 16:29:22 +01:00
parent 51663cd8d0
commit e91e10e29a
37 changed files with 1121 additions and 118 deletions

View file

@ -29,6 +29,8 @@ builds:
ignore:
- goos: darwin
goarch: '386'
- goos: windows
goarch: 'arm6'
binary: '{{ .ProjectName }}_v{{ .Version }}'
archives:
- formats: [ 'zip' ]

View file

@ -0,0 +1,31 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "stackitprivatepreview_sqlserverflexalpha_database Data Source - stackitprivatepreview"
subcategory: ""
description: |-
---
# stackitprivatepreview_sqlserverflexalpha_database (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `database_name` (String) The name of the database.
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
### Read-Only
- `collation_name` (String) 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` (Number) CompatibilityLevel of the Database.
- `id` (Number) The id of the database.
- `name` (String) The name of the database.
- `owner` (String) The owner of the database.

View file

@ -0,0 +1,36 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "stackitprivatepreview_sqlserverflexalpha_database Resource - stackitprivatepreview"
subcategory: ""
description: |-
---
# stackitprivatepreview_sqlserverflexalpha_database (Resource)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `name` (String) The name of the database.
- `owner` (String) The owner of the database.
### Optional
- `collation` (String) 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` (Number) CompatibilityLevel of the Database.
- `database_name` (String) The name of the database.
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
### Read-Only
- `collation_name` (String) 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` (Number) CompatibilityLevel of the Database.
- `id` (Number) The id of the database.

View file

View file

@ -501,10 +501,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {

View file

@ -501,10 +501,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {

View file

@ -501,10 +501,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {

View file

@ -501,10 +501,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {

View file

@ -501,10 +501,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {

View file

@ -501,10 +501,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {

View file

@ -82,22 +82,42 @@ type InstanceGetConsumedObjectStorageArgType = string
type InstanceGetConsumedObjectStorageRetType = string
/*
types and functions for created_at
types and functions for created
*/
// isDateTime
type InstanceGetCreatedAtAttributeType = *time.Time
type InstanceGetCreatedAtArgType = time.Time
type InstanceGetCreatedAtRetType = time.Time
type InstanceGetCreatedAttributeType = *time.Time
type InstanceGetCreatedArgType = time.Time
type InstanceGetCreatedRetType = time.Time
func getInstanceGetCreatedAtAttributeTypeOk(arg InstanceGetCreatedAtAttributeType) (ret InstanceGetCreatedAtRetType, ok bool) {
func getInstanceGetCreatedAttributeTypeOk(arg InstanceGetCreatedAttributeType) (ret InstanceGetCreatedRetType, ok bool) {
if arg == nil {
return ret, false
}
return *arg, true
}
func setInstanceGetCreatedAtAttributeType(arg *InstanceGetCreatedAtAttributeType, val InstanceGetCreatedAtRetType) {
func setInstanceGetCreatedAttributeType(arg *InstanceGetCreatedAttributeType, val InstanceGetCreatedRetType) {
*arg = &val
}
/*
types and functions for feature_toggle
*/
// isModel
type InstanceGetFeatureToggleAttributeType = *FeatureToggle
type InstanceGetFeatureToggleArgType = FeatureToggle
type InstanceGetFeatureToggleRetType = FeatureToggle
func getInstanceGetFeatureToggleAttributeTypeOk(arg InstanceGetFeatureToggleAttributeType) (ret InstanceGetFeatureToggleRetType, ok bool) {
if arg == nil {
return ret, false
}
return *arg, true
}
func setInstanceGetFeatureToggleAttributeType(arg *InstanceGetFeatureToggleAttributeType, val InstanceGetFeatureToggleRetType) {
*arg = &val
}
@ -351,7 +371,9 @@ type Instance struct {
ConsumedObjectStorage InstanceGetConsumedObjectStorageAttributeType `json:"consumed_object_storage" required:"true"`
// The date and time the creation of the STACKIT Git instance was triggered.
// REQUIRED
CreatedAt InstanceGetCreatedAtAttributeType `json:"created_at" required:"true"`
Created InstanceGetCreatedAttributeType `json:"created" required:"true"`
// REQUIRED
FeatureToggle InstanceGetFeatureToggleAttributeType `json:"feature_toggle" required:"true"`
// Instance flavor.
// REQUIRED
Flavor InstanceGetFlavorAttributeType `json:"flavor" required:"true"`
@ -378,12 +400,13 @@ type _Instance Instance
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func NewInstance(acl InstanceGetAclArgType, consumedDisk InstanceGetConsumedDiskArgType, consumedObjectStorage InstanceGetConsumedObjectStorageArgType, createdAt InstanceGetCreatedAtArgType, flavor InstanceGetFlavorArgType, id InstanceGetIdArgType, name InstanceGetNameArgType, state InstanceGetStateArgType, url InstanceGetUrlArgType, version InstanceGetVersionArgType) *Instance {
func NewInstance(acl InstanceGetAclArgType, consumedDisk InstanceGetConsumedDiskArgType, consumedObjectStorage InstanceGetConsumedObjectStorageArgType, created InstanceGetCreatedArgType, featureToggle InstanceGetFeatureToggleArgType, flavor InstanceGetFlavorArgType, id InstanceGetIdArgType, name InstanceGetNameArgType, state InstanceGetStateArgType, url InstanceGetUrlArgType, version InstanceGetVersionArgType) *Instance {
this := Instance{}
setInstanceGetAclAttributeType(&this.Acl, acl)
setInstanceGetConsumedDiskAttributeType(&this.ConsumedDisk, consumedDisk)
setInstanceGetConsumedObjectStorageAttributeType(&this.ConsumedObjectStorage, consumedObjectStorage)
setInstanceGetCreatedAtAttributeType(&this.CreatedAt, createdAt)
setInstanceGetCreatedAttributeType(&this.Created, created)
setInstanceGetFeatureToggleAttributeType(&this.FeatureToggle, featureToggle)
setInstanceGetFlavorAttributeType(&this.Flavor, flavor)
setInstanceGetIdAttributeType(&this.Id, id)
setInstanceGetNameAttributeType(&this.Name, name)
@ -452,21 +475,38 @@ func (o *Instance) SetConsumedObjectStorage(v InstanceGetConsumedObjectStorageRe
setInstanceGetConsumedObjectStorageAttributeType(&o.ConsumedObjectStorage, v)
}
// GetCreatedAt returns the CreatedAt field value
func (o *Instance) GetCreatedAt() (ret InstanceGetCreatedAtRetType) {
ret, _ = o.GetCreatedAtOk()
// GetCreated returns the Created field value
func (o *Instance) GetCreated() (ret InstanceGetCreatedRetType) {
ret, _ = o.GetCreatedOk()
return ret
}
// GetCreatedAtOk returns a tuple with the CreatedAt field value
// GetCreatedOk returns a tuple with the Created field value
// and a boolean to check if the value has been set.
func (o *Instance) GetCreatedAtOk() (ret InstanceGetCreatedAtRetType, ok bool) {
return getInstanceGetCreatedAtAttributeTypeOk(o.CreatedAt)
func (o *Instance) GetCreatedOk() (ret InstanceGetCreatedRetType, ok bool) {
return getInstanceGetCreatedAttributeTypeOk(o.Created)
}
// SetCreatedAt sets field value
func (o *Instance) SetCreatedAt(v InstanceGetCreatedAtRetType) {
setInstanceGetCreatedAtAttributeType(&o.CreatedAt, v)
// SetCreated sets field value
func (o *Instance) SetCreated(v InstanceGetCreatedRetType) {
setInstanceGetCreatedAttributeType(&o.Created, v)
}
// GetFeatureToggle returns the FeatureToggle field value
func (o *Instance) GetFeatureToggle() (ret InstanceGetFeatureToggleRetType) {
ret, _ = o.GetFeatureToggleOk()
return ret
}
// GetFeatureToggleOk returns a tuple with the FeatureToggle field value
// and a boolean to check if the value has been set.
func (o *Instance) GetFeatureToggleOk() (ret InstanceGetFeatureToggleRetType, ok bool) {
return getInstanceGetFeatureToggleAttributeTypeOk(o.FeatureToggle)
}
// SetFeatureToggle sets field value
func (o *Instance) SetFeatureToggle(v InstanceGetFeatureToggleRetType) {
setInstanceGetFeatureToggleAttributeType(&o.FeatureToggle, v)
}
// GetFlavor returns the Flavor field value
@ -582,8 +622,11 @@ func (o Instance) ToMap() (map[string]interface{}, error) {
if val, ok := getInstanceGetConsumedObjectStorageAttributeTypeOk(o.ConsumedObjectStorage); ok {
toSerialize["ConsumedObjectStorage"] = val
}
if val, ok := getInstanceGetCreatedAtAttributeTypeOk(o.CreatedAt); ok {
toSerialize["CreatedAt"] = val
if val, ok := getInstanceGetCreatedAttributeTypeOk(o.Created); ok {
toSerialize["Created"] = val
}
if val, ok := getInstanceGetFeatureToggleAttributeTypeOk(o.FeatureToggle); ok {
toSerialize["FeatureToggle"] = val
}
if val, ok := getInstanceGetFlavorAttributeTypeOk(o.Flavor); ok {
toSerialize["Flavor"] = val

View file

@ -501,10 +501,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {

View file

@ -501,10 +501,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {

View file

@ -501,10 +501,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {

View file

@ -501,10 +501,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {

View file

@ -501,10 +501,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {

View file

@ -501,10 +501,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {

View file

@ -501,10 +501,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {

View file

@ -17,6 +17,26 @@ import (
// checks if the CreateInstanceRequestPayload type satisfies the MappedNullable interface at compile time
var _ MappedNullable = &CreateInstanceRequestPayload{}
/*
types and functions for acl
*/
// isModel
type CreateInstancePayloadGetAclAttributeType = *[]string
type CreateInstancePayloadGetAclArgType = *[]string
type CreateInstancePayloadGetAclRetType = []string
func getCreateInstancePayloadGetAclAttributeTypeOk(arg CreateInstancePayloadGetAclAttributeType) (ret CreateInstancePayloadGetAclRetType, ok bool) {
if arg == nil {
return ret, false
}
return *arg, true
}
func setCreateInstancePayloadGetAclAttributeType(arg *CreateInstancePayloadGetAclAttributeType, val CreateInstancePayloadGetAclRetType) {
*arg = &val
}
/*
types and functions for backupSchedule
*/
@ -203,6 +223,8 @@ type CreateInstanceRequestPayloadGetVersionRetType = string
// CreateInstanceRequestPayload struct for CreateInstanceRequestPayload
type CreateInstanceRequestPayload struct {
// REQUIRED
Acl CreateInstancePayloadGetAclAttributeType `json:"acl" required:"true"`
// The schedule for on what time and how often the database backup will be created. The schedule is written as a cron schedule.
// REQUIRED
BackupSchedule CreateInstanceRequestPayloadGetBackupScheduleAttributeType `json:"backupSchedule" required:"true"`

View file

@ -501,10 +501,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {

View file

@ -501,10 +501,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {

View file

@ -501,10 +501,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {

View file

@ -501,10 +501,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {

View file

@ -51,7 +51,7 @@ resource "stackitprivatepreview_postgresflexalpha_user" "ptlsdbuser" {
}
resource "stackitprivatepreview_postgresflexalpha_database" "example" {
count = 25
count = 5
depends_on = [stackitprivatepreview_postgresflexalpha_user.ptlsdbadminuser]
project_id = var.project_id
instance_id = stackitprivatepreview_postgresflexalpha_instance.msh-sna-pe-example.instance_id

View file

@ -3,6 +3,10 @@ provider:
resources:
database:
schema:
attributes:
aliases:
id: database_id
create:
path: /v3alpha1/projects/{projectId}/regions/{region}/instances/{instanceId}/databases
method: POST
@ -21,6 +25,9 @@ data_sources:
method: GET
database:
attributes:
aliases:
id: database_id
read:
path: /v3alpha1/projects/{projectId}/regions/{region}/instances/{instanceId}/databases/{databaseName}
method: GET

View file

@ -211,7 +211,7 @@ func (r *instanceResource) Create(
func modelToCreateInstancePayload(netAcl []string, model postgresflexalpha.InstanceModel, replVal int32) postgresflex.CreateInstanceRequestPayload {
payload := postgresflex.CreateInstanceRequestPayload{
// Acl: &netAcl,
Acl: &netAcl,
BackupSchedule: model.BackupSchedule.ValueStringPointer(),
Encryption: &postgresflex.InstanceEncryption{
KekKeyId: model.Encryption.KekKeyId.ValueStringPointer(),

View file

@ -0,0 +1,48 @@
package sqlserverflexalpha
import (
"context"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)
var _ datasource.DataSource = (*backupDataSource)(nil)
func NewBackupDataSource() datasource.DataSource {
return &backupDataSource{}
}
type backupDataSource struct{}
type backupDataSourceModel struct {
Id types.String `tfsdk:"id"`
}
func (d *backupDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "sqlserverflexalpha_backup"
}
func (d *backupDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = sqlserverflexalphaGen.BackupDataSourceSchema(ctx)
}
func (d *backupDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data sqlserverflexalphaGen.backupDataSourceModel
// 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)...)
}

View file

@ -0,0 +1,48 @@
package sqlserverflexalpha
import (
"context"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)
var _ datasource.DataSource = (*collationDataSource)(nil)
func NewCollationDataSource() datasource.DataSource {
return &collationDataSource{}
}
type collationDataSource struct{}
type collationDataSourceModel struct {
Id types.String `tfsdk:"id"`
}
func (d *collationDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "sqlserverflexalpha_collation"
}
func (d *collationDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = sqlserverflexalphaGen.CollationDataSourceSchema(ctx)
}
func (d *collationDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data sqlserverflexalphaGen.collationDataSourceModel
// 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)...)
}

View file

@ -0,0 +1,49 @@
package sqlserverflexalpha
import (
"context"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/types"
sqlserverflexalphaGen "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/database/datasources_gen"
)
var _ datasource.DataSource = (*databaseDataSource)(nil)
func NewDatabaseDataSource() datasource.DataSource {
return &databaseDataSource{}
}
type databaseDataSource struct{}
type databaseDataSourceModel struct {
Id types.String `tfsdk:"id"`
}
func (d *databaseDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_database"
}
func (d *databaseDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = sqlserverflexalphaGen.DatabaseDataSourceSchema(ctx)
}
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)...)
}

View file

@ -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(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_database"
}
func (r *databaseResource) Schema(ctx context.Context, req 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")
}

View file

@ -0,0 +1,48 @@
package sqlserverflexalpha
import (
"context"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)
var _ datasource.DataSource = (*versionDataSource)(nil)
func NewVersionDataSource() datasource.DataSource {
return &versionDataSource{}
}
type versionDataSource struct{}
type versionDataSourceModel struct {
Id types.String `tfsdk:"id"`
}
func (d *versionDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "sqlserverflexalpha_version"
}
func (d *versionDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = sqlserverflexalphaGen.VersionDataSourceSchema(ctx)
}
func (d *versionDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data sqlserverflexalphaGen.versionDataSourceModel
// 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)...)
}

View file

@ -22,6 +22,7 @@ import (
postgresFlexAlphaFlavor "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/flavor"
postgresFlexAlphaInstance "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/instance"
postgresFlexAlphaUser "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/user"
sqlserverflexalpha "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/database"
sqlserverFlexAlphaFlavor "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/flavor"
sqlServerFlexAlphaInstance "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance"
sqlserverFlexAlphaUser "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/user"
@ -499,6 +500,7 @@ func (p *Provider) DataSources(_ context.Context) []func() datasource.DataSource
sqlserverFlexAlphaFlavor.NewFlavorDataSource,
sqlServerFlexAlphaInstance.NewInstanceDataSource,
sqlserverFlexAlphaUser.NewUserDataSource,
sqlserverflexalpha.NewDatabaseDataSource,
}
}
@ -510,6 +512,7 @@ func (p *Provider) Resources(_ context.Context) []func() resource.Resource {
postgresFlexAlphaUser.NewUserResource,
sqlServerFlexAlphaInstance.NewInstanceResource,
sqlserverFlexAlphaUser.NewUserResource,
sqlserverflexalpha.NewDatabaseResource,
}
return resources
}

53
tools/formats.go Normal file
View file

@ -0,0 +1,53 @@
package tools
import (
"regexp"
"strings"
"unicode"
"unicode/utf8"
)
// snakeLetters will match to the first letter and an underscore followed by a letter
var snakeLetters = regexp.MustCompile("(^[a-z])|_[a-z0-9]")
func ToPascalCase(in string) string {
inputSplit := strings.Split(in, ".")
var ucName string
for _, v := range inputSplit {
if len(v) < 1 {
continue
}
firstChar := v[0:1]
ucFirstChar := strings.ToUpper(firstChar)
if len(v) < 2 {
ucName += ucFirstChar
continue
}
ucName += ucFirstChar + v[1:]
}
return snakeLetters.ReplaceAllStringFunc(ucName, func(s string) string {
return strings.ToUpper(strings.Replace(s, "_", "", -1))
})
}
func ToCamelCase(in string) string {
pascal := ToPascalCase(in)
// Grab first rune and lower case it
firstLetter, size := utf8.DecodeRuneInString(pascal)
if firstLetter == utf8.RuneError && size <= 1 {
return pascal
}
return string(unicode.ToLower(firstLetter)) + pascal[size:]
}
func ValidateSnakeCase(in string) bool {
return snakeLetters.MatchString(string(in))
}

View file

@ -14,7 +14,7 @@ import (
"regexp"
"strconv"
"strings"
"time"
"text/template"
"github.com/ldez/go-git-cmd-wrapper/v2/clone"
"github.com/ldez/go-git-cmd-wrapper/v2/git"
@ -50,6 +50,12 @@ func Build() error {
return err
}
slog.Info("Cleaning up old packages directory")
err = os.RemoveAll(path.Join(*root, "pkg"))
if err != nil {
return err
}
slog.Info("Creating generator dir", "dir", fmt.Sprintf("%s/%s", *root, GEN_REPO_NAME))
genDir, err := createGeneratorDir(*root, GEN_REPO, GEN_REPO_NAME)
if err != nil {
@ -162,6 +168,10 @@ func Build() error {
}
slog.Info("Rearranging package directories")
err = os.MkdirAll(path.Join(*root, "pkg"), 0755)
if err != nil {
return err
}
srcDir := path.Join(genDir, "sdk-repo-updated", "services")
items, err := os.ReadDir(srcDir)
if err != nil {
@ -171,27 +181,30 @@ func Build() error {
if item.IsDir() {
slog.Info(" -> package", "name", item.Name())
tgtDir := path.Join(*root, "pkg", item.Name())
bakName := fmt.Sprintf("%s.%s", item.Name(), time.Now().Format("20060102-150405"))
if _, err = os.Stat(tgtDir); !os.IsNotExist(err) {
err = os.Rename(
tgtDir,
path.Join(*root, "pkg", bakName),
)
if err != nil {
return err
}
}
// no backup needed as we generate new
//bakName := fmt.Sprintf("%s.%s", item.Name(), time.Now().Format("20060102-150405"))
//if _, err = os.Stat(tgtDir); !os.IsNotExist(err) {
// err = os.Rename(
// tgtDir,
// path.Join(*root, "pkg", bakName),
// )
// if err != nil {
// return err
// }
//}
err = os.Rename(path.Join(srcDir, item.Name()), tgtDir)
if err != nil {
return err
}
if _, err = os.Stat(path.Join(*root, "pkg", bakName, "wait")); !os.IsNotExist(err) {
slog.Info(" Copying wait subfolder")
err = os.Rename(path.Join(*root, "pkg", bakName, "wait"), path.Join(tgtDir, "wait"))
if err != nil {
return err
}
}
// wait is placed outside now
//if _, err = os.Stat(path.Join(*root, "pkg", bakName, "wait")); !os.IsNotExist(err) {
// slog.Info(" Copying wait subfolder")
// err = os.Rename(path.Join(*root, "pkg", bakName, "wait"), path.Join(tgtDir, "wait"))
// if err != nil {
// return err
// }
//}
}
}
@ -216,19 +229,17 @@ func Build() error {
return err
}
// TODO
for _, testDir := range []string{
path.Join(*root, "stackit", "internal", "services"),
} {
fmt.Println(testDir)
err = createBoilerplate(*root, path.Join(*root, "stackit", "internal", "services"))
if err != nil {
return err
}
slog.Info("Finally removing temporary files and directories")
err = os.RemoveAll(path.Join(*root, "generated"))
if err != nil {
slog.Error("RemoveAll", "dir", path.Join(*root, "generated"), "err", err)
return err
}
//err = os.RemoveAll(path.Join(*root, "generated"))
//if err != nil {
// slog.Error("RemoveAll", "dir", path.Join(*root, "generated"), "err", err)
// return err
//}
err = os.RemoveAll(path.Join(*root, GEN_REPO_NAME))
if err != nil {
@ -240,6 +251,146 @@ func Build() error {
return nil
}
type templateData struct {
PackageName string
NameCamel string
NamePascal string
NameSnake string
}
func fileExists(path string) bool {
_, err := os.Stat(path)
if os.IsNotExist(err) {
return false
}
if err != nil {
panic(err)
}
return true
}
func createBoilerplate(rootFolder, folder string) error {
services, err := os.ReadDir(folder)
if err != nil {
return err
}
for _, svc := range services {
if !svc.IsDir() {
continue
}
resources, err := os.ReadDir(path.Join(folder, svc.Name()))
if err != nil {
return err
}
handleDS := false
handleRes := false
foundDS := false
foundRes := false
for _, res := range resources {
if !res.IsDir() {
continue
}
resourceName := res.Name()
dsFile := path.Join(folder, svc.Name(), res.Name(), "datasources_gen", fmt.Sprintf("%s_data_source_gen.go", res.Name()))
handleDS = fileExists(dsFile)
resFile := path.Join(folder, svc.Name(), res.Name(), "resources_gen", fmt.Sprintf("%s_resource_gen.go", res.Name()))
handleRes = fileExists(resFile)
dsGoFile := path.Join(folder, svc.Name(), res.Name(), "datasource.go")
foundDS = fileExists(dsGoFile)
resGoFile := path.Join(folder, svc.Name(), res.Name(), "resource.go")
foundRes = fileExists(resGoFile)
if handleDS && !foundDS {
slog.Info("Creating missing datasource.go", "service", svc.Name(), "resource", resourceName)
if !ValidateSnakeCase(resourceName) {
return errors.New("resource name is invalid")
}
tplName := "data_source_scaffold.gotmpl"
err = writeTemplateToFile(
tplName,
path.Join(rootFolder, "tools", "templates", tplName),
path.Join(folder, svc.Name(), res.Name(), "datasource.go"),
&templateData{
PackageName: svc.Name(),
NameCamel: ToCamelCase(resourceName),
NamePascal: ToPascalCase(resourceName),
NameSnake: resourceName,
},
)
if err != nil {
panic(err)
}
}
if handleRes && !foundRes {
slog.Info("Creating missing resource.go", "service", svc.Name(), "resource", resourceName)
if !ValidateSnakeCase(resourceName) {
return errors.New("resource name is invalid")
}
tplName := "resource_scaffold.gotmpl"
err = writeTemplateToFile(
tplName,
path.Join(rootFolder, "tools", "templates", tplName),
path.Join(folder, svc.Name(), res.Name(), "resource.go"),
&templateData{
PackageName: svc.Name(),
NameCamel: ToCamelCase(resourceName),
NamePascal: ToPascalCase(resourceName),
NameSnake: resourceName,
},
)
if err != nil {
return err
}
}
}
}
return nil
}
func ucfirst(s string) string {
if len(s) == 0 {
return ""
}
return strings.ToUpper(s[:1]) + s[1:]
}
func writeTemplateToFile(tplName, tplFile, outFile string, data *templateData) error {
fn := template.FuncMap{
"ucfirst": ucfirst,
}
tmpl, err := template.New(tplName).Funcs(fn).ParseFiles(tplFile)
if err != nil {
return err
}
var f *os.File
f, err = os.Create(outFile)
if err != nil {
return err
}
err = tmpl.Execute(f, *data)
if err != nil {
return err
}
err = f.Close()
if err != nil {
return err
}
return nil
}
func generateServiceFiles(rootDir, generatorDir string) error {
// slog.Info("Generating specs folder")
err := os.MkdirAll(path.Join(rootDir, "generated", "specs"), 0755)

View file

@ -0,0 +1,49 @@
package {{.PackageName}}
import (
"context"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
{{.PackageName}}Gen "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/{{.PackageName}}/{{.NameSnake}}/datasources_gen"
)
var _ datasource.DataSource = (*{{.NameCamel}}DataSource)(nil)
func New{{.NamePascal}}DataSource() datasource.DataSource {
return &{{.NameCamel}}DataSource{}
}
type {{.NameCamel}}DataSource struct{
client *{{.PackageName}}.APIClient
providerData core.ProviderData
}
func (d *{{.NameCamel}}DataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_{{.PackageName}}_{{.NameSnake}}"
}
func (d *{{.NameCamel}}DataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = {{.PackageName}}Gen.{{.NamePascal}}DataSourceSchema(ctx)
}
func (d *{{.NameCamel}}DataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data {{.PackageName}}Gen.{{.NameCamel}}Model
// 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)...)
}

View file

@ -0,0 +1,39 @@
package {{.PackageName}}
import (
"context"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/resource"
)
var _ provider.Provider = (*{{.NameCamel}}Provider)(nil)
func New() func() provider.Provider {
return func() provider.Provider {
return &{{.NameCamel}}Provider{}
}
}
type {{.NameCamel}}Provider struct{}
func (p *{{.NameCamel}}Provider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) {
}
func (p *{{.NameCamel}}Provider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
}
func (p *{{.NameCamel}}Provider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) {
resp.TypeName = "{{.NameSnake}}"
}
func (p *{{.NameCamel}}Provider) DataSources(ctx context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{}
}
func (p *{{.NameCamel}}Provider) Resources(ctx context.Context) []func() resource.Resource {
return []func() resource.Resource{}
}

View file

@ -0,0 +1,208 @@
package {{.PackageName}}
import (
"context"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/core"
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/utils"
{{.PackageName}}Gen "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/{{.PackageName}}/{{.NameSnake}}/resources_gen"
)
var (
_ resource.Resource = &{{.NameCamel}}Resource{}
_ resource.ResourceWithConfigure = &{{.NameCamel}}Resource{}
_ resource.ResourceWithImportState = &{{.NameCamel}}Resource{}
_ resource.ResourceWithModifyPlan = &{{.NameCamel}}Resource{}
)
func New{{.NamePascal}}Resource() resource.Resource {
return &{{.NameCamel}}Resource{}
}
type {{.NameCamel}}Resource struct{
client *{{.PackageName}}.APIClient
providerData core.ProviderData
}
func (r *{{.NameCamel}}Resource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_{{.PackageName}}_{{.NameSnake}}"
}
func (r *{{.NameCamel}}Resource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = {{.PackageName}}Gen.{{.NamePascal}}ResourceSchema(ctx)
}
// Configure adds the provider configured client to the resource.
func (r *{{.NameCamel}}Resource) 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 := {{.PackageName}}.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, "{{.PackageName}}.{{.NamePascal}} client configured")
}
func (r *{{.NameCamel}}Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
var data {{.PackageName}}Gen.{{.NamePascal}}Model
// 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.{{.NameCamel | ucfirst}}Id = types.StringValue("id-from-response")
// Save data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
tflog.Info(ctx, "{{.PackageName}}.{{.NamePascal}} created")
}
func (r *{{.NameCamel}}Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
var data {{.PackageName}}Gen.{{.NamePascal}}Model
// 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, "{{.PackageName}}.{{.NamePascal}} read")
}
func (r *{{.NameCamel}}Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var data {{.PackageName}}Gen.{{.NamePascal}}Model
// 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, "{{.PackageName}}.{{.NamePascal}} updated")
}
func (r *{{.NameCamel}}Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
var data {{.PackageName}}Gen.{{.NamePascal}}Model
// 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, "{{.PackageName}}.{{.NamePascal}} deleted")
}
// ModifyPlan implements resource.ResourceWithModifyPlan.
// Use the modifier to set the effective region in the current plan.
func (r *{{.NameCamel}}Resource) ModifyPlan(
ctx context.Context,
req resource.ModifyPlanRequest,
resp *resource.ModifyPlanResponse,
) { // nolint:gocritic // function signature required by Terraform
var configModel {{.PackageName}}Gen.{{.NamePascal}}Model
// 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 {{.PackageName}}Gen.{{.NamePascal}}Model
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 *{{.NameCamel}}Resource) 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,
"{{.PackageName | ucfirst}} 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, "{{.PackageName | ucfirst}} {{.NameCamel}} state imported")
}