Skip to content

Commit

Permalink
Merge pull request #91 from padok-team/feat/0.3.0
Browse files Browse the repository at this point in the history
feat(0.3.0): new check
  • Loading branch information
Laudenlaruto authored Oct 21, 2024
2 parents 1f1b7c9 + c57410d commit 8eeec2d
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 167 deletions.
46 changes: 28 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ Check the [IaC guild guidelines](https://padok-team.github.io/docs-terraform-gui
brew tap padok-team/tap
brew install guacamole
```

### From GitHub

**Prerequisites :**

- Golang
- Terraform
- Terragrunt
Expand All @@ -39,46 +41,54 @@ Three modes currently exist :
guacamole static -p /path/to/your/codebase
```

- By default, it will launch [module](#static-module-check) and [layer](#static-layer-check) checks
- To launch [layer](#static-layer-check) check use `guacamole static layer`
- To launch [module](#static-module-check) check use `guacamole static module`

- [EXPERIMENTAL] State mode : runs quality checks based on your layers' state
We recommend to use this command after checking that your codebase has been initialized properly.
We recommend using this command after checking that your codebase has been initialized properly.
```bash
guacamole state -p /path/to/your/codebase
```
- [EXPERIMENTAL] Profile mode : creates a detailed report of the contents of your codebase
We recommend to use this command after checking that your codebase has been initialized properly.
We recommend using this command after checking that your codebase has been initialized properly.
```bash
guacamole profile -p /path/to/your/codebase
```
A verbose mode (`-v`) exists to add more infos to the output.
A verbose mode (`-v`) exists to add more information to the output.
## Demo
## List of checks
![Demo](/assets/demo.gif)
### Static module check for Terraform
## List of checks
- `TF_MOD_001` - [Remote module call should be pinned to a specific version](https://padok-team.github.io/docs-terraform-guidelines/terraform/terraform_versioning.html#module-layer-versioning)
- `TF_MOD_002` - [Provider should be defined by the consumer of the module](https://padok-team.github.io/docs-terraform-guidelines/terraform/donts.html#using-provider-block-in-modules)
- `TF_MOD_003` - [Required provider versions in modules should be set with ~> operator](https://padok-team.github.io/docs-terraform-guidelines/terraform/terraform_versioning.html#required-providers-version-for-modules)
- `TF_NAM_001` - [Resources in modules should be named "this" or "these" if their type is unique](https://padok-team.github.io/docs-terraform-guidelines/terraform/terraform_naming.html#resource-andor-data-source-naming)
- `TF_NAM_002` - [snake_case should be used for all resource names](https://padok-team.github.io/docs-terraform-guidelines/terraform/terraform_naming.html#resource-andor-data-source-naming)
- `TF_NAM_003` - [Stuttering in the naming of resources](https://padok-team.github.io/docs-terraform-guidelines/terraform/terraform_naming.html#resource-andor-data-source-naming)
- `TF_NAM_004` - [Variable name's number should match its type](https://padok-team.github.io/docs-terraform-guidelines/terraform/terraform_naming.html#variables)
- `TF_NAM_005` - [Resources and data sources should not be named \"this\" or \"these\" if there are more than 1 of the same type](https://padok-team.github.io/docs-terraform-guidelines/terraform/terraform_naming.html#resource-andor-data-source-naming)
- `TF_VAR_001` - [Variable should contain a description](https://padok-team.github.io/docs-terraform-guidelines/terraform/donts.html#variables)
- `TF_VAR_002` - [Variable should declare a specific type](https://padok-team.github.io/docs-terraform-guidelines/terraform/donts.html#using-type-any-in-variables)

### Static
### Static layer check for Terragrunt

- `TF_MOD_001` - Remote module call should be pinned to a specific version
- `TF_MOD_002` - Provider should be defined by the consumer of the module
- `TF_MOD_003` - Required provider versions in modules should be set with ~> operator
- `TF_NAM_001` - Resources and datasources in modules should be named "this" or "these" if their type is unique
- `TF_NAM_002` - snake_case should be used for all resource names
- `TF_NAM_003` - Stuttering in the naming of resources
- `TF_NAM_004` - Variable name's number should match its type
- `TF_VAR_001` - Variable should contain a description
- `TF_VAR_002` - Variable should declare a specific type
- `TG_DRY_001` - [No duplicate inputs within a layer](https://padok-team.github.io/docs-terraform-guidelines/terragrunt/context_pattern.html#%EF%B8%8F-context)

### State

- `TF_MOD_004` - Use for_each to create multiple resources of the same type
- `TF_MOD_004` - [Use for_each to create multiple resources of the same type](https://padok-team.github.io/docs-terraform-guidelines/terraform/iterate_on_your_resources.html)

## Demo

![Demo](/assets/demo.gif)

## License

Expand Down
1 change: 1 addition & 0 deletions checks/module_static_checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func ModuleStaticChecks() []data.Check {
"RemoteModuleVersion": RemoteModuleVersion,
"RequiredProviderVersionOperatorInModules": RequiredProviderVersionOperatorInModules,
"ResourceNamingThisThese": ResourceNamingThisThese,
"ResourceNaming": ResourceNaming,
}

var checkResults []data.Check
Expand Down
73 changes: 73 additions & 0 deletions checks/resource_naming.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package checks

import (
"github.com/padok-team/guacamole/data"

"github.com/hashicorp/terraform-config-inspect/tfconfig"
)

func ResourceNaming(modules map[string]data.TerraformModule) (data.Check, error) {
dataCheck := data.Check{
ID: "TF_NAM_005",
Name: "Resources and data sources should not be named \"this\" or \"these\" if there are more than 1 of the same type",
RelatedGuidelines: "https://padok-team.github.io/docs-terraform-guidelines/terraform/terraform_naming.html#resource-andor-data-source-naming",
Status: "✅",
}

resourcesInError := []data.Error{}

for _, module := range modules {
moduleConf, diags := tfconfig.LoadModule(module.FullPath)
if diags.HasErrors() {
return data.Check{}, diags.Err()
}
// Check resources
for _, resource := range moduleConf.ManagedResources {
// Check if the type of the resource is unique within the module
numberOfSameType := 0
for _, res := range moduleConf.ManagedResources {
if res.Type == resource.Type {
numberOfSameType++
}
}
// If there is only one instance of this type of resource, check if its named this or these (If they create more than 1 with a for each)
if numberOfSameType > 1 {
if resource.Name == "these" || resource.Name == "this" {
resourcesInError = append(resourcesInError, data.Error{
Path: resource.Pos.Filename,
LineNumber: resource.Pos.Line,
Description: resource.Type + " - " + resource.Name,
})
}
}
}
// Check data sources
for _, dataResource := range moduleConf.DataResources {
// Check if the type of the resource is unique within the module
numberOfSameType := 0
for _, res := range moduleConf.DataResources {
if res.Type == dataResource.Type {
numberOfSameType++
}
}
// If there is only one instance of this type of resource, check if its named this or these (If they create more than 1 with a for each)
if numberOfSameType > 1 {
if dataResource.Name == "these" || dataResource.Name == "this" {
resourcesInError = append(resourcesInError, data.Error{
Path: dataResource.Pos.Filename,
LineNumber: dataResource.Pos.Line,
Description: dataResource.Type + " - " + dataResource.Name,
})
}
}
}
}

dataCheck.Errors = resourcesInError

if len(resourcesInError) > 0 {
dataCheck.Status = "❌"
}

return dataCheck, nil
}
32 changes: 1 addition & 31 deletions checks/resource_naming_this_these.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
func ResourceNamingThisThese(modules map[string]data.TerraformModule) (data.Check, error) {
dataCheck := data.Check{
ID: "TF_NAM_001",
Name: "Resources and datasources in modules should be named \"this\" or \"these\" if their type is unique",
Name: "Resources in modules should be named \"this\" or \"these\" if their type is unique",
RelatedGuidelines: "https://padok-team.github.io/docs-terraform-guidelines/terraform/terraform_naming.html#resource-andor-data-source-naming",
Status: "✅",
}
Expand Down Expand Up @@ -54,36 +54,6 @@ func ResourceNamingThisThese(modules map[string]data.TerraformModule) (data.Chec
}
}
}
// Check data sources
for _, dataResource := range moduleConf.DataResources {
// Check if the type of the resource is unique within the module
numberOfSameType := 0
for _, res := range moduleConf.DataResources {
if res.Type == dataResource.Type {
numberOfSameType++
}
}
// If there is only one instance of this type of resource, check if its named this or these (If they create more than 1 with a for each)
if numberOfSameType == 1 {
if pluralize.IsPlural(dataResource.Name) {
if dataResource.Name != "these" {
resourcesInError = append(resourcesInError, data.Error{
Path: dataResource.Pos.Filename,
LineNumber: dataResource.Pos.Line,
Description: dataResource.Type + " - " + dataResource.Name,
})
}
} else {
if dataResource.Name != "this" {
resourcesInError = append(resourcesInError, data.Error{
Path: dataResource.Pos.Filename,
LineNumber: dataResource.Pos.Line,
Description: dataResource.Type + " - " + dataResource.Name,
})
}
}
}
}
}

dataCheck.Errors = resourcesInError
Expand Down
8 changes: 4 additions & 4 deletions cmd/static_checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ import (
// plan represents the run command
var static = &cobra.Command{
Use: "static",
Short: "Run static code checks (default: module)",
Short: "Run static code checks",
Run: func(cmd *cobra.Command, args []string) {
l := log.New(os.Stderr, "", 0)
l.Println("You can specify what you want to check : layer or module")
l.Println("Defaulting to module check")
l.Println("Running static checks on modules...")
l.Println("Defaulting to checking both")
checkResults := checks.ModuleStaticChecks()
// helpers.RenderTable(checkResults)
l.Println("Running static checks on layer...")
checkResults = append(checkResults, checks.LayerStaticChecks()...)
verbose := viper.GetBool("verbose")
helpers.RenderChecks(checkResults, verbose)
// If there is at least one error, exit with code 1
Expand Down
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ go 1.21
toolchain go1.21.5

require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
github.com/fatih/color v1.16.0
github.com/gertd/go-pluralize v0.2.1
github.com/gruntwork-io/terragrunt v0.55.1
Expand Down Expand Up @@ -43,7 +42,6 @@ require (
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-cidr v1.1.0 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/apparentlymart/go-versions v1.0.1 // indirect
github.com/armon/go-metrics v0.4.1 // indirect
Expand All @@ -56,6 +54,7 @@ require (
github.com/cloudflare/circl v1.3.3 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/creack/pty v1.1.17 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dimchansky/utfbom v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect
Expand Down
Loading

0 comments on commit 8eeec2d

Please sign in to comment.