1
1
package rules
2
2
3
3
import (
4
+ "strings"
5
+
4
6
hcl "github.com/hashicorp/hcl/v2"
7
+ hclsyntax "github.com/hashicorp/hcl/v2/hclsyntax"
8
+ lang "github.com/terraform-linters/tflint-plugin-sdk/terraform/lang"
5
9
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
6
10
"github.com/terraform-linters/tflint-ruleset-aws/project"
7
11
)
8
12
9
- // AwsS3NoGlobalEndpointRule checks whether deprecated s3 global endpoint is used instead
10
- // of the regional endoint
13
+ // AwsS3NoGlobalEndpointRule checks whether deprecated s3 global endpoint is used
11
14
type AwsS3NoGlobalEndpointRule struct {
12
15
tflint.DefaultRule
13
-
14
- // TODO: do we need this, if so why
15
- resourceType string
16
- attributeName string
17
16
}
18
17
19
18
// NewAwsS3NoGlobalEndpointRule returns new rule with default attributes
20
19
func NewAwsS3NoGlobalEndpointRule () * AwsS3NoGlobalEndpointRule {
21
- return & AwsS3NoGlobalEndpointRule {
22
- resourceType : "aws_s3_bucket" ,
23
- attributeName : "" ,
24
- }
20
+ return & AwsS3NoGlobalEndpointRule {}
25
21
}
26
22
27
23
// Name returns the rule name
28
24
func (r * AwsS3NoGlobalEndpointRule ) Name () string {
29
- return "aws_acm_certificate_lifecycle "
25
+ return "aws_s3_no_global_endpoint "
30
26
}
31
27
32
28
// Enabled returns whether the rule is enabled by default
33
29
func (r * AwsS3NoGlobalEndpointRule ) Enabled () bool {
34
- return true
30
+ return false
35
31
}
36
32
37
33
// Severity returns the rule severity
@@ -44,23 +40,47 @@ func (r *AwsS3NoGlobalEndpointRule) Link() string {
44
40
return project .ReferenceLink (r .Name ())
45
41
}
46
42
47
- // Check checks whether the aws_acm_certificate resource contains create_before_destroy = true in lifecycle block
43
+ func isS3BucketResourceOrData (str string ) bool {
44
+ return strings .HasPrefix (str , "aws_s3_bucket" ) || strings .HasPrefix (str , "data.aws_s3_bucket" )
45
+ }
46
+
47
+ func getRealRange (srcRange hcl.Range ) hcl.Range {
48
+ // ref.SourceRange doesn't include the bucket_domain_name attribute which is 19 characters long
49
+ srcRange .End .Column += 19
50
+ return srcRange
51
+ }
52
+
53
+ // Check checks whether the deprecated s3 global endpoint is used
48
54
func (r * AwsS3NoGlobalEndpointRule ) Check (runner tflint.Runner ) error {
49
55
var err error
50
56
runner .WalkExpressions (tflint .ExprWalkFunc (func (expr hcl.Expression ) hcl.Diagnostics {
51
- vars := expr .Variables ()
57
+ _ , isTemplateExpr := expr .(* hclsyntax.TemplateExpr )
58
+ if isTemplateExpr {
59
+ // TODO: check sth like .s3.amazonaws.com inside template expression ?
52
60
53
- if len ( vars ) == 0 {
61
+ // "${aws_s3_bucket.test.bucket_domain_name}" would report the same error twice if we didn't return here
54
62
return nil
55
63
}
56
64
57
- // is this ever greater than 0
58
- v := vars [0 ]
65
+ refs := lang .ReferencesInExpr (expr )
59
66
60
- if v . RootName () == "aws_s3_bucket" && len (v ) == 3 && v [ 2 ].(hcl. TraverseAttr ). Name == "bucket_domain_name" {
61
- err = runner . EmitIssue ( r , "`bucket_domain_name` returns the legacy s3 global endpoint, use `bucket_regional_domain_name` instead" , v . SourceRange ())
67
+ if len (refs ) != 1 {
68
+ return nil
62
69
}
63
70
71
+ ref := refs [0 ]
72
+
73
+ // lang.ReferencesInExpr(expr) is broken when the reference contains subexpression ?
74
+ // e.g. aws_s3_bucket.test[length(var.bucket_names) - 1]
75
+ // TODO: seems like a niche case, should we handle this ?
76
+ if isS3BucketResourceOrData (ref .Subject .String ()) && len (ref .Remaining ) == 1 && ref .Remaining [0 ].(hcl.TraverseAttr ).Name == "bucket_domain_name" {
77
+ // ref.SourceRange doesn't include the bucket_domain_name attribute which is 19 characters long
78
+ srcRange := getRealRange (ref .SourceRange )
79
+ err = runner .EmitIssue (r , "`bucket_domain_name` returns the legacy s3 global endpoint, use `bucket_regional_domain_name` instead" , srcRange )
80
+ }
81
+
82
+ // TODO: handle foreach, count, dynamic blocks
83
+
64
84
return nil
65
85
}))
66
86
0 commit comments