From 91cd8bbe4fe0ad5c970c19730b0175c302155fbc Mon Sep 17 00:00:00 2001 From: Rajat Bajaj Date: Mon, 28 Oct 2024 17:03:51 +0530 Subject: [PATCH 1/2] Added a flag for terraform version during generate --- internal/cli/terraform.go | 42 ++++++++++++++++++----------- internal/cli/terraform_test.go | 49 +++++++++++++++++++--------------- 2 files changed, 53 insertions(+), 38 deletions(-) diff --git a/internal/cli/terraform.go b/internal/cli/terraform.go index 973633b2..cf7f8565 100644 --- a/internal/cli/terraform.go +++ b/internal/cli/terraform.go @@ -38,17 +38,26 @@ var tfFlags = terraformFlags{ Help: "Resource types to generate Terraform config for. If not provided, config files for all " + "available resources will be generated.", }, + TerraformVersion: Flag{ + Name: "Terraform Version", + LongForm: "tf-version", + ShortForm: "v", + Help: "Terraform version that ought to be used while generating the terraform files for resources. " + + "If not provided, 1.5.0 is used by default", + }, } type ( terraformFlags struct { - OutputDIR Flag - Resources Flag + OutputDIR Flag + Resources Flag + TerraformVersion Flag } terraformInputs struct { - OutputDIR string - Resources []string + OutputDIR string + Resources []string + TerraformVersion string } ) @@ -147,6 +156,7 @@ func generateTerraformCmd(cli *cli) *cobra.Command { cmd.Flags().BoolVar(&cli.force, "force", false, "Skip confirmation.") tfFlags.OutputDIR.RegisterString(cmd, &inputs.OutputDIR, "./") tfFlags.Resources.RegisterStringSlice(cmd, &inputs.Resources, defaultResources) + tfFlags.TerraformVersion.RegisterString(cmd, &inputs.TerraformVersion, "1.5.0") return cmd } @@ -175,7 +185,7 @@ func generateTerraformCmdRun(cli *cli, inputs *terraformInputs) func(cmd *cobra. return err } - if err := generateTerraformImportConfig(inputs.OutputDIR, data); err != nil { + if err := generateTerraformImportConfig(inputs, data); err != nil { return err } @@ -191,7 +201,7 @@ func generateTerraformCmdRun(cli *cli, inputs *terraformInputs) func(cmd *cobra. } err = ansi.Spinner("Generating Terraform configuration", func() error { - return generateTerraformResourceConfig(cmd.Context(), inputs.OutputDIR) + return generateTerraformResourceConfig(cmd.Context(), inputs) }) if err != nil { @@ -241,20 +251,20 @@ func fetchImportData(ctx context.Context, fetchers ...resourceDataFetcher) (impo return deduplicateResourceNames(importData), nil } -func generateTerraformImportConfig(outputDIR string, data importDataList) error { +func generateTerraformImportConfig(inputs *terraformInputs, data importDataList) error { if len(data) == 0 { return errors.New("no import data available") } - if err := createOutputDirectory(outputDIR); err != nil { + if err := createOutputDirectory(inputs.OutputDIR); err != nil { return err } - if err := createMainFile(outputDIR); err != nil { + if err := createMainFile(inputs); err != nil { return err } - return createImportFile(outputDIR, data) + return createImportFile(inputs.OutputDIR, data) } func createOutputDirectory(outputDIR string) error { @@ -267,8 +277,8 @@ func createOutputDirectory(outputDIR string) error { return nil } -func createMainFile(outputDIR string) error { - filePath := path.Join(outputDIR, "auth0_main.tf") +func createMainFile(input *terraformInputs) error { + filePath := path.Join(input.OutputDIR, "auth0_main.tf") file, err := os.Create(filePath) if err != nil { @@ -279,7 +289,7 @@ func createMainFile(outputDIR string) error { }() fileContent := `terraform { - required_version = ">= 1.5.0" + required_version = ">= ` + input.TerraformVersion + `" required_providers { auth0 = { source = "auth0/auth0" @@ -327,15 +337,15 @@ import { return t.Execute(file, data) } -func generateTerraformResourceConfig(ctx context.Context, outputDIR string) error { - absoluteOutputPath, err := filepath.Abs(outputDIR) +func generateTerraformResourceConfig(ctx context.Context, input *terraformInputs) error { + absoluteOutputPath, err := filepath.Abs(input.OutputDIR) if err != nil { return err } installer := &releases.ExactVersion{ Product: product.Terraform, - Version: version.Must(version.NewVersion("1.5.0")), + Version: version.Must(version.NewVersion(input.TerraformVersion)), InstallDir: absoluteOutputPath, } diff --git a/internal/cli/terraform_test.go b/internal/cli/terraform_test.go index fe499c9f..9fcef3ec 100644 --- a/internal/cli/terraform_test.go +++ b/internal/cli/terraform_test.go @@ -79,78 +79,78 @@ func TestFetchImportData(t *testing.T) { func TestGenerateTerraformImportConfig(t *testing.T) { t.Run("it can correctly generate the terraform config files", func(t *testing.T) { - outputDIR, importData := setupTestDIRAndImportData(t) + input, importData := setupTestDIRAndImportData(t) - err := generateTerraformImportConfig(outputDIR, importData) + err := generateTerraformImportConfig(&input, importData) require.NoError(t, err) - assertTerraformMainFileWasGeneratedCorrectly(t, outputDIR) - assertTerraformImportFileWasGeneratedCorrectly(t, outputDIR, importData) + assertTerraformMainFileWasGeneratedCorrectly(t, input.OutputDIR) + assertTerraformImportFileWasGeneratedCorrectly(t, input.OutputDIR, importData) }) t.Run("it can correctly generate the terraform main config file even if the dir exists", func(t *testing.T) { - outputDIR, importData := setupTestDIRAndImportData(t) + input, importData := setupTestDIRAndImportData(t) - err := os.MkdirAll(outputDIR, 0755) + err := os.MkdirAll(input.OutputDIR, 0755) require.NoError(t, err) - err = generateTerraformImportConfig(outputDIR, importData) + err = generateTerraformImportConfig(&input, importData) require.NoError(t, err) - assertTerraformMainFileWasGeneratedCorrectly(t, outputDIR) - assertTerraformImportFileWasGeneratedCorrectly(t, outputDIR, importData) + assertTerraformMainFileWasGeneratedCorrectly(t, input.OutputDIR) + assertTerraformImportFileWasGeneratedCorrectly(t, input.OutputDIR, importData) }) t.Run("it fails to generate the terraform config files if there's no import data", func(t *testing.T) { - outputDIR, _ := setupTestDIRAndImportData(t) + input, _ := setupTestDIRAndImportData(t) - err := generateTerraformImportConfig(outputDIR, importDataList{}) + err := generateTerraformImportConfig(&input, importDataList{}) assert.EqualError(t, err, "no import data available") }) t.Run("it fails to create the directory if path is empty", func(t *testing.T) { _, importData := setupTestDIRAndImportData(t) - err := generateTerraformImportConfig("", importData) + err := generateTerraformImportConfig(&terraformInputs{OutputDIR: ""}, importData) assert.EqualError(t, err, "mkdir : no such file or directory") }) t.Run("it fails to create the main.tf file if file is already created and read only", func(t *testing.T) { - outputDIR, importData := setupTestDIRAndImportData(t) + input, importData := setupTestDIRAndImportData(t) - err := os.MkdirAll(outputDIR, 0755) + err := os.MkdirAll(input.OutputDIR, 0755) require.NoError(t, err) - mainFilePath := path.Join(outputDIR, "auth0_main.tf") + mainFilePath := path.Join(input.OutputDIR, "auth0_main.tf") _, err = os.Create(mainFilePath) require.NoError(t, err) err = os.Chmod(mainFilePath, 0444) require.NoError(t, err) - err = generateTerraformImportConfig(outputDIR, importData) + err = generateTerraformImportConfig(&input, importData) assert.EqualError(t, err, fmt.Sprintf("open %s: permission denied", mainFilePath)) }) t.Run("it fails to create the auth0_import.tf file if file is already created and read only", func(t *testing.T) { - outputDIR, importData := setupTestDIRAndImportData(t) + input, importData := setupTestDIRAndImportData(t) - err := os.MkdirAll(outputDIR, 0755) + err := os.MkdirAll(input.OutputDIR, 0755) require.NoError(t, err) - importFilePath := path.Join(outputDIR, "auth0_import.tf") + importFilePath := path.Join(input.OutputDIR, "auth0_import.tf") _, err = os.Create(importFilePath) require.NoError(t, err) err = os.Chmod(importFilePath, 0444) require.NoError(t, err) - err = generateTerraformImportConfig(outputDIR, importData) + err = generateTerraformImportConfig(&input, importData) assert.EqualError(t, err, fmt.Sprintf("open %s: permission denied", importFilePath)) }) } -func setupTestDIRAndImportData(t *testing.T) (string, importDataList) { +func setupTestDIRAndImportData(t *testing.T) (terraformInputs, importDataList) { dirPath, err := os.MkdirTemp("", "terraform-*") require.NoError(t, err) @@ -179,7 +179,12 @@ func setupTestDIRAndImportData(t *testing.T) (string, importDataList) { }, } - return outputDIR, importData + input := terraformInputs{ + outputDIR, + nil, + "1.5.0", + } + return input, importData } func assertTerraformMainFileWasGeneratedCorrectly(t *testing.T, outputDIR string) { From da4c6966495005033756db27c16775937fbff81d Mon Sep 17 00:00:00 2001 From: Rajat Bajaj Date: Thu, 31 Oct 2024 13:27:36 +0530 Subject: [PATCH 2/2] Updated docs --- docs/auth0_terraform_generate.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/auth0_terraform_generate.md b/docs/auth0_terraform_generate.md index 02a4232a..19326a29 100644 --- a/docs/auth0_terraform_generate.md +++ b/docs/auth0_terraform_generate.md @@ -34,6 +34,7 @@ auth0 terraform generate [flags] --force Skip confirmation. -o, --output-dir string Output directory for the generated Terraform config files. If not provided, the files will be saved in the current working directory. (default "./") -r, --resources strings Resource types to generate Terraform config for. If not provided, config files for all available resources will be generated. (default [auth0_action,auth0_attack_protection,auth0_branding,auth0_client,auth0_client_grant,auth0_connection,auth0_custom_domain,auth0_flow,auth0_flow_vault_connection,auth0_form,auth0_email_provider,auth0_email_template,auth0_guardian,auth0_organization,auth0_pages,auth0_prompt,auth0_prompt_custom_text,auth0_resource_server,auth0_role,auth0_tenant,auth0_trigger_actions]) + -v, --tf-version string Terraform version that ought to be used while generating the terraform files for resources. If not provided, 1.5.0 is used by default (default "1.5.0") ```