From 1bf3e41ec3eb6935d7b2a0e6555556fceac5ab4b Mon Sep 17 00:00:00 2001 From: wellsiau-aws Date: Fri, 31 May 2024 13:13:32 -0700 Subject: [PATCH 1/5] add schema rename function --- GNUmakefile | 3 +- .../generators/schema_rename/README.md | 13 +++ .../provider/generators/schema_rename/main.go | 34 ++++++ .../generators/schema_rename/rename/rename.go | 103 ++++++++++++++++++ 4 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 internal/provider/generators/schema_rename/README.md create mode 100644 internal/provider/generators/schema_rename/main.go create mode 100644 internal/provider/generators/schema_rename/rename/rename.go diff --git a/GNUmakefile b/GNUmakefile index 909b322ad..438e94acf 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -37,6 +37,7 @@ resources: schemas: $(GO_VER) generate internal/provider/schemas.go + $(GO_VER) run internal/provider/generators/schema_rename/main.go test: $(GO_VER) test $(TEST) $(TESTARGS) -timeout=5m @@ -65,4 +66,4 @@ docs: $(GO_VER) run internal/provider/generators/import-examples/main.go rm -f docs/data-sources/*.md rm -f docs/resources/*.md - @tfplugindocs generate + @tfplugindocs generate \ No newline at end of file diff --git a/internal/provider/generators/schema_rename/README.md b/internal/provider/generators/schema_rename/README.md new file mode 100644 index 000000000..d4b2a662d --- /dev/null +++ b/internal/provider/generators/schema_rename/README.md @@ -0,0 +1,13 @@ +# AWS CloudFormation Resource Schema Renamer + +Find any reference to the **AWS CloudFormation** in the resource schema attributes / descriptions. + +This tool + +* Reads the schema files under `./internal/service/cloudformation/schemas/` +* Checks whether any reference to **AWS CloudFormation** exists in the schema attributes or description. +* Replace reference of **AWS CloudFormation** with **Terraform** + +## Allowlist + +This tool will skips any CloudFormation schema file with prefix `AWS_CloudFormation_` which denotes all AWS CloudFormation resources (stack, hooks, etc). diff --git a/internal/provider/generators/schema_rename/main.go b/internal/provider/generators/schema_rename/main.go new file mode 100644 index 000000000..1198a4f4c --- /dev/null +++ b/internal/provider/generators/schema_rename/main.go @@ -0,0 +1,34 @@ +package main + +import ( + "fmt" + "path/filepath" + "os" + "strings" + "github.com/hashicorp/terraform-provider-awscc/internal/provider/generators/schema_rename/rename" +) + +func main() { + baseDir := "./internal/service/cloudformation/schemas/" + err := filepath.Walk(baseDir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if !info.IsDir() && filepath.Ext(path) == ".json" { + // Skip files that start with "AWS_CloudFormation_" + if !strings.HasPrefix(info.Name(), "AWS_CloudFormation_") { + err = rename.RenameCfnSchemaFile(path) + if err != nil { + return err + } + } + } + + return nil + }) + + if err != nil { + fmt.Println("Error:", err) + } +} diff --git a/internal/provider/generators/schema_rename/rename/rename.go b/internal/provider/generators/schema_rename/rename/rename.go new file mode 100644 index 000000000..37a590f85 --- /dev/null +++ b/internal/provider/generators/schema_rename/rename/rename.go @@ -0,0 +1,103 @@ +package rename + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "strings" + "reflect" +) + +func RenameCfnSchemaFile (filePath string) error { + // Open JSON schema file from base directory + file, err := os.Open(filePath) + if err != nil { + fmt.Println("Error opening file:", err) + return err + } + defer file.Close() + + // Read the JSON data + data, err := ioutil.ReadAll(file) + if err != nil { + fmt.Println("Error reading file:", err) + return err + } + + // Unmarshal the JSON data into a map while preserving the order + var jsonData map[string]interface{} + err = json.Unmarshal(data, &jsonData) + if err != nil { + fmt.Println("Error unmarshaling JSON:", err) + return err + } + + // Create a copy of the original JSON data + originalData := make(map[string]interface{}) + for k, v := range jsonData { + originalData[k] = v + } + + // Replace "CloudFormation" with "Terraform" in the description + err = updateDescription(jsonData) + if err != nil { + fmt.Println("Error updating description:", err) + return err + } + + // Check if the JSON data has changed + if reflect.DeepEqual(jsonData, originalData) { + // No changes detected, skip writing the file + return nil + } + + // Marshal the updated JSON data while preserving the order + updatedDataBytes, err := json.MarshalIndent(jsonData, "", " ") + if err != nil { + fmt.Println("Error marshaling JSON:", err) + return err + } + + // Write the updated JSON data back to the file + err = ioutil.WriteFile(filePath, updatedDataBytes, 0644) + if err != nil { + fmt.Println("Error writing file:", err) + return err + } + + fmt.Printf("File %s updated successfully\n", filePath) + return nil +} + +func updateDescription(data map[string]interface{}) error { + for key, value := range data { + if key == "description" { + description, ok := value.(string) + if ok { + updatedDescription := strings.ReplaceAll(description, "AWS CloudFormation", "Terraform") + data[key] = updatedDescription + } + } else { + switch v := value.(type) { + case map[string]interface{}: + err := updateDescription(v) + if err != nil { + return err + } + case []interface{}: + for i, item := range v { + switch item.(type) { + case map[string]interface{}: + err := updateDescription(item.(map[string]interface{})) + if err != nil { + return err + } + v[i] = item + } + } + } + } + } + return nil +} \ No newline at end of file From 8038cbe0cd4512412f450f2c2d5d40fdb612e526 Mon Sep 17 00:00:00 2001 From: wellsiau-aws Date: Fri, 31 May 2024 14:09:01 -0700 Subject: [PATCH 2/5] address linting --- .../provider/generators/schema_rename/main.go | 7 ++- .../generators/schema_rename/rename/rename.go | 48 ++++++++++++------- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/internal/provider/generators/schema_rename/main.go b/internal/provider/generators/schema_rename/main.go index 1198a4f4c..7d6d1300d 100644 --- a/internal/provider/generators/schema_rename/main.go +++ b/internal/provider/generators/schema_rename/main.go @@ -5,6 +5,7 @@ import ( "path/filepath" "os" "strings" + "github.com/hashicorp/terraform-provider-awscc/internal/provider/generators/schema_rename/rename" ) @@ -16,9 +17,11 @@ func main() { } if !info.IsDir() && filepath.Ext(path) == ".json" { + generator := rename.NewGenerator() // Skip files that start with "AWS_CloudFormation_" if !strings.HasPrefix(info.Name(), "AWS_CloudFormation_") { - err = rename.RenameCfnSchemaFile(path) + + err = generator.RenameCfnSchemaFile(path) if err != nil { return err } @@ -29,6 +32,6 @@ func main() { }) if err != nil { - fmt.Println("Error:", err) + fmt.Fprintf( os.Stderr, "Error:", err) } } diff --git a/internal/provider/generators/schema_rename/rename/rename.go b/internal/provider/generators/schema_rename/rename/rename.go index 37a590f85..ff972162c 100644 --- a/internal/provider/generators/schema_rename/rename/rename.go +++ b/internal/provider/generators/schema_rename/rename/rename.go @@ -2,18 +2,30 @@ package rename import ( "encoding/json" - "fmt" - "io/ioutil" + "io" "os" "strings" "reflect" + "github.com/hashicorp/terraform-provider-awscc/internal/provider/generators/common" ) -func RenameCfnSchemaFile (filePath string) error { +type Generator struct { + *common.Generator +} + +func NewGenerator() *Generator { + return &Generator{ + Generator: common.NewGenerator(), + } +} + +const filePermMode = 0644 // Read/write for owner, read for group/others + +func (g *Generator) RenameCfnSchemaFile (filePath string) error { // Open JSON schema file from base directory file, err := os.Open(filePath) if err != nil { - fmt.Println("Error opening file:", err) + g.Errorf("Error opening file:", err) return err } defer file.Close() @@ -21,7 +33,7 @@ func RenameCfnSchemaFile (filePath string) error { // Read the JSON data data, err := ioutil.ReadAll(file) if err != nil { - fmt.Println("Error reading file:", err) + g.Errorf("Error reading file:", err) return err } @@ -29,7 +41,7 @@ func RenameCfnSchemaFile (filePath string) error { var jsonData map[string]interface{} err = json.Unmarshal(data, &jsonData) if err != nil { - fmt.Println("Error unmarshaling JSON:", err) + g.Errorf("Error unmarshaling JSON:", err) return err } @@ -42,7 +54,7 @@ func RenameCfnSchemaFile (filePath string) error { // Replace "CloudFormation" with "Terraform" in the description err = updateDescription(jsonData) if err != nil { - fmt.Println("Error updating description:", err) + g.Errorf("Error updating description:", err) return err } @@ -55,18 +67,18 @@ func RenameCfnSchemaFile (filePath string) error { // Marshal the updated JSON data while preserving the order updatedDataBytes, err := json.MarshalIndent(jsonData, "", " ") if err != nil { - fmt.Println("Error marshaling JSON:", err) + g.Errorf("Error marshaling JSON:", err) return err } // Write the updated JSON data back to the file - err = ioutil.WriteFile(filePath, updatedDataBytes, 0644) + err = os.WriteFile(filePath, updatedDataBytes, filePermMode) if err != nil { - fmt.Println("Error writing file:", err) + g.Errorf("Error writing file:", err) return err } - fmt.Printf("File %s updated successfully\n", filePath) + g.Infof("File %s updated successfully\n", filePath) return nil } @@ -87,13 +99,13 @@ func updateDescription(data map[string]interface{}) error { } case []interface{}: for i, item := range v { - switch item.(type) { - case map[string]interface{}: - err := updateDescription(item.(map[string]interface{})) - if err != nil { - return err - } - v[i] = item + switch item := item.(type) { + case map[string]interface{}: + err := updateDescription(item) + if err != nil { + return err + } + v[i] = item } } } From b6bf95fa57d871c8e8430e8d53b706e4ac0f55f3 Mon Sep 17 00:00:00 2001 From: wellsiau-aws Date: Fri, 31 May 2024 14:12:54 -0700 Subject: [PATCH 3/5] fix io --- internal/provider/generators/schema_rename/rename/rename.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/provider/generators/schema_rename/rename/rename.go b/internal/provider/generators/schema_rename/rename/rename.go index ff972162c..e5ddbe4b0 100644 --- a/internal/provider/generators/schema_rename/rename/rename.go +++ b/internal/provider/generators/schema_rename/rename/rename.go @@ -31,7 +31,7 @@ func (g *Generator) RenameCfnSchemaFile (filePath string) error { defer file.Close() // Read the JSON data - data, err := ioutil.ReadAll(file) + data, err := io.ReadAll(file) if err != nil { g.Errorf("Error reading file:", err) return err From d83cd540b49c52af0d2637fb44c2bab5c4367e54 Mon Sep 17 00:00:00 2001 From: wellsiau-aws Date: Fri, 31 May 2024 14:34:53 -0700 Subject: [PATCH 4/5] misc linting --- internal/provider/generators/schema_rename/main.go | 3 +-- .../generators/schema_rename/rename/rename.go | 13 +++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/internal/provider/generators/schema_rename/main.go b/internal/provider/generators/schema_rename/main.go index 7d6d1300d..7ecbb33d2 100644 --- a/internal/provider/generators/schema_rename/main.go +++ b/internal/provider/generators/schema_rename/main.go @@ -20,7 +20,6 @@ func main() { generator := rename.NewGenerator() // Skip files that start with "AWS_CloudFormation_" if !strings.HasPrefix(info.Name(), "AWS_CloudFormation_") { - err = generator.RenameCfnSchemaFile(path) if err != nil { return err @@ -32,6 +31,6 @@ func main() { }) if err != nil { - fmt.Fprintf( os.Stderr, "Error:", err) + fmt.Fprintf(os.Stderr, "Error: %v", err) } } diff --git a/internal/provider/generators/schema_rename/rename/rename.go b/internal/provider/generators/schema_rename/rename/rename.go index e5ddbe4b0..d32db9781 100644 --- a/internal/provider/generators/schema_rename/rename/rename.go +++ b/internal/provider/generators/schema_rename/rename/rename.go @@ -6,6 +6,7 @@ import ( "os" "strings" "reflect" + "github.com/hashicorp/terraform-provider-awscc/internal/provider/generators/common" ) @@ -25,7 +26,7 @@ func (g *Generator) RenameCfnSchemaFile (filePath string) error { // Open JSON schema file from base directory file, err := os.Open(filePath) if err != nil { - g.Errorf("Error opening file:", err) + g.Errorf("Error opening file: %v", err) return err } defer file.Close() @@ -33,7 +34,7 @@ func (g *Generator) RenameCfnSchemaFile (filePath string) error { // Read the JSON data data, err := io.ReadAll(file) if err != nil { - g.Errorf("Error reading file:", err) + g.Errorf("Error reading file: %v", err) return err } @@ -41,7 +42,7 @@ func (g *Generator) RenameCfnSchemaFile (filePath string) error { var jsonData map[string]interface{} err = json.Unmarshal(data, &jsonData) if err != nil { - g.Errorf("Error unmarshaling JSON:", err) + g.Errorf("Error unmarshaling JSON: %v", err) return err } @@ -54,7 +55,7 @@ func (g *Generator) RenameCfnSchemaFile (filePath string) error { // Replace "CloudFormation" with "Terraform" in the description err = updateDescription(jsonData) if err != nil { - g.Errorf("Error updating description:", err) + g.Errorf("Error updating description: %v", err) return err } @@ -67,14 +68,14 @@ func (g *Generator) RenameCfnSchemaFile (filePath string) error { // Marshal the updated JSON data while preserving the order updatedDataBytes, err := json.MarshalIndent(jsonData, "", " ") if err != nil { - g.Errorf("Error marshaling JSON:", err) + g.Errorf("Error marshaling JSON: %v", err) return err } // Write the updated JSON data back to the file err = os.WriteFile(filePath, updatedDataBytes, filePermMode) if err != nil { - g.Errorf("Error writing file:", err) + g.Errorf("Error writing file: %v", err) return err } From f2d299a7000b2fc3f1025271cad62505b06101d6 Mon Sep 17 00:00:00 2001 From: wellsiau-aws Date: Fri, 31 May 2024 14:45:59 -0700 Subject: [PATCH 5/5] fmt --- .../provider/generators/schema_rename/main.go | 50 ++--- .../generators/schema_rename/rename/rename.go | 176 +++++++++--------- 2 files changed, 113 insertions(+), 113 deletions(-) diff --git a/internal/provider/generators/schema_rename/main.go b/internal/provider/generators/schema_rename/main.go index 7ecbb33d2..47240f286 100644 --- a/internal/provider/generators/schema_rename/main.go +++ b/internal/provider/generators/schema_rename/main.go @@ -1,36 +1,36 @@ package main import ( - "fmt" - "path/filepath" + "fmt" "os" - "strings" - - "github.com/hashicorp/terraform-provider-awscc/internal/provider/generators/schema_rename/rename" + "path/filepath" + "strings" + + "github.com/hashicorp/terraform-provider-awscc/internal/provider/generators/schema_rename/rename" ) func main() { - baseDir := "./internal/service/cloudformation/schemas/" - err := filepath.Walk(baseDir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } + baseDir := "./internal/service/cloudformation/schemas/" + err := filepath.Walk(baseDir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } - if !info.IsDir() && filepath.Ext(path) == ".json" { - generator := rename.NewGenerator() - // Skip files that start with "AWS_CloudFormation_" - if !strings.HasPrefix(info.Name(), "AWS_CloudFormation_") { - err = generator.RenameCfnSchemaFile(path) - if err != nil { - return err - } - } - } + if !info.IsDir() && filepath.Ext(path) == ".json" { + generator := rename.NewGenerator() + // Skip files that start with "AWS_CloudFormation_" + if !strings.HasPrefix(info.Name(), "AWS_CloudFormation_") { + err = generator.RenameCfnSchemaFile(path) + if err != nil { + return err + } + } + } - return nil - }) + return nil + }) - if err != nil { - fmt.Fprintf(os.Stderr, "Error: %v", err) - } + if err != nil { + fmt.Fprintf(os.Stderr, "Error: %v", err) + } } diff --git a/internal/provider/generators/schema_rename/rename/rename.go b/internal/provider/generators/schema_rename/rename/rename.go index d32db9781..073e7e407 100644 --- a/internal/provider/generators/schema_rename/rename/rename.go +++ b/internal/provider/generators/schema_rename/rename/rename.go @@ -1,13 +1,13 @@ package rename import ( - "encoding/json" - "io" - "os" - "strings" - "reflect" - - "github.com/hashicorp/terraform-provider-awscc/internal/provider/generators/common" + "encoding/json" + "io" + "os" + "reflect" + "strings" + + "github.com/hashicorp/terraform-provider-awscc/internal/provider/generators/common" ) type Generator struct { @@ -22,95 +22,95 @@ func NewGenerator() *Generator { const filePermMode = 0644 // Read/write for owner, read for group/others -func (g *Generator) RenameCfnSchemaFile (filePath string) error { - // Open JSON schema file from base directory - file, err := os.Open(filePath) - if err != nil { - g.Errorf("Error opening file: %v", err) - return err - } - defer file.Close() +func (g *Generator) RenameCfnSchemaFile(filePath string) error { + // Open JSON schema file from base directory + file, err := os.Open(filePath) + if err != nil { + g.Errorf("Error opening file: %v", err) + return err + } + defer file.Close() - // Read the JSON data - data, err := io.ReadAll(file) - if err != nil { - g.Errorf("Error reading file: %v", err) - return err - } + // Read the JSON data + data, err := io.ReadAll(file) + if err != nil { + g.Errorf("Error reading file: %v", err) + return err + } - // Unmarshal the JSON data into a map while preserving the order - var jsonData map[string]interface{} - err = json.Unmarshal(data, &jsonData) - if err != nil { - g.Errorf("Error unmarshaling JSON: %v", err) - return err - } + // Unmarshal the JSON data into a map while preserving the order + var jsonData map[string]interface{} + err = json.Unmarshal(data, &jsonData) + if err != nil { + g.Errorf("Error unmarshaling JSON: %v", err) + return err + } - // Create a copy of the original JSON data - originalData := make(map[string]interface{}) - for k, v := range jsonData { - originalData[k] = v - } + // Create a copy of the original JSON data + originalData := make(map[string]interface{}) + for k, v := range jsonData { + originalData[k] = v + } - // Replace "CloudFormation" with "Terraform" in the description - err = updateDescription(jsonData) - if err != nil { - g.Errorf("Error updating description: %v", err) - return err - } + // Replace "CloudFormation" with "Terraform" in the description + err = updateDescription(jsonData) + if err != nil { + g.Errorf("Error updating description: %v", err) + return err + } - // Check if the JSON data has changed - if reflect.DeepEqual(jsonData, originalData) { - // No changes detected, skip writing the file - return nil - } + // Check if the JSON data has changed + if reflect.DeepEqual(jsonData, originalData) { + // No changes detected, skip writing the file + return nil + } - // Marshal the updated JSON data while preserving the order - updatedDataBytes, err := json.MarshalIndent(jsonData, "", " ") - if err != nil { - g.Errorf("Error marshaling JSON: %v", err) - return err - } + // Marshal the updated JSON data while preserving the order + updatedDataBytes, err := json.MarshalIndent(jsonData, "", " ") + if err != nil { + g.Errorf("Error marshaling JSON: %v", err) + return err + } - // Write the updated JSON data back to the file - err = os.WriteFile(filePath, updatedDataBytes, filePermMode) - if err != nil { - g.Errorf("Error writing file: %v", err) - return err - } + // Write the updated JSON data back to the file + err = os.WriteFile(filePath, updatedDataBytes, filePermMode) + if err != nil { + g.Errorf("Error writing file: %v", err) + return err + } - g.Infof("File %s updated successfully\n", filePath) - return nil + g.Infof("File %s updated successfully\n", filePath) + return nil } func updateDescription(data map[string]interface{}) error { - for key, value := range data { - if key == "description" { - description, ok := value.(string) - if ok { - updatedDescription := strings.ReplaceAll(description, "AWS CloudFormation", "Terraform") - data[key] = updatedDescription - } - } else { - switch v := value.(type) { - case map[string]interface{}: - err := updateDescription(v) - if err != nil { - return err - } - case []interface{}: - for i, item := range v { - switch item := item.(type) { - case map[string]interface{}: - err := updateDescription(item) - if err != nil { - return err - } - v[i] = item - } - } - } - } - } - return nil -} \ No newline at end of file + for key, value := range data { + if key == "description" { + description, ok := value.(string) + if ok { + updatedDescription := strings.ReplaceAll(description, "AWS CloudFormation", "Terraform") + data[key] = updatedDescription + } + } else { + switch v := value.(type) { + case map[string]interface{}: + err := updateDescription(v) + if err != nil { + return err + } + case []interface{}: + for i, item := range v { + switch item := item.(type) { + case map[string]interface{}: + err := updateDescription(item) + if err != nil { + return err + } + v[i] = item + } + } + } + } + } + return nil +}