Skip to content

Commit

Permalink
Make GetRuleConfigContent doesn't return an error even if config not …
Browse files Browse the repository at this point in the history
…found (#1481)
  • Loading branch information
wata727 authored Aug 27, 2022
1 parent c1d4e77 commit 3fbef3f
Show file tree
Hide file tree
Showing 16 changed files with 205 additions and 12 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ require (
github.com/sourcegraph/go-lsp v0.0.0-20200429204803-219e11d77f5d
github.com/sourcegraph/jsonrpc2 v0.1.0
github.com/spf13/afero v1.9.2
github.com/terraform-linters/tflint-plugin-sdk v0.11.1-0.20220806124604-77ef4504052f
github.com/terraform-linters/tflint-plugin-sdk v0.11.1-0.20220812135228-391859ca83f5
github.com/xeipuuv/gojsonschema v1.2.0
github.com/zclconf/go-cty v1.11.0
github.com/zclconf/go-cty-yaml v1.0.2
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/terraform-linters/tflint-plugin-sdk v0.11.1-0.20220806124604-77ef4504052f h1:lhrE318Jy4OlkeO/Y5s8CH58TmqpzSW506E/vToKY9g=
github.com/terraform-linters/tflint-plugin-sdk v0.11.1-0.20220806124604-77ef4504052f/go.mod h1:g5BTK4enaWI/EPr2qWfRDJU/Qqnu84Y33JTETyVxxMA=
github.com/terraform-linters/tflint-plugin-sdk v0.11.1-0.20220812135228-391859ca83f5 h1:U90aIT3pRv9zDCf1aIWclXyRnjIILe6BvrDDywrGBMo=
github.com/terraform-linters/tflint-plugin-sdk v0.11.1-0.20220812135228-391859ca83f5/go.mod h1:g5BTK4enaWI/EPr2qWfRDJU/Qqnu84Y33JTETyVxxMA=
github.com/ulikunitz/xz v0.5.8 h1:ERv8V6GKqVi23rgu5cj9pVfVzJbOqAY2Ntl88O6c2nQ=
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
plugin "testing" {
enabled = true
}
3 changes: 3 additions & 0 deletions integrationtest/inspection/enable-config-rule-by-cli/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "aws_db_instance" "main" {
name = "staging"
}
25 changes: 25 additions & 0 deletions integrationtest/inspection/enable-config-rule-by-cli/result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"issues": [
{
"rule": {
"name": "aws_db_instance_with_default_config_example",
"severity": "warning",
"link": ""
},
"message": "DB name is staging, config=default",
"range": {
"filename": "main.tf",
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 19
}
},
"callers": []
}
],
"errors": []
}
15 changes: 15 additions & 0 deletions integrationtest/inspection/inspection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ func TestIntegration(t *testing.T) {
Command: "./tflint --format json --enable-rule aws_s3_bucket_with_config_example",
Dir: "enable-required-config-rule-by-cli",
},
{
Name: "enable rule which does not have required configuration by CLI options",
Command: "./tflint --format json --enable-rule aws_db_instance_with_default_config_example",
Dir: "enable-config-rule-by-cli",
},
{
Name: "heredoc",
Command: "./tflint --format json",
Expand Down Expand Up @@ -147,6 +152,16 @@ func TestIntegration(t *testing.T) {
Command: "tflint --only aws_s3_bucket_with_config_example --format json",
Dir: "rule-config",
},
{
Name: "rule config without required attributes",
Command: "tflint --format json",
Dir: "rule-required-config",
},
{
Name: "rule config without optional attributes",
Command: "tflint --format json",
Dir: "rule-optional-config",
},
{
Name: "enable plugin by CLI",
Command: "tflint --enable-plugin testing --format json",
Expand Down
7 changes: 7 additions & 0 deletions integrationtest/inspection/rule-optional-config/.tflint.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
plugin "testing" {
enabled = true
}

rule "aws_db_instance_with_default_config_example" {
enabled = true
}
3 changes: 3 additions & 0 deletions integrationtest/inspection/rule-optional-config/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "aws_db_instance" "main" {
name = "staging"
}
25 changes: 25 additions & 0 deletions integrationtest/inspection/rule-optional-config/result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"issues": [
{
"rule": {
"name": "aws_db_instance_with_default_config_example",
"severity": "warning",
"link": ""
},
"message": "DB name is staging, config=default",
"range": {
"filename": "main.tf",
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 19
}
},
"callers": []
}
],
"errors": []
}
7 changes: 7 additions & 0 deletions integrationtest/inspection/rule-required-config/.tflint.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
plugin "testing" {
enabled = true
}

