fix: sqlserver_beta (#33)
## 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: #33
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
581e45eb9c
commit
c22e758b2c
14 changed files with 456 additions and 102 deletions
|
|
@ -4,6 +4,9 @@ import (
|
|||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io"
|
||||
"log"
|
||||
"log/slog"
|
||||
|
|
@ -260,6 +263,7 @@ type templateData struct {
|
|||
NameCamel string
|
||||
NamePascal string
|
||||
NameSnake string
|
||||
Fields []string
|
||||
}
|
||||
|
||||
func fileExists(path string) bool {
|
||||
|
|
@ -317,11 +321,16 @@ func createBoilerplate(rootFolder, folder string) error {
|
|||
return errors.New("resource name is invalid")
|
||||
}
|
||||
|
||||
fields, tokenErr := getTokens(dsFile)
|
||||
if tokenErr != nil {
|
||||
return fmt.Errorf("error reading tokens: %w", tokenErr)
|
||||
}
|
||||
|
||||
tplName := "data_source_scaffold.gotmpl"
|
||||
err = writeTemplateToFile(
|
||||
tplName,
|
||||
path.Join(rootFolder, "cmd", "cmd", "build", "templates", tplName),
|
||||
path.Join(folder, svc.Name(), res.Name(), "datasource.go"),
|
||||
dsGoFile,
|
||||
&templateData{
|
||||
PackageName: svc.Name(),
|
||||
PackageNameCamel: ToCamelCase(svc.Name()),
|
||||
|
|
@ -329,6 +338,7 @@ func createBoilerplate(rootFolder, folder string) error {
|
|||
NameCamel: ToCamelCase(resourceName),
|
||||
NamePascal: ToPascalCase(resourceName),
|
||||
NameSnake: resourceName,
|
||||
Fields: fields,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
|
|
@ -342,11 +352,16 @@ func createBoilerplate(rootFolder, folder string) error {
|
|||
return errors.New("resource name is invalid")
|
||||
}
|
||||
|
||||
fields, tokenErr := getTokens(resFile)
|
||||
if tokenErr != nil {
|
||||
return fmt.Errorf("error reading tokens: %w", tokenErr)
|
||||
}
|
||||
|
||||
tplName := "resource_scaffold.gotmpl"
|
||||
err = writeTemplateToFile(
|
||||
tplName,
|
||||
path.Join(rootFolder, "cmd", "cmd", "build", "templates", tplName),
|
||||
path.Join(folder, svc.Name(), res.Name(), "resource.go"),
|
||||
resGoFile,
|
||||
&templateData{
|
||||
PackageName: svc.Name(),
|
||||
PackageNameCamel: ToCamelCase(svc.Name()),
|
||||
|
|
@ -354,6 +369,7 @@ func createBoilerplate(rootFolder, folder string) error {
|
|||
NameCamel: ToCamelCase(resourceName),
|
||||
NamePascal: ToPascalCase(resourceName),
|
||||
NameSnake: resourceName,
|
||||
Fields: fields,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
|
|
@ -813,3 +829,41 @@ func getRoot() (*string, error) {
|
|||
lines := strings.Split(string(out), "\n")
|
||||
return &lines[0], nil
|
||||
}
|
||||
|
||||
func getTokens(fileName string) ([]string, error) {
|
||||
fset := token.NewFileSet()
|
||||
|
||||
var result []string
|
||||
|
||||
node, err := parser.ParseFile(fset, fileName, nil, parser.ParseComments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ast.Inspect(node, func(n ast.Node) bool {
|
||||
// Suche nach Typ-Deklarationen (structs)
|
||||
ts, ok := n.(*ast.TypeSpec)
|
||||
if ok {
|
||||
if strings.Contains(ts.Name.Name, "Model") {
|
||||
// fmt.Printf("found model: %s\n", ts.Name.Name)
|
||||
ast.Inspect(ts, func(sn ast.Node) bool {
|
||||
tts, tok := sn.(*ast.Field)
|
||||
if tok {
|
||||
// fmt.Printf(" found: %+v\n", tts.Names[0])
|
||||
// spew.Dump(tts.Type)
|
||||
|
||||
result = append(result, tts.Names[0].String())
|
||||
|
||||
//fld, fldOk := tts.Type.(*ast.Ident)
|
||||
//if fldOk {
|
||||
// fmt.Printf("type: %+v\n", fld)
|
||||
//}
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
return result, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,15 +6,16 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
"github.com/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"
|
||||
|
||||
{{.PackageName}}Pkg "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/{{.PackageName}}"
|
||||
|
||||
{{.PackageName}}Utils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/{{.PackageName}}/utils"
|
||||
|
||||
{{.PackageName}}Gen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/{{.PackageName}}/{{.NameSnake}}/datasources_gen"
|
||||
)
|
||||
|
||||
|
|
@ -26,6 +27,11 @@ func New{{.NamePascal}}DataSource() datasource.DataSource {
|
|||
return &{{.NameCamel}}DataSource{}
|
||||
}
|
||||
|
||||
type dsModel struct {
|
||||
{{.PackageName}}Gen.{{.NamePascal}}Model
|
||||
TfId types.String `tfsdk:"id"`
|
||||
}
|
||||
|
||||
type {{.NameCamel}}DataSource struct{
|
||||
client *{{.PackageName}}Pkg.APIClient
|
||||
providerData core.ProviderData
|
||||
|
|
@ -37,6 +43,11 @@ func (d *{{.NameCamel}}DataSource) Metadata(_ context.Context, req datasource.Me
|
|||
|
||||
func (d *{{.NameCamel}}DataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
||||
resp.Schema = {{.PackageName}}Gen.{{.NamePascal}}DataSourceSchema(ctx)
|
||||
resp.Schema.Attributes["id"] = schema.StringAttribute{
|
||||
Computed: true,
|
||||
Description: "The terraform internal identifier.",
|
||||
MarkdownDescription: "The terraform internal identifier.",
|
||||
}
|
||||
}
|
||||
|
||||
// Configure adds the provider configured client to the data source.
|
||||
|
|
@ -51,8 +62,30 @@ func (d *{{.NameCamel}}DataSource) Configure(
|
|||
return
|
||||
}
|
||||
|
||||
apiClient := {{.PackageName}}Utils.ConfigureClient(ctx, &d.providerData, &resp.Diagnostics)
|
||||
if resp.Diagnostics.HasError() {
|
||||
apiClientConfigOptions := []config.ConfigurationOption{
|
||||
config.WithCustomAuth(d.providerData.RoundTripper),
|
||||
utils.UserAgentConfigOption(d.providerData.Version),
|
||||
}
|
||||
if d.providerData.{{.PackageNamePascal}}CustomEndpoint != "" {
|
||||
apiClientConfigOptions = append(
|
||||
apiClientConfigOptions,
|
||||
config.WithEndpoint(d.providerData.{{.PackageNamePascal}}CustomEndpoint),
|
||||
)
|
||||
} else {
|
||||
apiClientConfigOptions = append(
|
||||
apiClientConfigOptions,
|
||||
config.WithRegion(d.providerData.GetRegion()),
|
||||
)
|
||||
}
|
||||
apiClient, err := {{.PackageName}}Pkg.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
|
||||
}
|
||||
d.client = apiClient
|
||||
|
|
@ -60,7 +93,7 @@ func (d *{{.NameCamel}}DataSource) Configure(
|
|||
}
|
||||
|
||||
func (d *{{.NameCamel}}DataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
||||
var data {{.PackageName}}Gen.{{.NamePascal}}Model
|
||||
var data dsModel
|
||||
|
||||
// Read Terraform configuration data into the model
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
|
||||
|
|
@ -77,8 +110,11 @@ func (d *{{.NameCamel}}DataSource) Read(ctx context.Context, req datasource.Read
|
|||
|
||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||
ctx = tflog.SetField(ctx, "region", region)
|
||||
|
||||
// TODO: implement needed fields
|
||||
ctx = tflog.SetField(ctx, "{{.NameCamel}}_id", {{.NameCamel}}Id)
|
||||
|
||||
// TODO: refactor to correct implementation
|
||||
{{.NameCamel}}Resp, err := d.client.Get{{.NamePascal}}Request(ctx, projectId, region, {{.NameCamel}}Id).Execute()
|
||||
if err != nil {
|
||||
utils.LogError(
|
||||
|
|
@ -98,22 +134,15 @@ func (d *{{.NameCamel}}DataSource) Read(ctx context.Context, req datasource.Read
|
|||
ctx = core.LogResponse(ctx)
|
||||
|
||||
|
||||
// Todo: Read API call logic
|
||||
data.TfId = utils.BuildInternalTerraformId(projectId, region, ..)
|
||||
|
||||
// Example data value setting
|
||||
// data.Id = types.StringValue("example-id")
|
||||
|
||||
err = mapResponseToModel(ctx, {{.NameCamel}}Resp, &data, resp.Diagnostics)
|
||||
if err != nil {
|
||||
core.LogAndAddError(
|
||||
ctx,
|
||||
&resp.Diagnostics,
|
||||
fmt.Sprintf("%s Read", errorPrefix),
|
||||
fmt.Sprintf("Processing API payload: %v", err),
|
||||
)
|
||||
return
|
||||
}
|
||||
// TODO: fill remaining fields
|
||||
{{- range .Fields }}
|
||||
// data.{{.}} = types.Sometype(apiResponse.Get{{.}}())
|
||||
{{- end -}}
|
||||
|
||||
// Save data into Terraform state
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||
|
||||
tflog.Info(ctx, fmt.Sprintf("%s read successful", errorPrefix))
|
||||
}
|
||||
|
|
|
|||
147
cmd/cmd/getFieldsCmd.go
Normal file
147
cmd/cmd/getFieldsCmd.go
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
inFile string
|
||||
svcName string
|
||||
resName string
|
||||
resType string
|
||||
filePath string
|
||||
)
|
||||
|
||||
var getFieldsCmd = &cobra.Command{
|
||||
Use: "get-fields",
|
||||
Short: "get fields from file",
|
||||
Long: `...`,
|
||||
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
typeStr := "data_source"
|
||||
if resType != "resource" && resType != "datasource" {
|
||||
return fmt.Errorf("--type can only be resource or datasource")
|
||||
}
|
||||
|
||||
if resType == "resource" {
|
||||
typeStr = resType
|
||||
}
|
||||
|
||||
if inFile == "" && svcName == "" && resName == "" {
|
||||
return fmt.Errorf("--infile or --service and --resource must be provided")
|
||||
}
|
||||
|
||||
if inFile != "" {
|
||||
if svcName != "" || resName != "" {
|
||||
return fmt.Errorf("--infile is provided and excludes --service and --resource")
|
||||
}
|
||||
p, err := filepath.Abs(inFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
filePath = p
|
||||
return nil
|
||||
}
|
||||
|
||||
if svcName != "" && resName == "" {
|
||||
return fmt.Errorf("if --service is provided, you MUST also provide --resource")
|
||||
}
|
||||
|
||||
if svcName == "" && resName != "" {
|
||||
return fmt.Errorf("if --resource is provided, you MUST also provide --service")
|
||||
}
|
||||
|
||||
p, err := filepath.Abs(
|
||||
path.Join(
|
||||
"stackit",
|
||||
"internal",
|
||||
"services",
|
||||
svcName,
|
||||
resName,
|
||||
fmt.Sprintf("%ss_gen", resType),
|
||||
fmt.Sprintf("%s_%s_gen.go", resName, typeStr),
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
filePath = p
|
||||
|
||||
//// Enum check
|
||||
//switch format {
|
||||
//case "json", "yaml":
|
||||
//default:
|
||||
// return fmt.Errorf("invalid --format: %s (want json|yaml)", format)
|
||||
//}
|
||||
return nil
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return getFields(filePath)
|
||||
},
|
||||
}
|
||||
|
||||
func getFields(f string) error {
|
||||
tokens, err := getTokens(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, item := range tokens {
|
||||
fmt.Printf("%s \n", item)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getTokens(fileName string) ([]string, error) {
|
||||
fset := token.NewFileSet()
|
||||
var result []string
|
||||
|
||||
node, err := parser.ParseFile(fset, fileName, nil, parser.ParseComments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ast.Inspect(node, func(n ast.Node) bool {
|
||||
// Suche nach Typ-Deklarationen (structs)
|
||||
ts, ok := n.(*ast.TypeSpec)
|
||||
if ok {
|
||||
if strings.Contains(ts.Name.Name, "Model") {
|
||||
// fmt.Printf("found model: %s\n", ts.Name.Name)
|
||||
ast.Inspect(ts, func(sn ast.Node) bool {
|
||||
tts, tok := sn.(*ast.Field)
|
||||
if tok {
|
||||
// fmt.Printf(" found: %+v\n", tts.Names[0])
|
||||
// spew.Dump(tts.Type)
|
||||
|
||||
result = append(result, tts.Names[0].String())
|
||||
|
||||
//fld, fldOk := tts.Type.(*ast.Ident)
|
||||
//if fldOk {
|
||||
// fmt.Printf("type: %+v\n", fld)
|
||||
//}
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func NewGetFieldsCmd() *cobra.Command {
|
||||
return getFieldsCmd
|
||||
}
|
||||
|
||||
func init() { // nolint: gochecknoinits
|
||||
getFieldsCmd.Flags().StringVarP(&inFile, "infile", "i", "", "input filename incl path")
|
||||
getFieldsCmd.Flags().StringVarP(&svcName, "service", "s", "", "service name")
|
||||
getFieldsCmd.Flags().StringVarP(&resName, "resource", "r", "", "resource name")
|
||||
getFieldsCmd.Flags().StringVarP(&resType, "type", "t", "resource", "resource type (data-source or resource [default])")
|
||||
}
|
||||
|
|
@ -28,6 +28,7 @@ func main() {
|
|||
rootCmd.AddCommand(
|
||||
cmd.NewBuildCmd(),
|
||||
cmd.NewPublishCmd(),
|
||||
cmd.NewGetFieldsCmd(),
|
||||
)
|
||||
|
||||
err := rootCmd.Execute()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue