Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 42 additions & 7 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,23 +61,26 @@ ifneq ($(SKIP_CLEAN),)
endif
endif

terraform build provider: validate_environment clean-provider mmv1 tpgtools
TEMP_DIR := $(shell mktemp -d)
export TEMP_DIR

terraform build provider: validate_environment clean-provider mmv1 tpgtools clean-temp
@echo "Provider generation process finished for $(VERSION) in $(OUTPUT_PATH)"


mmv1:
mmv1: prepare-temp
@echo "Executing mmv1 build for $(OUTPUT_PATH)";
@cd mmv1;\
@cd $(TEMP_DIR)/mmv1;\
if [ "$(VERSION)" = "ga" ]; then \
go run . --output $(OUTPUT_PATH) --version ga --no-docs $(mmv1_compile) \
&& go run . --output $(OUTPUT_PATH) --version beta --no-code $(mmv1_compile); \
else \
go run . --output $(OUTPUT_PATH) --version $(VERSION) $(mmv1_compile); \
fi

tpgtools: serialize
tpgtools: prepare-temp serialize
@echo "Executing tpgtools build for $(OUTPUT_PATH)";
@cd tpgtools;\
@cd $(TEMP_DIR)/tpgtools;\
go run . --output $(OUTPUT_PATH) --version $(VERSION) $(tpgtools_compile); \
rm serialization.go

Expand Down Expand Up @@ -137,7 +140,7 @@ test:
go test ./...

serialize:
cd tpgtools;\
cd $(TEMP_DIR)/tpgtools;\
cp -f serialization.go.base serialization.go &&\
go run . $(serialize_compile) --mode "serialization" > temp.serial &&\
mv -f temp.serial serialization.go
Expand Down Expand Up @@ -175,4 +178,36 @@ check_safe_build:
doctor:
./scripts/doctor

.PHONY: mmv1 tpgtools test clean-provider validate_environment serialize doctor

prepare-temp:

@echo "Setting up temporary workspace for conversion at $(TEMP_DIR)..."
@rm -rf $(TEMP_DIR)
@mkdir -p $(TEMP_DIR)/mmv1 $(TEMP_DIR)/tpgtools $(TEMP_DIR)/tools
@echo "Copying files to $(TEMP_DIR)..."
@cp -R ./mmv1/. $(TEMP_DIR)/mmv1/
@cp -R ./tpgtools/. $(TEMP_DIR)/tpgtools/
@cp -R ./tools/. $(TEMP_DIR)/tools/
@echo "Building resource template converter in temp..."
cd $(TEMP_DIR)/tools/resource-template-converter && go env -w GO111MODULE=on && go mod tidy && go build -v -o $(TEMP_DIR)/tools/convert-resource-template . && echo "BUILD SUCCEEDED" || (echo "BUILD FAILED"; exit 1)
@echo "Build finished, running converter..."
@ls -la $(TEMP_DIR)/tools/convert-resource-template
@$(TEMP_DIR)/tools/convert-resource-template convert-resource-template $(TEMP_DIR)
@echo "Temporary workspace setup complete."

test-convert:
@echo $(TEMP_DIR)

clean-temp:
@echo "Cleaning up temporary workspace $(TEMP_DIR)..."
@rm -rf $(TEMP_DIR)

convert-templates:
@echo "Checking and running resource template converter..."
@if [ ! -f ./convert-resource-template ]; then \
echo "Building convert-resource-template tool..."; \
(cd tools/resource-template-converter && go build -o ../../convert-resource-template); \
fi
@./convert-resource-template convert-resource-template .

.PHONY: mmv1 tpgtools test clean-provider validate_environment serialize doctor convert-templates prepare-temp clean-temp
82 changes: 82 additions & 0 deletions tools/resource-template-converter/cmd/convert_resource_template.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package cmd

import (
"fmt"
"log"
"os"
"path/filepath"
"regexp"

"github.com/GoogleCloudPlatform/magic-modules/tools/resource-template-converter/copy"
"github.com/GoogleCloudPlatform/magic-modules/tools/resource-template-converter/migrate"
"github.com/spf13/cobra"
)

var resourceFileRegex = regexp.MustCompile(`mmv1/products/([^/]+)/([^/]+\.yaml)`)

var convertResourceTemplateCmd = &cobra.Command{
Use: "convert-resource-template",
Short: "convert resource template from using examples to samples",
Long: `This command convert resource yaml template to use new version samples within existing legacy examples.


The command expects the following argument(s):
1. Root directory path

It then performs the following operations:
1. Updates existing example config to new vars and then copy them to the new samples/services/<service> dir
2. Updates resource yaml teplate to use new samples blocks from existing legacy examples block`,

Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
root := args[0]
return exeCconvertResourceTemplate(root)
},
}

func exeCconvertResourceTemplate(basePath string) error {
if _, err := os.Stat(filepath.Join(basePath, "mmv1")); os.IsNotExist(err) {
log.Fatalf("magic-modules directory structure not found. Please ensure this tool is run from 'magic-modules/tools/example-split'.")
}

productsPath := filepath.Join(basePath, "mmv1", "products")
templatesPath := filepath.Join(basePath, "mmv1", "templates", "terraform")
examplesSourceDir := filepath.Join(templatesPath, "examples")
samplesDestDir := filepath.Join(templatesPath, "samples", "services")
fmt.Printf("Starting processing of product YAML files in: %s\n", productsPath)

err := filepath.Walk(productsPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() && filepath.Ext(path) == ".yaml" {
matches := resourceFileRegex.FindStringSubmatch(path)
if matches == nil {
log.Printf("Skipping non-resource file: %s\n", path)
return nil
}
serviceName := matches[1]

if err := copy.ProcessResourceFile(path, serviceName, examplesSourceDir, samplesDestDir); err != nil {
log.Printf("Error copying templates registered in file %s: %v\n", path, err)
// Continue processing other files even if one fails.
}
if err := migrate.MigrateFile(path, serviceName); err != nil {
log.Printf("Failed to migrate file %s: %v\n", path, err)
// Continue migrating other files even if one fails.
}
}
return nil
})

if err != nil {
log.Fatalf("Error walking the products path %q: %v\n", productsPath, err)
}

fmt.Println("Processing complete.")
return nil
}

func init() {
rootCmd.AddCommand(convertResourceTemplateCmd)
}
26 changes: 26 additions & 0 deletions tools/resource-template-converter/cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package cmd

import (
"fmt"
"os"

"github.com/spf13/cobra"
)

// rootCmd represents the base command when called without any subcommands

var rootCmd = &cobra.Command{
Use: "resource-template-coverter",
Short: "Tool for migrating resource yaml templates",
Long: `Tool for migrating resource yaml templates`,
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
err := rootCmd.Execute()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
106 changes: 106 additions & 0 deletions tools/resource-template-converter/copy/copy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package copy

import (
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"

"gopkg.in/yaml.v2"
)

type Resource struct {
Examples []Example `yaml:"examples"`
}

type Example struct {
Name string `yaml:"name"`
ConfigPath string `yaml:"config_path,omitempty"`
}

func ProcessResourceFile(filePath, serviceName, examplesSourceDir, samplesDestDir string) error {
originalBytes, err := ioutil.ReadFile(filePath)
if err != nil {
return fmt.Errorf("failed to read YAML file: %w", err)
}

var resource Resource
err = yaml.Unmarshal(originalBytes, &resource)
if err != nil {
return fmt.Errorf("failed to unmarshal YAML: %w", err)
}

if len(resource.Examples) == 0 {
return nil
}

// fmt.Printf("Found %d examples in %s for service '%s'\n", len(resource.Examples), filepath.Base(filePath), serviceName)

for _, example := range resource.Examples {
if example.Name == "" {
log.Printf("Skipping example with empty name in file: %s\n", filePath)
continue
}

// Determine the source file name. Use config_path if it exists,
// otherwise fall back to the example's name.
var sourceFileName string
if example.ConfigPath != "" {
sourceFileName = filepath.Base(example.ConfigPath)
} else {
sourceFileName = fmt.Sprintf("%s.tf.tmpl", example.Name)
}

sourcePath := filepath.Join(examplesSourceDir, sourceFileName)

// Check if the source template file actually exists.
if _, err := os.Stat(sourcePath); os.IsNotExist(err) {
// Skip if the template doesn't exist.
continue
}

destDir := filepath.Join(samplesDestDir, serviceName)
destPath := filepath.Join(destDir, sourceFileName)

err := copyFile(sourcePath, destPath)
if err != nil {
// Log the error but don't stop processing other examples.
log.Printf("Failed to copy '%s' to '%s': %v\n", sourcePath, destPath, err)
} else {
// fmt.Printf(" - Copied '%s'\n", sourceFileName)
fmt.Print()
}
}

return nil
}

func copyFile(src, dst string) error {
input, err := ioutil.ReadFile(src)
if err != nil {
return fmt.Errorf("could not read source file %s: %w", src, err)
}

// Switch existing Vars to PrefixedVars
output := strings.ReplaceAll(string(input), "$.Vars", "$.PrefixedVars")

if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
return fmt.Errorf("could not create destination directory for %s: %w", dst, err)
}

// Get the source file's permissions to apply to the destination file.
info, err := os.Stat(src)
if err != nil {
return fmt.Errorf("could not stat source file %s: %w", src, err)
}

// Write the modified content to the destination file.
err = ioutil.WriteFile(dst, []byte(output), info.Mode())
if err != nil {
return fmt.Errorf("could not write to destination file %s: %w", dst, err)
}

return nil
}
13 changes: 13 additions & 0 deletions tools/resource-template-converter/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module github.com/GoogleCloudPlatform/magic-modules/tools/resource-template-converter

go 1.23.2

require (
github.com/spf13/cobra v1.10.1
gopkg.in/yaml.v2 v2.4.0
)

require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/spf13/pflag v1.0.9 // indirect
)
13 changes: 13 additions & 0 deletions tools/resource-template-converter/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
9 changes: 9 additions & 0 deletions tools/resource-template-converter/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package main

import (
"github.com/GoogleCloudPlatform/magic-modules/tools/resource-template-converter/cmd"
)

func main() {
cmd.Execute()
}
Loading
Loading