Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rule skipping for resources in k8s #455

Merged
merged 24 commits into from
Jan 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4bd932b
annotations based skipping
patilpankaj212 Jan 6, 2021
d7a2543
test for resource skipping
patilpankaj212 Jan 6, 2021
fe2dca0
fix tests breaks due to resource config change
patilpankaj212 Jan 6, 2021
60ce034
add annotations in test file
patilpankaj212 Jan 6, 2021
4fbe4ac
1. fix debug messages
patilpankaj212 Jan 6, 2021
b1c8f99
exit with status 1 in case of an scan error
patilpankaj212 Jan 7, 2021
e8d1068
policy for CVE-2020-8555
harkirat22 Jan 7, 2021
5385258
Merge pull request #457 from harkirat22/master
Jan 7, 2021
c4b9aa7
1. update fix for exit code
patilpankaj212 Jan 7, 2021
c39a76d
Merge pull request #458 from patilpankaj212/fix-exit-code-on-error
kanchwala-yusuf Jan 7, 2021
31ee512
add support for extracting rules to skip from terraform resource conf…
Dec 17, 2020
51888c4
adding unit tests for extracting rule ids to skip from terraform reso…
Dec 17, 2020
a4857a3
fixing existing terraform unit tests
Dec 17, 2020
72653b4
fixing existing writer unit tests
Dec 17, 2020
380e60a
adding unit tests for testing no rule ids present
Dec 19, 2020
08f94ec
move function to extract rules IDs to utils package
Jan 7, 2021
3bafe49
add comment for SkipRules in ResourceConfig struct
Jan 8, 2021
32ff137
Merge pull request #434 from kanchwala-yusuf/feature/skip-rules
Jan 8, 2021
919aece
annotations based skipping
patilpankaj212 Jan 6, 2021
846a792
test for resource skipping
patilpankaj212 Jan 6, 2021
ff73e3a
add annotations in test file
patilpankaj212 Jan 6, 2021
3fd3d95
1. fix debug messages
patilpankaj212 Jan 6, 2021
e5cec3e
merge with origin
patilpankaj212 Jan 8, 2021
0ea7356
incorporate review comments
patilpankaj212 Jan 8, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions pkg/cli/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,18 @@ var initCmd = &cobra.Command{

Initializes Terrascan and clones policies from the Terrascan GitHub repository.
`,
Run: initial,
RunE: initial,
SilenceUsage: true,
SilenceErrors: true,
}

func initial(cmd *cobra.Command, args []string) {
func initial(cmd *cobra.Command, args []string) error {
// initialize terrascan
if err := initialize.Run(); err != nil {
zap.S().Error("failed to initialize terrascan")
return
return err
}
return nil
}

func init() {
Expand Down
24 changes: 0 additions & 24 deletions pkg/cli/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package cli

import (
"flag"
"fmt"
"os"

"github.com/accurics/terrascan/pkg/config"
Expand All @@ -31,27 +30,6 @@ func RegisterCommand(baseCommand *cobra.Command, command *cobra.Command) {
baseCommand.AddCommand(command)
}

func subCommands() (commandNames []string) {
for _, command := range rootCmd.Commands() {
commandNames = append(commandNames, append(command.Aliases, command.Name())...)
}
return
}

// setDefaultCommand sets `scan` as default command if no other command is specified
func setDefaultCommandIfNonePresent() {
if len(os.Args) > 1 {
potentialCommand := os.Args[1]
for _, command := range subCommands() {
if command == potentialCommand {
return
}
}
os.Args = append([]string{os.Args[0], "scan"}, os.Args[1:]...)
}

}

// Execute the entrypoint called by main
func Execute() {
rootCmd.PersistentFlags().StringVarP(&LogLevel, "log-level", "l", "info", "log level (debug, info, warn, error, panic, fatal)")
Expand Down Expand Up @@ -81,9 +59,7 @@ func Execute() {
}
}

setDefaultCommandIfNonePresent()
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
10 changes: 6 additions & 4 deletions pkg/cli/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,17 @@ var scanCmd = &cobra.Command{

Detect compliance and security violations across Infrastructure as Code to mitigate risk before provisioning cloud native infrastructure.
`,
PreRun: initial,
Run: scan,
PreRunE: initial,
RunE: scan,
SilenceUsage: true,
SilenceErrors: true,
}

func scan(cmd *cobra.Command, args []string) {
func scan(cmd *cobra.Command, args []string) error {
zap.S().Debug("running terrascan in cli mode")
scanOptions.configFile = ConfigFile
scanOptions.outputType = OutputType
scanOptions.Scan()
return scanOptions.Scan()
}

func init() {
Expand Down
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