Skip to content

Commit

Permalink
simplify linter package by using FileLinter with different ResourceLo…
Browse files Browse the repository at this point in the history
…ader for file based implementations
  • Loading branch information
lhitchon committed Apr 6, 2018
1 parent e500ed9 commit abe7f0b
Show file tree
Hide file tree
Showing 10 changed files with 19 additions and 90 deletions.
2 changes: 1 addition & 1 deletion cli/app.go
Expand Up @@ -78,7 +78,7 @@ func applyRules(rulesFilenames arrayFlags, args arrayFlags, options ApplyOptions
fmt.Println("Unable to parse rules in:" + rulesFilename)
fmt.Println(err.Error())
}
l, err := linter.NewLinter(ruleSet.Type, args)
l, err := linter.NewLinter(ruleSet, args)
if err != nil {
fmt.Println(err)
return
Expand Down
1 change: 1 addition & 0 deletions linter/common.go
Expand Up @@ -32,6 +32,7 @@ func getResourceIDFromFilename(filename string) string {
return resourceID
}

// CombineValidationReports merges results from two separate Validate runs
func CombineValidationReports(r1, r2 assertion.ValidationReport) assertion.ValidationReport {
return assertion.ValidationReport{
FilesScanned: append(r1.FilesScanned, r2.FilesScanned...),
Expand Down
8 changes: 4 additions & 4 deletions linter/file_linter.go
Expand Up @@ -17,8 +17,8 @@ type FileLinter struct {
Loader FileResourceLoader
}

// ValidateFiles validates a collection of filenames using a RuleSet
func (fl FileLinter) ValidateFiles(ruleSet assertion.RuleSet, options Options) (assertion.ValidationReport, error) {
// Validate validates a collection of filenames using a RuleSet
func (fl FileLinter) Validate(ruleSet assertion.RuleSet, options Options) (assertion.ValidationReport, error) {

report := assertion.ValidationReport{
FilesScanned: []string{},
Expand Down Expand Up @@ -46,8 +46,8 @@ func (fl FileLinter) ValidateFiles(ruleSet assertion.RuleSet, options Options) (
return report, nil
}

// SearchFiles evaluates a JMESPath expression against resources in a collection of filenames
func (fl FileLinter) SearchFiles(ruleSet assertion.RuleSet, searchExpression string) {
// Search evaluates a JMESPath expression against resources in a collection of filenames
func (fl FileLinter) Search(ruleSet assertion.RuleSet, searchExpression string) {
for _, filename := range fl.Filenames {
include, _ := assertion.ShouldIncludeFile(ruleSet.Files, filename) // FIXME what about error?
if include {
Expand Down
14 changes: 0 additions & 14 deletions linter/kubernetes.go
Expand Up @@ -47,17 +47,3 @@ func (l KubernetesResourceLoader) Load(filename string) ([]assertion.Resource, e
}
return resources, nil
}

// Validate runs validate on a collection of filenames using a RuleSet
func (l KubernetesLinter) Validate(ruleSet assertion.RuleSet, options Options) (assertion.ValidationReport, error) {
loader := KubernetesResourceLoader{}
f := FileLinter{Filenames: l.Filenames, ValueSource: l.ValueSource, Loader: loader}
return f.ValidateFiles(ruleSet, options)
}

// Search evaluates a JMESPath expression against the resources in a collection of filenames
func (l KubernetesLinter) Search(ruleSet assertion.RuleSet, searchExpression string) {
loader := KubernetesResourceLoader{}
f := FileLinter{Filenames: l.Filenames, ValueSource: l.ValueSource, Loader: loader}
f.SearchFiles(ruleSet, searchExpression)
}
15 changes: 8 additions & 7 deletions linter/linter.go
Expand Up @@ -19,22 +19,23 @@ type (
}
)

func NewLinter(linterType string, args []string) (Linter, error) {
// NewLinter create the right kind of Linter based on the type argument
func NewLinter(ruleSet assertion.RuleSet, args []string) (Linter, error) {
vs := assertion.StandardValueSource{}
switch linterType {
switch ruleSet.Type {
case "Kubernetes":
return KubernetesLinter{Filenames: args, ValueSource: vs}, nil
return FileLinter{Filenames: args, ValueSource: vs, Loader: KubernetesResourceLoader{}}, nil
case "Terraform":
return TerraformLinter{Filenames: args, ValueSource: vs}, nil
return FileLinter{Filenames: args, ValueSource: vs, Loader: TerraformResourceLoader{}}, nil
case "SecurityGroup":
return AWSResourceLinter{Loader: SecurityGroupLoader{}, ValueSource: vs}, nil
case "IAMUser":
return AWSResourceLinter{Loader: IAMUserLoader{}, ValueSource: vs}, nil
case "LintRules":
return RulesLinter{Filenames: args, ValueSource: vs}, nil
return FileLinter{Filenames: args, ValueSource: vs, Loader: RulesResourceLoader{}}, nil
case "YAML":
return YAMLLinter{Filenames: args, ValueSource: vs}, nil
return FileLinter{Filenames: args, ValueSource: vs, Loader: YAMLResourceLoader{Resources: ruleSet.Resources}}, nil
default:
return nil, fmt.Errorf("Type not supported: %s", linterType)
return nil, fmt.Errorf("Type not supported: %s", ruleSet.Type)
}
}
20 changes: 0 additions & 20 deletions linter/rules_linter.go → linter/rules_resource_loader.go
Expand Up @@ -4,12 +4,6 @@ import (
"github.com/stelligent/config-lint/assertion"
)

// RulesLinter lints rules files for itself
type RulesLinter struct {
Filenames []string
ValueSource assertion.ValueSource
}

// RulesResourceLoader converts a YAML configuration file into a collection with Resource objects
type RulesResourceLoader struct{}

Expand Down Expand Up @@ -55,17 +49,3 @@ func (l RulesResourceLoader) Load(filename string) ([]assertion.Resource, error)
}
return resources, nil
}

// Validate runs validate on a collection of filenames using a RuleSet
func (l RulesLinter) Validate(ruleSet assertion.RuleSet, options Options) (assertion.ValidationReport, error) {
loader := RulesResourceLoader{}
f := FileLinter{Filenames: l.Filenames, ValueSource: l.ValueSource, Loader: loader}
return f.ValidateFiles(ruleSet, options)
}

// Search evaluates a JMESPath expression against the resources in a collection of filenames
func (l RulesLinter) Search(ruleSet assertion.RuleSet, searchExpression string) {
loader := RulesResourceLoader{}
f := FileLinter{Filenames: l.Filenames, ValueSource: l.ValueSource, Loader: loader}
f.SearchFiles(ruleSet, searchExpression)
}
20 changes: 0 additions & 20 deletions linter/terraform.go
Expand Up @@ -10,12 +10,6 @@ import (
"io/ioutil"
)

// TerraformLinter implements a Linter for Terraform configuration files
type TerraformLinter struct {
Filenames []string
ValueSource assertion.ValueSource
}

// TerraformResourceLoader converts Terraform configuration files into JSON objects
type TerraformResourceLoader struct{}

Expand Down Expand Up @@ -111,17 +105,3 @@ func (l TerraformResourceLoader) Load(filename string) ([]assertion.Resource, er
}
return resources, nil
}

// Validate uses a RuleSet to validate resources in a collection of Terraform configuration files
func (l TerraformLinter) Validate(ruleSet assertion.RuleSet, options Options) (assertion.ValidationReport, error) {
loader := TerraformResourceLoader{}
f := FileLinter{Filenames: l.Filenames, ValueSource: l.ValueSource, Loader: loader}
return f.ValidateFiles(ruleSet, options)
}

// Search applies a JMESPath expression to the resources in a collection of Terraform configuration files
func (l TerraformLinter) Search(ruleSet assertion.RuleSet, searchExpression string) {
loader := TerraformResourceLoader{}
f := FileLinter{Filenames: l.Filenames, ValueSource: l.ValueSource, Loader: loader}
f.SearchFiles(ruleSet, searchExpression)
}
2 changes: 1 addition & 1 deletion linter/terraform_test.go
Expand Up @@ -11,7 +11,7 @@ func TestTerraformLinter(t *testing.T) {
RuleIDs: []string{},
}
filenames := []string{"./testdata/resources/terraform_instance.tf"}
linter := TerraformLinter{Filenames: filenames, ValueSource: TestingValueSource{}}
linter := FileLinter{Filenames: filenames, ValueSource: TestingValueSource{}, Loader: TerraformResourceLoader{}}
ruleSet := loadRulesForTest("./testdata/rules/terraform_instance.yml", t)
report, err := linter.Validate(ruleSet, options)
if err != nil {
Expand Down
20 changes: 0 additions & 20 deletions linter/yaml_linter.go → linter/yaml_resource_loader.go
Expand Up @@ -4,12 +4,6 @@ import (
"github.com/stelligent/config-lint/assertion"
)

// YAMLLinter lints rules from a generic YAML file
type YAMLLinter struct {
Filenames []string
ValueSource assertion.ValueSource
}

// YAMLResourceLoader loads a list of Resource objects based on the list of ResourceConfig objects
type YAMLResourceLoader struct {
Resources []assertion.ResourceConfig
Expand Down Expand Up @@ -52,17 +46,3 @@ func (l YAMLResourceLoader) Load(filename string) ([]assertion.Resource, error)
}
return resources, nil
}

// Validate runs validate on a collection of filenames using a RuleSet
func (l YAMLLinter) Validate(ruleSet assertion.RuleSet, options Options) (assertion.ValidationReport, error) {
loader := YAMLResourceLoader{Resources: ruleSet.Resources}
f := FileLinter{Filenames: l.Filenames, ValueSource: l.ValueSource, Loader: loader}
return f.ValidateFiles(ruleSet, options)
}

// Search evaluates a JMESPath expression against the resources in a collection of filenames
func (l YAMLLinter) Search(ruleSet assertion.RuleSet, searchExpression string) {
loader := YAMLResourceLoader{Resources: ruleSet.Resources}
f := FileLinter{Filenames: l.Filenames, ValueSource: l.ValueSource, Loader: loader}
f.SearchFiles(ruleSet, searchExpression)
}
Expand Up @@ -9,15 +9,16 @@ func TestYAMLLinter(t *testing.T) {
Tags: []string{},
RuleIDs: []string{},
}
filenames := []string{"./testdata/resources/generic.config"}
linter := YAMLLinter{Filenames: filenames, ValueSource: TestingValueSource{}}
ruleSet := loadRulesForTest("./testdata/rules/generic.yml", t)
filenames := []string{"./testdata/resources/generic.config"}
loader := YAMLResourceLoader{Resources: ruleSet.Resources}
linter := FileLinter{Filenames: filenames, ValueSource: TestingValueSource{}, Loader: loader}
report, err := linter.Validate(ruleSet, options)
if err != nil {
t.Error("Expecting TestYAMLLinter to not return an error")
}
if len(report.ResourcesScanned) != 17 {
t.Errorf("TestTerraformLinter scanned %d resources, expecting 17", len(report.ResourcesScanned))
t.Errorf("TestYAMLLinter scanned %d resources, expecting 17", len(report.ResourcesScanned))
}
if len(report.FilesScanned) != 1 {
t.Errorf("TestYAMLLinter scanned %d files, expecting 1", len(report.FilesScanned))
Expand Down

0 comments on commit abe7f0b

Please sign in to comment.