feat: SQL server beta and templates refactoring #32

Merged
marcel.henselin merged 8 commits from feat/templates into alpha 2026-02-05 09:55:33 +00:00
3 changed files with 171 additions and 18 deletions
Showing only changes of commit 27a9d7f20e - Show all commits

View file

@ -312,7 +312,7 @@ func createBoilerplate(rootFolder, folder string) error {
foundRes = fileExists(resGoFile)
if handleDS && !foundDS {
slog.Info("Creating missing datasource.go", "service", svc.Name(), "resource", resourceName)
slog.Info(" creating missing datasource.go", "service", svc.Name(), "resource", resourceName)
if !ValidateSnakeCase(resourceName) {
return errors.New("resource name is invalid")
}
@ -320,7 +320,7 @@ func createBoilerplate(rootFolder, folder string) error {
tplName := "data_source_scaffold.gotmpl"
err = writeTemplateToFile(
tplName,
path.Join(rootFolder, "cmd", "build", "templates", tplName),
path.Join(rootFolder, "cmd", "cmd", "build", "templates", tplName),
path.Join(folder, svc.Name(), res.Name(), "datasource.go"),
&templateData{
PackageName: svc.Name(),
@ -337,7 +337,7 @@ func createBoilerplate(rootFolder, folder string) error {
}
if handleRes && !foundRes {
slog.Info("Creating missing resource.go", "service", svc.Name(), "resource", resourceName)
slog.Info(" creating missing resource.go", "service", svc.Name(), "resource", resourceName)
if !ValidateSnakeCase(resourceName) {
return errors.New("resource name is invalid")
}
@ -345,7 +345,7 @@ func createBoilerplate(rootFolder, folder string) error {
tplName := "resource_scaffold.gotmpl"
err = writeTemplateToFile(
tplName,
path.Join(rootFolder, "cmd", "build", "templates", tplName),
path.Join(rootFolder, "cmd", "cmd", "build", "templates", tplName),
path.Join(folder, svc.Name(), res.Name(), "resource.go"),
&templateData{
PackageName: svc.Name(),
@ -359,6 +359,31 @@ func createBoilerplate(rootFolder, folder string) error {
if err != nil {
return err
}
if !fileExists(path.Join(folder, svc.Name(), res.Name(), "functions.go")) {
slog.Info(" creating missing functions.go", "service", svc.Name(), "resource", resourceName)
if !ValidateSnakeCase(resourceName) {
return errors.New("resource name is invalid")
}
fncTplName := "functions_scaffold.gotmpl"
err = writeTemplateToFile(
fncTplName,
path.Join(rootFolder, "cmd", "cmd", "build", "templates", fncTplName),
path.Join(folder, svc.Name(), res.Name(), "functions.go"),
&templateData{
PackageName: svc.Name(),
PackageNameCamel: ToCamelCase(svc.Name()),
PackageNamePascal: ToPascalCase(svc.Name()),
NameCamel: ToCamelCase(resourceName),
NamePascal: ToPascalCase(resourceName),
NameSnake: resourceName,
},
)
if err != nil {
return err
}
}
}
}
}

View file

@ -0,0 +1,96 @@
package {{.PackageName}}
import (
"context"
"fmt"
"math"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/types"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
{{.PackageName}} "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/{{.PackageName}}"
{{.PackageName}}ResGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/{{.PackageName}}alpha/instance/resources_gen"
)
func mapResponseToModel(
ctx context.Context,
resp *{{.PackageName}}.Get{{.NamePascal}}Response,
m *{{.PackageName}}ResGen.{{.NamePascal}}Model,
tfDiags diag.Diagnostics,
) error {
// TODO: complete and refactor
m.Id = types.StringValue(resp.GetId())
sampleList, diags := types.ListValueFrom(ctx, types.StringType, resp.GetList())
tfDiags.Append(diags...)
if diags.HasError() {
return fmt.Errorf(
"error converting list response value",
)
}
sample, diags := {{.PackageName}}ResGen.NewSampleValue(
{{.PackageName}}ResGen.SampleValue{}.AttributeTypes(ctx),
map[string]attr.Value{
"field": types.StringValue(string(resp.GetField())),
},
)
tfDiags.Append(diags...)
if diags.HasError() {
return fmt.Errorf(
"error converting sample response value",
"sample",
types.StringValue(string(resp.GetField())),
)
}
m.Sample = sample
return nil
}
func handleEncryption(
m *{{.PackageName}}ResGen.{{.NamePascal}}Model,
resp *{{.PackageName}}.Get{{.NamePascal}}Response,
) {{.PackageName}}ResGen.EncryptionValue {
if !resp.HasEncryption() ||
resp.Encryption == nil ||
resp.Encryption.KekKeyId == nil ||
resp.Encryption.KekKeyRingId == nil ||
resp.Encryption.KekKeyVersion == nil ||
resp.Encryption.ServiceAccount == nil {
if m.Encryption.IsNull() || m.Encryption.IsUnknown() {
return {{.PackageName}}ResGen.NewEncryptionValueNull()
}
return m.Encryption
}
enc := {{.PackageName}}ResGen.NewEncryptionValueNull()
if kVal, ok := resp.Encryption.GetKekKeyIdOk(); ok {
enc.KekKeyId = types.StringValue(kVal)
}
if kkVal, ok := resp.Encryption.GetKekKeyRingIdOk(); ok {
enc.KekKeyRingId = types.StringValue(kkVal)
}
if kkvVal, ok := resp.Encryption.GetKekKeyVersionOk(); ok {
enc.KekKeyVersion = types.StringValue(kkvVal)
}
if sa, ok := resp.Encryption.GetServiceAccountOk(); ok {
enc.ServiceAccount = types.StringValue(sa)
}
return enc
}
func toCreatePayload(
ctx context.Context,
model *{{.PackageName}}ResGen.{{.NamePascal}}Model,
) (*{{.PackageName}}.Create{{.NamePascal}}RequestPayload, error) {
if model == nil {
return nil, fmt.Errorf("nil model")
}
return &{{.PackageName}}.Create{{.NamePascal}}RequestPayload{
// TODO: fill fields
}, nil
}

View file

@ -2,15 +2,23 @@ package {{.PackageName}}
import (
"context"
"fmt"
"strings"
"github.com/hashicorp/terraform-plugin-framework/resource/identityschema"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/identityschema"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/stackitcloud/stackit-sdk-go/core/config"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/{{.PackageName}}"
{{.PackageName}}Gen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/{{.PackageName}}/{{.NameSnake}}/resources_gen"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
{{.PackageName}}ResGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/{{.PackageName}}/{{.NameSnake}}/resources_gen"
)
var (
@ -151,6 +159,9 @@ func (r *{{.NameCamel}}Resource) Read(ctx context.Context, req resource.ReadRequ
// Read Terraform prior state data into the model
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
// Read identity data
var identityData {{.NamePascal}}ResourceIdentityModel
@ -159,9 +170,13 @@ func (r *{{.NameCamel}}Resource) Read(ctx context.Context, req resource.ReadRequ
return
}
if resp.Diagnostics.HasError() {
return
}
ctx = core.InitProviderContext(ctx)
projectId := identityData.ProjectID.ValueString()
region := identityData.Region.ValueString()
ctx = tflog.SetField(ctx, "project_id", projectId)
ctx = tflog.SetField(ctx, "region", region)
// Todo: Read API call logic
@ -185,9 +200,8 @@ func (r *{{.NameCamel}}Resource) Read(ctx context.Context, req resource.ReadRequ
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)...)
// Read Terraform prior state data into the model
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
@ -199,9 +213,13 @@ func (r *{{.NameCamel}}Resource) Update(ctx context.Context, req resource.Update
return
}
if resp.Diagnostics.HasError() {
return
}
ctx = core.InitProviderContext(ctx)
projectId := identityData.ProjectID.ValueString()
region := identityData.Region.ValueString()
ctx = tflog.SetField(ctx, "project_id", projectId)
ctx = tflog.SetField(ctx, "region", region)
// Todo: Update API call logic
@ -216,11 +234,25 @@ func (r *{{.NameCamel}}Resource) Delete(ctx context.Context, req resource.Delete
// Read Terraform prior state data into the model
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
// Read identity data
var identityData {{.NamePascal}}ResourceIdentityModel
resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...)
if resp.Diagnostics.HasError() {
return
}
ctx = core.InitProviderContext(ctx)
projectId := identityData.ProjectID.ValueString()
region := identityData.Region.ValueString()
ctx = tflog.SetField(ctx, "project_id", projectId)
ctx = tflog.SetField(ctx, "region", region)
// Todo: Delete API call logic
tflog.Info(ctx, "{{.PackageName}}.{{.NamePascal}} deleted")