fix: linting (#77)
## Description
<!-- **Please link some issue here describing what you are trying to achieve.**
In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->
relates to #1234
## Checklist
- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)
Reviewed-on: #77
Co-authored-by: Andre Harms <andre.harms@stackit.cloud>
Co-committed-by: Andre Harms <andre.harms@stackit.cloud>
This commit is contained in:
parent
36eccc52c3
commit
4a2819787d
74 changed files with 3010 additions and 2432 deletions
|
|
@ -60,7 +60,7 @@ func (b *Builder) Build() error {
|
|||
|
||||
if !b.PackagesOnly {
|
||||
slog.Info(" ... Checking needed commands available")
|
||||
err := checkCommands([]string{"tfplugingen-framework", "tfplugingen-openapi"})
|
||||
err := checkCommands([]string{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -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,27 +531,44 @@ 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",
|
||||
"go",
|
||||
"run",
|
||||
"github.com/hashicorp/terraform-plugin-codegen-openapi/cmd/tfplugingen-openapi",
|
||||
"generate",
|
||||
"--config",
|
||||
path.Join(rootDir, "service_specs", service.Name(), svcVersion.Name(), fileName),
|
||||
|
|
@ -553,11 +595,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,18 +625,26 @@ 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",
|
||||
"go",
|
||||
"run",
|
||||
"github.com/hashicorp/terraform-plugin-codegen-framework/cmd/tfplugingen-framework",
|
||||
"generate",
|
||||
"resources",
|
||||
"--input",
|
||||
|
|
@ -597,27 +665,53 @@ 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",
|
||||
"go",
|
||||
"run",
|
||||
"github.com/hashicorp/terraform-plugin-codegen-framework/cmd/tfplugingen-framework",
|
||||
"generate",
|
||||
"data-sources",
|
||||
"--input",
|
||||
|
|
@ -639,11 +733,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 +786,10 @@ func handleTfTagForDatasourceFile(filePath, service, resource string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
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,6 @@ func handleTfTagForDatasourceFile(filePath, service, resource string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tmp.Close()
|
||||
|
||||
sc := bufio.NewScanner(f)
|
||||
for sc.Scan() {
|
||||
|
|
@ -709,6 +820,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 +885,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 +912,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 +927,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 +948,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 +1049,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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -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])",
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue