Skip to content

Commit

Permalink
Merge branch 'aws'
Browse files Browse the repository at this point in the history
  • Loading branch information
lhitchon committed Sep 29, 2018
2 parents b9f8d95 + 088d574 commit 962b5ea
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 99 deletions.
90 changes: 90 additions & 0 deletions linter/aws.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package linter

import (
"fmt"
"github.com/stelligent/config-lint/assertion"
"io"
)

type (
// AWSResourceLoader provides the interface that a Linter needs to load a collection or Resource objects
AWSResourceLoader interface {
Load(ruleSet assertion.RuleSet) ([]assertion.Resource, error)
}
AWSAPIResourceLoader interface {
Load() ([]assertion.Resource, error)
}

// AWSLazyLoader provides the
AWSLazyLoader struct{}

// AWSResourceLinter implements a Linter for data returned by the calls to the AWS SDK
AWSResourceLinter struct {
RuleSet assertion.RuleSet
Loader AWSResourceLoader
ValueSource assertion.ValueSource
}
)

// Load uses the AWS API to load resources
func (l AWSLazyLoader) Load(ruleSet assertion.RuleSet) ([]assertion.Resource, error) {
types := map[string]bool{}
for _, r := range ruleSet.Rules {
if r.Resource != "" {
types[r.Resource] = true
}
if len(r.Resources) > 0 {
for _, t := range r.Resources {
types[t] = true
}
}
}
resources := []assertion.Resource{}
loaders := map[string]AWSAPIResourceLoader{
"AWS::IAM::User": IAMUserLoader{},
"AWS::IAM::Role": IAMRoleLoader{},
"AWS::IAM::Group": IAMGroupLoader{},
"AWS::EC2::SecurityGroup": SecurityGroupLoader{},
}
for t, _ := range types {
if loader, ok := loaders[t]; ok {
fmt.Println("Load:", t)
r, err := loader.Load()
if err == nil {
resources = append(resources, r...)
}
} else {
fmt.Println("Load:", t, "not implemented")
}
}
return resources, nil
}

// Validate applies a Ruleset to all SecurityGroups
func (l AWSResourceLinter) Validate(ruleSet assertion.RuleSet, options Options) (assertion.ValidationReport, error) {
rules := assertion.FilterRulesByTagAndID(ruleSet.Rules, options.Tags, options.RuleIDs, options.IgnoreRuleIDs)
rl := ResourceLinter{ValueSource: l.ValueSource}
resources, err := l.Loader.Load(ruleSet)
if err != nil {
return assertion.ValidationReport{}, err
}
return rl.ValidateResources(resources, rules)
}

// Search applies a JMESPath to all SecurityGroups
func (l AWSResourceLinter) Search(ruleSet assertion.RuleSet, searchExpression string, w io.Writer) {
resources, _ := l.Loader.Load(ruleSet)
for _, resource := range resources {
v, err := assertion.SearchData(searchExpression, resource.Properties)
if err != nil {
fmt.Fprintln(w, err)
} else {
s, err := assertion.JSONStringify(v)
if err != nil {
fmt.Fprintln(w, err)
} else {
fmt.Fprintf(w, "%s: %s\n", resource.ID, s)
}
}
}
}
49 changes: 0 additions & 49 deletions linter/aws_resource_linter.go

This file was deleted.

