Skip to content

Commit

Permalink
Makes saving of admission requests configurable via a config file opt…
Browse files Browse the repository at this point in the history
…ion (#665)

* change config file section from k8s-deny-rules to k8s-admission-control

* adding 'save-requests' variable in config file to make saving of admission requests configurable

* fixing unit tests
  • Loading branch information
kanchwala-yusuf authored Apr 19, 2021
1 parent 2033718 commit 225a914
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 29 deletions.
6 changes: 3 additions & 3 deletions pkg/config/config-reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func (r TerrascanConfigReader) getSeverity() Severity {
return r.config.Severity
}

// GetK8sDenyRules will return the k8s deny rules specified in the terrascan config file
func (r TerrascanConfigReader) GetK8sDenyRules() K8sDenyRules {
return r.config.K8sDenyRules
// GetK8sAdmissionControl will return the k8s deny rules specified in the terrascan config file
func (r TerrascanConfigReader) GetK8sAdmissionControl() K8sAdmissionControl {
return r.config.K8sAdmissionControl
}
7 changes: 7 additions & 0 deletions pkg/config/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ func LoadGlobalConfig(configFile string) error {
global.Category.List = configReader.getCategory().List
}

global.K8sAdmissionControl = configReader.GetK8sAdmissionControl()

zap.S().Debugf("global config loaded")

return nil
Expand Down Expand Up @@ -160,3 +162,8 @@ func GetCategoryList() []string {
func GetNotifications() map[string]Notifier {
return global.Notifications
}

// GetK8sAdmissionControl returns kubernetes admission control configuration
func GetK8sAdmissionControl() K8sAdmissionControl {
return global.K8sAdmissionControl
}
17 changes: 9 additions & 8 deletions pkg/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ var global *TerrascanConfig = &TerrascanConfig{}

// TerrascanConfig struct defines global variables/configurations across terrascan
type TerrascanConfig struct {
Policy `toml:"policy,omitempty"`
Notifications map[string]Notifier `toml:"notifications,omitempty"`
Rules `toml:"rules,omitempty"`
Category `toml:"category,omitempty"`
Severity `toml:"severity,omitempty"`
K8sDenyRules `toml:"k8s-deny-rules,omitempty"`
Policy `toml:"policy,omitempty"`
Notifications map[string]Notifier `toml:"notifications,omitempty"`
Rules `toml:"rules,omitempty"`
Category `toml:"category,omitempty"`
Severity `toml:"severity,omitempty"`
K8sAdmissionControl `toml:"k8s-admission-control,omitempty"`
}

// Category defines the categories of violations that you want to be reported
Expand Down Expand Up @@ -63,8 +63,9 @@ type Rules struct {
SkipRules []string `toml:"skip-rules,omitempty"`
}

// K8sDenyRules deny rules in the terrascan config file
type K8sDenyRules struct {
// K8sAdmissionControl deny rules in the terrascan config file
type K8sAdmissionControl struct {
DeniedSeverity string `toml:"denied-severity,omitempty"`
Categories []string `toml:"denied-categories,omitempty"`
SaveRequests bool `toml:"save-requests,omitempty"`
}
2 changes: 1 addition & 1 deletion pkg/http-server/k8s_testdata/config-deny-category.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[k8s-deny-rules]
[k8s-admission-control]
denied-categories = [
"Identity and Access Management",
"Network Security",
Expand Down
2 changes: 1 addition & 1 deletion pkg/http-server/k8s_testdata/config-deny-high.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[severity]
level = "medium"

[k8s-deny-rules]
[k8s-admission-control]
denied-severity = "high"
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[severity]
level = "medium"

[k8s-deny-rules]
[k8s-admission-control]
denied-categories = [
"Hola",
"Invalid",
Expand Down
5 changes: 5 additions & 0 deletions pkg/http-server/webhook-scan-logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"net/http"
"time"

"github.com/accurics/terrascan/pkg/config"
"github.com/accurics/terrascan/pkg/k8s/dblogs"
"github.com/accurics/terrascan/pkg/results"
"github.com/gorilla/mux"
Expand Down Expand Up @@ -215,6 +216,10 @@ func (g *APIHandler) getLogReasoning(log dblogs.WebhookScanLog) string {
func (g *APIHandler) getLogRequest(log dblogs.WebhookScanLog) string {
var review webhookDisplayedReview

if !config.GetK8sAdmissionControl().SaveRequests {
return "{}"
}

err := json.Unmarshal([]byte(log.Request), &review)

if err != nil {
Expand Down
8 changes: 4 additions & 4 deletions pkg/http-server/webhook-scan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,15 +217,15 @@ func TestUWebhooks(t *testing.T) {

if res.Code == http.StatusOK {
if tt.warnings && response.Response.Warnings == nil {
t.Errorf("Expected warnings but received None")
t.Errorf("expected warnings but received None")
}

if tt.allowed != response.Response.Allowed {
t.Errorf("Mismach in allowed. Got: %v, expected: %v", response.Response.Allowed, tt.allowed)
t.Errorf("mismatch in allowed. Got: %v, expected: %v", response.Response.Allowed, tt.allowed)
}

if tt.statusCode != 0 && tt.statusCode != response.Response.Result.Code {
t.Errorf("Mismach Statud code Got: %v, expected: %v", response.Response.Result.Code, tt.statusCode)
t.Errorf("mismatch Status code Got: %v, expected: %v", response.Response.Result.Code, tt.statusCode)
}

if tt.warnings || tt.statusMessage {
Expand All @@ -240,7 +240,7 @@ func TestUWebhooks(t *testing.T) {
expectedLogPath := fmt.Sprintf("For more details please visit %q", subLogPath)

if logPath != expectedLogPath {
t.Errorf("Mismach Log path. Got: %v, expected: %v", logPath, expectedLogPath)
t.Errorf("mismatch Log path. Got: %v, expected: %v", logPath, expectedLogPath)
}
}
}
Expand Down
13 changes: 9 additions & 4 deletions pkg/k8s/admission-webhook/validating-webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,12 +212,12 @@ func (w ValidatingWebhook) getDenyViolations(output runtime.Output) ([]results.V
return nil, err
}

denyViolations := w.getDeniedViolations(*output.Violations.ViolationStore, configReader.GetK8sDenyRules())
denyViolations := w.getDeniedViolations(*output.Violations.ViolationStore, configReader.GetK8sAdmissionControl())

return denyViolations, nil
}

func (w ValidatingWebhook) getDeniedViolations(violations results.ViolationStore, denyRules config.K8sDenyRules) []results.Violation {
func (w ValidatingWebhook) getDeniedViolations(violations results.ViolationStore, denyRules config.K8sAdmissionControl) []results.Violation {
// Check whether one of the violations matches the deny violations configuration

var denyViolations []results.Violation
Expand All @@ -241,6 +241,7 @@ func (w ValidatingWebhook) logWebhook(output runtime.Output,
var (
currentTime = time.Now()
deniedViolationsEncoded string
requestBody string
)

// encode denied violations into a string
Expand All @@ -253,10 +254,14 @@ func (w ValidatingWebhook) logWebhook(output runtime.Output,

encodedViolationsSummary, _ := json.Marshal(output.Violations.ViolationStore)

if config.GetK8sAdmissionControl().SaveRequests {
requestBody = string(w.requestBody)
}

// insert the webhook log into db
err := w.dblogger.Log(dblogs.WebhookScanLog{
UID: uid,
Request: string(w.requestBody),
Request: requestBody,
Allowed: allowed,
DeniableViolations: deniedViolationsEncoded,
ViolationsSummary: string(encodedViolationsSummary),
Expand Down Expand Up @@ -310,7 +315,7 @@ type webhookDenyRuleMatcher struct {
}

// This class should check if one of the violations found is relevant for the specified K8s deny rules
func (g *webhookDenyRuleMatcher) match(violation results.Violation, denyRules config.K8sDenyRules) bool {
func (g *webhookDenyRuleMatcher) match(violation results.Violation, denyRules config.K8sAdmissionControl) bool {

if denyRules.DeniedSeverity == "" && len(denyRules.Categories) == 0 {
return false
Expand Down
14 changes: 7 additions & 7 deletions pkg/k8s/admission-webhook/webhook-deny-rule-matcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func TestDenyRuleMatcher(t *testing.T) {
ruleSeverity string
ruleCategory string
ruleName string
k8sDenyRules config.K8sDenyRules
k8sDenyRules config.K8sAdmissionControl
expectedResult bool
}{
{
Expand All @@ -48,7 +48,7 @@ func TestDenyRuleMatcher(t *testing.T) {
ruleSeverity: testMediumSeverity,
ruleCategory: testCategory,
ruleName: testRuleName,
k8sDenyRules: config.K8sDenyRules{DeniedSeverity: testMediumSeverity},
k8sDenyRules: config.K8sAdmissionControl{DeniedSeverity: testMediumSeverity},
expectedResult: true,
},

Expand All @@ -57,23 +57,23 @@ func TestDenyRuleMatcher(t *testing.T) {
ruleSeverity: testMediumSeverity,
ruleCategory: testCategory,
ruleName: testRuleName,
k8sDenyRules: config.K8sDenyRules{DeniedSeverity: "LOW"},
k8sDenyRules: config.K8sAdmissionControl{DeniedSeverity: "LOW"},
expectedResult: true,
},
{
name: "higher severity",
ruleSeverity: testMediumSeverity,
ruleCategory: testCategory,
ruleName: testRuleName,
k8sDenyRules: config.K8sDenyRules{DeniedSeverity: "High"},
k8sDenyRules: config.K8sAdmissionControl{DeniedSeverity: "High"},
expectedResult: false,
},
{
name: "not matching category",
ruleSeverity: testMediumSeverity,
ruleCategory: testCategory,
ruleName: testRuleName,
k8sDenyRules: config.K8sDenyRules{Categories: []string{"WRONG!"}},
k8sDenyRules: config.K8sAdmissionControl{Categories: []string{"WRONG!"}},
expectedResult: false,
},

Expand All @@ -82,15 +82,15 @@ func TestDenyRuleMatcher(t *testing.T) {
ruleSeverity: testMediumSeverity,
ruleCategory: testCategory,
ruleName: testRuleName,
k8sDenyRules: config.K8sDenyRules{Categories: []string{"WRONG!", testCategory}},
k8sDenyRules: config.K8sAdmissionControl{Categories: []string{"WRONG!", testCategory}},
expectedResult: true,
},
{
name: "incorrect severity by matching category",
ruleSeverity: testMediumSeverity,
ruleCategory: testCategory,
ruleName: testRuleName,
k8sDenyRules: config.K8sDenyRules{Categories: []string{"WRONG!", testCategory}, DeniedSeverity: "HIGH"},
k8sDenyRules: config.K8sAdmissionControl{Categories: []string{"WRONG!", testCategory}, DeniedSeverity: "HIGH"},
expectedResult: true,
},
}
Expand Down

0 comments on commit 225a914

Please sign in to comment.