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

DXCDT-500: auth0_import.tf file creation function #793

Merged
merged 6 commits into from
Aug 8, 2023
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
64 changes: 52 additions & 12 deletions internal/cli/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package cli

import (
"context"
"errors"
"os"
"path"
"text/template"

"github.com/spf13/cobra"

Expand Down Expand Up @@ -80,11 +82,7 @@ func generateTerraformCmdRun(cli *cli, inputs *terraformInputs) func(cmd *cobra.
return err
}

// Just temporarily. Remove this once import file generation is in place.
cli.renderer.JSONResult(data)
cli.renderer.Newline()

if err := generateTerraformConfigFiles(inputs); err != nil {
if err := generateTerraformConfigFiles(inputs.OutputDIR, data); err != nil {
return err
}

Expand Down Expand Up @@ -115,21 +113,35 @@ func fetchImportData(ctx context.Context, fetchers ...resourceDataFetcher) (impo
return importData, nil
}

func generateTerraformConfigFiles(inputs *terraformInputs) error {
func generateTerraformConfigFiles(outputDIR string, data importDataList) error {
if len(data) == 0 {
return errors.New("no import data available")
}

const readWritePermission = 0755
if err := os.MkdirAll(inputs.OutputDIR, readWritePermission); err != nil {
if err := os.MkdirAll(outputDIR, readWritePermission); err != nil {
if !os.IsExist(err) {
return err
}
}

mainTerraformConfigFile, err := os.Create(path.Join(inputs.OutputDIR, "main.tf"))
if err := createMainFile(outputDIR); err != nil {
return err
}

return createImportFile(outputDIR, data)
}

func createMainFile(outputDIR string) error {
filePath := path.Join(outputDIR, "main.tf")

file, err := os.Create(filePath)
if err != nil {
return err
}
defer mainTerraformConfigFile.Close()
defer file.Close()

mainTerraformConfigFileContent := `terraform {
fileContent := `terraform {
required_version = "~> 1.5.0"
required_providers {
auth0 = {
Expand All @@ -140,10 +152,38 @@ func generateTerraformConfigFiles(inputs *terraformInputs) error {
}

provider "auth0" {
debug = true
debug = true
}
`

_, err = mainTerraformConfigFile.WriteString(mainTerraformConfigFileContent)
_, err = file.WriteString(fileContent)
return err
}

func createImportFile(outputDIR string, data importDataList) error {
filePath := path.Join(outputDIR, "auth0_import.tf")

file, err := os.Create(filePath)
if err != nil {
return err
}
defer file.Close()

fileContent := `# This file is automatically generated via the Auth0 CLI.
# It can be safely removed after the successful generation
# of Terraform resource definition files.
{{range .}}
import {
id = "{{ .ImportID }}"
to = {{ .ResourceName }}
}
{{end}}
`

t, err := template.New("terraform").Parse(fileContent)
if err != nil {
return err
}

return t.Execute(file, data)
}
135 changes: 112 additions & 23 deletions internal/cli/terraform_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package cli

import (
"bytes"
"context"
"errors"
"fmt"
"os"
"path"
"testing"
"text/template"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -51,58 +54,110 @@ func TestFetchImportData(t *testing.T) {
}

func TestGenerateTerraformConfigFiles(t *testing.T) {
testInputs := terraformInputs{
OutputDIR: "./terraform/dev",
}
defer os.RemoveAll("./terraform")
t.Run("it can correctly generate the terraform config files", func(t *testing.T) {
outputDIR, importData := setupTestDIRAndImportData(t)

err := generateTerraformConfigFiles(outputDIR, importData)
require.NoError(t, err)

t.Run("it can correctly generate the terraform main config file", func(t *testing.T) {
assertTerraformConfigFilesWereGeneratedWithCorrectContent(t, &testInputs)
assertTerraformMainFileWasGeneratedCorrectly(t, outputDIR)
assertTerraformImportFileWasGeneratedCorrectly(t, outputDIR, importData)
})

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)
outputDIR, importData := setupTestDIRAndImportData(t)

err := os.MkdirAll(outputDIR, 0755)
require.NoError(t, err)

err = generateTerraformConfigFiles(outputDIR, importData)
require.NoError(t, err)

assertTerraformConfigFilesWereGeneratedWithCorrectContent(t, &testInputs)
assertTerraformMainFileWasGeneratedCorrectly(t, outputDIR)
assertTerraformImportFileWasGeneratedCorrectly(t, 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)

err := generateTerraformConfigFiles(outputDIR, 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) {
testInputs := terraformInputs{
OutputDIR: "",
}
_, importData := setupTestDIRAndImportData(t)

err := generateTerraformConfigFiles(&testInputs)
err := generateTerraformConfigFiles("", 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) {
err := os.MkdirAll(testInputs.OutputDIR, 0755)
outputDIR, importData := setupTestDIRAndImportData(t)

err := os.MkdirAll(outputDIR, 0755)
require.NoError(t, err)

mainFilePath := path.Join(testInputs.OutputDIR, "main.tf")
mainFilePath := path.Join(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")
err = generateTerraformConfigFiles(outputDIR, 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)

err := os.MkdirAll(outputDIR, 0755)
require.NoError(t, err)

importFilePath := path.Join(outputDIR, "auth0_import.tf")
_, err = os.Create(importFilePath)
require.NoError(t, err)

err = os.Chmod(importFilePath, 0444)
require.NoError(t, err)

err = generateTerraformConfigFiles(outputDIR, importData)
assert.EqualError(t, err, fmt.Sprintf("open %s: permission denied", importFilePath))
})
}

func assertTerraformConfigFilesWereGeneratedWithCorrectContent(t *testing.T, testInputs *terraformInputs) {
err := generateTerraformConfigFiles(testInputs)
func setupTestDIRAndImportData(t *testing.T) (string, importDataList) {
dirPath, err := os.MkdirTemp("", "terraform-*")
require.NoError(t, err)

t.Cleanup(func() {
err := os.RemoveAll(dirPath)
require.NoError(t, err)
})

outputDIR := path.Join(dirPath, "dev")
importData := importDataList{
{
ResourceName: "auth0_client.MyTestClient1",
ImportID: "clientID_1",
},
{
ResourceName: "auth0_client.MyTestClient2",
ImportID: "clientID_2",
},
}

return outputDIR, importData
}

func assertTerraformMainFileWasGeneratedCorrectly(t *testing.T, outputDIR string) {
// Assert that the directory was created.
_, err = os.Stat(testInputs.OutputDIR)
_, err := os.Stat(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)
filePath := path.Join(outputDIR, "main.tf")
_, err = os.Stat(filePath)
assert.NoError(t, err)

expectedContent := `terraform {
Expand All @@ -116,11 +171,45 @@ func assertTerraformConfigFilesWereGeneratedWithCorrectContent(t *testing.T, tes
}

provider "auth0" {
debug = true
debug = true
}
`
// Read the file content and check if it matches the expected content
content, err := os.ReadFile(mainTerraformConfigFilePath)
content, err := os.ReadFile(filePath)
assert.NoError(t, err)
assert.Equal(t, expectedContent, string(content))
}

func assertTerraformImportFileWasGeneratedCorrectly(t *testing.T, outputDIR string, data importDataList) {
// Assert that the directory was created.
_, err := os.Stat(outputDIR)
assert.NoError(t, err)

// Assert that the auth0_import.tf file was created with the correct content.
filePath := path.Join(outputDIR, "auth0_import.tf")
_, err = os.Stat(filePath)
assert.NoError(t, err)

contentTemplate := `# This file is automatically generated via the Auth0 CLI.
# It can be safely removed after the successful generation
# of Terraform resource definition files.
{{range .}}
import {
id = "{{ .ImportID }}"
to = {{ .ResourceName }}
}
{{end}}
`

tmpl, err := template.New("terraform").Parse(contentTemplate)
require.NoError(t, err)

var expectedContent bytes.Buffer
err = tmpl.Execute(&expectedContent, data)
require.NoError(t, err)

// Read the file content and check if it matches the expected content
content, err := os.ReadFile(filePath)
assert.NoError(t, err)
assert.Equal(t, expectedContent.String(), string(content))
}
Loading