forked from terraform-linters/tflint-ruleset-aws
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaws_s3_bucket_name.go
110 lines (92 loc) · 2.56 KB
/
aws_s3_bucket_name.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package rules
import (
"fmt"
"regexp"
"strings"
"github.com/terraform-linters/tflint-plugin-sdk/hclext"
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
"github.com/terraform-linters/tflint-ruleset-aws/project"
)
// AwsS3BucketNameRule checks that an S3 bucket name matches naming rules
type AwsS3BucketNameRule struct {
tflint.DefaultRule
resourceType string
attributeName string
}
type awsS3BucketNameConfig struct {
Regex string `hclext:"regex,optional"`
Prefix string `hclext:"prefix,optional"`
}
// NewAwsS3BucketNameRule returns a new rule with default attributes
func NewAwsS3BucketNameRule() *AwsS3BucketNameRule {
return &AwsS3BucketNameRule{
resourceType: "aws_s3_bucket",
attributeName: "bucket",
}
}
// Name returns the rule name
func (r *AwsS3BucketNameRule) Name() string {
return "aws_s3_bucket_name"
}
// Enabled returns whether the rule is enabled by default
func (r *AwsS3BucketNameRule) Enabled() bool {
return false
}
// Severity returns the rule severity
func (r *AwsS3BucketNameRule) Severity() tflint.Severity {
return tflint.WARNING
}
// Link returns the rule reference link
func (r *AwsS3BucketNameRule) Link() string {
return project.ReferenceLink(r.Name())
}
// Check if the name of the s3 bucket matches the regex defined in the rule
func (r *AwsS3BucketNameRule) Check(runner tflint.Runner) error {
config := awsS3BucketNameConfig{}
if err := runner.DecodeRuleConfig(r.Name(), &config); err != nil {
return err
}
regex, err := regexp.Compile(config.Regex)
if err != nil {
return fmt.Errorf("invalid regex (%s): %w", config.Regex, err)
}
resources, err := runner.GetResourceContent(r.resourceType, &hclext.BodySchema{
Attributes: []hclext.AttributeSchema{{Name: r.attributeName}},
}, nil)
if err != nil {
return err
}
for _, resource := range resources.Blocks {
attribute, exists := resource.Body.Attributes[r.attributeName]
if !exists {
continue
}
var name string
err := runner.EvaluateExpr(attribute.Expr, &name, nil)
err = runner.EnsureNoError(err, func() error {
if config.Prefix != "" {
if !strings.HasPrefix(name, config.Prefix) {
runner.EmitIssue(
r,
fmt.Sprintf(`Bucket name "%s" does not have prefix "%s"`, name, config.Prefix),
attribute.Expr.Range(),
)
}
}
if config.Regex != "" {
if !regex.MatchString(name) {
runner.EmitIssue(
r,
fmt.Sprintf(`Bucket name "%s" does not match regex "%s"`, name, config.Regex),
attribute.Expr.Range(),
)
}
}
return nil
})
if err != nil {
return err
}
}
return nil
}