-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add terraform generate command skeleton
- Loading branch information
Showing
3 changed files
with
198 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package cli | ||
|
||
import ( | ||
"os" | ||
"path" | ||
|
||
"github.com/spf13/cobra" | ||
) | ||
|
||
var tfFlags = terraformFlags{ | ||
OutputDIR: Flag{ | ||
Name: "Output Dir", | ||
LongForm: "output-dir", | ||
ShortForm: "o", | ||
Help: "Output directory for the generated Terraform config files.", | ||
}, | ||
} | ||
|
||
type ( | ||
terraformFlags struct { | ||
OutputDIR Flag | ||
} | ||
|
||
terraformInputs struct { | ||
OutputDIR string | ||
} | ||
) | ||
|
||
func terraformCmd(cli *cli) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "terraform", | ||
Aliases: []string{"tf"}, | ||
Short: "Manage terraform configuration for your Auth0 Tenant", | ||
Long: "This command facilitates the integration of Auth0 with [Terraform](https://www.terraform.io/), an " + | ||
"infrastructure as code tool.", | ||
} | ||
|
||
cmd.SetUsageTemplate(resourceUsageTemplate()) | ||
cmd.AddCommand(generateTerraformCmd(cli)) | ||
|
||
return cmd | ||
} | ||
|
||
func generateTerraformCmd(cli *cli) *cobra.Command { | ||
var inputs terraformInputs | ||
|
||
cmd := &cobra.Command{ | ||
Use: "generate", | ||
Aliases: []string{"gen", "export"}, | ||
Short: "Generate terraform configuration for your Auth0 Tenant", | ||
Long: "This command is designed to streamline the process of generating Terraform configuration files for " + | ||
"your Auth0 resources, serving as a bridge between the two.\n\n It automatically scans your Auth0 Tenant " + | ||
"and compiles a set of Terraform configuration files based on the existing resources and configurations." + | ||
"\n\nThe generated Terraform files are written in HashiCorp Configuration Language (HCL).", | ||
RunE: generateTerraformCmdRun(cli, &inputs), | ||
} | ||
|
||
tfFlags.OutputDIR.RegisterString(cmd, &inputs.OutputDIR, "./") | ||
|
||
return cmd | ||
} | ||
|
||
func generateTerraformCmdRun(cli *cli, inputs *terraformInputs) func(cmd *cobra.Command, args []string) error { | ||
return func(cmd *cobra.Command, args []string) error { | ||
if err := generateTerraformConfigFiles(inputs); err != nil { | ||
return err | ||
} | ||
|
||
cli.renderer.Infof("Terraform config files generated successfully.") | ||
cli.renderer.Infof( | ||
"Follow this " + | ||
"[quickstart](https://registry.terraform.io/providers/auth0/auth0/latest/docs/guides/quickstart) " + | ||
"to go through setting up an Auth0 application for the provider to authenticate against and manage " + | ||
"resources.", | ||
) | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func generateTerraformConfigFiles(inputs *terraformInputs) error { | ||
const readWritePermission = 0755 | ||
if err := os.MkdirAll(inputs.OutputDIR, readWritePermission); err != nil { | ||
if !os.IsExist(err) { | ||
return err | ||
} | ||
} | ||
|
||
mainTerraformConfigFile, err := os.Create(path.Join(inputs.OutputDIR, "main.tf")) | ||
if err != nil { | ||
return err | ||
} | ||
defer mainTerraformConfigFile.Close() | ||
|
||
mainTerraformConfigFileContent := `terraform { | ||
required_version = "~> 1.5.0" | ||
required_providers { | ||
auth0 = { | ||
source = "auth0/auth0" | ||
version = "1.0.0-beta.1" | ||
} | ||
} | ||
} | ||
provider "auth0" { | ||
debug = true | ||
} | ||
` | ||
|
||
_, err = mainTerraformConfigFile.WriteString(mainTerraformConfigFileContent) | ||
return err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package cli | ||
|
||
import ( | ||
"os" | ||
"path" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestGenerateTerraformConfigFiles(t *testing.T) { | ||
testInputs := terraformInputs{ | ||
OutputDIR: "./terraform/dev", | ||
} | ||
defer os.RemoveAll(testInputs.OutputDIR) | ||
|
||
t.Run("it can correctly generate the terraform main config file", func(t *testing.T) { | ||
assertTerraformConfigFilesWereGeneratedWithCorrectContent(t, &testInputs) | ||
}) | ||
|
||
t.Run("it can correctly generate the terraform main config file even if the dir exists", func(t *testing.T) { | ||
err := os.MkdirAll(testInputs.OutputDIR, 0755) | ||
require.NoError(t, err) | ||
|
||
assertTerraformConfigFilesWereGeneratedWithCorrectContent(t, &testInputs) | ||
}) | ||
|
||
t.Run("it fails to create the directory if path is a read only location", func(t *testing.T) { | ||
testInputs := terraformInputs{ | ||
OutputDIR: "/terraform/dev", | ||
} | ||
|
||
err := generateTerraformConfigFiles(&testInputs) | ||
assert.EqualError(t, err, "mkdir /terraform: read-only file system") | ||
}) | ||
|
||
t.Run("it fails to create the main.tf file if file is already created and read only", func(t *testing.T) { | ||
err := os.MkdirAll(testInputs.OutputDIR, 0755) | ||
require.NoError(t, err) | ||
|
||
mainFilePath := path.Join(testInputs.OutputDIR, "main.tf") | ||
_, err = os.Create(mainFilePath) | ||
require.NoError(t, err) | ||
|
||
err = os.Chmod(mainFilePath, 0444) | ||
require.NoError(t, err) | ||
|
||
err = generateTerraformConfigFiles(&testInputs) | ||
assert.EqualError(t, err, "open terraform/dev/main.tf: permission denied") | ||
}) | ||
} | ||
|
||
func assertTerraformConfigFilesWereGeneratedWithCorrectContent(t *testing.T, testInputs *terraformInputs) { | ||
err := generateTerraformConfigFiles(testInputs) | ||
require.NoError(t, err) | ||
|
||
// Assert that the directory was created. | ||
_, err = os.Stat(testInputs.OutputDIR) | ||
assert.NoError(t, err) | ||
|
||
// Assert that the main.tf file was created with the correct content. | ||
mainTerraformConfigFilePath := path.Join(testInputs.OutputDIR, "main.tf") | ||
_, err = os.Stat(mainTerraformConfigFilePath) | ||
assert.NoError(t, err) | ||
|
||
expectedContent := `terraform { | ||
required_version = "~> 1.5.0" | ||
required_providers { | ||
auth0 = { | ||
source = "auth0/auth0" | ||
version = "1.0.0-beta.1" | ||
} | ||
} | ||
} | ||
provider "auth0" { | ||
debug = true | ||
} | ||
` | ||
// Read the file content and check if it matches the expected content | ||
content, err := os.ReadFile(mainTerraformConfigFilePath) | ||
assert.NoError(t, err) | ||
assert.Equal(t, expectedContent, string(content)) | ||
} |