From 2c0e8e874ede6da2c2b5f72818b253db7322d91a Mon Sep 17 00:00:00 2001 From: "Marcel S. Henselin" Date: Tue, 3 Feb 2026 09:25:43 +0100 Subject: [PATCH] fix: spec files in subfolders and refactored builder --- cmd/cmd/build/build.go | 302 ++++++++++-------- .../alpha/database_config.yml} | 0 .../alpha/flavors_config.yml} | 0 .../alpha/instance_config.yml} | 0 .../alpha/role_config.yml} | 0 .../alpha/user_config.yml} | 0 .../alpha/version_config.yml} | 0 .../alpha/backup_config.yml.disabled} | 0 .../alpha/collation_config.yml.disabled} | 0 .../alpha/database_config.yml} | 0 .../alpha/flavors_config.yml} | 0 .../alpha/instance_config.yml} | 0 .../alpha/user_config.yml} | 0 .../alpha/version_config.yml} | 0 14 files changed, 165 insertions(+), 137 deletions(-) rename service_specs/{postgres-flex_database_config.yml => postgres-flex/alpha/database_config.yml} (100%) rename service_specs/{postgres-flex_flavors_config.yml => postgres-flex/alpha/flavors_config.yml} (100%) rename service_specs/{postgres-flex_instance_config.yml => postgres-flex/alpha/instance_config.yml} (100%) rename service_specs/{postgres-flex_role_config.yml => postgres-flex/alpha/role_config.yml} (100%) rename service_specs/{postgres-flex_user_config.yml => postgres-flex/alpha/user_config.yml} (100%) rename service_specs/{postgres-flex_version_config.yml => postgres-flex/alpha/version_config.yml} (100%) rename service_specs/{sqlserverflex_backup_config.yml.disabled => sqlserverflex/alpha/backup_config.yml.disabled} (100%) rename service_specs/{sqlserverflex_collation_config.yml.disabled => sqlserverflex/alpha/collation_config.yml.disabled} (100%) rename service_specs/{sqlserverflex_database_config.yml => sqlserverflex/alpha/database_config.yml} (100%) rename service_specs/{sqlserverflex_flavors_config.yml => sqlserverflex/alpha/flavors_config.yml} (100%) rename service_specs/{sqlserverflex_instance_config.yml => sqlserverflex/alpha/instance_config.yml} (100%) rename service_specs/{sqlserverflex_user_config.yml => sqlserverflex/alpha/user_config.yml} (100%) rename service_specs/{sqlserverflex_version_config.yml => sqlserverflex/alpha/version_config.yml} (100%) diff --git a/cmd/cmd/build/build.go b/cmd/cmd/build/build.go index 81ea75a0..e822afaf 100644 --- a/cmd/cmd/build/build.go +++ b/cmd/cmd/build/build.go @@ -27,6 +27,8 @@ const ( GEN_REPO = "https://github.com/stackitcloud/stackit-sdk-generator.git" ) +var supportedVersions = []string{"alpha", "beta"} + type version struct { verString string major int @@ -35,6 +37,13 @@ type version struct { func Build() error { slog.Info("Starting Builder") + + slog.Info("Checking needed commands available") + err := checkCommands([]string{"tfplugingen-framework", "tfplugingen-openapi"}) + if err != nil { + return err + } + root, err := getRoot() if err != nil { log.Fatal(err) @@ -209,12 +218,6 @@ func Build() error { } } - slog.Info("Checking needed commands available") - err = checkCommands([]string{"tfplugingen-framework", "tfplugingen-openapi"}) - if err != nil { - return err - } - slog.Info("Generating service boilerplate") err = generateServiceFiles(*root, path.Join(*root, GEN_REPO_NAME)) if err != nil { @@ -400,159 +403,184 @@ func generateServiceFiles(rootDir, generatorDir string) error { return err } - specs, err := os.ReadDir(path.Join(rootDir, "service_specs")) + services, err := os.ReadDir(path.Join(rootDir, "service_specs")) if err != nil { return err } - for _, spec := range specs { - if spec.IsDir() { + for _, service := range services { + if !service.IsDir() { continue } - // slog.Info("Checking spec", "name", spec.Name()) - r := regexp.MustCompile(`^([a-z-]+)_(.*)_config.yml$`) - matches := r.FindAllStringSubmatch(spec.Name(), -1) - if matches != nil { - fileName := matches[0][0] - service := matches[0][1] - resource := matches[0][2] - slog.Info( - "Found service spec", - "name", - spec.Name(), - "service", - service, - "resource", - resource, - ) - for _, part := range []string{"alpha", "beta"} { - oasFile := path.Join(generatorDir, "oas", fmt.Sprintf("%s%s.json", service, part)) - if _, err = os.Stat(oasFile); !os.IsNotExist(err) { - slog.Info("found matching oas", "service", service, "version", part) - scName := fmt.Sprintf("%s%s", service, part) - scName = strings.ReplaceAll(scName, "-", "") - err = os.MkdirAll(path.Join(rootDir, "generated", "internal", "services", scName, resource), 0755) - if err != nil { - return err - } + versions, err := os.ReadDir(path.Join(rootDir, "service_specs", service.Name())) + if err != nil { + return err + } + for _, svcVersion := range versions { + if !svcVersion.IsDir() { + continue + } - // slog.Info("Generating openapi spec json") - specFile := path.Join(rootDir, "generated", "specs", fmt.Sprintf("%s_%s_spec.json", scName, resource)) + if svcVersion.Name() != "alpha" && svcVersion.Name() != "beta" { + continue + } - var stdOut, stdErr bytes.Buffer + specFiles, err := os.ReadDir(path.Join(rootDir, "service_specs", service.Name(), svcVersion.Name())) + if err != nil { + return err + } - // noqa:gosec - cmd := exec.Command( - "tfplugingen-openapi", - "generate", - "--config", - path.Join(rootDir, "service_specs", fileName), - "--output", - specFile, - oasFile, - ) - cmd.Stdout = &stdOut - cmd.Stderr = &stdErr + for _, specFile := range specFiles { + if specFile.IsDir() { + continue + } - if err = cmd.Start(); err != nil { - slog.Error("tfplugingen-openapi generate", "error", err) - return err - } - - 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()) - return fmt.Errorf("%s", stdErr.String()) - } - if err != nil { - slog.Error("tfplugingen-openapi generate", "err", err, "stdout", stdOut.String(), "stderr", stdErr.String()) - return err - } - } - - // slog.Info("Creating terraform service resource files folder") - tgtFolder := path.Join(rootDir, "generated", "internal", "services", scName, resource, "resources_gen") - err = os.MkdirAll(tgtFolder, 0755) - if err != nil { - return err - } - - // slog.Info("Generating terraform service resource files") - - // noqa:gosec - cmd2 := exec.Command( - "tfplugingen-framework", - "generate", - "resources", - "--input", - specFile, - "--output", - tgtFolder, - "--package", - scName, + // slog.Info("Checking spec", "name", spec.Name()) + r := regexp.MustCompile(`^(.*)_config.yml$`) + matches := r.FindAllStringSubmatch(specFile.Name(), -1) + if matches != nil { + fileName := matches[0][0] + resource := matches[0][1] + slog.Info( + "Found service spec", + "name", + specFile.Name(), + "service", + service.Name(), + "resource", + resource, ) - cmd2.Stdout = &stdOut - cmd2.Stderr = &stdErr - if err = cmd2.Start(); err != nil { - slog.Error("tfplugingen-framework generate resources", "error", err) - return err - } - - 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()) - return fmt.Errorf("%s", stdErr.String()) - } + //for _, part := range []string{"alpha", "beta"} { + oasFile := path.Join(generatorDir, "oas", fmt.Sprintf("%s%s.json", service.Name(), svcVersion)) + if _, err = os.Stat(oasFile); !os.IsNotExist(err) { + slog.Info("found matching oas", "svc", service.Name(), "version", svcVersion.Name()) + 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) if err != nil { - slog.Error("tfplugingen-framework generate resources", "err", err, "stdout", stdOut.String(), "stderr", stdErr.String()) return err } - } - // slog.Info("Creating terraform service datasource files folder") - tgtFolder = path.Join(rootDir, "generated", "internal", "services", scName, resource, "datasources_gen") - err = os.MkdirAll(tgtFolder, 0755) - 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)) - // slog.Info("Generating terraform service resource files") + var stdOut, stdErr bytes.Buffer - // noqa:gosec - cmd3 := exec.Command( - "tfplugingen-framework", - "generate", - "data-sources", - "--input", - specFile, - "--output", - tgtFolder, - "--package", - scName, - ) - var stdOut3, stdErr3 bytes.Buffer - cmd3.Stdout = &stdOut3 - cmd3.Stderr = &stdErr3 + // noqa:gosec + cmd := exec.Command( + "tfplugingen-openapi", + "generate", + "--config", + path.Join(rootDir, "service_specs", fileName), + "--output", + specJsonFile, + oasFile, + ) + cmd.Stdout = &stdOut + cmd.Stderr = &stdErr - if err = cmd3.Start(); err != nil { - slog.Error("tfplugingen-framework generate data-sources", "error", err) - return err - } - - 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()) - return fmt.Errorf("%s", stdErr.String()) - } - if err != nil { - slog.Error("tfplugingen-framework generate data-sources", "err", err, "stdout", stdOut.String(), "stderr", stdErr.String()) + if err = cmd.Start(); err != nil { + slog.Error("tfplugingen-openapi generate", "error", err) return err } + + 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()) + return fmt.Errorf("%s", stdErr.String()) + } + if err != nil { + slog.Error("tfplugingen-openapi generate", "err", err, "stdout", stdOut.String(), "stderr", stdErr.String()) + return err + } + } + + // slog.Info("Creating terraform svc resource files folder") + tgtFolder := path.Join(rootDir, "generated", "internal", "services", scName, resource, "resources_gen") + err = os.MkdirAll(tgtFolder, 0755) + if err != nil { + return err + } + + // slog.Info("Generating terraform svc resource files") + + // noqa:gosec + cmd2 := exec.Command( + "tfplugingen-framework", + "generate", + "resources", + "--input", + specJsonFile, + "--output", + tgtFolder, + "--package", + scName, + ) + + cmd2.Stdout = &stdOut + cmd2.Stderr = &stdErr + if err = cmd2.Start(); err != nil { + slog.Error("tfplugingen-framework generate resources", "error", err) + return err + } + + 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()) + return fmt.Errorf("%s", stdErr.String()) + } + if err != nil { + 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) + if err != nil { + return err + } + + // slog.Info("Generating terraform svc resource files") + + // noqa:gosec + cmd3 := exec.Command( + "tfplugingen-framework", + "generate", + "data-sources", + "--input", + specJsonFile, + "--output", + tgtFolder, + "--package", + scName, + ) + var stdOut3, stdErr3 bytes.Buffer + cmd3.Stdout = &stdOut3 + cmd3.Stderr = &stdErr3 + + if err = cmd3.Start(); err != nil { + slog.Error("tfplugingen-framework generate data-sources", "error", err) + return err + } + + 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()) + return fmt.Errorf("%s", stdErr.String()) + } + if err != nil { + slog.Error("tfplugingen-framework generate data-sources", "err", err, "stdout", stdOut.String(), "stderr", stdErr.String()) + return err + } + } } + //} } } } diff --git a/service_specs/postgres-flex_database_config.yml b/service_specs/postgres-flex/alpha/database_config.yml similarity index 100% rename from service_specs/postgres-flex_database_config.yml rename to service_specs/postgres-flex/alpha/database_config.yml diff --git a/service_specs/postgres-flex_flavors_config.yml b/service_specs/postgres-flex/alpha/flavors_config.yml similarity index 100% rename from service_specs/postgres-flex_flavors_config.yml rename to service_specs/postgres-flex/alpha/flavors_config.yml diff --git a/service_specs/postgres-flex_instance_config.yml b/service_specs/postgres-flex/alpha/instance_config.yml similarity index 100% rename from service_specs/postgres-flex_instance_config.yml rename to service_specs/postgres-flex/alpha/instance_config.yml diff --git a/service_specs/postgres-flex_role_config.yml b/service_specs/postgres-flex/alpha/role_config.yml similarity index 100% rename from service_specs/postgres-flex_role_config.yml rename to service_specs/postgres-flex/alpha/role_config.yml diff --git a/service_specs/postgres-flex_user_config.yml b/service_specs/postgres-flex/alpha/user_config.yml similarity index 100% rename from service_specs/postgres-flex_user_config.yml rename to service_specs/postgres-flex/alpha/user_config.yml diff --git a/service_specs/postgres-flex_version_config.yml b/service_specs/postgres-flex/alpha/version_config.yml similarity index 100% rename from service_specs/postgres-flex_version_config.yml rename to service_specs/postgres-flex/alpha/version_config.yml diff --git a/service_specs/sqlserverflex_backup_config.yml.disabled b/service_specs/sqlserverflex/alpha/backup_config.yml.disabled similarity index 100% rename from service_specs/sqlserverflex_backup_config.yml.disabled rename to service_specs/sqlserverflex/alpha/backup_config.yml.disabled diff --git a/service_specs/sqlserverflex_collation_config.yml.disabled b/service_specs/sqlserverflex/alpha/collation_config.yml.disabled similarity index 100% rename from service_specs/sqlserverflex_collation_config.yml.disabled rename to service_specs/sqlserverflex/alpha/collation_config.yml.disabled diff --git a/service_specs/sqlserverflex_database_config.yml b/service_specs/sqlserverflex/alpha/database_config.yml similarity index 100% rename from service_specs/sqlserverflex_database_config.yml rename to service_specs/sqlserverflex/alpha/database_config.yml diff --git a/service_specs/sqlserverflex_flavors_config.yml b/service_specs/sqlserverflex/alpha/flavors_config.yml similarity index 100% rename from service_specs/sqlserverflex_flavors_config.yml rename to service_specs/sqlserverflex/alpha/flavors_config.yml diff --git a/service_specs/sqlserverflex_instance_config.yml b/service_specs/sqlserverflex/alpha/instance_config.yml similarity index 100% rename from service_specs/sqlserverflex_instance_config.yml rename to service_specs/sqlserverflex/alpha/instance_config.yml diff --git a/service_specs/sqlserverflex_user_config.yml b/service_specs/sqlserverflex/alpha/user_config.yml similarity index 100% rename from service_specs/sqlserverflex_user_config.yml rename to service_specs/sqlserverflex/alpha/user_config.yml diff --git a/service_specs/sqlserverflex_version_config.yml b/service_specs/sqlserverflex/alpha/version_config.yml similarity index 100% rename from service_specs/sqlserverflex_version_config.yml rename to service_specs/sqlserverflex/alpha/version_config.yml -- 2.49.1