Refactor code, remove ignore_config logic, will add back in the future.

Add version ensure test to ensure that the releases in the future have proper version meta-data.
This commit is contained in:
zjhe 2022-09-20 22:49:11 +08:00
Родитель cb12c64e13
Коммит 61f50ab1f9
15 изменённых файлов: 112 добавлений и 241 удалений

9
go.mod
Просмотреть файл

@ -3,11 +3,14 @@ module github.com/terraform-linters/tflint-ruleset-azurerm-ext
go 1.18
require (
github.com/google/go-cmp v0.5.8
github.com/google/go-cmp v0.5.9
github.com/google/go-github/v47 v47.1.0
github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/hcl/v2 v2.14.0
github.com/hashicorp/terraform-provider-azurerm v0.0.0-00010101000000-000000000000
github.com/stretchr/testify v1.7.2
github.com/terraform-linters/tflint-plugin-sdk v0.12.0
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4
)
require (
@ -30,10 +33,11 @@ require (
github.com/gofrs/uuid v4.0.0+incompatible // indirect
github.com/golang-jwt/jwt/v4 v4.4.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/uuid v1.1.2 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-azure-helpers v0.40.0 // indirect
github.com/hashicorp/go-azure-sdk v0.20220907.1111434 // indirect
github.com/hashicorp/go-azure-sdk v0.20220916.1125744 // indirect
github.com/hashicorp/go-checkpoint v0.5.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect
@ -63,6 +67,7 @@ require (
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/oklog/run v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rickb777/date v1.12.5-0.20200422084442-6300e543c4d9 // indirect
github.com/rickb777/plural v1.2.0 // indirect
github.com/tombuildsstuff/giovanni v0.20.0 // indirect

14
go.sum
Просмотреть файл

@ -172,9 +172,15 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-github/v47 v47.1.0 h1:Cacm/WxQBOa9lF0FT0EMjZ2BWMetQ1TQfyurn4yF1z8=
github.com/google/go-github/v47 v47.1.0/go.mod h1:VPZBXNbFSJGjyjFRUKo9vZGawTajnWzC/YjGw/oFKi0=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@ -196,8 +202,8 @@ github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv
github.com/hashicorp/go-azure-helpers v0.12.0/go.mod h1:Zc3v4DNeX6PDdy7NljlYpnrdac1++qNW0I4U+ofGwpg=
github.com/hashicorp/go-azure-helpers v0.40.0 h1:NjiyF+jN+0mRdFBU894yzZSxu1SNrbvj8l4rEDpCB0A=
github.com/hashicorp/go-azure-helpers v0.40.0/go.mod h1:gcutZ/Hf/O7YN9M3UIvyZ9l0Rxv7Yrc9x5sSfM9cuSw=
github.com/hashicorp/go-azure-sdk v0.20220907.1111434 h1:AaVzM1kzNIqjre7VDpYCWkk4Ov83TKlQNscYrf0xwt0=
github.com/hashicorp/go-azure-sdk v0.20220907.1111434/go.mod h1:jOhjVttoXh2We/glz4BC/0t0Lo8+M9WQBA4sbAPQPMY=
github.com/hashicorp/go-azure-sdk v0.20220916.1125744 h1:13Q0gsr+6UZJyH3OQ9z/2HX2qrbdzY2anS4ttL2NkHY=
github.com/hashicorp/go-azure-sdk v0.20220916.1125744/go.mod h1:jOhjVttoXh2We/glz4BC/0t0Lo8+M9WQBA4sbAPQPMY=
github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU=
github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
@ -398,6 +404,8 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=

Просмотреть файл

@ -1,25 +0,0 @@
{
"issues": [
{
"rule": {
"name": "azurerm_arg_order",
"severity": "info",
"link": "https://github.com/DrikoldLun/tflint-ruleset-azurerm-ext/blob/v0.0.2/docs/rules/azurerm_arg_order.md"
},
"message": "Arguments are expected to be sorted in following order:\nresource \"azurerm_container_group\" \"example\" {\n location = azurerm_resource_group.example.location\n name = \"example-continst\"\n os_type = \"Linux\"\n resource_group_name = azurerm_resource_group.example.name\n dns_name_label = \"aci-label\"\n ip_address_type = \"Public\"\n tags = {\n environment = \"testing\"\n }\n\n container {\n cpu = \"0.5\"\n image = \"mcr.microsoft.com/azuredocs/aci-helloworld:latest\"\n memory = \"1.5\"\n name = \"hello-world\"\n\n ports {\n port = 443\n protocol = \"TCP\"\n }\n }\n container {\n cpu = \"0.5\"\n image = \"mcr.microsoft.com/azuredocs/aci-tutorial-sidecar\"\n memory = \"1.5\"\n name = \"sidecar\"\n }\n\n depends_on = [\n azurerm_resource_group.example\n ]\n}",
"range": {
"filename": "main.tf",
"start": {
"line": 1,
"column": 1
},
"end": {
"line": 1,
"column": 45
}
},
"callers": []
}
],
"errors": []
}

Просмотреть файл

@ -2,13 +2,9 @@ package integration
import (
"bytes"
"encoding/json"
"io/ioutil"
"os"
"os/exec"
"testing"
"github.com/google/go-cmp/cmp"
)
func TestIntegration(t *testing.T) {
@ -37,24 +33,5 @@ func TestIntegration(t *testing.T) {
if err := tc.Command.Run(); err != nil {
t.Fatalf("Failed `%s`: %s, stdout=%s stderr=%s", tc.Name, err, stdout.String(), stderr.String())
}
ret, err := ioutil.ReadFile("result.json")
if err != nil {
t.Fatalf("Failed `%s`: %s", tc.Name, err)
}
var expected interface{}
if err := json.Unmarshal(ret, &expected); err != nil {
t.Fatalf("Failed `%s`: %s", tc.Name, err)
}
var got interface{}
if err := json.Unmarshal(stdout.Bytes(), &got); err != nil {
t.Fatalf("Failed `%s`: %s", tc.Name, err)
}
if !cmp.Equal(got, expected) {
t.Fatalf("Failed `%s`: diff=%s", tc.Name, cmp.Diff(expected, got))
}
}
}

Просмотреть файл

@ -12,7 +12,10 @@ func main() {
RuleSet: &tflint.BuiltinRuleSet{
Name: "azurerm-ext",
Version: project.Version,
Rules: rules.Rules,
Rules: []tflint.Rule{
rules.NewAzurermArgOrderRule(),
rules.NewAzurermResourceTagRule(),
},
},
})
}

Просмотреть файл

@ -3,9 +3,9 @@ package project
import "fmt"
// Version is ruleset version
const Version string = "0.0.2"
const Version string = "0.0.3"
// ReferenceLink returns the rule reference link
func ReferenceLink(name string) string {
return fmt.Sprintf("https://github.com/DrikoldLun/tflint-ruleset-azurerm-ext/blob/v%s/docs/rules/%s.md", Version, name)
return fmt.Sprintf("https://github.com/Azure/tflint-ruleset-azurerm-ext/blob/v%s/docs/rules/%s.md", Version, name)
}

Просмотреть файл

@ -7,13 +7,30 @@ import (
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/hashicorp/terraform-provider-azurerm/provider"
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
"github.com/terraform-linters/tflint-ruleset-azurerm-ext/project"
)
var _ myRule = new(AzurermArgOrderRule)
var _ tflint.Rule = new(AzurermArgOrderRule)
// AzurermArgOrderRule checks whether the arguments in a block are sorted in azure doc order
type AzurermArgOrderRule struct {
DefaultRule
tflint.DefaultRule
}
func (r *AzurermArgOrderRule) Enabled() bool {
return false
}
func (r *AzurermArgOrderRule) Severity() tflint.Severity {
return tflint.NOTICE
}
func (r *AzurermArgOrderRule) Check(runner tflint.Runner) error {
return Check(runner, r.CheckFile)
}
func (r *AzurermArgOrderRule) Link() string {
return project.ReferenceLink(r.Name())
}
// NewAzurermArgOrderRule returns a new rule

Просмотреть файл

@ -642,7 +642,7 @@ resource "azurerm_container_group" "example" {
},
}
rule := NewRule(NewAzurermArgOrderRule())
rule := NewAzurermArgOrderRule()
for _, tc := range cases {
runner := helper.TestRunner(t, map[string]string{"config.tf": tc.Content})
@ -663,7 +663,7 @@ resource "random_string" "key_vault_prefix" {
upper = false
numeric = false
}`
rule := NewRule(NewAzurermArgOrderRule())
rule := NewAzurermArgOrderRule()
runner := helper.TestRunner(t, map[string]string{"config.tf": code})
if err := rule.Check(runner); err != nil {
t.Fatalf("Unexpected error occurred: %s", err)

Просмотреть файл

@ -7,14 +7,35 @@ import (
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/hashicorp/terraform-provider-azurerm/provider"
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
"github.com/terraform-linters/tflint-ruleset-azurerm-ext/project"
"strings"
)
var _ myRule = new(AzurermResourceTagRule)
var _ tflint.Rule = new(AzurermResourceTagRule)
// AzurermResourceTagRule checks whether the tags arg is specified if supported
type AzurermResourceTagRule struct {
DefaultRule
tflint.DefaultRule
}
func (r *AzurermResourceTagRule) Name() string {
return "azurerm_resource_tag"
}
func (r *AzurermResourceTagRule) Enabled() bool {
return false
}
func (r *AzurermResourceTagRule) Severity() tflint.Severity {
return tflint.NOTICE
}
func (r *AzurermResourceTagRule) Link() string {
return project.ReferenceLink(r.Name())
}
func (r *AzurermResourceTagRule) Check(runner tflint.Runner) error {
return Check(runner, r.CheckFile)
}
// NewAzurermResourceTagRule returns a new rule

Просмотреть файл

@ -131,7 +131,7 @@ resource "azurerm_container_registry" "acr" {
},
}
rule := NewRule(NewAzurermResourceTagRule())
rule := NewAzurermResourceTagRule()
for _, tc := range cases {
runner := helper.TestRunner(t, map[string]string{"config.tf": tc.Content})

Просмотреть файл

@ -1,6 +1,8 @@
package rules
import (
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/hcl/v2"
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
)
@ -19,10 +21,16 @@ func IsTailMeta(argName string) bool {
return isTailMeta
}
func getExistedRules() map[string]tflint.Rule {
rules := make(map[string]tflint.Rule)
for _, rule := range Rules {
rules[rule.Name()] = rule
// Check checks whether the tf config files match given rules
func Check(runner tflint.Runner, check func(tflint.Runner, *hcl.File) error) error {
files, err := runner.GetFiles()
if err != nil {
return err
}
return rules
for _, file := range files {
if subErr := check(runner, file); subErr != nil {
err = multierror.Append(err, subErr)
}
}
return err
}

Просмотреть файл

@ -1,93 +0,0 @@
package rules
import (
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/hcl/v2/hclsimple"
"log"
"os"
"regexp"
"strings"
)
var ignores map[string][]*regexp.Regexp
var retains map[string][]*regexp.Regexp
var ignoreConfigFile = ".tflintignore.azurerm-ext.json"
func loadIgnoreConfig() {
ignores = make(map[string][]*regexp.Regexp)
retains = make(map[string][]*regexp.Regexp)
if _, err := os.Stat(ignoreConfigFile); err != nil {
if !os.IsNotExist(err) {
log.Panicf("Ignore config file %s check failed:\n%s", ignoreConfigFile, err)
}
return
}
ruleIgnoreRegExps := make(map[string][]string)
if err := hclsimple.DecodeFile(ignoreConfigFile, nil, &ruleIgnoreRegExps); err != nil {
log.Panicf("Ignore config file %s read error:\n%s", ignoreConfigFile, err)
}
for ruleName, regExps := range ruleIgnoreRegExps {
registerPatterns(ruleName, regExps)
}
}
func registerPatterns(ruleName string, regExps []string) {
existingRules := getExistedRules()
if _, isRuleExist := existingRules[ruleName]; !isRuleExist {
log.Panicf("Rule %s in %s not found", ruleName, ignoreConfigFile)
}
var err error
for _, regExp := range regExps {
isIgnorePattern := true
if strings.HasPrefix(regExp, "!") {
isIgnorePattern = false
regExp = regExp[1:]
}
pattern, subErr := regexp.Compile(regExp)
if subErr != nil {
err = multierror.Append(err, subErr)
continue
}
if isIgnorePattern {
ignores[ruleName] = append(ignores[ruleName], pattern)
} else {
retains[ruleName] = append(retains[ruleName], pattern)
}
}
if err != nil {
log.Panicf("Error found when compile regexps in %s:\n%s", ignoreConfigFile, err)
}
}
func ignoreFile(filename string, rulename string) bool {
isIgnore := false
_, isDefined := ignores[rulename]
if isDefined {
isIgnore = matchIgnorePatterns(filename, rulename)
}
_, isDefined = retains[rulename]
if isDefined {
isIgnore = !matchRetainPatterns(filename, rulename)
}
return isIgnore
}
func matchIgnorePatterns(filename string, rulename string) bool {
patterns := ignores[rulename]
for _, pattern := range patterns {
if pattern.MatchString(filename) {
return true
}
}
return false
}
func matchRetainPatterns(filename string, rulename string) bool {
patterns := retains[rulename]
for _, pattern := range patterns {
if pattern.MatchString(filename) {
return true
}
}
return false
}

Просмотреть файл

@ -1,13 +0,0 @@
package rules
import "github.com/terraform-linters/tflint-plugin-sdk/tflint"
// Rules is a list of all rules
var Rules = []tflint.Rule{
NewAzurermArgOrderRule(),
NewAzurermResourceTagRule(),
}
func init() {
loadIgnoreConfig()
}

Просмотреть файл

@ -1,67 +0,0 @@
package rules
import (
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/hcl/v2"
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
"github.com/terraform-linters/tflint-ruleset-azurerm-ext/project"
)
// DefaultRule is the default template for rules in this plugin
type DefaultRule struct {
tflint.DefaultRule
Rulename string
CheckFile func(runner tflint.Runner, file *hcl.File) error
}
// Check checks whether the tf config files match given rules
func (r *DefaultRule) Check(runner tflint.Runner) error {
files, err := runner.GetFiles()
if err != nil {
return err
}
for filename, file := range files {
if ignoreFile(filename, r.Rulename) {
continue
}
if subErr := r.CheckFile(runner, file); subErr != nil {
err = multierror.Append(err, subErr)
}
}
return err
}
// Link returns the rule reference link
func (r *DefaultRule) Link() string { return project.ReferenceLink(r.Rulename) }
// Enabled returns whether the rule is enabled by default
func (r *DefaultRule) Enabled() bool { return false }
// Severity returns the rule severity
func (r *DefaultRule) Severity() tflint.Severity { return tflint.NOTICE }
// Name returns the rule name
func (r *DefaultRule) Name() string { return "" }
func (r *DefaultRule) setName(n string) {
r.Rulename = n
}
func (r *DefaultRule) setCheckFunc(f func(runner tflint.Runner, file *hcl.File) error) {
r.CheckFile = f
}
type myRule interface {
tflint.Rule
Name() string
CheckFile(runner tflint.Runner, file *hcl.File) error
setCheckFunc(f func(runner tflint.Runner, file *hcl.File) error)
setName(string)
}
// NewRule returns a rule to be checked
func NewRule(r myRule) tflint.Rule {
r.setName(r.Name())
r.setCheckFunc(r.CheckFile)
return r
}

Просмотреть файл

@ -0,0 +1,30 @@
package version_test
import (
"context"
"fmt"
"github.com/terraform-linters/tflint-ruleset-azurerm-ext/project"
"golang.org/x/mod/semver"
"testing"
"github.com/google/go-github/v47/github"
"github.com/stretchr/testify/assert"
)
func Test_EnsureVersionHasBeenBumpedUp(t *testing.T) {
currentVersion := fmt.Sprintf("v%s", project.Version)
assert.True(t, semver.IsValid(currentVersion))
client := github.NewClient(nil)
tags, _, err := client.Repositories.ListTags(context.TODO(), "Azure", "tflint-ruleset-azurerm-ext", &github.ListOptions{
Page: 0,
PerPage: 10,
})
assert.Nil(t, err)
assert.NotEmpty(t, tags)
for _, tag := range tags {
v := tag.GetName()
if semver.IsValid(v) && semver.Compare(v, currentVersion) >= 0 {
t.Fatalf("latest version: %s, current version %s, please update current version in project/main.go", v, currentVersion)
}
}
}