-
Notifications
You must be signed in to change notification settings - Fork 162
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1562 from snyk/fix/tf-hcl-schema
Support tfstate discovering within workspaces
- Loading branch information
Showing
16 changed files
with
171 additions
and
42 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
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 |
---|---|---|
@@ -1,78 +1,129 @@ | ||
package hcl | ||
|
||
import ( | ||
"path" | ||
"testing" | ||
|
||
"github.com/snyk/driftctl/pkg/iac/config" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestHCL_getCurrentWorkspaceName(t *testing.T) { | ||
cases := []struct { | ||
name string | ||
dir string | ||
want string | ||
}{ | ||
{ | ||
name: "test with non-default workspace", | ||
dir: "testdata/foo_workspace", | ||
want: "foo", | ||
}, | ||
{ | ||
name: "test with non-existing directory", | ||
dir: "testdata/noenvfile", | ||
want: "default", | ||
}, | ||
} | ||
|
||
for _, tt := range cases { | ||
t.Run(tt.name, func(t *testing.T) { | ||
workspace := GetCurrentWorkspaceName(tt.dir) | ||
assert.Equal(t, tt.want, workspace) | ||
}) | ||
} | ||
} | ||
|
||
func TestBackend_SupplierConfig(t *testing.T) { | ||
cases := []struct { | ||
name string | ||
dir string | ||
want *config.SupplierConfig | ||
wantErr string | ||
name string | ||
filename string | ||
want *config.SupplierConfig | ||
wantErr string | ||
}{ | ||
{ | ||
name: "test with no backend block", | ||
dir: "testdata/no_backend_block.tf", | ||
want: nil, | ||
wantErr: "testdata/no_backend_block.tf:1,11-11: Missing backend block; A backend block is required.", | ||
name: "test with no backend block", | ||
filename: "testdata/no_backend_block.tf", | ||
want: nil, | ||
wantErr: "testdata/no_backend_block.tf:1,11-11: Missing backend block; A backend block is required.", | ||
}, | ||
{ | ||
name: "test with local backend block", | ||
dir: "testdata/local_backend_block.tf", | ||
name: "test with local backend block", | ||
filename: "testdata/local_backend_block.tf", | ||
want: &config.SupplierConfig{ | ||
Key: "tfstate", | ||
Path: "terraform-state-prod/network/terraform.tfstate", | ||
}, | ||
}, | ||
{ | ||
name: "test with S3 backend block", | ||
dir: "testdata/s3_backend_block.tf", | ||
name: "test with S3 backend block", | ||
filename: "testdata/s3_backend_block.tf", | ||
want: &config.SupplierConfig{ | ||
Key: "tfstate", | ||
Backend: "s3", | ||
Path: "terraform-state-prod/network/terraform.tfstate", | ||
}, | ||
}, | ||
{ | ||
name: "test with GCS backend block", | ||
dir: "testdata/gcs_backend_block.tf", | ||
name: "test with S3 backend block with non-default workspace", | ||
filename: "testdata/s3_backend_workspace/s3_backend_block.tf", | ||
want: &config.SupplierConfig{ | ||
Key: "tfstate", | ||
Backend: "s3", | ||
Path: "terraform-state-prod/env:/bar/network/terraform.tfstate", | ||
}, | ||
}, | ||
{ | ||
name: "test with GCS backend block", | ||
filename: "testdata/gcs_backend_block.tf", | ||
want: &config.SupplierConfig{ | ||
Key: "tfstate", | ||
Backend: "gs", | ||
Path: "tf-state-prod/terraform/state.tfstate", | ||
Path: "tf-state-prod/terraform/state/default.tfstate", | ||
}, | ||
}, | ||
{ | ||
name: "test with Azure backend block", | ||
dir: "testdata/azurerm_backend_block.tf", | ||
name: "test with Azure backend block", | ||
filename: "testdata/azurerm_backend_block.tf", | ||
want: &config.SupplierConfig{ | ||
Key: "tfstate", | ||
Backend: "azurerm", | ||
Path: "states/prod.terraform.tfstate", | ||
}, | ||
}, | ||
{ | ||
name: "test with Azure backend block with non-default workspace", | ||
filename: "testdata/azurerm_backend_workspace/azurerm_backend_block.tf", | ||
want: &config.SupplierConfig{ | ||
Key: "tfstate", | ||
Backend: "azurerm", | ||
Path: "states/prod.terraform.tfstateenv:bar", | ||
}, | ||
}, | ||
{ | ||
name: "test with unknown backend", | ||
filename: "testdata/unknown_backend_block.tf", | ||
want: nil, | ||
}, | ||
} | ||
|
||
for _, tt := range cases { | ||
t.Run(tt.name, func(t *testing.T) { | ||
hcl, err := ParseTerraformFromHCL(tt.dir) | ||
hcl, err := ParseTerraformFromHCL(tt.filename) | ||
if tt.wantErr == "" { | ||
assert.NoError(t, err) | ||
} else { | ||
assert.EqualError(t, err, tt.wantErr) | ||
return | ||
} | ||
|
||
if hcl.Backend.SupplierConfig() == nil { | ||
ws := GetCurrentWorkspaceName(path.Dir(tt.filename)) | ||
if hcl.Backend.SupplierConfig(ws) == nil { | ||
assert.Nil(t, tt.want) | ||
return | ||
} | ||
|
||
assert.Equal(t, *tt.want, *hcl.Backend.SupplierConfig()) | ||
assert.Equal(t, *tt.want, *hcl.Backend.SupplierConfig(ws)) | ||
}) | ||
} | ||
} |
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 |
---|---|---|
@@ -1,31 +1,53 @@ | ||
package hcl | ||
|
||
import ( | ||
"io/ioutil" | ||
"path" | ||
"strings" | ||
|
||
"github.com/hashicorp/hcl/v2" | ||
"github.com/hashicorp/hcl/v2/gohcl" | ||
"github.com/hashicorp/hcl/v2/hclparse" | ||
) | ||
|
||
const DefaultStateName = "default" | ||
|
||
type MainBodyBlock struct { | ||
Terraform TerraformBlock `hcl:"terraform,block"` | ||
Remain hcl.Body `hcl:",remain"` | ||
} | ||
|
||
type TerraformBlock struct { | ||
Backend BackendBlock `hcl:"backend,block"` | ||
Remain hcl.Body `hcl:",remain"` | ||
} | ||
|
||
func ParseTerraformFromHCL(filename string) (*TerraformBlock, error) { | ||
var v MainBodyBlock | ||
var body MainBodyBlock | ||
|
||
parser := hclparse.NewParser() | ||
f, diags := parser.ParseHCLFile(filename) | ||
if diags.HasErrors() { | ||
return nil, diags | ||
} | ||
|
||
diags = gohcl.DecodeBody(f.Body, nil, &v) | ||
diags = gohcl.DecodeBody(f.Body, nil, &body) | ||
if diags.HasErrors() { | ||
return nil, diags | ||
} | ||
|
||
return &v.Terraform, nil | ||
return &body.Terraform, nil | ||
} | ||
|
||
func GetCurrentWorkspaceName(cwd string) string { | ||
name := DefaultStateName // See https://github.com/hashicorp/terraform/blob/main/internal/backend/backend.go#L33 | ||
|
||
data, err := ioutil.ReadFile(path.Join(cwd, ".terraform/environment")) | ||
if err != nil { | ||
return name | ||
} | ||
if v := strings.Trim(string(data), "\n"); v != "" { | ||
name = v | ||
} | ||
return name | ||
} |
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 |
---|---|---|
|
@@ -6,3 +6,7 @@ terraform { | |
key = "prod.terraform.tfstate" | ||
} | ||
} | ||
|
||
provider "azurerm" { | ||
features {} | ||
} |
1 change: 1 addition & 0 deletions
1
pkg/terraform/hcl/testdata/azurerm_backend_workspace/.gitignore
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 @@ | ||
!.terraform |
1 change: 1 addition & 0 deletions
1
pkg/terraform/hcl/testdata/azurerm_backend_workspace/.terraform/environment
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 @@ | ||
bar |
12 changes: 12 additions & 0 deletions
12
pkg/terraform/hcl/testdata/azurerm_backend_workspace/azurerm_backend_block.tf
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,12 @@ | ||
terraform { | ||
backend "azurerm" { | ||
resource_group_name = "StorageAccount-ResourceGroup" | ||
storage_account_name = "abcd1234" | ||
container_name = "states" | ||
key = "prod.terraform.tfstate" | ||
} | ||
} | ||
|
||
provider "azurerm" { | ||
features {} | ||
} |
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 @@ | ||
!.terraform |
1 change: 1 addition & 0 deletions
1
pkg/terraform/hcl/testdata/foo_workspace/.terraform/environment
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 @@ | ||
foo |
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 |
---|---|---|
|
@@ -5,3 +5,5 @@ terraform { | |
region = "us-east-1" | ||
} | ||
} | ||
|
||
provider "aws" {} |
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 @@ | ||
!.terraform |
1 change: 1 addition & 0 deletions
1
pkg/terraform/hcl/testdata/s3_backend_workspace/.terraform/environment
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 @@ | ||
bar |
9 changes: 9 additions & 0 deletions
9
pkg/terraform/hcl/testdata/s3_backend_workspace/s3_backend_block.tf
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,9 @@ | ||
terraform { | ||
backend "s3" { | ||
bucket = "terraform-state-prod" | ||
key = "network/terraform.tfstate" | ||
region = "us-east-1" | ||
} | ||
} | ||
|
||
provider "aws" {} |
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,3 @@ | ||
terraform { | ||
backend "oss" {} | ||
} |