Skip to content

Commit

Permalink
Merge pull request #455 from patilpankaj212/annotations-based-skipping
Browse files Browse the repository at this point in the history
rule skipping for resources in k8s
  • Loading branch information
Willie authored Jan 8, 2021
2 parents 32ff137 + 0ea7356 commit 20a4bdb
Show file tree
Hide file tree
Showing 6 changed files with 413 additions and 3 deletions.
4 changes: 4 additions & 0 deletions pkg/cli/testdata/run-test/test_pod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ metadata:
app: myapp
test: someupdate
test2: someupdate3
annotations:
terrascanSkip: [accurics.kubernetes.IAM.109]
spec:
containers:
- name: myapp-container
Expand All @@ -22,6 +24,8 @@ metadata:
app: myapp
test: someupdate
test2: someupdate3
annotations:
terrascanSkip: [accurics.kubernetes.IAM.3, accurics.kubernetes.OPS.461]
spec:
template:
spec:
Expand Down
6 changes: 6 additions & 0 deletions pkg/iac-providers/kubernetes/v1/load-file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ func TestLoadIacFile(t *testing.T) {
k8sV1: K8sV1{},
wantErr: nil,
},
{
name: "file with skip rules in annotations",
filePath: "./testdata/file-test-data/test_pod_skip_rules.yaml",
k8sV1: K8sV1{},
wantErr: nil,
},
}

for _, tt := range table {
Expand Down
41 changes: 38 additions & 3 deletions pkg/iac-providers/kubernetes/v1/normalize.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,23 @@ import (
"github.com/accurics/terrascan/pkg/utils"
yamltojson "github.com/ghodss/yaml"
"github.com/iancoleman/strcase"
"go.uber.org/zap"
"gopkg.in/yaml.v3"
)

const terrascanSkip = "terrascanSkip"

var (
errUnsupportedDoc = fmt.Errorf("unsupported document type")
// ErrNoKind is returned when the "kind" key is not available (not a valid kubernetes resource)
ErrNoKind = fmt.Errorf("kind does not exist")
)

// k8sMetadata is used to pull the name and namespace types for a given resource
// k8sMetadata is used to pull the name, namespace types and annotations for a given resource
type k8sMetadata struct {
Name string `yaml:"name" json:"name"`
Namespace string `yaml:"namespace" json:"namespace"`
Name string `yaml:"name" json:"name"`
Namespace string `yaml:"namespace" json:"namespace"`
Annotations map[string]interface{} `yaml:"annotations" json:"annotations"`
}

// k8sResource is a generic struct to handle all k8s resource types
Expand Down Expand Up @@ -116,6 +120,12 @@ func (k *K8sV1) Normalize(doc *utils.IacDocument) (*output.ResourceConfig, error
resourceConfig.ID = resourceConfig.Type + "." + resource.Metadata.Name + "." + namespace
}

// read and update skip rules, if present
skipRules := readSkipRulesFromAnnotations(resource.Metadata.Annotations, resourceConfig.ID)
if skipRules != nil {
resourceConfig.SkipRules = append(resourceConfig.SkipRules, skipRules...)
}

configData := make(map[string]interface{})
if err = json.Unmarshal(*jsonData, &configData); err != nil {
return nil, err
Expand All @@ -126,3 +136,28 @@ func (k *K8sV1) Normalize(doc *utils.IacDocument) (*output.ResourceConfig, error

return &resourceConfig, nil
}

func readSkipRulesFromAnnotations(annotations map[string]interface{}, resourceID string) []string {

var skipRulesFromAnnotations interface{}
var ok bool
if skipRulesFromAnnotations, ok = annotations[terrascanSkip]; !ok {
zap.S().Debugf("%s not present for resource: %s", terrascanSkip, resourceID)
return nil
}

skipRules := make([]string, 0)
if rules, ok := skipRulesFromAnnotations.([]interface{}); ok {
for _, rule := range rules {
if value, ok := rule.(string); ok {
skipRules = append(skipRules, value)
} else {
zap.S().Debugf("each rule in %s must be of string type", terrascanSkip)
}
}
} else {
zap.S().Debugf("%s must be an array of rules to skip", terrascanSkip)
}

return skipRules
}
Loading

0 comments on commit 20a4bdb

Please sign in to comment.