From 2e313719bbfae6ac38a8d6fcc0ce7dc1d18e5d31 Mon Sep 17 00:00:00 2001 From: dwertent Date: Thu, 2 Sep 2021 14:54:04 +0300 Subject: [PATCH] adding scaore and excpetion to code --- cautils/armotypes/portaltypes.go | 3 + cautils/armotypes/portaltypesutils.go | 87 +++++++++++++++++-- .../armotypes/postureexceptionpolicytypes.go | 42 +++++++++ .../postureexceptionpolicytypesutils.go | 1 + cautils/opapolicy/datastructures.go | 38 ++++---- cautils/opapolicy/datastructuresmethods.go | 53 +++++++++-- 6 files changed, 195 insertions(+), 29 deletions(-) create mode 100644 cautils/armotypes/postureexceptionpolicytypes.go create mode 100644 cautils/armotypes/postureexceptionpolicytypesutils.go diff --git a/cautils/armotypes/portaltypes.go b/cautils/armotypes/portaltypes.go index ab611b6a..a258fd3d 100644 --- a/cautils/armotypes/portaltypes.go +++ b/cautils/armotypes/portaltypes.go @@ -22,6 +22,7 @@ type DesignatorType string // Supported designators const ( DesignatorAttributes DesignatorType = "Attributes" + DesignatorAttribute DesignatorType = "Attribute" // Deprecated /* WorkloadID format. k8s format: wlid://cluster-/namespace-/- @@ -45,6 +46,8 @@ const ( const ( AttributeCluster = "cluster" AttributeNamespace = "namespace" + AttributeKind = "kind" + AttributeName = "name" ) // PortalDesignator represented single designation options diff --git a/cautils/armotypes/portaltypesutils.go b/cautils/armotypes/portaltypesutils.go index 7e517beb..412c962c 100644 --- a/cautils/armotypes/portaltypesutils.go +++ b/cautils/armotypes/portaltypesutils.go @@ -1,24 +1,100 @@ package armotypes +import ( + "github.com/armosec/kubescape/cautils/cautils" + "github.com/golang/glog" +) + var IgnoreLabels = []string{AttributeCluster, AttributeNamespace} +func (designator *PortalDesignator) GetCluster() string { + cluster, _, _, _, _ := designator.DigestPortalDesignator() + return cluster +} + +func (designator *PortalDesignator) GetNamespace() string { + _, namespace, _, _, _ := designator.DigestPortalDesignator() + return namespace +} + +func (designator *PortalDesignator) GetKind() string { + _, _, kind, _, _ := designator.DigestPortalDesignator() + return kind +} + +func (designator *PortalDesignator) GetName() string { + _, _, _, name, _ := designator.DigestPortalDesignator() + return name +} +func (designator *PortalDesignator) GetLabels() map[string]string { + _, _, _, _, labels := designator.DigestPortalDesignator() + return labels +} + // DigestPortalDesignator - get cluster namespace and labels from designator +func (designator *PortalDesignator) DigestPortalDesignator() (string, string, string, string, map[string]string) { + switch designator.DesignatorType { + case DesignatorAttributes, DesignatorAttribute: + return designator.DigestAttributesDesignator() + case DesignatorWlid, DesignatorWildWlid: + return cautils.GetClusterFromWlid(designator.WLID), cautils.GetNamespaceFromWlid(designator.WLID), cautils.GetKindFromWlid(designator.WLID), cautils.GetNameFromWlid(designator.WLID), map[string]string{} + // case DesignatorSid: // TODO + default: + glog.Warningf("in 'digestPortalDesignator' designator type: '%v' not yet supported. please contact Armo team", designator.DesignatorType) + } + return "", "", "", "", nil +} + +func (designator *PortalDesignator) DigestAttributesDesignator() (string, string, string, string, map[string]string) { + cluster := "" + namespace := "" + kind := "" + name := "" + labels := map[string]string{} + attributes := designator.Attributes + if attributes == nil { + return cluster, namespace, kind, name, labels + } + for k, v := range attributes { + labels[k] = v + } + if v, ok := attributes[AttributeNamespace]; ok { + namespace = v + delete(labels, AttributeNamespace) + } + if v, ok := attributes[AttributeCluster]; ok { + cluster = v + delete(labels, AttributeCluster) + } + if v, ok := attributes[AttributeKind]; ok { + kind = v + delete(labels, AttributeKind) + } + if v, ok := attributes[AttributeName]; ok { + name = v + delete(labels, AttributeName) + } + return cluster, namespace, kind, name, labels +} + +// DigestPortalDesignator DEPRECATED. use designator.DigestPortalDesignator() - get cluster namespace and labels from designator func DigestPortalDesignator(designator *PortalDesignator) (string, string, map[string]string) { switch designator.DesignatorType { - case DesignatorAttributes: + case DesignatorAttributes, DesignatorAttribute: return DigestAttributesDesignator(designator.Attributes) - // case DesignatorWlid: TODO - // case DesignatorWildWlid: TODO + case DesignatorWlid, DesignatorWildWlid: + return cautils.GetClusterFromWlid(designator.WLID), cautils.GetNamespaceFromWlid(designator.WLID), map[string]string{} + // case DesignatorSid: // TODO default: + glog.Warningf("in 'digestPortalDesignator' designator type: '%v' not yet supported. please contact Armo team", designator.DesignatorType) } return "", "", nil } - func DigestAttributesDesignator(attributes map[string]string) (string, string, map[string]string) { cluster := "" namespace := "" labels := map[string]string{} - if attributes == nil || len(attributes) == 0 { + if attributes == nil { return cluster, namespace, labels } for k, v := range attributes { @@ -32,5 +108,6 @@ func DigestAttributesDesignator(attributes map[string]string) (string, string, m cluster = v delete(labels, AttributeCluster) } + return cluster, namespace, labels } diff --git a/cautils/armotypes/postureexceptionpolicytypes.go b/cautils/armotypes/postureexceptionpolicytypes.go new file mode 100644 index 00000000..81603b97 --- /dev/null +++ b/cautils/armotypes/postureexceptionpolicytypes.go @@ -0,0 +1,42 @@ +package armotypes + +type PostureExceptionPolicyActions string + +const AlertOnly PostureExceptionPolicyActions = "alertOnly" +const Disable PostureExceptionPolicyActions = "disable" + +type PostureExceptionPolicy struct { + PortalBase `json:",inline"` + PolicyType string `json:"policyType"` + CreationTime string `json:"creationTime"` + Actions []PostureExceptionPolicyActions `json:"actions"` + Resources []PortalDesignator `json:"resources"` + PosturePolicies []PosturePolicy `json:"posturePolicies"` +} + +type PosturePolicy struct { + FrameworkName string `json:"frameworkName"` + ControlName string `json:"controlName"` + RuleName string `json:"ruleName"` +} + +func (exceptionPolicy *PostureExceptionPolicy) IsAlertOnly() bool { + if exceptionPolicy.IsDisable() { + return false + } + + for i := range exceptionPolicy.Actions { + if exceptionPolicy.Actions[i] == AlertOnly { + return true + } + } + return false +} +func (exceptionPolicy *PostureExceptionPolicy) IsDisable() bool { + for i := range exceptionPolicy.Actions { + if exceptionPolicy.Actions[i] == Disable { + return true + } + } + return false +} diff --git a/cautils/armotypes/postureexceptionpolicytypesutils.go b/cautils/armotypes/postureexceptionpolicytypesutils.go new file mode 100644 index 00000000..c373357e --- /dev/null +++ b/cautils/armotypes/postureexceptionpolicytypesutils.go @@ -0,0 +1 @@ +package armotypes diff --git a/cautils/opapolicy/datastructures.go b/cautils/opapolicy/datastructures.go index 6a512499..a74163c5 100644 --- a/cautils/opapolicy/datastructures.go +++ b/cautils/opapolicy/datastructures.go @@ -16,14 +16,15 @@ const ( // RegoResponse the expected response of single run of rego policy type RuleResponse struct { - AlertMessage string `json:"alertMessage"` - PackageName string `json:"packagename"` - AlertScore AlertScore `json:"alertScore"` - // AlertObject AlertObject `json:"alertObject"` - AlertObject AlertObject `json:"alertObject"` // TODO - replace interface to AlertObject - Context []string `json:"context"` // TODO - Remove - Rulename string `json:"rulename"` // TODO - Remove - ExceptionName string `json:"exceptionName"` + AlertMessage string `json:"alertMessage"` + RuleStatus string `json:"ruleStatus"` + PackageName string `json:"packagename"` + AlertScore AlertScore `json:"alertScore"` + AlertObject AlertObject `json:"alertObject"` + Context []string `json:"context,omitempty"` // TODO - Remove + Rulename string `json:"rulename,omitempty"` // TODO - Remove + ExceptionName string `json:"exceptionName,omitempty"` // Not in use + Exception *armotypes.PostureExceptionPolicy `json:"exception,omitempty"` } type AlertObject struct { @@ -32,19 +33,26 @@ type AlertObject struct { } type FrameworkReport struct { - Name string `json:"name"` - ControlReports []ControlReport `json:"controlReports"` + Name string `json:"name"` + ControlReports []ControlReport `json:"controlReports"` + Score float32 `json:"score,omitempty"` + ARMOImprovement float32 `json:"ARMOImprovement,omitempty"` + WCSScore float32 `json:"wcsScore,omitempty"` } type ControlReport struct { - Name string `json:"name"` - RuleReports []RuleReport `json:"ruleReports"` - Remediation string `json:"remediation"` - Description string `json:"description"` + armotypes.PortalBase `json:",inline"` + Name string `json:"name"` + RuleReports []RuleReport `json:"ruleReports"` + Remediation string `json:"remediation"` + Description string `json:"description"` + Score float32 `json:"score,omitempty"` + BaseScore float32 `json:"baseScore,omitempty"` + ARMOImprovement float32 `json:"ARMOImprovement,omitempty"` } type RuleReport struct { Name string `json:"name"` Remediation string `json:"remediation"` - RuleStatus RuleStatus `json:"ruleStatus"` + RuleStatus RuleStatus `json:"ruleStatus"` // did we run the rule or not (if there where compile errors, the value will be failed) RuleResponses []RuleResponse `json:"ruleResponses"` ListInputResources []map[string]interface{} `json:"-"` ListInputKinds []string `json:"-"` diff --git a/cautils/opapolicy/datastructuresmethods.go b/cautils/opapolicy/datastructuresmethods.go index e2bce425..602f77c7 100644 --- a/cautils/opapolicy/datastructuresmethods.go +++ b/cautils/opapolicy/datastructuresmethods.go @@ -17,6 +17,19 @@ func (pn *PolicyNotification) ToJSONBytesBuffer() (*bytes.Buffer, error) { return bytes.NewBuffer(res), err } +func (RuleResponse *RuleResponse) GetSingleResultStatus() string { + if RuleResponse.Exception != nil { + if RuleResponse.Exception.IsAlertOnly() { + return "warning" + } + if RuleResponse.Exception.IsDisable() { + return "ignore" + } + } + return "failed" + +} + func (ruleReport *RuleReport) GetRuleStatus() (string, []RuleResponse, []RuleResponse) { if len(ruleReport.RuleResponses) == 0 { return "success", nil, nil @@ -26,9 +39,11 @@ func (ruleReport *RuleReport) GetRuleStatus() (string, []RuleResponse, []RuleRes for _, rule := range ruleReport.RuleResponses { if rule.ExceptionName != "" { - failed = append(failed, rule) - } else { exceptions = append(exceptions, rule) + } else if rule.Exception != nil { + exceptions = append(exceptions, rule) + } else { + failed = append(failed, rule) } } @@ -70,10 +85,9 @@ func ParseRegoResult(regoResult *rego.ResultSet) ([]RuleResponse, error) { func (controlReport *ControlReport) GetNumberOfResources() int { sum := 0 for i := range controlReport.RuleReports { - if controlReport.RuleReports[i].ListInputResources == nil { - continue + if controlReport.RuleReports[i].ListInputResources != nil { + sum += len(controlReport.RuleReports[i].ListInputResources) } - sum += len(controlReport.RuleReports[i].ListInputResources) } return sum } @@ -85,15 +99,36 @@ func (controlReport *ControlReport) ListControlsInputKinds() []string { } return listControlsInputKinds } + func (controlReport *ControlReport) Passed() bool { for i := range controlReport.RuleReports { - if len(controlReport.RuleReports[i].RuleResponses) > 0 { - return false + if len(controlReport.RuleReports[i].RuleResponses) == 0 { + return true } } - return true + return false +} + +func (controlReport *ControlReport) Warning() bool { + if controlReport.Passed() || controlReport.Failed() { + return false + } + for i := range controlReport.RuleReports { + if status, _, _ := controlReport.RuleReports[i].GetRuleStatus(); status == "warning" { + return true + } + } + return false } func (controlReport *ControlReport) Failed() bool { - return !controlReport.Passed() + if controlReport.Passed() { + return false + } + for i := range controlReport.RuleReports { + if status, _, _ := controlReport.RuleReports[i].GetRuleStatus(); status == "failed" { + return true + } + } + return false }