diff --git a/.github/workflows/build_dev.yaml b/.github/workflows/build_dev.yaml new file mode 100644 index 00000000..38387b7a --- /dev/null +++ b/.github/workflows/build_dev.yaml @@ -0,0 +1,35 @@ +name: build + +on: + push: + branches: [ dev ] + pull_request: + branches: [ dev ] + types: [ closed ] +jobs: + build: + name: Create cross-platform dev build + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + steps: + - uses: actions/checkout@v1 + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.16 + - name: Build + env: + RELEASE: v1.0.${{ github.run_number }} + ArmoBEServer: api.armo.cloud + ArmoERServer: report.euprod1.cyberarmorsoft.com + ArmoWebsite: portal.armo.cloud + run: mkdir -p build/${{ matrix.os }} && go mod tidy && go build -ldflags "-w -s -X github.com/armosec/kubescape/cmd.BuildNumber=$RELEASE -X github.com/armosec/kubescape/cautils/getter.ArmoBEURL=$ArmoBEServer -X github.com/armosec/kubescape/cautils/getter.ArmoERURL=$ArmoERServer -X github.com/armosec/kubescape/cautils/getter.ArmoFEURL=$ArmoWebsite" -o build/${{ matrix.os }}/kubescape # && md5sum build/${{ matrix.os }}/kubescape > build/${{ matrix.os }}/kubescape.md5 + + - name: Upload build artifacts + uses: actions/upload-artifact@v2 + with: + name: kubescape-${{ matrix.os }} + path: build/${{ matrix.os }}/kubescape diff --git a/cautils/opapolicy/datastructuresmethods.go b/cautils/opapolicy/datastructuresmethods.go index c503707f..57a499e8 100644 --- a/cautils/opapolicy/datastructuresmethods.go +++ b/cautils/opapolicy/datastructuresmethods.go @@ -3,6 +3,8 @@ package opapolicy import ( "bytes" "encoding/json" + + "github.com/armosec/kubescape/cautils/k8sinterface" ) func (pn *PolicyNotification) ToJSONBytesBuffer() (*bytes.Buffer, error) { @@ -83,11 +85,11 @@ func (controlReport *ControlReport) ListControlsInputKinds() []string { func (controlReport *ControlReport) Passed() bool { for i := range controlReport.RuleReports { - if len(controlReport.RuleReports[i].RuleResponses) == 0 { - return true + if len(controlReport.RuleReports[i].RuleResponses) != 0 { + return false } } - return false + return true } func (controlReport *ControlReport) Warning() bool { @@ -120,14 +122,50 @@ func (ruleReport *RuleReport) GetNumberOfResources() int { func (ruleReport *RuleReport) GetNumberOfFailedResources() int { sum := 0 - for i := range ruleReport.RuleResponses { + for i := len(ruleReport.RuleResponses) - 1; i >= 0; i-- { if ruleReport.RuleResponses[i].GetSingleResultStatus() == "failed" { - sum += 1 + if !ruleReport.DeleteIfRedundantResponse(&ruleReport.RuleResponses[i], i) { + sum++ + } } } return sum } +func (ruleReport *RuleReport) DeleteIfRedundantResponse(RuleResponse *RuleResponse, index int) bool { + if b, rr := ruleReport.IsDuplicateResponseOfResource(RuleResponse, index); b { + rr.AddMessageToResponse(RuleResponse.AlertMessage) + ruleReport.RuleResponses = removeResponse(ruleReport.RuleResponses, index) + return true + } + return false +} + +func (ruleResponse *RuleResponse) AddMessageToResponse(message string) { + ruleResponse.AlertMessage += message +} + +func (ruleReport *RuleReport) IsDuplicateResponseOfResource(RuleResponse *RuleResponse, index int) (bool, *RuleResponse) { + for i := range ruleReport.RuleResponses { + if i != index { + for j := range ruleReport.RuleResponses[i].AlertObject.K8SApiObjects { + for k := range RuleResponse.AlertObject.K8SApiObjects { + w1 := k8sinterface.NewWorkloadObj(ruleReport.RuleResponses[i].AlertObject.K8SApiObjects[j]) + w2 := k8sinterface.NewWorkloadObj(RuleResponse.AlertObject.K8SApiObjects[k]) + if w1.GetName() == w2.GetName() && w1.GetNamespace() == w2.GetNamespace() && w1.GetKind() != "Role" && w1.GetKind() != "ClusterRole" { + return true, &ruleReport.RuleResponses[i] + } + } + } + } + } + return false, nil +} + +func removeResponse(slice []RuleResponse, index int) []RuleResponse { + return append(slice[:index], slice[index+1:]...) +} + func (ruleReport *RuleReport) GetNumberOfWarningResources() int { sum := 0 for i := range ruleReport.RuleResponses {