Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new flag to specify terraform version in auth0 tf generate command #1098

Merged
merged 3 commits into from
Oct 31, 2024
Merged
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
1 change: 1 addition & 0 deletions docs/auth0_terraform_generate.md
Original file line number Diff line number Diff line change
Expand Up @@ -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")
```


Expand Down
42 changes: 26 additions & 16 deletions internal/cli/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
)

Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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
}

Expand All @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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"
Expand Down Expand Up @@ -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,
}

Expand Down
49 changes: 27 additions & 22 deletions internal/cli/terraform_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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) {
Expand Down
Loading