Skip to content

Commit d8fe9c6

Browse files
committed
Add invalid machine type rules
1 parent 4c57188 commit d8fe9c6

17 files changed

+1216
-3
lines changed

docs/README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,19 @@ This documentation describes a list of rules available by enabling this ruleset.
44

55
## Basic Rules
66

7-
No rules
7+
### Invalid machine types
8+
9+
These rules warn you if a machine type not listed at https://cloud.google.com/compute/docs/machine-types is being used. Please note that custom machine types cannot be detected correctly. These rules consider all machine types starting with `custom-` to be valid.
10+
11+
|Name|Severity|Enabled|
12+
| --- | --- | --- |
13+
|google_composer_environment_invalid_machine_type|ERROR||
14+
|google_compute_instance_invalid_machine_type|ERROR||
15+
|google_compute_instance_template_invalid_machine_type|ERROR||
16+
|google_compute_reservation_invalid_machine_type|ERROR||
17+
|google_container_cluster_invalid_machine_type|ERROR||
18+
|google_container_node_pool_invalid_machine_type|ERROR||
19+
|google_dataflow_job_invalid_machine_type|ERROR||
820

921
## Magic Modules Rules
1022

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package rules
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
hcl "github.com/hashicorp/hcl/v2"
8+
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
9+
)
10+
11+
// GoogleComposerEnvironmentInvalidMachineTypeRule checks whether the machine type is invalid
12+
type GoogleComposerEnvironmentInvalidMachineTypeRule struct{}
13+
14+
// NewGoogleComposerEnvironmentInvalidMachineTypeRule returns a new rule
15+
func NewGoogleComposerEnvironmentInvalidMachineTypeRule() *GoogleComposerEnvironmentInvalidMachineTypeRule {
16+
return &GoogleComposerEnvironmentInvalidMachineTypeRule{}
17+
}
18+
19+
// Name returns the rule name
20+
func (r *GoogleComposerEnvironmentInvalidMachineTypeRule) Name() string {
21+
return "google_composer_environment_invalid_machine_type"
22+
}
23+
24+
// Enabled returns whether the rule is enabled by default
25+
func (r *GoogleComposerEnvironmentInvalidMachineTypeRule) Enabled() bool {
26+
return true
27+
}
28+
29+
// Severity returns the rule severity
30+
func (r *GoogleComposerEnvironmentInvalidMachineTypeRule) Severity() string {
31+
return tflint.ERROR
32+
}
33+
34+
// Link returns the rule reference link
35+
func (r *GoogleComposerEnvironmentInvalidMachineTypeRule) Link() string {
36+
return ""
37+
}
38+
39+
// Check checks whether the machine type is invalid
40+
func (r *GoogleComposerEnvironmentInvalidMachineTypeRule) Check(runner tflint.Runner) error {
41+
return runner.WalkResourceBlocks("google_composer_environment", "config", func(block *hcl.Block) error {
42+
content, _, diags := block.Body.PartialContent(&hcl.BodySchema{
43+
Blocks: []hcl.BlockHeaderSchema{
44+
{Type: "node_config"},
45+
},
46+
})
47+
if diags.HasErrors() {
48+
return diags
49+
}
50+
51+
for _, block := range content.Blocks {
52+
content, _, diags := block.Body.PartialContent(&hcl.BodySchema{
53+
Attributes: []hcl.AttributeSchema{
54+
{Name: "machine_type"},
55+
},
56+
})
57+
58+
if diags.HasErrors() {
59+
return diags
60+
}
61+
62+
if attribute, exists := content.Attributes["machine_type"]; exists {
63+
var machineType string
64+
err := runner.EvaluateExpr(attribute.Expr, &machineType)
65+
66+
err = runner.EnsureNoError(err, func() error {
67+
if validMachineTypes[machineType] || strings.HasPrefix(machineType, "custom-") {
68+
return nil
69+
}
70+
71+
return runner.EmitIssueOnExpr(
72+
r,
73+
fmt.Sprintf(`"%s" is an invalid as machine type`, machineType),
74+
attribute.Expr,
75+
)
76+
})
77+
78+
if err != nil {
79+
return err
80+
}
81+
}
82+
}
83+
84+
return nil
85+
})
86+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package rules
2+
3+
import (
4+
"testing"
5+
6+
hcl "github.com/hashicorp/hcl/v2"
7+
"github.com/terraform-linters/tflint-plugin-sdk/helper"
8+
)
9+
10+
func Test_GoogleComposerEnvironmentInvalidMachineType(t *testing.T) {
11+
cases := []struct {
12+
Name string
13+
Content string
14+
Expected helper.Issues
15+
}{
16+
{
17+
Name: "invalid type",
18+
Content: `
19+
resource "google_composer_environment" "test" {
20+
name = "mycomposer"
21+
region = "us-central1"
22+
config {
23+
node_count = 4
24+
25+
node_config {
26+
zone = "us-central1-a"
27+
machine_type = "n1-standard-11"
28+
29+
network = google_compute_network.test.id
30+
subnetwork = google_compute_subnetwork.test.id
31+
32+
service_account = google_service_account.test.name
33+
}
34+
}
35+
36+
depends_on = [google_project_iam_member.composer-worker]
37+
}`,
38+
Expected: helper.Issues{
39+
{
40+
Rule: NewGoogleComposerEnvironmentInvalidMachineTypeRule(),
41+
Message: `"n1-standard-11" is an invalid as machine type`,
42+
Range: hcl.Range{
43+
Filename: "resource.tf",
44+
Start: hcl.Pos{Line: 10, Column: 22},
45+
End: hcl.Pos{Line: 10, Column: 38},
46+
},
47+
},
48+
},
49+
},
50+
{
51+
Name: "valid type",
52+
Content: `
53+
resource "google_composer_environment" "test" {
54+
name = "mycomposer"
55+
region = "us-central1"
56+
config {
57+
node_count = 4
58+
59+
node_config {
60+
zone = "us-central1-a"
61+
machine_type = "n2-standard-2"
62+
63+
network = google_compute_network.test.id
64+
subnetwork = google_compute_subnetwork.test.id
65+
66+
service_account = google_service_account.test.name
67+
}
68+
}
69+
70+
depends_on = [google_project_iam_member.composer-worker]
71+
}`,
72+
Expected: helper.Issues{},
73+
},
74+
{
75+
Name: "custom type",
76+
Content: `
77+
resource "google_composer_environment" "test" {
78+
name = "mycomposer"
79+
region = "us-central1"
80+
config {
81+
node_count = 4
82+
83+
node_config {
84+
zone = "us-central1-a"
85+
machine_type = "custom-6-20480"
86+
87+
network = google_compute_network.test.id
88+
subnetwork = google_compute_subnetwork.test.id
89+
90+
service_account = google_service_account.test.name
91+
}
92+
}
93+
94+
depends_on = [google_project_iam_member.composer-worker]
95+
}`,
96+
Expected: helper.Issues{},
97+
},
98+
}
99+
100+
rule := NewGoogleComposerEnvironmentInvalidMachineTypeRule()
101+
102+
for _, tc := range cases {
103+
runner := helper.TestRunner(t, map[string]string{"resource.tf": tc.Content})
104+
105+
if err := rule.Check(runner); err != nil {
106+
t.Fatalf("Unexpected error occurred: %s", err)
107+
}
108+
109+
helper.AssertIssues(t, tc.Expected, runner.Issues)
110+
}
111+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package rules
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
hcl "github.com/hashicorp/hcl/v2"
8+
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
9+
)
10+
11+
// GoogleComputeInstanceInvalidMachineTypeRule checks whether the machine type is invalid
12+
type GoogleComputeInstanceInvalidMachineTypeRule struct {}
13+
14+
// NewGoogleComputeInstanceInvalidMachineTypeRule returns a new rule
15+
func NewGoogleComputeInstanceInvalidMachineTypeRule() *GoogleComputeInstanceInvalidMachineTypeRule {
16+
return &GoogleComputeInstanceInvalidMachineTypeRule{}
17+
}
18+
19+
// Name returns the rule name
20+
func (r *GoogleComputeInstanceInvalidMachineTypeRule) Name() string {
21+
return "google_compute_instance_invalid_machine_type"
22+
}
23+
24+
// Enabled returns whether the rule is enabled by default
25+
func (r *GoogleComputeInstanceInvalidMachineTypeRule) Enabled() bool {
26+
return true
27+
}
28+
29+
// Severity returns the rule severity
30+
func (r *GoogleComputeInstanceInvalidMachineTypeRule) Severity() string {
31+
return tflint.ERROR
32+
}
33+
34+
// Link returns the rule reference link
35+
func (r *GoogleComputeInstanceInvalidMachineTypeRule) Link() string {
36+
return ""
37+
}
38+
39+
// Check checks whether the machine type is invalid
40+
func (r *GoogleComputeInstanceInvalidMachineTypeRule) Check(runner tflint.Runner) error {
41+
return runner.WalkResourceAttributes("google_compute_instance", "machine_type", func(attribute *hcl.Attribute) error {
42+
var machineType string
43+
err := runner.EvaluateExpr(attribute.Expr, &machineType)
44+
45+
return runner.EnsureNoError(err, func() error {
46+
if validMachineTypes[machineType] || strings.HasPrefix(machineType, "custom-") {
47+
return nil
48+
}
49+
50+
return runner.EmitIssueOnExpr(
51+
r,
52+
fmt.Sprintf(`"%s" is an invalid as machine type`, machineType),
53+
attribute.Expr,
54+
)
55+
})
56+
})
57+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package rules
2+
3+
import (
4+
"testing"
5+
6+
hcl "github.com/hashicorp/hcl/v2"
7+
"github.com/terraform-linters/tflint-plugin-sdk/helper"
8+
)
9+
10+
func Test_GoogleComputeInstanceInvalidMachineType(t *testing.T) {
11+
cases := []struct {
12+
Name string
13+
Content string
14+
Expected helper.Issues
15+
}{
16+
{
17+
Name: "invalid type",
18+
Content: `
19+
resource "google_compute_instance" "vm_instance" {
20+
machine_type = "n2-standard-1"
21+
}`,
22+
Expected: helper.Issues{
23+
{
24+
Rule: NewGoogleComputeInstanceInvalidMachineTypeRule(),
25+
Message: `"n2-standard-1" is an invalid as machine type`,
26+
Range: hcl.Range{
27+
Filename: "resource.tf",
28+
Start: hcl.Pos{Line: 3, Column: 20},
29+
End: hcl.Pos{Line: 3, Column: 35},
30+
},
31+
},
32+
},
33+
},
34+
{
35+
Name: "valid type",
36+
Content: `
37+
resource "google_compute_instance" "vm_instance" {
38+
machine_type = "n2-standard-2"
39+
}`,
40+
Expected: helper.Issues{},
41+
},
42+
{
43+
Name: "custom type",
44+
Content: `
45+
resource "google_compute_instance" "vm_instance" {
46+
machine_type = "custom-6-20480"
47+
}`,
48+
Expected: helper.Issues{},
49+
},
50+
}
51+
52+
rule := NewGoogleComputeInstanceInvalidMachineTypeRule()
53+
54+
for _, tc := range cases {
55+
runner := helper.TestRunner(t, map[string]string{"resource.tf": tc.Content})
56+
57+
if err := rule.Check(runner); err != nil {
58+
t.Fatalf("Unexpected error occurred: %s", err)
59+
}
60+
61+
helper.AssertIssues(t, tc.Expected, runner.Issues)
62+
}
63+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package rules
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
hcl "github.com/hashicorp/hcl/v2"
8+
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
9+
)
10+
11+
// GoogleComputeInstanceTemplateInvalidMachineTypeRule checks whether the machine type is invalid
12+
type GoogleComputeInstanceTemplateInvalidMachineTypeRule struct {}
13+
14+
// NewGoogleComputeInstanceTemplateInvalidMachineTypeRule returns a new rule
15+
func NewGoogleComputeInstanceTemplateInvalidMachineTypeRule() *GoogleComputeInstanceTemplateInvalidMachineTypeRule {
16+
return &GoogleComputeInstanceTemplateInvalidMachineTypeRule{}
17+
}
18+
19+
// Name returns the rule name
20+
func (r *GoogleComputeInstanceTemplateInvalidMachineTypeRule) Name() string {
21+
return "google_compute_instance_template_invalid_machine_type"
22+
}
23+
24+
// Enabled returns whether the rule is enabled by default
25+
func (r *GoogleComputeInstanceTemplateInvalidMachineTypeRule) Enabled() bool {
26+
return true
27+
}
28+
29+
// Severity returns the rule severity
30+
func (r *GoogleComputeInstanceTemplateInvalidMachineTypeRule) Severity() string {
31+
return tflint.ERROR
32+
}
33+
34+
// Link returns the rule reference link
35+
func (r *GoogleComputeInstanceTemplateInvalidMachineTypeRule) Link() string {
36+
return ""
37+
}
38+
39+
// Check checks whether the machine type is invalid
40+
func (r *GoogleComputeInstanceTemplateInvalidMachineTypeRule) Check(runner tflint.Runner) error {
41+
return runner.WalkResourceAttributes("google_compute_instance_template", "machine_type", func(attribute *hcl.Attribute) error {
42+
var machineType string
43+
err := runner.EvaluateExpr(attribute.Expr, &machineType)
44+
45+
return runner.EnsureNoError(err, func() error {
46+
if validMachineTypes[machineType] || strings.HasPrefix(machineType, "custom-") {
47+
return nil
48+
}
49+
50+
return runner.EmitIssueOnExpr(
51+
r,
52+
fmt.Sprintf(`"%s" is an invalid as machine type`, machineType),
53+
attribute.Expr,
54+
)
55+
})
56+
})
57+
}

0 commit comments

Comments
 (0)