11 changes: 5 additions & 6 deletions linter/aws_resource_linter_test.go → linter/aws_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ func TestAWSResourceLinterValidate(t *testing.T) {
Tags: []string{},
RuleIDs: []string{},
}
ruleSet := loadRulesForTest("./testdata/rules/aws_sg_resource.yml", t)
mockLoader := AWSMockLoader{}
linter := AWSResourceLinter{Loader: mockLoader, ValueSource: TestingValueSource{}}
ruleSet := loadRulesForTest("./testdata/rules/aws_resource.yml", t)
linter := AWSResourceLinter{Loader: AWSMockLoader{}, ValueSource: TestingValueSource{}}
report, err := linter.Validate(ruleSet, options)
if err != nil {
t.Error("Expecting TestYAMLLinter to not return an error")
t.Error("Expecting Validate to not return an error")
}
if len(report.ResourcesScanned) != 1 {
t.Errorf("AWSResourceLinter scanned %d resources, expecting 1", len(report.ResourcesScanned))
Expand All @@ -28,7 +27,7 @@ func TestAWSResourceLinterValidate(t *testing.T) {
}

func TestAWSResourceLinterSearch(t *testing.T) {
ruleSet := loadRulesForTest("./testdata/rules/aws_sg_resource.yml", t)
ruleSet := loadRulesForTest("./testdata/rules/aws_resource.yml", t)
mockLoader := AWSMockLoader{}
linter := AWSResourceLinter{Loader: mockLoader, ValueSource: TestingValueSource{}}
var b bytes.Buffer
Expand All @@ -40,7 +39,7 @@ func TestAWSResourceLinterSearch(t *testing.T) {

type AWSMockLoader struct{}

func (l AWSMockLoader) Load() ([]assertion.Resource, error) {
func (l AWSMockLoader) Load(ruleSet assertion.RuleSet) ([]assertion.Resource, error) {
r := assertion.Resource{
ID: "1",
Type: "AWS::S3::Bucket",
Expand Down
13 changes: 6 additions & 7 deletions linter/file_linter.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,14 @@ type (
Load(filename string) (FileResources, error)
PostLoad(resources FileResources) ([]assertion.Resource, error)
}
// FileLinter provides implementation for some common functions that are used by multiple Linter implementations
FileLinter struct {
Filenames []string
ValueSource assertion.ValueSource
Loader FileResourceLoader
}
)

// FileLinter provides implementation for some common functions that are used by multiple Linter implementations
type FileLinter struct {
Filenames []string
ValueSource assertion.ValueSource
Loader FileResourceLoader
}

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

Expand Down
10 changes: 10 additions & 0 deletions linter/iam.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,13 @@ func (u IAMUserLoader) Load() ([]assertion.Resource, error) {

return resources, nil
}

// Load gets group information from AWS and generates Resources suitable for linting
func (u IAMGroupLoader) Load() ([]assertion.Resource, error) {
return []assertion.Resource{}, nil
}

// Load gets role information from AWS and generates Resources suitable for linting
func (u IAMRoleLoader) Load() ([]assertion.Resource, error) {
return []assertion.Resource{}, nil
}
6 changes: 2 additions & 4 deletions linter/linter.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,8 @@ func NewLinter(ruleSet assertion.RuleSet, vs assertion.ValueSource, filenames []
return FileLinter{Filenames: filenames, ValueSource: vs, Loader: KubernetesResourceLoader{}}, nil
case "Terraform":
return FileLinter{Filenames: filenames, ValueSource: vs, Loader: TerraformResourceLoader{}}, nil
case "SecurityGroup":
return AWSResourceLinter{Loader: SecurityGroupLoader{}, ValueSource: vs}, nil
case "IAMUser":
return AWSResourceLinter{Loader: IAMUserLoader{}, ValueSource: vs}, nil
case "AWS":
return AWSResourceLinter{RuleSet: ruleSet, ValueSource: vs, Loader: AWSLazyLoader{}}, nil
case "LintRules":
return FileLinter{Filenames: filenames, ValueSource: vs, Loader: RulesResourceLoader{}}, nil
case "YAML":
Expand Down
3 changes: 1 addition & 2 deletions linter/linter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ func TestNewLinter(t *testing.T) {
{"./testdata/rules/generic-yaml.yml", "FileLinter"},
{"./testdata/rules/generic-json.yml", "FileLinter"},
{"./testdata/rules/generic-csv.yml", "FileLinter"},
{"./testdata/rules/aws_sg_resource.yml", "AWSResourceLinter"},
{"./testdata/rules/aws_iam_resource.yml", "AWSResourceLinter"},
{"./testdata/rules/aws_resource.yml", "AWSResourceLinter"},
{"./testdata/rules/kubernetes.yml", "FileLinter"},
{"./testdata/rules/rules.yml", "FileLinter"},
}
Expand Down
16 changes: 0 additions & 16 deletions linter/testdata/rules/aws_iam_resource.yml

This file was deleted.

46 changes: 46 additions & 0 deletions linter/testdata/rules/aws_resource.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
version: 1
description: Rules for AWS Resource
type: AWS
files:
- "*"
rules:

- id: IAM_USER_NAME
message: Testing
resource: AWS::IAM::User
assertions:
- key: UserName
op: present
severity: FAILURE

- id: IAM_GROUP_NAME
message: Testing
resource: AWS::IAM::Group
assertions:
- key: GroupName
op: present
severity: FAILURE

- id: IAM_ROLE_NAME
message: Testing
resource: AWS::IAM::Role
assertions:
- key: Name
op: present
severity: FAILURE

- id: SECURITY_GROUP_NAME
message: Testing
resource: AWS::EC2::SecurityGroup
assertions:
- key: GroupName
op: present
severity: FAILURE

- id: BUCKET_NAME
message: Testing
resource: AWS::S3::Bucket
assertions:
- key: Name
op: present
severity: FAILURE
15 changes: 0 additions & 15 deletions linter/testdata/rules/aws_sg_resource.yml

This file was deleted.

0 comments on commit 962b5ea

Please sign in to comment.