Skip to content

Commit e3bf174

Browse files
authored
terraform_naming_convention: Add support for checks and scoped data sources (#131)
* Add support for scoped data sources * Add support for check blocks
1 parent 7cb0f65 commit e3bf174

File tree

3 files changed

+121
-0
lines changed

3 files changed

+121
-0
lines changed

docs/rules/terraform_naming_convention.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Enforces naming conventions for the following blocks:
88
* Local values
99
* Modules
1010
* Data sources
11+
* Checks
1112

1213
## Configuration
1314

@@ -23,6 +24,7 @@ module | | Block settings to override naming convention for modules
2324
output | | Block settings to override naming convention for output values
2425
resource | | Block settings to override naming convention for resources
2526
variable | | Block settings to override naming convention for input variables
27+
check | | Block settings to override naming convention for checks
2628

2729

2830
#### `format`

rules/terraform_naming_convention.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type terraformNamingConventionRuleConfig struct {
2929
Output *BlockFormatConfig `hclext:"output,block"`
3030
Resource *BlockFormatConfig `hclext:"resource,block"`
3131
Variable *BlockFormatConfig `hclext:"variable,block"`
32+
Check *BlockFormatConfig `hclext:"check,block"`
3233
}
3334

3435
// CustomFormatConfig defines a custom format that can be used instead of the predefined formats
@@ -128,6 +129,19 @@ func (r *TerraformNamingConventionRule) Check(rr tflint.Runner) error {
128129
LabelNames: []string{"name"},
129130
Body: &hclext.BodySchema{},
130131
},
132+
{
133+
Type: "check",
134+
LabelNames: []string{"name"},
135+
Body: &hclext.BodySchema{
136+
Blocks: []hclext.BlockSchema{
137+
{
138+
Type: "data",
139+
LabelNames: []string{"type", "name"},
140+
Body: &hclext.BodySchema{},
141+
},
142+
},
143+
},
144+
},
131145
},
132146
}, &tflint.GetModuleContentOption{ExpandMode: tflint.ExpandModeNone})
133147
if err != nil {
@@ -146,6 +160,14 @@ func (r *TerraformNamingConventionRule) Check(rr tflint.Runner) error {
146160
return err
147161
}
148162
}
163+
checkBlockName := "check"
164+
for _, checkBlock := range blocks[checkBlockName] {
165+
for _, block := range checkBlock.Body.Blocks {
166+
if err := nameValidator.checkBlock(runner, r, dataBlockName, block.Labels[1], &block.DefRange); err != nil {
167+
return err
168+
}
169+
}
170+
}
149171

150172
// modules
151173
moduleBlockName := "module"
@@ -195,6 +217,17 @@ func (r *TerraformNamingConventionRule) Check(rr tflint.Runner) error {
195217
}
196218
}
197219

220+
// checks
221+
nameValidator, err = config.Check.getNameValidator(defaultNameValidator, &config, checkBlockName)
222+
if err != nil {
223+
return err
224+
}
225+
for _, block := range blocks[checkBlockName] {
226+
if err := nameValidator.checkBlock(runner, r, checkBlockName, block.Labels[0], &block.DefRange); err != nil {
227+
return err
228+
}
229+
}
230+
198231
// locals
199232
localBlockName := "local value"
200233
nameValidator, err = config.Locals.getNameValidator(defaultNameValidator, &config, localBlockName)

rules/terraform_naming_convention_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,36 @@ data "aws_eip" "foo_bar" {
295295
Name: fmt.Sprintf("data: %s - Valid single word", testType),
296296
Content: `
297297
data "aws_eip" "foo" {
298+
}`,
299+
Config: config,
300+
Expected: helper.Issues{},
301+
},
302+
{
303+
Name: fmt.Sprintf("data: %s - Invalid snake_case in a check block", testType),
304+
Content: `
305+
check "ignored" {
306+
data "aws_eip" "dash-name" {
307+
}
308+
}`,
309+
Config: config,
310+
Expected: helper.Issues{
311+
{
312+
Rule: rule,
313+
Message: fmt.Sprintf("data name `dash-name` must match the following %s", formatName),
314+
Range: hcl.Range{
315+
Filename: "tests.tf",
316+
Start: hcl.Pos{Line: 3, Column: 3},
317+
End: hcl.Pos{Line: 3, Column: 29},
318+
},
319+
},
320+
},
321+
},
322+
{
323+
Name: fmt.Sprintf("data: %s - Valid snake_case in a check block", testType),
324+
Content: `
325+
check "ignored" {
326+
data "aws_eip" "foo_bar" {
327+
}
298328
}`,
299329
Config: config,
300330
Expected: helper.Issues{},
@@ -2926,3 +2956,59 @@ variable "camelCase" {
29262956
})
29272957
}
29282958
}
2959+
2960+
func Test_TerraformNamingConventionRule_Check(t *testing.T) {
2961+
rule := NewTerraformNamingConventionRule()
2962+
2963+
config := `
2964+
rule "terraform_naming_convention" {
2965+
enabled = true
2966+
2967+
check {
2968+
format = "snake_case"
2969+
}
2970+
}`
2971+
2972+
tests := []struct {
2973+
name string
2974+
content string
2975+
want helper.Issues
2976+
}{
2977+
{
2978+
name: "Invalid snake_case",
2979+
content: `
2980+
check "dash-name" {
2981+
}`,
2982+
want: helper.Issues{
2983+
{
2984+
Rule: rule,
2985+
Message: "check name `dash-name` must match the following format: snake_case",
2986+
Range: hcl.Range{
2987+
Filename: "tests.tf",
2988+
Start: hcl.Pos{Line: 2, Column: 1},
2989+
End: hcl.Pos{Line: 2, Column: 18},
2990+
},
2991+
},
2992+
},
2993+
},
2994+
{
2995+
name: "Valid snake_case",
2996+
content: `
2997+
check "foo_bar" {
2998+
}`,
2999+
want: helper.Issues{},
3000+
},
3001+
}
3002+
3003+
for _, test := range tests {
3004+
t.Run(test.name, func(t *testing.T) {
3005+
runner := testRunner(t, map[string]string{"tests.tf": test.content, ".tflint.hcl": config})
3006+
3007+
if err := rule.Check(runner); err != nil {
3008+
t.Fatalf("Unexpected error occurred: %s", err)
3009+
}
3010+
3011+
helper.AssertIssues(t, test.want, runner.Runner.(*helper.Runner).Issues)
3012+
})
3013+
}
3014+
}

0 commit comments

Comments
 (0)