From 7181f87abad6a1437e04138c45f13e7797bf27ef Mon Sep 17 00:00:00 2001 From: Andre Harms Date: Wed, 18 Feb 2026 14:00:15 +0100 Subject: [PATCH] fix: clean up code --- cmd/cmd/build/build.go | 333 ++++++++++++------ cmd/cmd/build/copy.go | 15 +- cmd/cmd/buildCmd.go | 4 +- cmd/cmd/examplesCmd.go | 51 ++- cmd/cmd/getFieldsCmd.go | 59 ++-- cmd/cmd/publish/architecture.go | 44 +-- cmd/cmd/publish/provider.go | 36 +- cmd/cmd/publish/versions.go | 33 +- cmd/cmd/publishCmd.go | 21 +- .../resource.tf | 2 +- .../resource.tf | 2 +- internal/testutils/activateMocks.go | 21 +- scripts/lint-golangci-lint.sh | 19 - stackit/internal/core/core.go | 34 +- stackit/internal/core/retry_round_tripper.go | 6 +- .../internal/core/retry_round_tripper_test.go | 14 +- .../postgresflexalpha/instance/resource.go | 16 - .../postgresflex_acc_test.go | 271 +++++++------- .../postgresflexalpha/user/resource.go | 1 - .../sqlserverflexalpha/database/datasource.go | 1 - .../sqlserverflexalpha/database/resource.go | 29 +- .../sqlserverflexalpha/instance/functions.go | 1 - .../sqlserverflexalpha/instance/resource.go | 5 +- .../sqlserverflex_acc_test.go | 8 +- .../sqlserverflexalpha/user/datasource.go | 2 - .../sqlserverflexalpha/user/resource.go | 6 +- .../sqlserverflexbeta/database/datasource.go | 1 - .../sqlserverflexbeta/database/resource.go | 52 +-- .../sqlserverflexbeta/instance/functions.go | 1 - .../instance/functions_test.go | 106 +++--- .../sqlserverflexbeta/instance/resource.go | 5 +- .../sqlserverflex_acc_test.go | 8 +- .../sqlserverflexbeta/user/datasource.go | 2 - .../sqlserverflexbeta/user/resource.go | 35 +- .../internal/wait/postgresflexalpha/wait.go | 30 +- .../internal/wait/sqlserverflexalpha/wait.go | 17 +- .../wait/sqlserverflexalpha/wait_test.go | 3 +- .../internal/wait/sqlserverflexbeta/wait.go | 29 +- .../wait/sqlserverflexbeta/wait_test.go | 3 +- stackit/provider.go | 5 +- stackit/provider_acc_test.go | 226 +++++++----- 41 files changed, 875 insertions(+), 682 deletions(-) delete mode 100755 scripts/lint-golangci-lint.sh diff --git a/cmd/cmd/build/build.go b/cmd/cmd/build/build.go index d381de63..e46ff56e 100644 --- a/cmd/cmd/build/build.go +++ b/cmd/cmd/build/build.go @@ -111,7 +111,7 @@ func (b *Builder) Build() error { } slog.Info("Creating OAS dir") - err = os.MkdirAll(path.Join(genDir, "oas"), 0755) + err = os.MkdirAll(path.Join(genDir, "oas"), 0o755) //nolint:gosec // this dir is not sensitive, so we can use 0755 if err != nil { return err } @@ -158,7 +158,17 @@ func (b *Builder) Build() error { if err = cmd.Wait(); err != nil { var exitErr *exec.ExitError if errors.As(err, &exitErr) { - slog.Error("cmd.Wait", "code", exitErr.ExitCode(), "error", err, "stdout", stdOut.String(), "stderr", stdErr.String()) + slog.Error( + "cmd.Wait", + "code", + exitErr.ExitCode(), + "error", + err, + "stdout", + stdOut.String(), + "stderr", + stdErr.String(), + ) return fmt.Errorf("%s", stdErr.String()) } if err != nil { @@ -192,7 +202,11 @@ func (b *Builder) Build() error { } slog.Info("Rearranging package directories") - err = os.MkdirAll(path.Join(*root, "pkg_gen"), 0755) // noqa:gosec + //nolint:gosec // this dir is not sensitive, so we can use 0755 + err = os.MkdirAll( + path.Join(*root, "pkg_gen"), + 0o755, + ) if err != nil { return err } @@ -202,20 +216,21 @@ func (b *Builder) Build() error { return err } for _, item := range items { - if item.IsDir() { - slog.Info(" -> package", "name", item.Name()) - tgtDir := path.Join(*root, "pkg_gen", item.Name()) - if fileExists(tgtDir) { - delErr := os.RemoveAll(tgtDir) - if delErr != nil { - return delErr - } - } - err = os.Rename(path.Join(srcDir, item.Name()), tgtDir) - if err != nil { - return err + if !item.IsDir() { + continue + } + slog.Info(" -> package", "name", item.Name()) + tgtDir := path.Join(*root, "pkg_gen", item.Name()) + if fileExists(tgtDir) { + delErr := os.RemoveAll(tgtDir) + if delErr != nil { + return delErr } } + err = os.Rename(path.Join(srcDir, item.Name()), tgtDir) + if err != nil { + return err + } } if !b.PackagesOnly { @@ -275,8 +290,8 @@ type templateData struct { Fields []string } -func fileExists(path string) bool { - _, err := os.Stat(path) +func fileExists(pathValue string) bool { + _, err := os.Stat(pathValue) if os.IsNotExist(err) { return false } @@ -312,10 +327,22 @@ func createBoilerplate(rootFolder, folder string) error { resourceName := res.Name() - dsFile := path.Join(folder, svc.Name(), res.Name(), "datasources_gen", fmt.Sprintf("%s_data_source_gen.go", 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())) + 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") @@ -407,7 +434,6 @@ func createBoilerplate(rootFolder, folder string) error { if err != nil { return err } - } } } @@ -416,7 +442,7 @@ func createBoilerplate(rootFolder, folder string) error { } func ucfirst(s string) string { - if len(s) == 0 { + if s == "" { return "" } return strings.ToUpper(s[:1]) + s[1:] @@ -451,8 +477,8 @@ func writeTemplateToFile(tplName, tplFile, outFile string, data *templateData) e } func generateServiceFiles(rootDir, generatorDir string) error { - // slog.Info("Generating specs folder") - err := os.MkdirAll(path.Join(rootDir, "generated", "specs"), 0755) + //nolint:gosec // this file is not sensitive, so we can use 0755 + err := os.MkdirAll(path.Join(rootDir, "generated", "specs"), 0o755) if err != nil { return err } @@ -490,7 +516,6 @@ func generateServiceFiles(rootDir, generatorDir string) error { continue } - // slog.Info("Checking spec", "name", spec.Name()) r := regexp.MustCompile(`^(.*)_config.yml$`) matches := r.FindAllStringSubmatch(specFile.Name(), -1) if matches != nil { @@ -506,25 +531,40 @@ func generateServiceFiles(rootDir, generatorDir string) error { resource, ) - oasFile := path.Join(generatorDir, "oas", fmt.Sprintf("%s%s.json", service.Name(), svcVersion.Name())) + oasFile := path.Join( + generatorDir, + "oas", + fmt.Sprintf("%s%s.json", service.Name(), svcVersion.Name()), + ) if _, oasErr := os.Stat(oasFile); os.IsNotExist(oasErr) { - slog.Warn(" could not find matching oas", "svc", service.Name(), "version", svcVersion.Name()) + slog.Warn( + " could not find matching oas", + "svc", + service.Name(), + "version", + svcVersion.Name(), + ) continue } scName := fmt.Sprintf("%s%s", service.Name(), svcVersion.Name()) scName = strings.ReplaceAll(scName, "-", "") - err = os.MkdirAll(path.Join(rootDir, "generated", "internal", "services", scName, resource), 0755) + //nolint:gosec // this file is not sensitive, so we can use 0755 + err = os.MkdirAll(path.Join(rootDir, "generated", "internal", "services", scName, resource), 0o755) if err != nil { return err } - // slog.Info("Generating openapi spec json") - specJsonFile := path.Join(rootDir, "generated", "specs", fmt.Sprintf("%s_%s_spec.json", scName, resource)) + specJsonFile := path.Join( + rootDir, + "generated", + "specs", + fmt.Sprintf("%s_%s_spec.json", scName, resource), + ) var stdOut, stdErr bytes.Buffer - // noqa:gosec + // nolint:gosec // #nosec this command is not using any untrusted input, so we can ignore gosec warning cmd := exec.Command( "tfplugingen-openapi", "generate", @@ -553,11 +593,29 @@ func generateServiceFiles(rootDir, generatorDir string) error { if err = cmd.Wait(); err != nil { var exitErr *exec.ExitError if errors.As(err, &exitErr) { - slog.Error("tfplugingen-openapi generate", "code", exitErr.ExitCode(), "error", err, "stdout", stdOut.String(), "stderr", stdErr.String()) + slog.Error( + "tfplugingen-openapi generate", + "code", + exitErr.ExitCode(), + "error", + err, + "stdout", + stdOut.String(), + "stderr", + stdErr.String(), + ) return fmt.Errorf("%s", stdErr.String()) } if err != nil { - slog.Error("tfplugingen-openapi generate", "err", err, "stdout", stdOut.String(), "stderr", stdErr.String()) + slog.Error( + "tfplugingen-openapi generate", + "err", + err, + "stdout", + stdOut.String(), + "stderr", + stdErr.String(), + ) return err } } @@ -565,16 +623,22 @@ func generateServiceFiles(rootDir, generatorDir string) error { slog.Warn(" command output", "stdout", stdOut.String(), "stderr", stdErr.String()) } - // slog.Info("Creating terraform svc resource files folder") - tgtFolder := path.Join(rootDir, "generated", "internal", "services", scName, resource, "resources_gen") - err = os.MkdirAll(tgtFolder, 0755) + tgtFolder := path.Join( + rootDir, + "generated", + "internal", + "services", + scName, + resource, + "resources_gen", + ) + //nolint:gosec // this file is not sensitive, so we can use 0755 + err = os.MkdirAll(tgtFolder, 0o755) if err != nil { return err } - // slog.Info("Generating terraform svc resource files") - - // noqa:gosec + // nolint:gosec // #nosec this command is not using any untrusted input, so we can ignore gosec warning cmd2 := exec.Command( "tfplugingen-framework", "generate", @@ -597,25 +661,49 @@ func generateServiceFiles(rootDir, generatorDir string) error { if err = cmd2.Wait(); err != nil { var exitErr *exec.ExitError if errors.As(err, &exitErr) { - slog.Error("tfplugingen-framework generate resources", "code", exitErr.ExitCode(), "error", err, "stdout", stdOut.String(), "stderr", stdErr.String()) + slog.Error( + "tfplugingen-framework generate resources", + "code", + exitErr.ExitCode(), + "error", + err, + "stdout", + stdOut.String(), + "stderr", + stdErr.String(), + ) return fmt.Errorf("%s", stdErr.String()) } if err != nil { - slog.Error("tfplugingen-framework generate resources", "err", err, "stdout", stdOut.String(), "stderr", stdErr.String()) + slog.Error( + "tfplugingen-framework generate resources", + "err", + err, + "stdout", + stdOut.String(), + "stderr", + stdErr.String(), + ) return err } } - // slog.Info("Creating terraform svc datasource files folder") - tgtFolder = path.Join(rootDir, "generated", "internal", "services", scName, resource, "datasources_gen") - err = os.MkdirAll(tgtFolder, 0755) + tgtFolder = path.Join( + rootDir, + "generated", + "internal", + "services", + scName, + resource, + "datasources_gen", + ) + //nolint:gosec // this directory is not sensitive, so we can use 0755 + err = os.MkdirAll(tgtFolder, 0o755) if err != nil { return err } - // slog.Info("Generating terraform svc resource files") - - // noqa:gosec + // nolint:gosec // #nosec this command is not using any untrusted input, so we can ignore gosec warning cmd3 := exec.Command( "tfplugingen-framework", "generate", @@ -639,11 +727,29 @@ func generateServiceFiles(rootDir, generatorDir string) error { if err = cmd3.Wait(); err != nil { var exitErr *exec.ExitError if errors.As(err, &exitErr) { - slog.Error("tfplugingen-framework generate data-sources", "code", exitErr.ExitCode(), "error", err, "stdout", stdOut.String(), "stderr", stdErr.String()) + slog.Error( + "tfplugingen-framework generate data-sources", + "code", + exitErr.ExitCode(), + "error", + err, + "stdout", + stdOut.String(), + "stderr", + stdErr.String(), + ) return fmt.Errorf("%s", stdErr.String()) } if err != nil { - slog.Error("tfplugingen-framework generate data-sources", "err", err, "stdout", stdOut.String(), "stderr", stdErr.String()) + slog.Error( + "tfplugingen-framework generate data-sources", + "err", + err, + "stdout", + stdOut.String(), + "stderr", + stdErr.String(), + ) return err } } @@ -674,10 +780,16 @@ func handleTfTagForDatasourceFile(filePath, service, resource string) error { if err != nil { return err } - defer f.Close() + defer func(f *os.File) { + err := f.Close() + if err != nil { + slog.Error("handleTfTagForDatasourceFile", "err", err) + } + }(f) root, err := getRoot() if err != nil { + //nolint:gocritic // in this case, we want to log the error and exit, as we cannot proceed without the root directory log.Fatal(err) } @@ -685,7 +797,12 @@ func handleTfTagForDatasourceFile(filePath, service, resource string) error { if err != nil { return err } - defer tmp.Close() + defer func(tmp *os.File) { + err := tmp.Close() + if err != nil { + slog.Error("handleTfTagForDatasourceFile", "err", err) + } + }(tmp) sc := bufio.NewScanner(f) for sc.Scan() { @@ -709,6 +826,7 @@ func handleTfTagForDatasourceFile(filePath, service, resource string) error { return err } + //nolint:gosec // path traversal is not a concern here if err := os.Rename(tmp.Name(), filePath); err != nil { log.Fatal(err) } @@ -773,13 +891,23 @@ func copyFile(src, dst string) (int64, error) { if err != nil { return 0, err } - defer source.Close() + defer func(source *os.File) { + err := source.Close() + if err != nil { + slog.Error("copyFile", "err", err) + } + }(source) destination, err := os.Create(dst) if err != nil { return 0, err } - defer destination.Close() + defer func(destination *os.File) { + err := destination.Close() + if err != nil { + slog.Error("copyFile", "err", err) + } + }(destination) nBytes, err := io.Copy(destination, source) return nBytes, err } @@ -790,10 +918,8 @@ func getOnlyLatest(m map[string]version) (map[string]version, error) { item, ok := tmpMap[k] if !ok { tmpMap[k] = v - } else { - if item.major == v.major && item.minor < v.minor { - tmpMap[k] = v - } + } else if item.major == v.major && item.minor < v.minor { + tmpMap[k] = v } } return tmpMap, nil @@ -807,18 +933,19 @@ func getVersions(dir string) (map[string]version, error) { } for _, entry := range children { - if entry.IsDir() { - versions, err := os.ReadDir(path.Join(dir, "services", entry.Name())) - if err != nil { - return nil, err - } - m, err2 := extractVersions(entry.Name(), versions) - if err2 != nil { - return m, err2 - } - for k, v := range m { - res[k] = v - } + if !entry.IsDir() { + continue + } + versions, err := os.ReadDir(path.Join(dir, "services", entry.Name())) + if err != nil { + return nil, err + } + m, err2 := extractVersions(entry.Name(), versions) + if err2 != nil { + return m, err2 + } + for k, v := range m { + res[k] = v } } return res, nil @@ -827,20 +954,21 @@ func getVersions(dir string) (map[string]version, error) { func extractVersions(service string, versionDirs []os.DirEntry) (map[string]version, error) { res := make(map[string]version) for _, vDir := range versionDirs { - if vDir.IsDir() { - r := regexp.MustCompile(`v([0-9]+)([a-z]+)([0-9]*)`) - matches := r.FindAllStringSubmatch(vDir.Name(), -1) - if matches == nil { - continue - } - svc, ver, err := handleVersion(service, matches[0]) - if err != nil { - return nil, err - } + if !vDir.IsDir() { + continue + } + r := regexp.MustCompile(`v(\d+)([a-z]+)(\d*)`) + matches := r.FindAllStringSubmatch(vDir.Name(), -1) + if matches == nil { + continue + } + svc, ver, err := handleVersion(service, matches[0]) + if err != nil { + return nil, err + } - if svc != nil && ver != nil { - res[*svc] = *ver - } + if svc != nil && ver != nil { + res[*svc] = *ver } } return res, nil @@ -927,30 +1055,25 @@ func getTokens(fileName string) ([]string, error) { 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 - }) + 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") { + ast.Inspect( + ts, func(sn ast.Node) bool { + tts, tok := sn.(*ast.Field) + if tok { + result = append(result, tts.Names[0].String()) + } + return true + }, + ) + } } - } - return true - }) + return true + }, + ) return result, nil } diff --git a/cmd/cmd/build/copy.go b/cmd/cmd/build/copy.go index ec0affe9..e1243c05 100644 --- a/cmd/cmd/build/copy.go +++ b/cmd/cmd/build/copy.go @@ -3,6 +3,7 @@ package build import ( "fmt" "io" + "log/slog" "os" "path/filepath" "syscall" @@ -74,14 +75,24 @@ func Copy(srcFile, dstFile string) error { return err } - defer out.Close() + defer func(out *os.File) { + err := out.Close() + if err != nil { + slog.Error("failed to close file", slog.Any("err", err)) + } + }(out) in, err := os.Open(srcFile) if err != nil { return err } - defer in.Close() + defer func(in *os.File) { + err := in.Close() + if err != nil { + slog.Error("error closing destination file", slog.Any("err", err)) + } + }(in) _, err = io.Copy(out, in) if err != nil { diff --git a/cmd/cmd/buildCmd.go b/cmd/cmd/buildCmd.go index b9f4c835..e3e8e7ae 100644 --- a/cmd/cmd/buildCmd.go +++ b/cmd/cmd/buildCmd.go @@ -16,7 +16,7 @@ var buildCmd = &cobra.Command{ Use: "build", Short: "Build the necessary boilerplate", Long: `...`, - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(_ *cobra.Command, _ []string) error { b := build.Builder{ SkipClone: skipClone, SkipCleanup: skipCleanup, @@ -30,7 +30,7 @@ func NewBuildCmd() *cobra.Command { return buildCmd } -func init() { // nolint: gochecknoinits +func init() { //nolint:gochecknoinits // This is the standard way to set up Cobra commands buildCmd.Flags().BoolVarP(&skipCleanup, "skip-clean", "c", false, "Skip cleanup steps") buildCmd.Flags().BoolVarP(&skipClone, "skip-clone", "g", false, "Skip cloning from git") buildCmd.Flags().BoolVarP(&packagesOnly, "packages-only", "p", false, "Only generate packages") diff --git a/cmd/cmd/examplesCmd.go b/cmd/cmd/examplesCmd.go index 6c95a799..a4c75962 100644 --- a/cmd/cmd/examplesCmd.go +++ b/cmd/cmd/examplesCmd.go @@ -12,16 +12,15 @@ var examplesCmd = &cobra.Command{ Use: "examples", Short: "create examples", Long: `...`, - RunE: func(cmd *cobra.Command, args []string) error { - - //filePathStr := "stackit/internal/services/postgresflexalpha/database/datasources_gen/database_data_source_gen.go" + RunE: func(_ *cobra.Command, _ []string) error { + // filePathStr := "stackit/internal/services/postgresflexalpha/database/datasources_gen/database_data_source_gen.go" // - //src, err := os.ReadFile(filePathStr) - //if err != nil { + // src, err := os.ReadFile(filePathStr) + // if err != nil { // return err //} // - //i := interp.New( + // i := interp.New( // interp.Options{ // GoPath: "/home/henselinm/.asdf/installs/golang/1.25.6/packages", // BuildTags: nil, @@ -34,46 +33,46 @@ var examplesCmd = &cobra.Command{ // Unrestricted: false, // }, //) - //err = i.Use(i.Symbols("github.com/hashicorp/terraform-plugin-framework-validators")) - //if err != nil { + // err = i.Use(i.Symbols("github.com/hashicorp/terraform-plugin-framework-validators")) + // if err != nil { // return err //} - //err = i.Use(stdlib.Symbols) - //if err != nil { + // err = i.Use(stdlib.Symbols) + // if err != nil { // return err //} - //_, err = i.Eval(string(src)) - //if err != nil { + // _, err = i.Eval(string(src)) + // if err != nil { // return err //} // - //v, err := i.Eval("DatabaseDataSourceSchema") - //if err != nil { + // v, err := i.Eval("DatabaseDataSourceSchema") + // if err != nil { // return err //} // - //bar := v.Interface().(func(string) string) + // bar := v.Interface().(func(string) string) // - //r := bar("Kung") - //println(r) + // r := bar("Kung") + // println(r) // - //evalPath, err := i.EvalPath(filePathStr) - //if err != nil { + // evalPath, err := i.EvalPath(filePathStr) + // if err != nil { // return err //} // - //fmt.Printf("%+v\n", evalPath) + // fmt.Printf("%+v\n", evalPath) - //_, err = i.Eval(`import "fmt"`) - //if err != nil { + // _, err = i.Eval(`import "fmt"`) + // if err != nil { // return err //} - //_, err = i.Eval(`func Hallo() { fmt.Println("Hi!") }`) - //if err != nil { + // _, err = i.Eval(`func Hallo() { fmt.Println("Hi!") }`) + // if err != nil { // return err //} - //v = i.Symbols("Hallo") + // v = i.Symbols("Hallo") // fmt.Println(v) return workServices() @@ -110,6 +109,6 @@ func NewExamplesCmd() *cobra.Command { return examplesCmd } -//func init() { // nolint: gochecknoinits +// func init() { // nolint: gochecknoinits // examplesCmd.Flags().BoolVarP(&example, "example", "e", false, "example") //} diff --git a/cmd/cmd/getFieldsCmd.go b/cmd/cmd/getFieldsCmd.go index 48cb379a..06fe9e66 100644 --- a/cmd/cmd/getFieldsCmd.go +++ b/cmd/cmd/getFieldsCmd.go @@ -24,7 +24,7 @@ var getFieldsCmd = &cobra.Command{ Use: "get-fields", Short: "get fields from file", Long: `...`, - PreRunE: func(cmd *cobra.Command, args []string) error { + PreRunE: func(_ *cobra.Command, _ []string) error { typeStr := "data_source" if resType != "resource" && resType != "datasource" { return fmt.Errorf("--type can only be resource or datasource") @@ -76,13 +76,13 @@ var getFieldsCmd = &cobra.Command{ //// Enum check // switch format { - //case "json", "yaml": + // case "json", "yaml": //default: // return fmt.Errorf("invalid --format: %s (want json|yaml)", format) //} return nil }, - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(_ *cobra.Command, _ []string) error { return getFields(filePath) }, } @@ -107,31 +107,26 @@ func getTokens(fileName string) ([]string, error) { 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 - }) + 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") { + ast.Inspect( + ts, func(sn ast.Node) bool { + tts, tok := sn.(*ast.Field) + if tok { + result = append(result, tts.Names[0].String()) + } + return true + }, + ) + } } - } - return true - }) + return true + }, + ) return result, nil } @@ -139,9 +134,15 @@ func NewGetFieldsCmd() *cobra.Command { return getFieldsCmd } -func init() { // nolint: gochecknoinits +func init() { //nolint:gochecknoinits //this is the only way to add the command to the rootCmd 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])") + getFieldsCmd.Flags().StringVarP( + &resType, + "type", + "t", + "resource", + "resource type (data-source or resource [default])", + ) } diff --git a/cmd/cmd/publish/architecture.go b/cmd/cmd/publish/architecture.go index 5fffa585..7316a03d 100644 --- a/cmd/cmd/publish/architecture.go +++ b/cmd/cmd/publish/architecture.go @@ -35,36 +35,27 @@ type GpgPublicKey struct { } func (p *Provider) CreateArchitectureFiles() error { - // var namespace, provider, distPath, repoName, version, gpgFingerprint, gpgPubKeyFile, domain string - log.Println("* Creating architecture files in target directories") - // filename = terraform-provider-[provider]_0.0.1_darwin_amd64.zip - provider_name + version + target + architecture + .zip - // prefix := fmt.Sprintf("v1/providers/%s/%s/%s/", namespace, provider, version) prefix := path.Join("v1", "providers", p.Namespace, p.Provider, p.Version) - // pathPrefix := fmt.Sprintf("release/%s", prefix) pathPrefix := path.Join("release", prefix) - // urlPrefix := fmt.Sprintf("https://%s/%s", domain, prefix) urlPrefix, err := url.JoinPath("https://", p.Domain, prefix) if err != nil { return fmt.Errorf("error creating base url: %w", err) } - // download url = https://example.com/v1/providers/namespace/provider/0.0.1/download/terraform-provider_0.0.1_darwin_amd64.zip downloadUrlPrefix, err := url.JoinPath(urlPrefix, "download") if err != nil { return fmt.Errorf("error crearting download url: %w", err) } downloadPathPrefix := path.Join(pathPrefix, "download") - // shasums url = https://example.com/v1/providers/namespace/provider/0.0.1/terraform-provider_0.0.1_SHA256SUMS shasumsUrl, err := url.JoinPath(urlPrefix, fmt.Sprintf("%s_%s_SHA256SUMS", p.RepoName, p.Version)) if err != nil { return fmt.Errorf("error creating shasums url: %w", err) } - // shasums_signature_url = https://example.com/v1/providers/namespace/provider/0.0.1/terraform-provider_0.0.1_SHA256SUMS.sig shasumsSigUrl := shasumsUrl + ".sig" gpgAsciiPub, err := p.ReadGpgFile() @@ -116,33 +107,6 @@ func (p *Provider) CreateArchitectureFiles() error { }, }, } - // var architectureTemplate = []byte(fmt.Sprintf(` - //{ - // "protocols": [ - // "4.0", - // "5.1", - // "6.0" - // ], - // "os": "%s", - // "arch": "%s", - // "filename": "%s", - // "download_url": "%s", - // "shasums_url": "%s", - // "shasums_signature_url": "%s", - // "shasum": "%s", - // "signing_keys": { - // "gpg_public_keys": [ - // { - // "key_id": "%s", - // "ascii_armor": "%s", - // "trust_signature": "", - // "source": "", - // "source_url": "" - // } - // ] - // } - //} - // `, target, arch, fileName, downloadUrl, shasumsUrl, shasumsSigUrl, shasum, gpgFingerprint, gpgAsciiPub)) log.Printf(" - Arch file: %s", archFileName) @@ -160,8 +124,12 @@ func WriteArchitectureFile(filePath string, arch Architecture) error { if err != nil { return fmt.Errorf("error encoding data: %w", err) } - - err = os.WriteFile(filePath, jsonString, os.ModePerm) + //nolint:gosec // this file is not sensitive, so we can use os.ModePerm + err = os.WriteFile( + filePath, + jsonString, + os.ModePerm, + ) if err != nil { return fmt.Errorf("error writing data: %w", err) } diff --git a/cmd/cmd/publish/provider.go b/cmd/cmd/publish/provider.go index 36d7af1d..88849eb0 100644 --- a/cmd/cmd/publish/provider.go +++ b/cmd/cmd/publish/provider.go @@ -161,10 +161,12 @@ func (p *Provider) createVersionsFile() error { target := fileNameSplit[2] arch := fileNameSplit[3] - version.Platforms = append(version.Platforms, Platform{ - OS: target, - Arch: arch, - }) + version.Platforms = append( + version.Platforms, Platform{ + OS: target, + Arch: arch, + }, + ) } data := Data{} @@ -206,16 +208,19 @@ func (p *Provider) CreateWellKnown() error { log.Println("* Creating .well-known directory") pathString := path.Join(p.RootPath, "release", ".well-known") + //nolint:gosec // this file is not sensitive, so we can use ModePerm err := os.MkdirAll(pathString, os.ModePerm) if err != nil && !errors.Is(err, fs.ErrExist) { return fmt.Errorf("error creating '%s' dir: %w", pathString, err) } log.Println(" - Writing to .well-known/terraform.json file") + + //nolint:gosec // this file is not sensitive, so we can use 0644 err = os.WriteFile( fmt.Sprintf("%s/terraform.json", pathString), []byte(`{"providers.v1": "/v1/providers/"}`), - 0644, + 0o644, ) if err != nil { return err @@ -224,9 +229,10 @@ func (p *Provider) CreateWellKnown() error { return nil } -func CreateDir(path string) error { - log.Printf("* Creating %s directory", path) - err := os.MkdirAll(path, os.ModePerm) +func CreateDir(pathValue string) error { + log.Printf("* Creating %s directory", pathValue) + //nolint:gosec // this file is not sensitive, so we can use ModePerm + err := os.MkdirAll(pathValue, os.ModePerm) if errors.Is(err, fs.ErrExist) { return nil } @@ -269,13 +275,23 @@ func CopyFile(src, dst string) (int64, error) { if err != nil { return 0, err } - defer source.Close() + defer func(source *os.File) { + err := source.Close() + if err != nil { + slog.Error("error closing source file", slog.Any("err", err)) + } + }(source) destination, err := os.Create(dst) if err != nil { return 0, err } - defer destination.Close() + defer func(destination *os.File) { + err := destination.Close() + if err != nil { + slog.Error("error closing destination file", slog.Any("err", err)) + } + }(destination) nBytes, err := io.Copy(destination, source) return nBytes, err } diff --git a/cmd/cmd/publish/versions.go b/cmd/cmd/publish/versions.go index 397afa15..5f75d45d 100644 --- a/cmd/cmd/publish/versions.go +++ b/cmd/cmd/publish/versions.go @@ -35,7 +35,12 @@ func (d *Data) WriteToFile(filePath string) error { return fmt.Errorf("error encoding data: %w", err) } - err = os.WriteFile(filePath, jsonString, os.ModePerm) + //nolint:gosec // this file is not sensitive, so we can use os.ModePerm + err = os.WriteFile( + filePath, + jsonString, + os.ModePerm, + ) if err != nil { return fmt.Errorf("error writing data: %w", err) } @@ -86,7 +91,13 @@ func (d *Data) LoadFromUrl(uri string) error { if err != nil { return err } - defer os.Remove(file.Name()) // Clean up + defer func(name string) { + //nolint:gosec // The file path is generated by os.CreateTemp and is not user-controllable + err := os.Remove(name) + if err != nil { + slog.Error("failed to remove temporary file", slog.Any("err", err)) + } + }(file.Name()) // Clean up err = DownloadFile( u.String(), @@ -123,20 +134,30 @@ func (v *Version) AddProtocol(p string) error { // DownloadFile will download a url and store it in local filepath. // It writes to the destination file as it downloads it, without // loading the entire file into memory. -func DownloadFile(url string, filepath string) error { +func DownloadFile(urlValue, filepath string) error { // Create the file + //nolint:gosec // path traversal is not a concern here, as the filepath is generated by us and not user input out, err := os.Create(filepath) if err != nil { return err } - defer out.Close() + defer func(out *os.File) { + err := out.Close() + if err != nil { + slog.Error("failed to close file", slog.Any("err", err)) + } + }(out) // Get the data - resp, err := http.Get(url) + + //nolint:gosec,bodyclose // this is a controlled URL, not user input + resp, err := http.Get(urlValue) if err != nil { return err } - defer resp.Body.Close() + defer func(Body io.ReadCloser) { + _ = Body.Close() + }(resp.Body) // Write the body to file _, err = io.Copy(out, resp.Body) diff --git a/cmd/cmd/publishCmd.go b/cmd/cmd/publishCmd.go index 4849ba4b..a428d436 100644 --- a/cmd/cmd/publishCmd.go +++ b/cmd/cmd/publishCmd.go @@ -29,20 +29,32 @@ var publishCmd = &cobra.Command{ Use: "publish", Short: "Publish terraform provider", Long: `...`, - RunE: func(_ *cobra.Command, args []string) error { + RunE: func(_ *cobra.Command, _ []string) error { return publish() }, } -func init() { // nolint: gochecknoinits +func init() { //nolint:gochecknoinits //this is the standard way to set up cobra commands publishCmd.Flags().StringVarP(&namespace, "namespace", "n", "", "Namespace for the Terraform registry.") publishCmd.Flags().StringVarP(&domain, "domain", "d", "", "Domain for the Terraform registry.") publishCmd.Flags().StringVarP(&providerName, "providerName", "p", "", "ProviderName for the Terraform registry.") publishCmd.Flags().StringVarP(&distPath, "distPath", "x", "dist", "Dist Path for the Terraform registry.") publishCmd.Flags().StringVarP(&repoName, "repoName", "r", "", "RepoName for the Terraform registry.") publishCmd.Flags().StringVarP(&version, "version", "v", "", "Version for the Terraform registry.") - publishCmd.Flags().StringVarP(&gpgFingerprint, "gpgFingerprint", "f", "", "GPG Fingerprint for the Terraform registry.") - publishCmd.Flags().StringVarP(&gpgPubKeyFile, "gpgPubKeyFile", "k", "", "GPG PubKey file name for the Terraform registry.") + publishCmd.Flags().StringVarP( + &gpgFingerprint, + "gpgFingerprint", + "f", + "", + "GPG Fingerprint for the Terraform registry.", + ) + publishCmd.Flags().StringVarP( + &gpgPubKeyFile, + "gpgPubKeyFile", + "k", + "", + "GPG PubKey file name for the Terraform registry.", + ) err := publishCmd.MarkFlagRequired("namespace") if err != nil { @@ -105,6 +117,7 @@ func publish() error { // Create release dir - only the contents of this need to be uploaded to S3 log.Printf("* Creating release directory") + //nolint:gosec // this directory is not sensitive, so we can use 0750 err = os.MkdirAll(path.Join(p.RootPath, "release"), os.ModePerm) if err != nil && !errors.Is(err, fs.ErrExist) { return fmt.Errorf("error creating '%s' dir: %w", path.Join(p.RootPath, "release"), err) diff --git a/examples/resources/stackitprivatepreview_postgresflexalpha_instance/resource.tf b/examples/resources/stackitprivatepreview_postgresflexalpha_instance/resource.tf index 711a9f60..b503f0ce 100644 --- a/examples/resources/stackitprivatepreview_postgresflexalpha_instance/resource.tf +++ b/examples/resources/stackitprivatepreview_postgresflexalpha_instance/resource.tf @@ -17,7 +17,7 @@ resource "stackitprivatepreview_postgresflexalpha_instance" "example-instance" { service_account = "service@account.email" } network = { - acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"] + acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"] access_scope = "PUBLIC" } version = 17 diff --git a/examples/resources/stackitprivatepreview_postgresflexalpha_user/resource.tf b/examples/resources/stackitprivatepreview_postgresflexalpha_user/resource.tf index 756e854d..695741c4 100644 --- a/examples/resources/stackitprivatepreview_postgresflexalpha_user/resource.tf +++ b/examples/resources/stackitprivatepreview_postgresflexalpha_user/resource.tf @@ -1,7 +1,7 @@ resource "stackitprivatepreview_postgresflexalpha_user" "example" { project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - name = "username" + name = "username" roles = ["role"] } diff --git a/internal/testutils/activateMocks.go b/internal/testutils/activateMocks.go index ddeaff83..c8f7dd05 100644 --- a/internal/testutils/activateMocks.go +++ b/internal/testutils/activateMocks.go @@ -20,13 +20,20 @@ func TestName() string { } func ActivateEnvironmentHttpMocks() { - httpmock.RegisterNoResponder(func(req *http.Request) (*http.Response, error) { - return nil, fmt.Errorf("no responder found for %s %s, please check your http mocks", req.Method, req.URL) - }) - - httpmock.RegisterRegexpResponder("GET", regexp.MustCompile(`^https://api\.bap\.microsoft\.com/providers/Microsoft\.BusinessAppPlatform/locations/(europe|unitedstates)/environmentLanguages\?api-version=2023-06-01$`), + httpmock.RegisterNoResponder( func(req *http.Request) (*http.Response, error) { - return httpmock.NewStringResponse(http.StatusOK, httpmock.File("../../services/languages/tests/datasource/Validate_Read/get_languages.json").String()), nil - }) + return nil, fmt.Errorf("no responder found for %s %s, please check your http mocks", req.Method, req.URL) + }, + ) + httpmock.RegisterRegexpResponder( + "GET", + regexp.MustCompile(`^https://api\.bap\.microsoft\.com/providers/Microsoft\.BusinessAppPlatform/locations/(europe|unitedstates)/environmentLanguages\?api-version=2023-06-01$`), + func(_ *http.Request) (*http.Response, error) { + return httpmock.NewStringResponse( + http.StatusOK, + httpmock.File("../../services/languages/tests/datasource/Validate_Read/get_languages.json").String(), + ), nil + }, + ) } diff --git a/scripts/lint-golangci-lint.sh b/scripts/lint-golangci-lint.sh deleted file mode 100755 index 0a883589..00000000 --- a/scripts/lint-golangci-lint.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -# This script lints the SDK modules and the internal examples -# Pre-requisites: golangci-lint -set -eo pipefail - -ROOT_DIR=$(git rev-parse --show-toplevel) -GOLANG_CI_YAML_PATH="${ROOT_DIR}/golang-ci.yaml" -GOLANG_CI_ARGS="--allow-parallel-runners --timeout=5m --config=${GOLANG_CI_YAML_PATH}" - -if type -p golangci-lint >/dev/null; then - : -else - echo "golangci-lint not installed, unable to proceed." - exit 1 -fi - -cd ${ROOT_DIR} -golangci-lint run ${GOLANG_CI_ARGS} diff --git a/stackit/internal/core/core.go b/stackit/internal/core/core.go index d3ea252c..3680ae65 100644 --- a/stackit/internal/core/core.go +++ b/stackit/internal/core/core.go @@ -32,7 +32,7 @@ const ( type EphemeralProviderData struct { ProviderData - PrivateKey string + PrivateKey string //nolint:gosec //this is a placeholder and not used in this code PrivateKeyPath string ServiceAccountKey string ServiceAccountKeyPath string @@ -105,11 +105,13 @@ func DiagsToError(diags diag.Diagnostics) error { diagsError := diags.Errors() diagsStrings := make([]string, 0) for _, diagnostic := range diagsError { - diagsStrings = append(diagsStrings, fmt.Sprintf( - "(%s) %s", - diagnostic.Summary(), - diagnostic.Detail(), - )) + diagsStrings = append( + diagsStrings, fmt.Sprintf( + "(%s) %s", + diagnostic.Summary(), + diagnostic.Detail(), + ), + ) } return fmt.Errorf("%s", strings.Join(diagsStrings, ";")) } @@ -136,14 +138,22 @@ func LogAndAddWarning(ctx context.Context, diags *diag.Diagnostics, summary, det func LogAndAddWarningBeta(ctx context.Context, diags *diag.Diagnostics, name string, resourceType ResourceType) { warnTitle := fmt.Sprintf("The %s %q is in beta", resourceType, name) - warnContent := fmt.Sprintf("The %s %q is in beta and may be subject to breaking changes in the future. Use with caution.", resourceType, name) + warnContent := fmt.Sprintf( + "The %s %q is in beta and may be subject to breaking changes in the future. Use with caution.", + resourceType, + name, + ) tflog.Warn(ctx, fmt.Sprintf("%s | %s", warnTitle, warnContent)) diags.AddWarning(warnTitle, warnContent) } func LogAndAddErrorBeta(ctx context.Context, diags *diag.Diagnostics, name string, resourceType ResourceType) { errTitle := fmt.Sprintf("The %s %q is in beta and beta is not enabled", resourceType, name) - errContent := fmt.Sprintf(`The %s %q is in beta and the beta functionality is currently not enabled. To enable it, set the environment variable STACKIT_TF_ENABLE_BETA_RESOURCES to "true" or set the "enable_beta_resources" provider field to true.`, resourceType, name) + errContent := fmt.Sprintf( + `The %s %q is in beta and the beta functionality is currently not enabled. To enable it, set the environment variable STACKIT_TF_ENABLE_BETA_RESOURCES to "true" or set the "enable_beta_resources" provider field to true.`, + resourceType, + name, + ) tflog.Error(ctx, fmt.Sprintf("%s | %s", errTitle, errContent)) diags.AddError(errTitle, errContent) } @@ -161,8 +171,10 @@ func LogResponse(ctx context.Context) context.Context { traceId := runtime.GetTraceId(ctx) ctx = tflog.SetField(ctx, "x-trace-id", traceId) - tflog.Info(ctx, "response data", map[string]interface{}{ - "x-trace-id": traceId, - }) + tflog.Info( + ctx, "response data", map[string]interface{}{ + "x-trace-id": traceId, + }, + ) return ctx } diff --git a/stackit/internal/core/retry_round_tripper.go b/stackit/internal/core/retry_round_tripper.go index 945a3061..568be431 100644 --- a/stackit/internal/core/retry_round_tripper.go +++ b/stackit/internal/core/retry_round_tripper.go @@ -98,7 +98,7 @@ func (rrt *RetryRoundTripper) retryLoop( waitDuration := rrt.calculateWaitDurationWithJitter(ctx, currentDelay) if err := rrt.waitForDelay(ctx, waitDuration); err != nil { - return nil, err // Context was cancelled during wait. + return nil, err // Context was canceled during wait. } // Exponential backoff for the next potential retry. @@ -153,7 +153,6 @@ func (rrt *RetryRoundTripper) handleFinalError( ) error { if resp != nil { if err := resp.Body.Close(); err != nil { - tflog.Warn( ctx, "Failed to close response body", map[string]interface{}{ "error": err.Error(), @@ -194,7 +193,6 @@ func (rrt *RetryRoundTripper) shouldRetry(resp *http.Response, err error) bool { } return false - } // calculateWaitDurationWithJitter calculates the backoff duration for the next retry, @@ -232,7 +230,7 @@ func (rrt *RetryRoundTripper) calculateWaitDurationWithJitter( func (rrt *RetryRoundTripper) waitForDelay(ctx context.Context, delay time.Duration) error { select { case <-ctx.Done(): - return fmt.Errorf("context cancelled during backoff wait: %w", ctx.Err()) + return fmt.Errorf("context canceled during backoff wait: %w", ctx.Err()) case <-time.After(delay): return nil } diff --git a/stackit/internal/core/retry_round_tripper_test.go b/stackit/internal/core/retry_round_tripper_test.go index e19c553c..ac84db8b 100644 --- a/stackit/internal/core/retry_round_tripper_test.go +++ b/stackit/internal/core/retry_round_tripper_test.go @@ -72,7 +72,7 @@ func TestRetryRoundTripper_RoundTrip(t *testing.T) { }, } tripper := testRetryConfig(mock) - req := httptest.NewRequest(http.MethodGet, "/", nil) + req := httptest.NewRequest(http.MethodGet, "/", http.NoBody) resp, err := tripper.RoundTrip(req) if resp != nil { @@ -110,7 +110,7 @@ func TestRetryRoundTripper_RoundTrip(t *testing.T) { }, } tripper := testRetryConfig(mock) - req := httptest.NewRequest(http.MethodGet, "/", nil) + req := httptest.NewRequest(http.MethodGet, "/", http.NoBody) resp, err := tripper.RoundTrip(req) if resp != nil { @@ -155,7 +155,7 @@ func TestRetryRoundTripper_RoundTrip(t *testing.T) { }, nil } tripper := testRetryConfig(mock) - req := httptest.NewRequest(http.MethodGet, "/", nil) + req := httptest.NewRequest(http.MethodGet, "/", http.NoBody) resp, err := tripper.RoundTrip(req) if resp != nil { @@ -185,12 +185,12 @@ func TestRetryRoundTripper_RoundTrip(t *testing.T) { mockErr := errors.New("simulated network error") mock := &mockRoundTripper{ - roundTripFunc: func(req *http.Request) (*http.Response, error) { + roundTripFunc: func(_ *http.Request) (*http.Response, error) { return nil, mockErr }, } tripper := testRetryConfig(mock) - req := httptest.NewRequest(http.MethodGet, "/", nil) + req := httptest.NewRequest(http.MethodGet, "/", http.NoBody) resp, err := tripper.RoundTrip(req) if resp != nil { @@ -211,7 +211,7 @@ func TestRetryRoundTripper_RoundTrip(t *testing.T) { ) t.Run( - "should abort retries if the main context is cancelled", func(t *testing.T) { + "should abort retries if the main context is canceled", func(t *testing.T) { t.Parallel() mock := &mockRoundTripper{ @@ -230,7 +230,7 @@ func TestRetryRoundTripper_RoundTrip(t *testing.T) { ctx, cancel := context.WithTimeout(baseCtx, 20*time.Millisecond) defer cancel() - req := httptest.NewRequest(http.MethodGet, "/", nil).WithContext(ctx) + req := httptest.NewRequest(http.MethodGet, "/", http.NoBody).WithContext(ctx) resp, err := tripper.RoundTrip(req) if resp != nil { diff --git a/stackit/internal/services/postgresflexalpha/instance/resource.go b/stackit/internal/services/postgresflexalpha/instance/resource.go index 74661cd9..d4049fb5 100644 --- a/stackit/internal/services/postgresflexalpha/instance/resource.go +++ b/stackit/internal/services/postgresflexalpha/instance/resource.go @@ -328,10 +328,6 @@ func (r *instanceResource) Read( ctx = core.InitProviderContext(ctx) - // projectId := model.ProjectId.ValueString() - // region := r.providerData.GetRegionWithOverride(model.Region) - // instanceId := model.InstanceId.ValueString() - var projectId string if !model.ProjectId.IsNull() && !model.ProjectId.IsUnknown() { projectId = model.ProjectId.ValueString() @@ -435,18 +431,6 @@ func (r *instanceResource) Update( return } - // if model.InstanceId.IsNull() || model.InstanceId.IsUnknown() { - // core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating instance", "instanceId is null or unknown") - // return - //} - // - // if model.ProjectId.IsNull() || model.ProjectId.IsUnknown() { - // core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating instance", "projectId is null or unknown") - // return - //} - - // projectId := model.ProjectId.ValueString() - // instanceId := model.InstanceId.ValueString() projectId := identityData.ProjectID.ValueString() instanceId := identityData.InstanceID.ValueString() region := model.Region.ValueString() diff --git a/stackit/internal/services/postgresflexalpha/postgresflex_acc_test.go b/stackit/internal/services/postgresflexalpha/postgresflex_acc_test.go index 7e71a32f..d5ffd00c 100644 --- a/stackit/internal/services/postgresflexalpha/postgresflex_acc_test.go +++ b/stackit/internal/services/postgresflexalpha/postgresflex_acc_test.go @@ -30,39 +30,46 @@ var testInstances []string func init() { sweeperName := fmt.Sprintf("%s_%s", pfx, "sweeper") - resource.AddTestSweepers(sweeperName, &resource.Sweeper{ - Name: sweeperName, - F: func(region string) error { - ctx := context.Background() - apiClientConfigOptions := []config.ConfigurationOption{} - apiClient, err := postgresflexalpha2.NewAPIClient(apiClientConfigOptions...) - if err != nil { - log.Fatalln(err) - } + resource.AddTestSweepers( + sweeperName, &resource.Sweeper{ + Name: sweeperName, + F: func(_ string) error { // region is passed by the testing framework + ctx := context.Background() + apiClientConfigOptions := []config.ConfigurationOption{} + apiClient, err := postgresflexalpha2.NewAPIClient(apiClientConfigOptions...) + if err != nil { + log.Fatalln(err) + } - instances, err := apiClient.ListInstancesRequest(ctx, testutils.ProjectId, testutils.Region). - Size(100). - Execute() - if err != nil { - log.Fatalln(err) - } + instances, err := apiClient.ListInstancesRequest(ctx, testutils.ProjectId, testutils.Region). + Size(100). + Execute() + if err != nil { + log.Fatalln(err) + } - for _, inst := range instances.GetInstances() { - if strings.HasPrefix(inst.GetName(), "tf-acc-") { - for _, item := range testInstances { - if inst.GetName() == item { - delErr := apiClient.DeleteInstanceRequestExecute(ctx, testutils.ProjectId, testutils.Region, inst.GetId()) - if delErr != nil { - // TODO: maybe just warn? - log.Fatalln(delErr) + for _, inst := range instances.GetInstances() { + if strings.HasPrefix(inst.GetName(), "tf-acc-") { + for _, item := range testInstances { + if inst.GetName() == item { + delErr := apiClient.DeleteInstanceRequestExecute( + ctx, + testutils.ProjectId, + testutils.Region, + inst.GetId(), + ) + if delErr != nil { + // TODO: maybe just warn? + log.Fatalln(delErr) + } } } } } - } - return nil + return nil + }, }, - }) + ) } func TestInstanceResourceSchema(t *testing.T) { @@ -195,57 +202,67 @@ func TestAccInstance(t *testing.T) { updSizeData := exData updSizeData.Size = 25 - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - t.Logf(" ... working on instance %s", exData.TfName) - testInstances = append(testInstances, exData.TfName) - }, - ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, - Steps: []resource.TestStep{ - // Create and verify - { - Config: testutils.StringFromTemplateMust( - "testdata/instance_template.gompl", - exData, - ), - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr(testutils.ResStr(pfx, "instance", exData.TfName), "name", exData.Name), - resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "instance", exData.TfName), "id"), - ), + resource.ParallelTest( + t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + t.Logf(" ... working on instance %s", exData.TfName) + testInstances = append(testInstances, exData.TfName) }, - // Update name and verify - { - Config: testutils.StringFromTemplateMust( - "testdata/instance_template.gompl", - updNameData, - ), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(testutils.ResStr(pfx, "instance", exData.TfName), "name", updNameData.Name), - ), - }, - // Update size and verify - { - Config: testutils.StringFromTemplateMust( - "testdata/instance_template.gompl", - updSizeData, - ), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr( - testutils.ResStr(pfx, "instance", exData.TfName), - "storage.size", - strconv.Itoa(int(updSizeData.Size)), + ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create and verify + { + Config: testutils.StringFromTemplateMust( + "testdata/instance_template.gompl", + exData, ), - ), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr( + testutils.ResStr(pfx, "instance", exData.TfName), + "name", + exData.Name, + ), + resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "instance", exData.TfName), "id"), + ), + }, + // Update name and verify + { + Config: testutils.StringFromTemplateMust( + "testdata/instance_template.gompl", + updNameData, + ), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr( + testutils.ResStr(pfx, "instance", exData.TfName), + "name", + updNameData.Name, + ), + ), + }, + // Update size and verify + { + Config: testutils.StringFromTemplateMust( + "testdata/instance_template.gompl", + updSizeData, + ), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr( + testutils.ResStr(pfx, "instance", exData.TfName), + "storage.size", + strconv.Itoa(int(updSizeData.Size)), + ), + ), + }, + //// Import test + //{ + // ResourceName: "example_resource.test", + // ImportState: true, + // ImportStateVerify: true, + // }, }, - //// Import test - //{ - // ResourceName: "example_resource.test", - // ImportState: true, - // ImportStateVerify: true, - // }, }, - }) + ) } func TestAccInstanceWithUsers(t *testing.T) { @@ -260,29 +277,35 @@ func TestAccInstanceWithUsers(t *testing.T) { }, } - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - t.Logf(" ... working on instance %s", data.TfName) - testInstances = append(testInstances, data.TfName) - }, - ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, - Steps: []resource.TestStep{ - // Create and verify - { - Config: testutils.StringFromTemplateMust( - "testdata/instance_template.gompl", - data, - ), - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr(testutils.ResStr(pfx, "instance", data.TfName), "name", data.Name), - resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "instance", data.TfName), "id"), - resource.TestCheckResourceAttr(testutils.ResStr(pfx, "user", userName), "name", userName), - resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "user", userName), "id"), - ), + resource.ParallelTest( + t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + t.Logf(" ... working on instance %s", data.TfName) + testInstances = append(testInstances, data.TfName) + }, + ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create and verify + { + Config: testutils.StringFromTemplateMust( + "testdata/instance_template.gompl", + data, + ), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr( + testutils.ResStr(pfx, "instance", data.TfName), + "name", + data.Name, + ), + resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "instance", data.TfName), "id"), + resource.TestCheckResourceAttr(testutils.ResStr(pfx, "user", userName), "name", userName), + resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "user", userName), "id"), + ), + }, }, }, - }) + ) } func TestAccInstanceWithDatabases(t *testing.T) { @@ -306,32 +329,38 @@ func TestAccInstanceWithDatabases(t *testing.T) { }, } - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - t.Logf(" ... working on instance %s", data.TfName) - testInstances = append(testInstances, data.TfName) - }, - ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, - Steps: []resource.TestStep{ - // Create and verify - { - Config: testutils.StringFromTemplateMust( - "testdata/instance_template.gompl", - data, - ), - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr(testutils.ResStr(pfx, "instance", data.TfName), "name", data.Name), - resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "instance", data.TfName), "id"), - resource.TestCheckResourceAttr(testutils.ResStr(pfx, "user", userName), "name", userName), - resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "user", userName), "id"), - resource.TestCheckResourceAttr(testutils.ResStr(pfx, "database", dbName), "name", dbName), - resource.TestCheckResourceAttr(testutils.ResStr(pfx, "database", dbName), "owner", userName), - resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "database", dbName), "id"), - ), + resource.ParallelTest( + t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + t.Logf(" ... working on instance %s", data.TfName) + testInstances = append(testInstances, data.TfName) + }, + ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create and verify + { + Config: testutils.StringFromTemplateMust( + "testdata/instance_template.gompl", + data, + ), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr( + testutils.ResStr(pfx, "instance", data.TfName), + "name", + data.Name, + ), + resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "instance", data.TfName), "id"), + resource.TestCheckResourceAttr(testutils.ResStr(pfx, "user", userName), "name", userName), + resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "user", userName), "id"), + resource.TestCheckResourceAttr(testutils.ResStr(pfx, "database", dbName), "name", dbName), + resource.TestCheckResourceAttr(testutils.ResStr(pfx, "database", dbName), "owner", userName), + resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "database", dbName), "id"), + ), + }, }, }, - }) + ) } // func setupMockServer() *httptest.Server { @@ -461,7 +490,7 @@ func TestAccInstanceWithDatabases(t *testing.T) { // "project_id": testutils.ProjectId, //} // -//func configResources(backupSchedule string, _ *string) string { +// func configResources(backupSchedule string, _ *string) string { // return fmt.Sprintf( // ` // %s @@ -535,7 +564,7 @@ func TestAccInstanceWithDatabases(t *testing.T) { // ) //} // -//func TestAccPostgresFlexFlexResource(t *testing.T) { +// func TestAccPostgresFlexFlexResource(t *testing.T) { // resource.ParallelTest( // t, resource.TestCase{ // ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, @@ -954,7 +983,7 @@ func TestAccInstanceWithDatabases(t *testing.T) { // ) //} // -//func testAccCheckPostgresFlexDestroy(s *terraform.State) error { +// func testAccCheckPostgresFlexDestroy(s *terraform.State) error { // ctx := context.Background() // var client *postgresflex.APIClient // var err error diff --git a/stackit/internal/services/postgresflexalpha/user/resource.go b/stackit/internal/services/postgresflexalpha/user/resource.go index cf9fd389..ab7ec563 100644 --- a/stackit/internal/services/postgresflexalpha/user/resource.go +++ b/stackit/internal/services/postgresflexalpha/user/resource.go @@ -252,7 +252,6 @@ func (r *userResource) Create( model.UserId = types.Int64Value(id) model.Password = types.StringValue(userResp.GetPassword()) model.Status = types.StringValue(userResp.GetStatus()) - //model.ConnectionString = types.StringValue(userResp.GetConnectionString()) waitResp, err := postgresflexalphaWait.GetUserByIdWaitHandler( ctx, diff --git a/stackit/internal/services/sqlserverflexalpha/database/datasource.go b/stackit/internal/services/sqlserverflexalpha/database/datasource.go index 3c40d6b0..5155b41c 100644 --- a/stackit/internal/services/sqlserverflexalpha/database/datasource.go +++ b/stackit/internal/services/sqlserverflexalpha/database/datasource.go @@ -143,7 +143,6 @@ func (d *databaseDataSource) Read(ctx context.Context, req datasource.ReadReques resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) tflog.Info(ctx, "SQL Server Flex beta database read") - } // handleReadError centralizes API error handling for the Read operation. diff --git a/stackit/internal/services/sqlserverflexalpha/database/resource.go b/stackit/internal/services/sqlserverflexalpha/database/resource.go index 72e8105f..5b46c52c 100644 --- a/stackit/internal/services/sqlserverflexalpha/database/resource.go +++ b/stackit/internal/services/sqlserverflexalpha/database/resource.go @@ -36,10 +36,6 @@ var ( // Define errors errDatabaseNotFound = errors.New("database not found") - - // Error message constants - extractErrorSummary = "extracting failed" - extractErrorMessage = "Extracting identity data: %v" ) func NewDatabaseResource() resource.Resource { @@ -186,26 +182,6 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques payLoad.Name = data.Name.ValueStringPointer() payLoad.Owner = data.Owner.ValueStringPointer() - //_, err := wait.WaitForUserWaitHandler( - // ctx, - // r.client, - // projectId, - // instanceId, - // region, - // data.Owner.ValueString(), - //). - // SetSleepBeforeWait(10 * time.Second). - // WaitWithContext(ctx) - //if err != nil { - // core.LogAndAddError( - // ctx, - // &resp.Diagnostics, - // createErr, - // fmt.Sprintf("Calling API: %v", err), - // ) - // return - //} - createResp, err := r.client.CreateDatabaseRequest(ctx, projectId, region, instanceId). CreateDatabaseRequestPayload(payLoad). Execute() @@ -451,7 +427,9 @@ func (r *databaseResource) Delete(ctx context.Context, req resource.DeleteReques &resp.Diagnostics, "Error deleting database", fmt.Sprintf( - "Calling API: %v\nname: %s, region: %s, instanceId: %s", err, databaseName, region, instanceId)) + "Calling API: %v\nname: %s, region: %s, instanceId: %s", err, databaseName, region, instanceId, + ), + ) return } @@ -468,7 +446,6 @@ func (r *databaseResource) ModifyPlan( req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse, ) { // nolint:gocritic // function signature required by Terraform - // skip initial empty configuration to avoid follow-up errors if req.Config.Raw.IsNull() { return diff --git a/stackit/internal/services/sqlserverflexalpha/instance/functions.go b/stackit/internal/services/sqlserverflexalpha/instance/functions.go index 793b7e23..a8567903 100644 --- a/stackit/internal/services/sqlserverflexalpha/instance/functions.go +++ b/stackit/internal/services/sqlserverflexalpha/instance/functions.go @@ -247,7 +247,6 @@ func toCreatePayload( conversion.StringValueToPointer(model.Version), ), }, nil - } func toUpdatePayload( diff --git a/stackit/internal/services/sqlserverflexalpha/instance/resource.go b/stackit/internal/services/sqlserverflexalpha/instance/resource.go index 6adf07df..3b1f4fd3 100644 --- a/stackit/internal/services/sqlserverflexalpha/instance/resource.go +++ b/stackit/internal/services/sqlserverflexalpha/instance/resource.go @@ -54,7 +54,7 @@ type InstanceResourceIdentityModel struct { } func (r *instanceResource) Metadata( - ctx context.Context, + _ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse, ) { @@ -64,7 +64,7 @@ func (r *instanceResource) Metadata( //go:embed planModifiers.yaml var modifiersFileByte []byte -func (r *instanceResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { +func (r *instanceResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { s := sqlserverflexalphaResGen.InstanceResourceSchema(ctx) fields, err := utils.ReadModifiersConfig(modifiersFileByte) @@ -147,7 +147,6 @@ func (r *instanceResource) ModifyPlan( req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse, ) { // nolint:gocritic // function signature required by Terraform - // skip initial empty configuration to avoid follow-up errors if req.Config.Raw.IsNull() { return diff --git a/stackit/internal/services/sqlserverflexalpha/sqlserverflex_acc_test.go b/stackit/internal/services/sqlserverflexalpha/sqlserverflex_acc_test.go index 8658f0ce..9eebac99 100644 --- a/stackit/internal/services/sqlserverflexalpha/sqlserverflex_acc_test.go +++ b/stackit/internal/services/sqlserverflexalpha/sqlserverflex_acc_test.go @@ -288,8 +288,8 @@ func TestAccInstanceNoEncryption(t *testing.T) { // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_id"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_version"), - //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"), - //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"), + // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"), + // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.access_scope"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.acl"), @@ -389,8 +389,8 @@ func TestAccInstanceEncryption(t *testing.T) { // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_id"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_version"), - //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"), - //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"), + // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"), + // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.access_scope"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.acl"), diff --git a/stackit/internal/services/sqlserverflexalpha/user/datasource.go b/stackit/internal/services/sqlserverflexalpha/user/datasource.go index 64efb4a3..e191e5a7 100644 --- a/stackit/internal/services/sqlserverflexalpha/user/datasource.go +++ b/stackit/internal/services/sqlserverflexalpha/user/datasource.go @@ -20,8 +20,6 @@ import ( var _ datasource.DataSource = (*userDataSource)(nil) -const errorPrefix = "[sqlserverflexalpha - User]" - func NewUserDataSource() datasource.DataSource { return &userDataSource{} } diff --git a/stackit/internal/services/sqlserverflexalpha/user/resource.go b/stackit/internal/services/sqlserverflexalpha/user/resource.go index 8a0c1df7..ee322fab 100644 --- a/stackit/internal/services/sqlserverflexalpha/user/resource.go +++ b/stackit/internal/services/sqlserverflexalpha/user/resource.go @@ -20,7 +20,6 @@ import ( "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion" - sqlserverflexalphagen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/user/resources_gen" sqlserverflexalphaUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/utils" sqlserverflexalphaWait "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/wait/sqlserverflexalpha" @@ -59,7 +58,7 @@ type userResource struct { providerData core.ProviderData } -func (r *userResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { +func (r *userResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_user" } @@ -118,7 +117,7 @@ var modifiersFileByte []byte // Schema defines the schema for the resource. func (r *userResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { - s := sqlserverflexalphagen.UserResourceSchema(ctx) + s := sqlserverflexalphaResGen.UserResourceSchema(ctx) fields, err := utils.ReadModifiersConfig(modifiersFileByte) if err != nil { @@ -470,7 +469,6 @@ func (r *userResource) Delete( // Delete existing record set _, err = sqlserverflexalphaWait.DeleteUserWaitHandler(ctx, r.client, projectId, region, instanceId, userId). WaitWithContext(ctx) - // err := r.client.DeleteUserRequest(ctx, arg.projectId, arg.region, arg.instanceId, userId).Execute() if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "User Delete Error", fmt.Sprintf("Calling API: %v", err)) return diff --git a/stackit/internal/services/sqlserverflexbeta/database/datasource.go b/stackit/internal/services/sqlserverflexbeta/database/datasource.go index 401df291..c6fa31bf 100644 --- a/stackit/internal/services/sqlserverflexbeta/database/datasource.go +++ b/stackit/internal/services/sqlserverflexbeta/database/datasource.go @@ -143,7 +143,6 @@ func (d *databaseDataSource) Read(ctx context.Context, req datasource.ReadReques resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) tflog.Info(ctx, "SQL Server Flex beta database read") - } // handleReadError centralizes API error handling for the Read operation. diff --git a/stackit/internal/services/sqlserverflexbeta/database/resource.go b/stackit/internal/services/sqlserverflexbeta/database/resource.go index 99713dcf..9862ca57 100644 --- a/stackit/internal/services/sqlserverflexbeta/database/resource.go +++ b/stackit/internal/services/sqlserverflexbeta/database/resource.go @@ -36,10 +36,6 @@ var ( // Define errors errDatabaseNotFound = errors.New("database not found") - - // Error message constants - extractErrorSummary = "extracting failed" - extractErrorMessage = "Extracting identity data: %v" ) func NewDatabaseResource() resource.Resource { @@ -430,7 +426,9 @@ func (r *databaseResource) Delete(ctx context.Context, req resource.DeleteReques &resp.Diagnostics, "Error deleting database", fmt.Sprintf( - "Calling API: %v\nname: %s, region: %s, instanceId: %s", err, databaseName, region, instanceId)) + "Calling API: %v\nname: %s, region: %s, instanceId: %s", err, databaseName, region, instanceId, + ), + ) return } @@ -449,7 +447,6 @@ func (r *databaseResource) ModifyPlan( req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse, ) { // nolint:gocritic // function signature required by Terraform - // skip initial empty configuration to avoid follow-up errors if req.Config.Raw.IsNull() { return @@ -559,45 +556,4 @@ func (r *databaseResource) ImportState( tflog.Info(ctx, "Sqlserverflexbeta database state imported") } -// extractIdentityData extracts essential identifiers from the resource model, falling back to the identity model. -func (r *databaseResource) extractIdentityData( - model resourceModel, - identity DatabaseResourceIdentityModel, -) (projectId, region, instanceId, databaseName string, err error) { - if !model.Name.IsNull() && !model.Name.IsUnknown() { - databaseName = model.Name.ValueString() - } else { - if identity.DatabaseName.IsNull() || identity.DatabaseName.IsUnknown() { - return "", "", "", "", fmt.Errorf("database_name not found in config") - } - databaseName = identity.DatabaseName.ValueString() - } - - if !model.ProjectId.IsNull() && !model.ProjectId.IsUnknown() { - projectId = model.ProjectId.ValueString() - } else { - if identity.ProjectID.IsNull() || identity.ProjectID.IsUnknown() { - return "", "", "", "", fmt.Errorf("project_id not found in config") - } - projectId = identity.ProjectID.ValueString() - } - - if !model.Region.IsNull() && !model.Region.IsUnknown() { - region = r.providerData.GetRegionWithOverride(model.Region) - } else { - if identity.Region.IsNull() || identity.Region.IsUnknown() { - return "", "", "", "", fmt.Errorf("region not found in config") - } - region = r.providerData.GetRegionWithOverride(identity.Region) - } - - if !model.InstanceId.IsNull() && !model.InstanceId.IsUnknown() { - instanceId = model.InstanceId.ValueString() - } else { - if identity.InstanceID.IsNull() || identity.InstanceID.IsUnknown() { - return "", "", "", "", fmt.Errorf("instance_id not found in config") - } - instanceId = identity.InstanceID.ValueString() - } - return projectId, region, instanceId, databaseName, nil -} +// extractIdentityData extracts essential identifiers from the resource model, falling back to the identity mode diff --git a/stackit/internal/services/sqlserverflexbeta/instance/functions.go b/stackit/internal/services/sqlserverflexbeta/instance/functions.go index cd18314a..77791ee6 100644 --- a/stackit/internal/services/sqlserverflexbeta/instance/functions.go +++ b/stackit/internal/services/sqlserverflexbeta/instance/functions.go @@ -236,7 +236,6 @@ func toCreatePayload( conversion.StringValueToPointer(model.Version), ), }, nil - } func toUpdatePayload( diff --git a/stackit/internal/services/sqlserverflexbeta/instance/functions_test.go b/stackit/internal/services/sqlserverflexbeta/instance/functions_test.go index bf36c40e..0c6f6147 100644 --- a/stackit/internal/services/sqlserverflexbeta/instance/functions_test.go +++ b/stackit/internal/services/sqlserverflexbeta/instance/functions_test.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/stackitcloud/stackit-sdk-go/core/utils" + sqlserverflexbetaPkgGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexbeta" sqlserverflexbetaRs "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/instance/resources_gen" ) @@ -28,11 +29,13 @@ func Test_handleDSEncryption(t *testing.T) { // TODO: Add test cases. } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := handleDSEncryption(tt.args.m, tt.args.resp); !reflect.DeepEqual(got, tt.want) { - t.Errorf("handleDSEncryption() = %v, want %v", got, tt.want) - } - }) + t.Run( + tt.name, func(t *testing.T) { + if got := handleDSEncryption(t.Context(), tt.args.m, tt.args.resp); !reflect.DeepEqual(got, tt.want) { + t.Errorf("handleDSEncryption() = %v, want %v", got, tt.want) + } + }, + ) } } @@ -86,11 +89,13 @@ func Test_handleEncryption(t *testing.T) { }, } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := handleEncryption(tt.args.m, tt.args.resp); !reflect.DeepEqual(got, tt.want) { - t.Errorf("handleEncryption() = %v, want %v", got, tt.want) - } - }) + t.Run( + tt.name, func(t *testing.T) { + if got := handleEncryption(t.Context(), tt.args.m, tt.args.resp); !reflect.DeepEqual(got, tt.want) { + t.Errorf("handleEncryption() = %v, want %v", got, tt.want) + } + }, + ) } } @@ -109,11 +114,18 @@ func Test_mapDataResponseToModel(t *testing.T) { // TODO: Add test cases. } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if err := mapDataResponseToModel(tt.args.ctx, tt.args.resp, tt.args.m, tt.args.tfDiags); (err != nil) != tt.wantErr { - t.Errorf("mapDataResponseToModel() error = %v, wantErr %v", err, tt.wantErr) - } - }) + t.Run( + tt.name, func(t *testing.T) { + if err := mapDataResponseToModel( + tt.args.ctx, + tt.args.resp, + tt.args.m, + tt.args.tfDiags, + ); (err != nil) != tt.wantErr { + t.Errorf("mapDataResponseToModel() error = %v, wantErr %v", err, tt.wantErr) + } + }, + ) } } @@ -132,11 +144,18 @@ func Test_mapResponseToModel(t *testing.T) { // TODO: Add test cases. } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if err := mapResponseToModel(tt.args.ctx, tt.args.resp, tt.args.m, tt.args.tfDiags); (err != nil) != tt.wantErr { - t.Errorf("mapResponseToModel() error = %v, wantErr %v", err, tt.wantErr) - } - }) + t.Run( + tt.name, func(t *testing.T) { + if err := mapResponseToModel( + tt.args.ctx, + tt.args.resp, + tt.args.m, + tt.args.tfDiags, + ); (err != nil) != tt.wantErr { + t.Errorf("mapResponseToModel() error = %v, wantErr %v", err, tt.wantErr) + } + }, + ) } } @@ -208,19 +227,18 @@ func Test_toCreatePayload(t *testing.T) { }, } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := toCreatePayload(tt.args.ctx, tt.args.model) - if (err != nil) != tt.wantErr { - t.Errorf("toCreatePayload() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got); diff != "" { - t.Errorf("model mismatch (-want +got):\n%s", diff) - } - //if !reflect.DeepEqual(got, tt.want) { - // t.Errorf("toCreatePayload() got = %v, want %v", got, tt.want) - //} - }) + t.Run( + tt.name, func(t *testing.T) { + got, err := toCreatePayload(tt.args.ctx, tt.args.model) + if (err != nil) != tt.wantErr { + t.Errorf("toCreatePayload() error = %v, wantErr %v", err, tt.wantErr) + return + } + if diff := cmp.Diff(tt.want, got); diff != "" { + t.Errorf("model mismatch (-want +got):\n%s", diff) + } + }, + ) } } @@ -239,15 +257,17 @@ func Test_toUpdatePayload(t *testing.T) { // TODO: Add test cases. } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := toUpdatePayload(tt.args.ctx, tt.args.m, tt.args.resp) - if (err != nil) != tt.wantErr { - t.Errorf("toUpdatePayload() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("toUpdatePayload() got = %v, want %v", got, tt.want) - } - }) + t.Run( + tt.name, func(t *testing.T) { + got, err := toUpdatePayload(tt.args.ctx, tt.args.m, tt.args.resp) + if (err != nil) != tt.wantErr { + t.Errorf("toUpdatePayload() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("toUpdatePayload() got = %v, want %v", got, tt.want) + } + }, + ) } } diff --git a/stackit/internal/services/sqlserverflexbeta/instance/resource.go b/stackit/internal/services/sqlserverflexbeta/instance/resource.go index a91040bf..044b4b43 100644 --- a/stackit/internal/services/sqlserverflexbeta/instance/resource.go +++ b/stackit/internal/services/sqlserverflexbeta/instance/resource.go @@ -54,7 +54,7 @@ type InstanceResourceIdentityModel struct { } func (r *instanceResource) Metadata( - ctx context.Context, + _ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse, ) { @@ -64,7 +64,7 @@ func (r *instanceResource) Metadata( //go:embed planModifiers.yaml var modifiersFileByte []byte -func (r *instanceResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { +func (r *instanceResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { s := sqlserverflexbetaResGen.InstanceResourceSchema(ctx) fields, err := utils.ReadModifiersConfig(modifiersFileByte) @@ -147,7 +147,6 @@ func (r *instanceResource) ModifyPlan( req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse, ) { // nolint:gocritic // function signature required by Terraform - // skip initial empty configuration to avoid follow-up errors if req.Config.Raw.IsNull() { return diff --git a/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go b/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go index 3beb0da8..887c5edd 100644 --- a/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go +++ b/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go @@ -349,8 +349,8 @@ func TestAccInstanceNoEncryption(t *testing.T) { // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_id"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_version"), - //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"), - //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"), + // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"), + // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.access_scope"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.acl"), @@ -450,8 +450,8 @@ func TestAccInstanceEncryption(t *testing.T) { // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_id"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_version"), - //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"), - //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"), + // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"), + // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.access_scope"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.acl"), diff --git a/stackit/internal/services/sqlserverflexbeta/user/datasource.go b/stackit/internal/services/sqlserverflexbeta/user/datasource.go index 8457972a..d726bc2b 100644 --- a/stackit/internal/services/sqlserverflexbeta/user/datasource.go +++ b/stackit/internal/services/sqlserverflexbeta/user/datasource.go @@ -20,8 +20,6 @@ import ( var _ datasource.DataSource = (*userDataSource)(nil) -const errorPrefix = "[Sqlserverflexbeta - User]" - func NewUserDataSource() datasource.DataSource { return &userDataSource{} } diff --git a/stackit/internal/services/sqlserverflexbeta/user/resource.go b/stackit/internal/services/sqlserverflexbeta/user/resource.go index f960c726..efaf3fc1 100644 --- a/stackit/internal/services/sqlserverflexbeta/user/resource.go +++ b/stackit/internal/services/sqlserverflexbeta/user/resource.go @@ -20,7 +20,6 @@ import ( "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexbeta" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion" - sqlserverflexbetagen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/user/resources_gen" sqlserverflexbetaUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/utils" sqlserverflexbetaWait "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/wait/sqlserverflexbeta" @@ -59,7 +58,7 @@ type userResource struct { providerData core.ProviderData } -func (r *userResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { +func (r *userResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { resp.TypeName = req.ProviderTypeName + "_sqlserverflexbeta_user" } @@ -108,23 +107,23 @@ func (r *userResource) ModifyPlan( } //// TODO: verify if this is needed - START - //var planRoles []string - //diags := planModel.Roles.ElementsAs(ctx, &planRoles, false) - //resp.Diagnostics.Append(diags...) - //if diags.HasError() { + // var planRoles []string + // diags := planModel.Roles.ElementsAs(ctx, &planRoles, false) + // resp.Diagnostics.Append(diags...) + // if diags.HasError() { // return //} - //slices.Sort(planRoles) - //var roles []attr.Value - //for _, role := range planRoles { + // slices.Sort(planRoles) + // var roles []attr.Value + // for _, role := range planRoles { // roles = append(roles, types.StringValue(string(role))) //} - //rolesSet, diags := types.ListValue(types.StringType, roles) - //resp.Diagnostics.Append(diags...) - //if diags.HasError() { + // rolesSet, diags := types.ListValue(types.StringType, roles) + // resp.Diagnostics.Append(diags...) + // if diags.HasError() { // return //} - //planModel.Roles = rolesSet + // planModel.Roles = rolesSet //// TODO: verify if this is needed - END resp.Diagnostics.Append(resp.Plan.Set(ctx, planModel)...) @@ -138,7 +137,7 @@ var modifiersFileByte []byte // Schema defines the schema for the resource. func (r *userResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { - s := sqlserverflexbetagen.UserResourceSchema(ctx) + s := sqlserverflexbetaResGen.UserResourceSchema(ctx) fields, err := utils.ReadModifiersConfig(modifiersFileByte) if err != nil { @@ -435,7 +434,12 @@ func (r *userResource) Update( resp *resource.UpdateResponse, ) { // nolint:gocritic // function signature required by Terraform // Update shouldn't be called - core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating user", "an SQL server user can not be updated, only created") + core.LogAndAddError( + ctx, + &resp.Diagnostics, + "Error updating user", + "an SQL server user can not be updated, only created", + ) } // Delete deletes the resource and removes the Terraform state on success. @@ -489,7 +493,6 @@ func (r *userResource) Delete( // Delete existing record set _, err = sqlserverflexbetaWait.DeleteUserWaitHandler(ctx, r.client, projectId, region, instanceId, userId). WaitWithContext(ctx) - // err := r.client.DeleteUserRequest(ctx, arg.projectId, arg.region, arg.instanceId, userId).Execute() if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "User Delete Error", fmt.Sprintf("Calling API: %v", err)) return diff --git a/stackit/internal/wait/postgresflexalpha/wait.go b/stackit/internal/wait/postgresflexalpha/wait.go index 57106cec..4aea71e8 100644 --- a/stackit/internal/wait/postgresflexalpha/wait.go +++ b/stackit/internal/wait/postgresflexalpha/wait.go @@ -108,7 +108,7 @@ func CreateInstanceWaitHandler( ) if extendedTimeout < 3 { maxWait += time.Minute * 5 - extendedTimeout = extendedTimeout + 1 + extendedTimeout++ if *s.Network.AccessScope == "SNA" { ready := true if s.Network == nil || s.Network.InstanceAddress == nil { @@ -228,7 +228,7 @@ func GetUserByIdWaitHandler( if userId > math.MaxInt32 { return false, nil, fmt.Errorf("userId value is too big for int32") } - userId32 := int32(userId) + userId32 := int32(userId) //nolint:gosec // we need to convert databaseId to int32 because API expects int32 s, err := a.GetUserRequestExecute(ctx, projectId, region, instanceId, userId32) if err != nil { var oapiErr *oapierror.GenericOpenAPIError @@ -239,9 +239,11 @@ func GetUserByIdWaitHandler( switch oapiErr.StatusCode { case http.StatusBadGateway, http.StatusGatewayTimeout, http.StatusServiceUnavailable: case http.StatusNotFound: - tflog.Warn(ctx, "api responded with status", map[string]interface{}{ - "status": oapiErr.StatusCode, - }) + tflog.Warn( + ctx, "api responded with status", map[string]interface{}{ + "status": oapiErr.StatusCode, + }, + ) return false, nil, nil default: return false, nil, err @@ -262,7 +264,7 @@ func GetDatabaseByIdWaitHandler( ) *wait.AsyncActionHandler[postgresflex.GetDatabaseResponse] { handler := wait.New( func() (waitFinished bool, response *postgresflex.GetDatabaseResponse, err error) { - dbId32 := int32(databaseId) + dbId32 := int32(databaseId) //nolint:gosec // we need to convert databaseId to int32 because API expects int32 s, err := a.GetDatabaseRequestExecute(ctx, projectId, region, instanceId, dbId32) if err != nil { var oapiErr *oapierror.GenericOpenAPIError @@ -272,14 +274,18 @@ func GetDatabaseByIdWaitHandler( } switch oapiErr.StatusCode { case http.StatusBadGateway, http.StatusGatewayTimeout, http.StatusServiceUnavailable: - tflog.Warn(ctx, "api responded with 50[2,3,4] status", map[string]interface{}{ - "status": oapiErr.StatusCode, - }) + tflog.Warn( + ctx, "api responded with 50[2,3,4] status", map[string]interface{}{ + "status": oapiErr.StatusCode, + }, + ) return false, nil, nil case http.StatusNotFound: - tflog.Warn(ctx, "api responded with 404 status", map[string]interface{}{ - "status": oapiErr.StatusCode, - }) + tflog.Warn( + ctx, "api responded with 404 status", map[string]interface{}{ + "status": oapiErr.StatusCode, + }, + ) return false, nil, nil default: return false, nil, err diff --git a/stackit/internal/wait/sqlserverflexalpha/wait.go b/stackit/internal/wait/sqlserverflexalpha/wait.go index 05fa5eb4..712347d1 100644 --- a/stackit/internal/wait/sqlserverflexalpha/wait.go +++ b/stackit/internal/wait/sqlserverflexalpha/wait.go @@ -54,7 +54,12 @@ type APIClientInterface interface { instanceId string, ) (*sqlserverflex.ListRolesResponse, error) - ListUsersRequest(ctx context.Context, projectId string, region string, instanceId string) sqlserverflex.ApiListUsersRequestRequest + ListUsersRequest( + ctx context.Context, + projectId string, + region string, + instanceId string, + ) sqlserverflex.ApiListUsersRequestRequest ListUsersRequestExecute( ctx context.Context, @@ -256,7 +261,10 @@ func CreateDatabaseWaitHandler( var oapiErr *oapierror.GenericOpenAPIError ok := errors.As(err, &oapiErr) if !ok { - return false, nil, fmt.Errorf("get database - could not convert error to oapierror.GenericOpenAPIError: %s", err.Error()) + return false, nil, fmt.Errorf( + "get database - could not convert error to oapierror.GenericOpenAPIError: %s", + err.Error(), + ) } if oapiErr.StatusCode != http.StatusNotFound { return false, nil, err @@ -318,7 +326,10 @@ func WaitForUserWaitHandler( var oapiErr *oapierror.GenericOpenAPIError ok := errors.As(err, &oapiErr) if !ok { - return false, nil, fmt.Errorf("Wait (list users) could not convert error to oapierror.GenericOpenAPIError: %s", err.Error()) + return false, nil, fmt.Errorf( + "wait (list users) could not convert error to oapierror.GenericOpenAPIError: %s", + err.Error(), + ) } if oapiErr.StatusCode != http.StatusNotFound { return false, nil, err diff --git a/stackit/internal/wait/sqlserverflexalpha/wait_test.go b/stackit/internal/wait/sqlserverflexalpha/wait_test.go index 4c85e436..ca84ad1e 100644 --- a/stackit/internal/wait/sqlserverflexalpha/wait_test.go +++ b/stackit/internal/wait/sqlserverflexalpha/wait_test.go @@ -116,7 +116,6 @@ func (a *apiClientInstanceMocked) GetInstanceRequestExecute( }, nil } func TestCreateInstanceWaitHandler(t *testing.T) { - //stateSuccess := utils.Ptr(InstanceStateSuccess) instanceId := utils.Ptr("foo") tests := []struct { desc string @@ -160,7 +159,7 @@ func TestCreateInstanceWaitHandler(t *testing.T) { // Storage: nil, // Version: nil, // }, - //}, + // }, { desc: "create_failed", instanceId: *instanceId, diff --git a/stackit/internal/wait/sqlserverflexbeta/wait.go b/stackit/internal/wait/sqlserverflexbeta/wait.go index 41bfa2c1..2660cac5 100644 --- a/stackit/internal/wait/sqlserverflexbeta/wait.go +++ b/stackit/internal/wait/sqlserverflexbeta/wait.go @@ -54,7 +54,12 @@ type APIClientInterface interface { instanceId string, ) (*sqlserverflex.ListRolesResponse, error) - ListUsersRequest(ctx context.Context, projectId string, region string, instanceId string) sqlserverflex.ApiListUsersRequestRequest + ListUsersRequest( + ctx context.Context, + projectId string, + region string, + instanceId string, + ) sqlserverflex.ApiListUsersRequestRequest ListUsersRequestExecute( ctx context.Context, @@ -162,9 +167,17 @@ func CreateInstanceWaitHandler( } return true, s, nil case strings.ToLower(InstanceStateUnknown): - return true, nil, fmt.Errorf("create failed for instance %s with status %s", instanceId, InstanceStateUnknown) + return true, nil, fmt.Errorf( + "create failed for instance %s with status %s", + instanceId, + InstanceStateUnknown, + ) case strings.ToLower(InstanceStateFailed): - return true, nil, fmt.Errorf("create failed for instance %s with status %s", instanceId, InstanceStateFailed) + return true, nil, fmt.Errorf( + "create failed for instance %s with status %s", + instanceId, + InstanceStateFailed, + ) case strings.ToLower(InstanceStatePending), strings.ToLower(InstanceStateProcessing): tflog.Info( ctx, "request is being handled", map[string]interface{}{ @@ -268,7 +281,10 @@ func CreateDatabaseWaitHandler( var oapiErr *oapierror.GenericOpenAPIError ok := errors.As(err, &oapiErr) if !ok { - return false, nil, fmt.Errorf("get database - could not convert error to oapierror.GenericOpenAPIError: %s", err.Error()) + return false, nil, fmt.Errorf( + "get database - could not convert error to oapierror.GenericOpenAPIError: %s", + err.Error(), + ) } if oapiErr.StatusCode != http.StatusNotFound { return false, nil, err @@ -330,7 +346,10 @@ func WaitForUserWaitHandler( var oapiErr *oapierror.GenericOpenAPIError ok := errors.As(err, &oapiErr) if !ok { - return false, nil, fmt.Errorf("Wait (list users) could not convert error to oapierror.GenericOpenAPIError: %s", err.Error()) + return false, nil, fmt.Errorf( + "wait (list users) could not convert error to oapierror.GenericOpenAPIError: %s", + err.Error(), + ) } if oapiErr.StatusCode != http.StatusNotFound { return false, nil, err diff --git a/stackit/internal/wait/sqlserverflexbeta/wait_test.go b/stackit/internal/wait/sqlserverflexbeta/wait_test.go index 825761ce..0d10abae 100644 --- a/stackit/internal/wait/sqlserverflexbeta/wait_test.go +++ b/stackit/internal/wait/sqlserverflexbeta/wait_test.go @@ -116,7 +116,6 @@ func (a *apiClientInstanceMocked) GetInstanceRequestExecute( }, nil } func TestCreateInstanceWaitHandler(t *testing.T) { - //stateSuccess := utils.Ptr(InstanceStateSuccess) instanceId := utils.Ptr("foo") tests := []struct { desc string @@ -160,7 +159,7 @@ func TestCreateInstanceWaitHandler(t *testing.T) { // Storage: nil, // Version: nil, // }, - //}, + // }, { desc: "create_failed", instanceId: *instanceId, diff --git a/stackit/provider.go b/stackit/provider.go index bb9ffad0..086ae003 100644 --- a/stackit/provider.go +++ b/stackit/provider.go @@ -46,6 +46,7 @@ var ( _ provider.Provider = &Provider{} ) +//nolint:unused // These constants are defined for future use in retry logic for HTTP requests, which is not yet implemented. const ( // maxRetries is the maximum number of retries for a failed HTTP request. maxRetries = 3 @@ -123,6 +124,7 @@ type providerModel struct { // Schema defines the provider-level schema for configuration data. func (p *Provider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) { + //nolint:gosec // These are just descriptions, not actual credentials or sensitive information. descriptions := map[string]string{ "credentials_path": "Path of JSON from where the credentials are read. Takes precedence over the env var `STACKIT_CREDENTIALS_PATH`. Default value is `~/.stackit/credentials.json`.", "service_account_token": "Token used for authentication. If set, the token flow will be used to authenticate all operations.", @@ -489,7 +491,8 @@ func (p *Provider) Configure(ctx context.Context, req provider.ConfigureRequest, return } - //roundTripper := core.NewRetryRoundTripper( + //nolint:gocritic // maybe later in the code + // roundTripper := core.NewRetryRoundTripper( // baseRoundTripper, // maxRetries, // initialDelay, diff --git a/stackit/provider_acc_test.go b/stackit/provider_acc_test.go index 11cdf672..2230d731 100644 --- a/stackit/provider_acc_test.go +++ b/stackit/provider_acc_test.go @@ -12,11 +12,12 @@ import ( "time" "github.com/golang-jwt/jwt/v5" - test "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/google/go-cmp/cmp" + test "github.com/hashicorp/terraform-plugin-testing/helper/resource" //nolint:staticcheck // used for acceptance testing "github.com/jarcoal/httpmock" "github.com/stackitcloud/stackit-sdk-go/core/clients" "github.com/stackitcloud/stackit-sdk-go/core/utils" - "github.com/stretchr/testify/require" + "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/postgresflexalpha" postgresFlexAlphaFlavor "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/flavor" @@ -40,7 +41,7 @@ import ( "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/internal/testutils" "github.com/hashicorp/terraform-plugin-testing/config" - "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" //nolint:staticcheck // used for acceptance testing ) //go:embed testdata/provider-credentials.tf @@ -67,12 +68,15 @@ func TestMshTest(t *testing.T) { testutils.ActivateEnvironmentHttpMocks() - httpmock.RegisterResponder("POST", `https://service-account.api.stackit.cloud/token`, - func(req *http.Request) (*http.Response, error) { - token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ - "foo": "bar", - "nbf": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(), - }) + httpmock.RegisterResponder( + "POST", `https://service-account.api.stackit.cloud/token`, + func(_ *http.Request) (*http.Response, error) { + token := jwt.NewWithClaims( + jwt.SigningMethodHS256, jwt.MapClaims{ + "foo": "bar", + "nbf": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(), + }, + ) // Sign and get the complete encoded token as a string using the secret tokenString, err := token.SignedString([]byte("mySecret")) if err != nil { @@ -88,10 +92,13 @@ func TestMshTest(t *testing.T) { } return httpmock.NewJsonResponse(http.StatusOK, tR) - }) + }, + ) - httpmock.RegisterResponder("GET", `https://postgres-flex-service.api.eu01.stackit.cloud/v3alpha1/projects/xyz-project-id/regions/eu01/flavors?page=1&size=25&sort=id.asc`, - func(req *http.Request) (*http.Response, error) { + httpmock.RegisterResponder( + "GET", + `https://postgres-flex-service.api.eu01.stackit.cloud/v3alpha1/projects/xyz-project-id/regions/eu01/flavors?page=1&size=25&sort=id.asc`, + func(_ *http.Request) (*http.Response, error) { res := postgresflexalpha.GetFlavorsResponse{ Flavors: &[]postgresflexalpha.ListFlavors{ { @@ -120,15 +127,17 @@ func TestMshTest(t *testing.T) { }, ) - test.Test(t, test.TestCase{ - IsUnitTest: true, - ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, - Steps: []test.TestStep{ - { - ConfigVariables: map[string]config.Variable{ - "project_id": config.StringVariable("xyz-project-id"), - }, - Config: fmt.Sprintf(` + test.Test( + t, test.TestCase{ + IsUnitTest: true, + ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, + Steps: []test.TestStep{ + { + ConfigVariables: map[string]config.Variable{ + "project_id": config.StringVariable("xyz-project-id"), + }, + Config: fmt.Sprintf( + ` provider "stackitprivatepreview" { default_region = "%[1]s" service_account_key_path = "%[2]s" @@ -144,12 +153,13 @@ func TestMshTest(t *testing.T) { node_type = "Single" storage_class = "premium-perf2-stackit" }`, - os.Getenv("TF_ACC_REGION"), - os.Getenv("TF_ACC_SERVICE_ACCOUNT_FILE"), - ), + os.Getenv("TF_ACC_REGION"), + os.Getenv("TF_ACC_SERVICE_ACCOUNT_FILE"), + ), + }, }, }, - }) + ) } func TestUnitProviderHasChildDataSources_Basic(t *testing.T) { @@ -171,12 +181,24 @@ func TestUnitProviderHasChildDataSources_Basic(t *testing.T) { sqlserverFlexBetaUser.NewUserDataSource(), sqlserverFlexBetaFlavor.NewFlavorDataSource(), } - datasources := stackit.New("testing")().(*stackit.Provider).DataSources(context.Background()) + provider, ok := stackit.New("testing")().(*stackit.Provider) + if !ok { + t.Fatal("could not assert provider type") + } + datasources := provider.DataSources(context.Background()) - if !reflect.DeepEqual(len(expectedDataSources), len(datasources)) { - for _, d := range datasources { - require.Containsf(t, expectedDataSources, d(), "Data source %+v was not expected", reflect.TypeOf(d())) - } + expectedMap := map[string]struct{}{} + for _, d := range expectedDataSources { + expectedMap[reflect.TypeOf(d).String()] = struct{}{} + } + + actualMap := map[string]struct{}{} + for _, d := range datasources { + actualMap[reflect.TypeOf(d()).String()] = struct{}{} + } + + if diff := cmp.Diff(expectedMap, actualMap); diff != "" { + t.Errorf("DataSources mismatch (-expected +actual):\n%s", diff) } } @@ -194,12 +216,24 @@ func TestUnitProviderHasChildResources_Basic(t *testing.T) { sqlserverFlexBetaUser.NewUserResource(), sqlserverflexBetaDatabase.NewDatabaseResource(), } - resources := stackit.New("testing")().(*stackit.Provider).Resources(context.Background()) + provider, ok := stackit.New("testing")().(*stackit.Provider) + if !ok { + t.Fatal("could not assert provider type") + } + resources := provider.Resources(context.Background()) - if !reflect.DeepEqual(len(expectedResources), len(resources)) { - for _, d := range resources { - require.Containsf(t, expectedResources, d(), "Resource %+v was not expected", reflect.TypeOf(d())) - } + expectedMap := map[string]struct{}{} + for _, r := range expectedResources { + expectedMap[reflect.TypeOf(r).String()] = struct{}{} + } + + actualMap := map[string]struct{}{} + for _, r := range resources { + actualMap[reflect.TypeOf(r()).String()] = struct{}{} + } + + if diff := cmp.Diff(expectedMap, actualMap); diff != "" { + t.Errorf("Resources mismatch (-expected +actual):\n%s", diff) } } @@ -209,23 +243,25 @@ func TestAccEnvVarServiceAccountPathValid(t *testing.T) { if v := os.Getenv(resource.EnvTfAcc); v == "" { t.Skipf( "Acceptance tests skipped unless env '%s' set", - resource.EnvTfAcc) + resource.EnvTfAcc, + ) return } - // t.Setenv("STACKIT_CREDENTIALS_PATH", "") tempHomeFolder := testutils.CreateTemporaryHome(true, t) defer testutils.CleanupTemporaryHome(tempHomeFolder, t) - resource.Test(t, resource.TestCase{ - ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, - Steps: []resource.TestStep{ - { - PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) }, - ConfigVariables: testConfigProviderCredentials, - Config: providerCredentialConfig, + resource.Test( + t, resource.TestCase{ + ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) }, + ConfigVariables: testConfigProviderCredentials, + Config: providerCredentialConfig, + }, }, }, - }) + ) } func TestAccEnvVarServiceAccountPathInvalid(t *testing.T) { @@ -233,17 +269,19 @@ func TestAccEnvVarServiceAccountPathInvalid(t *testing.T) { t.Setenv("STACKIT_CREDENTIALS_PATH", "") tempHomeFolder := testutils.CreateTemporaryHome(false, t) defer testutils.CleanupTemporaryHome(tempHomeFolder, t) - resource.Test(t, resource.TestCase{ - ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, - Steps: []resource.TestStep{ - { - PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) }, - ConfigVariables: testConfigProviderCredentials, - Config: providerCredentialConfig, - ExpectError: regexp.MustCompile(`undefined response type, status code 401`), + resource.Test( + t, resource.TestCase{ + ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) }, + ConfigVariables: testConfigProviderCredentials, + Config: providerCredentialConfig, + ExpectError: regexp.MustCompile(`undefined response type, status code 401`), + }, }, }, - }) + ) } func TestAccCredentialsFileValid(t *testing.T) { @@ -251,16 +289,18 @@ func TestAccCredentialsFileValid(t *testing.T) { t.Setenv("STACKIT_CREDENTIALS_PATH", "") tempHomeFolder := testutils.CreateTemporaryHome(true, t) defer testutils.CleanupTemporaryHome(tempHomeFolder, t) - resource.Test(t, resource.TestCase{ - ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, - Steps: []resource.TestStep{ - { - PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) }, - ConfigVariables: testConfigProviderCredentials, - Config: providerCredentialConfig, + resource.Test( + t, resource.TestCase{ + ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) }, + ConfigVariables: testConfigProviderCredentials, + Config: providerCredentialConfig, + }, }, }, - }) + ) } func TestAccCredentialsFileInvalid(t *testing.T) { @@ -268,17 +308,19 @@ func TestAccCredentialsFileInvalid(t *testing.T) { t.Setenv("STACKIT_CREDENTIALS_PATH", "") tempHomeFolder := testutils.CreateTemporaryHome(false, t) defer testutils.CleanupTemporaryHome(tempHomeFolder, t) - resource.Test(t, resource.TestCase{ - ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, - Steps: []resource.TestStep{ - { - PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) }, - ConfigVariables: testConfigProviderCredentials, - Config: providerCredentialConfig, - ExpectError: regexp.MustCompile(`Jwt is not in(\r\n|\r|\n)the form of Header.Payload.Signature`), + resource.Test( + t, resource.TestCase{ + ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) }, + ConfigVariables: testConfigProviderCredentials, + Config: providerCredentialConfig, + ExpectError: regexp.MustCompile(`Jwt is not in(\r\n|\r|\n)the form of Header.Payload.Signature`), + }, }, }, - }) + ) } func TestAccProviderConfigureValidValues(t *testing.T) { @@ -287,21 +329,25 @@ func TestAccProviderConfigureValidValues(t *testing.T) { if v := os.Getenv(resource.EnvTfAcc); v == "" { t.Skipf( "Acceptance tests skipped unless env '%s' set", - resource.EnvTfAcc) + resource.EnvTfAcc, + ) return } t.Setenv("STACKIT_CREDENTIALS_PATH", "") tempHomeFolder := testutils.CreateTemporaryHome(true, t) defer testutils.CleanupTemporaryHome(tempHomeFolder, t) - resource.Test(t, resource.TestCase{ - ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, - Steps: []resource.TestStep{ - { // valid provider attributes - ConfigVariables: testConfigProviderCredentials, - Config: providerValidAttributes, + resource.Test( + t, resource.TestCase{ + ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + // valid provider attributes + ConfigVariables: testConfigProviderCredentials, + Config: providerValidAttributes, + }, }, }, - }) + ) } func TestAccProviderConfigureAnInvalidValue(t *testing.T) { @@ -310,21 +356,25 @@ func TestAccProviderConfigureAnInvalidValue(t *testing.T) { if v := os.Getenv(resource.EnvTfAcc); v == "" { t.Skipf( "Acceptance tests skipped unless env '%s' set", - resource.EnvTfAcc) + resource.EnvTfAcc, + ) return } t.Setenv("STACKIT_CREDENTIALS_PATH", "") tempHomeFolder := testutils.CreateTemporaryHome(true, t) defer testutils.CleanupTemporaryHome(tempHomeFolder, t) - resource.Test(t, resource.TestCase{ - ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, - Steps: []resource.TestStep{ - { // invalid test attribute should throw an error - ConfigVariables: testConfigProviderCredentials, - Config: providerInvalidAttribute, - ExpectError: regexp.MustCompile(`An argument named "test" is not expected here\.`), + resource.Test( + t, resource.TestCase{ + ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + // invalid test attribute should throw an error + ConfigVariables: testConfigProviderCredentials, + Config: providerInvalidAttribute, + ExpectError: regexp.MustCompile(`An argument named "test" is not expected here\.`), + }, }, }, - }) + ) }