Skip to content

Commit

Permalink
Merge pull request #39 from AlexNabokikh/recusive
Browse files Browse the repository at this point in the history
feat(#38): add recursive option
  • Loading branch information
AlexNabokikh authored Jul 29, 2023
2 parents 793b2dd + 1d4a708 commit 9306198
Show file tree
Hide file tree
Showing 7 changed files with 320 additions and 15 deletions.
1 change: 1 addition & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ linters:
enable-all: true
disable:
- deadcode
- depguard
- exhaustivestruct
- exhaustruct
- forbidigo
Expand Down
13 changes: 12 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ func Execute() {
filePath string
outputPath string
dryRun bool
recursive bool
)

rootCmd := &cobra.Command{
Expand All @@ -34,6 +35,11 @@ func Execute() {

i := tsort.NewIngestor()

if recursive {
// Ignore the outputPath when in recursive mode
return i.ParseAll(filePath, dryRun)
}

return i.Parse(filePath, outputPath, dryRun)
},
}
Expand All @@ -43,12 +49,17 @@ func Execute() {
"out",
"o",
"",
"path to the output file")
"path to the output file. Ignored if --recursive is used.")
rootCmd.PersistentFlags().BoolVarP(
&dryRun,
"dry-run",
"d", false,
"preview the changes without altering the original file.")
rootCmd.PersistentFlags().BoolVarP(
&recursive,
"recursive",
"r", false,
"parse all Terraform files within the provided directory and its subdirectories recursively")

if err := rootCmd.Execute(); err != nil {
log.Fatalf("error: %s", err)
Expand Down
82 changes: 82 additions & 0 deletions tsort/testdata/recursive/valid.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
variable "kubernetes_pipeline_roles" {
description = "IAM roles for pipelines required access to EKS."
type = list(object({
rolearn = string
namespaces = list(string)
}))
default = []
}




variable "kubernetes_pipeline_users" {
description = "IAM users for pipelines required access to EKS."
type = list(object({
userarn = string
namespaces = list(string)
}))
default = []
}


variable "external_dns_additional_managed_zones" {
description = "Additional managed zones for external-dns."
type = list(string)
default = []
}

variable "aws-profile" {
description = "The aws profile name, used when creating the kubeconfig file."
}

variable "additional_userdata" {
default = ""
}




terraform {
required_version = ">= 0.12"
}




variable "eks_shared_namespaces" {
description = "Namespaces to be shared between teams."
type = map(list(string))
default = {
dns = ["external-dns"]
infra = ["infra-shared"]
logging = ["logging"]
monitoring = ["infra-monitoring"]
ingress = ["infra-ingress"]
argo = ["argo"]
newrelic = ["newrelic"]
}
}

output "hardened-image-id" {
description = "The AMI ID of the hardened image."
value = data.aws_ami.hardened.id
}



locals {
kubernetes_pipeline_roles = [
for role in var.kubernetes_pipeline_roles : {
rolearn = role.rolearn
namespaces = role.namespaces
}
]
}



output "private_key_name" {
description = "The name of the private key made to share."
value = module.account.private_key_name
}
82 changes: 82 additions & 0 deletions tsort/testdata/recursive/valid1.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
variable "kubernetes_pipeline_roles" {
description = "IAM roles for pipelines required access to EKS."
type = list(object({
rolearn = string
namespaces = list(string)
}))
default = []
}




variable "kubernetes_pipeline_users" {
description = "IAM users for pipelines required access to EKS."
type = list(object({
userarn = string
namespaces = list(string)
}))
default = []
}


variable "external_dns_additional_managed_zones" {
description = "Additional managed zones for external-dns."
type = list(string)
default = []
}

variable "aws-profile" {
description = "The aws profile name, used when creating the kubeconfig file."
}

variable "additional_userdata" {
default = ""
}




terraform {
required_version = ">= 0.12"
}




variable "eks_shared_namespaces" {
description = "Namespaces to be shared between teams."
type = map(list(string))
default = {
dns = ["external-dns"]
infra = ["infra-shared"]
logging = ["logging"]
monitoring = ["infra-monitoring"]
ingress = ["infra-ingress"]
argo = ["argo"]
newrelic = ["newrelic"]
}
}

output "hardened-image-id" {
description = "The AMI ID of the hardened image."
value = data.aws_ami.hardened.id
}



locals {
kubernetes_pipeline_roles = [
for role in var.kubernetes_pipeline_roles : {
rolearn = role.rolearn
namespaces = role.namespaces
}
]
}



output "private_key_name" {
description = "The name of the private key made to share."
value = module.account.private_key_name
}
82 changes: 82 additions & 0 deletions tsort/testdata/recursive/valid2.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
variable "kubernetes_pipeline_roles" {
description = "IAM roles for pipelines required access to EKS."
type = list(object({
rolearn = string
namespaces = list(string)
}))
default = []
}




variable "kubernetes_pipeline_users" {
description = "IAM users for pipelines required access to EKS."
type = list(object({
userarn = string
namespaces = list(string)
}))
default = []
}


variable "external_dns_additional_managed_zones" {
description = "Additional managed zones for external-dns."
type = list(string)
default = []
}

variable "aws-profile" {
description = "The aws profile name, used when creating the kubeconfig file."
}

variable "additional_userdata" {
default = ""
}




terraform {
required_version = ">= 0.12"
}




variable "eks_shared_namespaces" {
description = "Namespaces to be shared between teams."
type = map(list(string))
default = {
dns = ["external-dns"]
infra = ["infra-shared"]
logging = ["logging"]
monitoring = ["infra-monitoring"]
ingress = ["infra-ingress"]
argo = ["argo"]
newrelic = ["newrelic"]
}
}

output "hardened-image-id" {
description = "The AMI ID of the hardened image."
value = data.aws_ami.hardened.id
}



locals {
kubernetes_pipeline_roles = [
for role in var.kubernetes_pipeline_roles : {
rolearn = role.rolearn
namespaces = role.namespaces
}
]
}



output "private_key_name" {
description = "The name of the private key made to share."
value = module.account.private_key_name
}
52 changes: 41 additions & 11 deletions tsort/tfsort_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package tsort_test

import (
"fmt"
"os"
"testing"

Expand Down Expand Up @@ -101,18 +102,53 @@ func TestParse(t *testing.T) {
}
})

