Skip to content

Commit

Permalink
Do not initiate policy engine incase of --config-only flag
Browse files Browse the repository at this point in the history
  • Loading branch information
devang-gaur authored and Devang Gaur committed Jul 13, 2021
1 parent 8bba815 commit 2443118
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 60 deletions.
16 changes: 9 additions & 7 deletions pkg/cli/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ func (s *ScanOptions) Run() error {
}

// executor output
results, err := executor.Execute()
results, err := executor.Execute(s.configOnly)
if err != nil {
return err
}
Expand All @@ -204,7 +204,7 @@ func (s *ScanOptions) Run() error {
return err
}

if results.Violations.ViolationStore.Summary.ViolatedPolicies != 0 && flag.Lookup("test.v") == nil {
if !s.configOnly && results.Violations.ViolationStore.Summary.ViolatedPolicies != 0 && flag.Lookup("test.v") == nil {
os.RemoveAll(tempDir)
os.Exit(3)
}
Expand All @@ -228,17 +228,19 @@ func (s *ScanOptions) downloadRemoteRepository(tempDir string) error {
}

func (s ScanOptions) writeResults(results runtime.Output) error {

outputWriter := NewOutputWriter(s.UseColors)

if s.configOnly {
return writer.Write(s.outputType, results.ResourceConfig, outputWriter)
}

// add verbose flag to the scan summary
results.Violations.ViolationStore.Summary.ShowViolationDetails = s.verbose

if !s.showPassedRules {
results.Violations.ViolationStore.PassedRules = nil
}

outputWriter := NewOutputWriter(s.UseColors)

if s.configOnly {
return writer.Write(s.outputType, results.ResourceConfig, outputWriter)
}
return writer.Write(s.outputType, results.Violations, outputWriter)
}
3 changes: 3 additions & 0 deletions pkg/cli/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ var scanCmd = &cobra.Command{
Detect compliance and security violations across Infrastructure as Code to mitigate risk before provisioning cloud native infrastructure.
`,
PreRunE: func(cmd *cobra.Command, args []string) error {
if scanOptions.configOnly {
return nil
}
return initial(cmd, args, true)
},
RunE: scan,
Expand Down
9 changes: 4 additions & 5 deletions pkg/http-server/file-scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ func (g *APIHandler) scanFile(w http.ResponseWriter, r *http.Request) {
apiErrorResponse(w, err.Error(), http.StatusBadRequest)
return
}
normalized, err := executor.Execute()
normalized, err := executor.Execute(configOnly)
if err != nil {
errMsg := fmt.Sprintf("failed to scan uploaded file. error: '%v'", err)
zap.S().Error(errMsg)
Expand All @@ -172,14 +172,13 @@ func (g *APIHandler) scanFile(w http.ResponseWriter, r *http.Request) {

var output interface{}

if !showPassed {
normalized.Violations.ViolationStore.PassedRules = nil
}

// if config only, return resource config else return violations
if configOnly {
output = normalized.ResourceConfig
} else {
if !showPassed {
normalized.Violations.ViolationStore.PassedRules = nil
}
output = normalized.Violations
}

Expand Down
19 changes: 10 additions & 9 deletions pkg/http-server/remote-repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,25 +135,26 @@ func (s *scanRemoteRepoReq) ScanRemoteRepo(iacType, iacVersion string, cloudType
}

// evaluate policies IaC for violations
results, err := executor.Execute()
results, err := executor.Execute(s.ConfigOnly)
if err != nil {
errMsg := fmt.Sprintf("failed to scan uploaded file. error: '%v'", err)
zap.S().Error(errMsg)
return output, isAdmissionDenied, err
}
// set remote url in case remote repo is scanned
if s.RemoteURL != "" {
results.Violations.Summary.ResourcePath = s.RemoteURL
}

if !s.ShowPassed {
results.Violations.ViolationStore.PassedRules = nil
}

// if config only, return only config else return only violations
if s.ConfigOnly {
output = results.ResourceConfig
} else {
// set remote url in case remote repo is scanned
if s.RemoteURL != "" {
results.Violations.Summary.ResourcePath = s.RemoteURL
}

if !s.ShowPassed {
results.Violations.ViolationStore.PassedRules = nil
}

isAdmissionDenied = hasK8sAdmissionDeniedViolations(results)
output = results.Violations
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/initialize/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ const terrascanReadmeURL string = "https://raw.githubusercontent.com/accurics/te

// Run initializes terrascan if not done already
func Run(isNonInitCmd bool) error {
zap.S().Debug("initializing terrascan")

// check if policy paths exist
if path, err := os.Stat(config.GetPolicyRepoPath()); err == nil && path.IsDir() {
if isNonInitCmd {
return nil
}
}

zap.S().Debug("initializing terrascan")

if !connected(terrascanReadmeURL) {
return errNoConnection
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/k8s/admission-webhook/validating-webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ func (w ValidatingWebhook) scanK8sFile(filePath string) (runtime.Output, error)
return result, err
}

result, err = executor.Execute()
result, err = executor.Execute(false)
if err != nil {
zap.S().Error("failed to scan resource object. error: '%v'", err)
return result, err
Expand Down
21 changes: 16 additions & 5 deletions pkg/runtime/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package runtime

import (
"github.com/accurics/terrascan/pkg/policy/opa"
"sort"

"go.uber.org/zap"
Expand All @@ -26,7 +27,6 @@ import (
"github.com/accurics/terrascan/pkg/iac-providers/output"
"github.com/accurics/terrascan/pkg/notifications"
"github.com/accurics/terrascan/pkg/policy"
opa "github.com/accurics/terrascan/pkg/policy/opa"
"github.com/hashicorp/go-multierror"
)

Expand Down Expand Up @@ -139,6 +139,11 @@ func (e *Executor) Init() error {
}
}

zap.S().Debug("initialized executor")
return nil
}

func (e *Executor) initPolicyEngines() (err error) {
// create a new policy engine based on IaC type
zap.S().Debugf("using policy path %v", e.policyPath)
for _, policyPath := range e.policyPath {
Expand All @@ -153,18 +158,16 @@ func (e *Executor) Init() error {

// initialize the engine
if err := engine.Init(policyPath, preloadFilter); err != nil {
zap.S().Errorf("%s", err)
zap.S().Errorf("failed to initialize policy engine for path %s, error: %s", policyPath, err)
return err
}
e.policyEngines = append(e.policyEngines, engine)
}

zap.S().Debug("initialized executor")
return nil
}

// Execute validates the inputs, processes the IaC, creates json output
func (e *Executor) Execute() (results Output, err error) {
func (e *Executor) Execute(configOnly bool) (results Output, err error) {

var merr *multierror.Error
var resourceConfig output.AllResourceConfigs
Expand Down Expand Up @@ -194,6 +197,14 @@ func (e *Executor) Execute() (results Output, err error) {
// update results with resource config
results.ResourceConfig = resourceConfig

if configOnly {
return results, nil
}

if err := e.initPolicyEngines(); err != nil {
return results, err
}

if err := e.findViolations(&results); err != nil {
return results, err
}
Expand Down
74 changes: 43 additions & 31 deletions pkg/runtime/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,49 @@ func TestExecute(t *testing.T) {

for _, tt := range table {
t.Run(tt.name, func(t *testing.T) {
_, gotErr := tt.executor.Execute()
_, gotErr := tt.executor.Execute(false)
if !reflect.DeepEqual(gotErr, tt.wantErr) {
t.Errorf("unexpected error; gotErr: '%v', wantErr: '%v'", gotErr, tt.wantErr)
}
})
}
}

func TestInitPolicyEngine(t *testing.T) {
table := []struct {
name string
executor Executor
wantErr error
}{
{
name: "invalid policy path",
executor: Executor{
filePath: filepath.Join(testDataDir, "testfile"),
dirPath: "",
policyTypes: []string{"aws"},
iacType: "terraform",
iacVersion: "v14",
policyPath: []string{filepath.Join(testDataDir, "notthere")},
},
wantErr: fmt.Errorf("failed to initialize OPA policy engine"),
},
{
name: "invalid policy path",
executor: Executor{
filePath: filepath.Join(testDataDir, "testfile"),
dirPath: "",
policyTypes: []string{"aws"},
iacType: "terraform",
iacVersion: "v12",
policyPath: []string{filepath.Join(testDataDir, "notthere")},
},
wantErr: fmt.Errorf("failed to initialize OPA policy engine"),
},
}

for _, tt := range table {
t.Run(tt.name, func(t *testing.T) {
gotErr := tt.executor.initPolicyEngines()
if !reflect.DeepEqual(gotErr, tt.wantErr) {
t.Errorf("unexpected error; gotErr: '%v', wantErr: '%v'", gotErr, tt.wantErr)
}
Expand Down Expand Up @@ -273,21 +315,6 @@ func TestInit(t *testing.T) {
wantErr: config.ErrNotPresent,
wantIacProvider: []iacProvider.IacProvider{&tfv14.TfV14{}},
},
{
name: "invalid policy path",
executor: Executor{
filePath: filepath.Join(testDataDir, "testfile"),
dirPath: "",
policyTypes: []string{"aws"},
iacType: "terraform",
iacVersion: "v14",
policyPath: []string{filepath.Join(testDataDir, "notthere")},
},
configFile: filepath.Join(testDataDir, "webhook.toml"),
wantErr: fmt.Errorf("failed to initialize OPA policy engine"),
wantIacProvider: []iacProvider.IacProvider{&tfv14.TfV14{}},
wantNotifiers: []notifications.Notifier{&webhook.Webhook{}},
},
{
name: "config file with invalid category",
executor: Executor{
Expand Down Expand Up @@ -358,21 +385,6 @@ func TestInit(t *testing.T) {
wantErr: config.ErrNotPresent,
wantIacProvider: []iacProvider.IacProvider{&tfv12.TfV12{}},
},
{
name: "invalid policy path",
executor: Executor{
filePath: filepath.Join(testDataDir, "testfile"),
dirPath: "",
policyTypes: []string{"aws"},
iacType: "terraform",
iacVersion: "v12",
policyPath: []string{filepath.Join(testDataDir, "notthere")},
},
configFile: filepath.Join(testDataDir, "webhook.toml"),
wantErr: fmt.Errorf("failed to initialize OPA policy engine"),
wantIacProvider: []iacProvider.IacProvider{&tfv12.TfV12{}},
wantNotifiers: []notifications.Notifier{&webhook.Webhook{}},
},
}

for _, tt := range table {
Expand Down

0 comments on commit 2443118

Please sign in to comment.