Skip to content

Commit

Permalink
define Linter interface, use for two existing linters
Browse files Browse the repository at this point in the history
  • Loading branch information
lhitchon committed Mar 11, 2018
1 parent 8211ab1 commit bf5dbb1
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 37 deletions.
48 changes: 24 additions & 24 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ type ValidationReport struct {
FilesScanned []string
}

type Linter interface {
Validate(filenames []string, ruleSet RuleSet, tags []string, ruleIds []string) ValidationReport
Search(filenames []string, searchExpression string)
}

func printReport(report ValidationReport, queryExpression string) int {
jsonData, err := json.MarshalIndent(report, "", " ")
if err != nil {
Expand Down Expand Up @@ -88,6 +93,18 @@ func makeRulesList(ruleIds string) []string {
return strings.Split(ruleIds, ",")
}

func makeLinter(linterType string, log LoggingFunction) Linter {
switch linterType {
case "Kubernetes":
return KubernetesLinter{Log: log}
case "Terraform":
return TerraformLinter{Log: log}
default:
fmt.Printf("Type not supported: %s\n", linterType)
return nil
}
}

func main() {
verboseLogging := flag.Bool("verbose", false, "Verbose logging")
rulesFilename := flag.String("rules", "./rules/terraform.yml", "Rules file")
Expand All @@ -97,34 +114,17 @@ func main() {
searchExpression := flag.String("search", "", "JMESPath expression to evaluation against the files")
flag.Parse()

logger := makeLogger(*verboseLogging)

exitCode := 0

ruleSet := MustParseRules(loadTerraformRules(*rulesFilename))

switch ruleSet.Type {
case "Kubernetes":
{
if *searchExpression != "" {
kubernetesSearch(flag.Args(), *searchExpression, logger)
} else {
report := kubernetes(flag.Args(), ruleSet, makeTagList(*tags), makeRulesList(*ids), logger)
exitCode = printReport(report, *queryExpression)
}
linter := makeLinter(ruleSet.Type, makeLogger(*verboseLogging))
if linter != nil {
if *searchExpression != "" {
linter.Search(flag.Args(), *searchExpression)
} else {
report := linter.Validate(flag.Args(), ruleSet, makeTagList(*tags), makeRulesList(*ids))
exitCode = printReport(report, *queryExpression)
}
case "Terraform":
{
if *searchExpression != "" {
terraformSearch(flag.Args(), *searchExpression, logger)
} else {
report := terraform(flag.Args(), ruleSet, makeTagList(*tags), makeRulesList(*ids), logger)
exitCode = printReport(report, *queryExpression)
}
}
default:
fmt.Printf("Type not supported: %s\n", ruleSet.Type)
exitCode = 1
}
os.Exit(exitCode)
}
18 changes: 11 additions & 7 deletions kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import (
"io/ioutil"
)

type KubernetesLinter struct {
Log LoggingFunction
}

// TODO - is it really necessary to have two types?
type KubernetesResource = TerraformResource

Expand Down Expand Up @@ -85,27 +89,27 @@ func validateKubernetesResources(report *ValidationReport, resources []Kubernete
}
}

func kubernetes(filenames []string, ruleSet RuleSet, tags []string, ruleIds []string, log LoggingFunction) ValidationReport {
func (l KubernetesLinter) Validate(filenames []string, ruleSet RuleSet, tags []string, ruleIds []string) ValidationReport {
report := ValidationReport{
Violations: make(map[string]([]Violation), 0),
FilesScanned: make([]string, 0),
}
rules := filterRulesById(ruleSet.Rules, ruleIds)
for _, filename := range filenames {
if shouldIncludeFile(ruleSet.Files, filename) {
log(fmt.Sprintf("Processing %s", filename))
resources := loadKubernetesResources(filename, log)
validateKubernetesResources(&report, resources, rules, tags, log)
l.Log(fmt.Sprintf("Processing %s", filename))
resources := loadKubernetesResources(filename, l.Log)
validateKubernetesResources(&report, resources, rules, tags, l.Log)
report.FilesScanned = append(report.FilesScanned, filename)
}
}
return report
}

func kubernetesSearch(filenames []string, searchExpression string, log LoggingFunction) {
func (l KubernetesLinter) Search(filenames []string, searchExpression string) {
for _, filename := range filenames {
log(fmt.Sprintf("Searching %s", filename))
resources := loadKubernetesResources(filename, log)
l.Log(fmt.Sprintf("Searching %s", filename))
resources := loadKubernetesResources(filename, l.Log)
for _, resource := range resources {
v, err := searchData(searchExpression, resource.Properties)
if err == nil && v != "null" {
Expand Down
16 changes: 10 additions & 6 deletions terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import (
"io/ioutil"
)

type TerraformLinter struct {
Log LoggingFunction
}

type TerraformResource struct {
Id string
Type string
Expand Down Expand Up @@ -116,26 +120,26 @@ func validateTerraformResources(report *ValidationReport, resources []TerraformR
}
}

func terraform(filenames []string, ruleSet RuleSet, tags []string, ruleIds []string, log LoggingFunction) ValidationReport {
func (l TerraformLinter) Validate(filenames []string, ruleSet RuleSet, tags []string, ruleIds []string) ValidationReport {
report := ValidationReport{
Violations: make(map[string]([]Violation), 0),
FilesScanned: make([]string, 0),
}
rules := filterRulesById(ruleSet.Rules, ruleIds)
for _, filename := range filenames {
if shouldIncludeFile(ruleSet.Files, filename) {
resources := loadTerraformResources(filename, log)
validateTerraformResources(&report, resources, rules, tags, log)
resources := loadTerraformResources(filename, l.Log)
validateTerraformResources(&report, resources, rules, tags, l.Log)
report.FilesScanned = append(report.FilesScanned, filename)
}
}
return report
}

func terraformSearch(filenames []string, searchExpression string, log LoggingFunction) {
func (l TerraformLinter) Search(filenames []string, searchExpression string) {
for _, filename := range filenames {
log(fmt.Sprintf("Searching %s", filename))
resources := loadTerraformResources(filename, log)
l.Log(fmt.Sprintf("Searching %s", filename))
resources := loadTerraformResources(filename, l.Log)
for _, resource := range resources {
v, err := searchData(searchExpression, resource.Properties)
if err == nil && v != "null" {
Expand Down

0 comments on commit bf5dbb1

Please sign in to comment.