rule "aws_s3_bucket_with_config_example" {
enabled = true
}
9 changes: 9 additions & 0 deletions integrationtest/inspection/rule-required-config/result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"issues": [],
"errors": [
{
"message": "Failed to check ruleset; Failed to check `aws_s3_bucket_with_config_example` rule: .tflint.hcl:5,42-42: Missing required argument; The argument \"name\" is required, but no definition was found.",
"severity": "error"
}
]
}
13 changes: 10 additions & 3 deletions plugin/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,22 @@ func (s *GRPCServer) GetFiles(ty sdk.ModuleCtxType) map[string][]byte {
func (s *GRPCServer) GetRuleConfigContent(name string, bodyS *hclext.BodySchema) (*hclext.BodyContent, map[string][]byte, error) {
config := s.runner.RuleConfig(name)
if config == nil {
return nil, s.runner.ConfigSources(), fmt.Errorf("rule `%s` is not found in config", name)
return &hclext.BodyContent{}, s.runner.ConfigSources(), nil
}

enabledByCLI := false
configBody := config.Body
// If you enable the rule through the CLI instead of the file, its hcl.Body will be nil.
if config.Body == nil {
return nil, s.runner.ConfigSources(), errors.New("This rule cannot be enabled with the `--enable-rule` option because it lacks the required configuration")
enabledByCLI = true
configBody = hcl.EmptyBody()
}

body, diags := hclext.Content(config.Body, bodyS)
body, diags := hclext.Content(configBody, bodyS)
if diags.HasErrors() {
if enabledByCLI {
return nil, s.runner.ConfigSources(), errors.New("This rule cannot be enabled with the `--enable-rule` option because it lacks the required configuration")
}
return body, s.runner.ConfigSources(), diags
}
return body, s.runner.ConfigSources(), nil
Expand Down
18 changes: 13 additions & 5 deletions plugin/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,18 +303,26 @@ rule "test_in_file" {
Attributes: []hclext.AttributeSchema{{Name: "foo"}},
}
},
Want: nil,
ErrCheck: func(err error) bool {
return err == nil || err.Error() != "rule `not_found` is not found in config"
},
Want: &hclext.BodyContent{},
ErrCheck: neverHappend,
},
{
Name: "get rule enabled by CLI",
Name: "get rule enabled by CLI without required attribute",
Args: func() (string, *hclext.BodySchema) {
return "test_in_cli", &hclext.BodySchema{
Attributes: []hclext.AttributeSchema{{Name: "foo"}},
}
},
Want: &hclext.BodyContent{Blocks: hclext.Blocks{}, Attributes: hclext.Attributes{}},
ErrCheck: neverHappend,
},
{
Name: "get rule enabled by CLI with required attribute",
Args: func() (string, *hclext.BodySchema) {
return "test_in_cli", &hclext.BodySchema{
Attributes: []hclext.AttributeSchema{{Name: "foo", Required: true}},
}
},
Want: nil,
ErrCheck: func(err error) bool {
return err == nil || err.Error() != "This rule cannot be enabled with the `--enable-rule` option because it lacks the required configuration"
Expand Down
1 change: 1 addition & 0 deletions plugin/stub-generator/sources/testing/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ func main() {
rules.NewAwsInstanceMapEvalExampleRule(),
rules.NewAwsS3BucketWithConfigExampleRule(),
rules.NewAwsRoute53RecordEvalOnRootCtxExampleRule(),
rules.NewAwsDBInstanceWithDefaultConfigExampleRule(),
},
},
})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package rules

import (
"fmt"

"github.com/terraform-linters/tflint-plugin-sdk/hclext"
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
)

// AwsDBInstanceWithDefaultConfigExampleRule checks whether ...
type AwsDBInstanceWithDefaultConfigExampleRule struct {
tflint.DefaultRule
}

type awsDBInstanceWithDefaultConfigExampleRule struct {
Name string `hclext:"name,optional"`
}

// NewAwsDBInstanceWithDefaultConfigExampleRule returns a new rule
func NewAwsDBInstanceWithDefaultConfigExampleRule() *AwsDBInstanceWithDefaultConfigExampleRule {
return &AwsDBInstanceWithDefaultConfigExampleRule{}
}

// Name returns the rule name
func (r *AwsDBInstanceWithDefaultConfigExampleRule) Name() string {
return "aws_db_instance_with_default_config_example"
}

// Enabled returns whether the rule is enabled by default
func (r *AwsDBInstanceWithDefaultConfigExampleRule) Enabled() bool {
return true
}

// Severity returns the rule severity
func (r *AwsDBInstanceWithDefaultConfigExampleRule) Severity() tflint.Severity {
return tflint.WARNING
}

// Link returns the rule reference link
func (r *AwsDBInstanceWithDefaultConfigExampleRule) Link() string {
return ""
}

// Check checks whether ...
func (r *AwsDBInstanceWithDefaultConfigExampleRule) Check(runner tflint.Runner) error {
config := awsDBInstanceWithDefaultConfigExampleRule{Name: "default"}
if err := runner.DecodeRuleConfig(r.Name(), &config); err != nil {
return err
}

resources, err := runner.GetResourceContent("aws_db_instance", &hclext.BodySchema{
Attributes: []hclext.AttributeSchema{{Name: "name"}},
}, nil)
if err != nil {
return err
}

for _, resource := range resources.Blocks {
attribute, exists := resource.Body.Attributes["name"]
if !exists {
continue
}

var name string
err := runner.EvaluateExpr(attribute.Expr, &name, nil)

err = runner.EnsureNoError(err, func() error {
return runner.EmitIssue(
r,
fmt.Sprintf("DB name is %s, config=%s", name, config.Name),
attribute.Expr.Range(),
)
})
if err != nil {
return err
}
}

return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func (r *AwsS3BucketWithConfigExampleRule) Name() string {

// Enabled returns whether the rule is enabled by default
func (r *AwsS3BucketWithConfigExampleRule) Enabled() bool {
return false
return true
}

// Severity returns the rule severity
Expand Down

0 comments on commit 3fbef3f

Please sign in to comment.