t.Run("Error writing to output file", func(t *testing.T) {
os.Remove(outputFile)
if err := os.WriteFile(outputFile, []byte("data"), 0o000); err != nil {
// cleanup
os.Remove(outputFile)
}

func TestParseAll(t *testing.T) {
ingestor := tsort.NewIngestor()

// Save original content of the files
originalContent, err := os.ReadFile("testdata/valid.tf")
if err != nil {
t.Fatalf("Failed to read original content: %v", err)
}

t.Run("Valid Directory", func(t *testing.T) {
if err := ingestor.ParseAll("testdata/recursive", false); err != nil {
t.Errorf("Unexpected error: %v", err)
}
for _, file := range []string{"valid.tf", "valid1.tf", "valid2.tf"} {
filePath := fmt.Sprintf("testdata/recursive/%s", file)
expectedFile, _ := os.ReadFile("testdata/expected.tf")
outFile, _ := os.ReadFile(filePath)

if string(outFile) != string(expectedFile) {
t.Errorf("Output file content in '%s' is not as expected", filePath)
}
}
})

t.Run("Write to stdout", func(t *testing.T) {
if err := ingestor.ParseAll("testdata/recursive", true); err != nil {
t.Errorf("Unexpected error: %v", err)
}
if err := ingestor.Parse(validFilePath, outputFile, false); err == nil {
})

t.Run("Error accessing file", func(t *testing.T) {
if err := ingestor.ParseAll("nonexistent_directory", false); err == nil {
t.Errorf("Expected error but not occurred")
}
})

// cleanup
os.Remove(outputFile)
for _, file := range []string{"valid.tf", "valid1.tf", "valid2.tf"} {
filePath := fmt.Sprintf("testdata/recursive/%s", file)
if err := os.WriteFile(filePath, originalContent, 0o644); err != nil {
t.Errorf("Unexpected error: %v", err)
}
}
}

func TestValidateFilePath(t *testing.T) {
Expand All @@ -128,12 +164,6 @@ func TestValidateFilePath(t *testing.T) {
}
})

t.Run("File is directory", func(t *testing.T) {
if err := tsort.ValidateFilePath("testdata"); err == nil {
t.Errorf("Expected error but not occurred")
}
})

t.Run("Valid File Path", func(t *testing.T) {
if err := tsort.ValidateFilePath(validFilePath); err != nil {
t.Errorf("Unexpected error: %v", err)
Expand Down
Loading

0 comments on commit 9306198

Please sign in to comment.