report v1 to v2

This commit is contained in:
dwertent
2021-12-30 11:52:17 +02:00
parent 521f8930d7
commit fde437312f
7 changed files with 335 additions and 146 deletions
+24 -12
View File
@@ -4,25 +4,31 @@ import (
"github.com/armosec/armoapi-go/armotypes"
"github.com/armosec/k8s-interface/workloadinterface"
"github.com/armosec/opa-utils/reporthandling"
"github.com/armosec/opa-utils/reporthandling/results/v1/resourcesresults"
reporthandlingv2 "github.com/armosec/opa-utils/reporthandling/v2"
)
// K8SResources map[<api group>/<api version>/<resource>][]<resourceID>
type K8SResources map[string][]string
type OPASessionObj struct {
K8SResources *K8SResources // input k8s objects
Frameworks []reporthandling.Framework // list of frameworks to scan
AllResources map[string]workloadinterface.IMetadata // all scanned resources, map[<rtesource ID>]<resource>
PostureReport *reporthandling.PostureReport // scan results
Exceptions []armotypes.PostureExceptionPolicy // list of exceptions to apply on scan results
RegoInputData RegoInputData // input passed to rgo for scanning. map[<control name>][<input arguments>]
K8SResources *K8SResources // input k8s objects
Frameworks []reporthandling.Framework // list of frameworks to scan
AllResources map[string]workloadinterface.IMetadata // all scanned resources, map[<rtesource ID>]<resource>
ResourcesResult map[string]resourcesresults.Result // resources scan results, map[<rtesource ID>]<resource result>
PostureReport *reporthandling.PostureReport // scan results v1
Report *reporthandlingv2.PostureReport // scan results v2
Exceptions []armotypes.PostureExceptionPolicy // list of exceptions to apply on scan results
RegoInputData RegoInputData // input passed to rgo for scanning. map[<control name>][<input arguments>]
}
func NewOPASessionObj(frameworks []reporthandling.Framework, k8sResources *K8SResources) *OPASessionObj {
return &OPASessionObj{
Frameworks: frameworks,
K8SResources: k8sResources,
AllResources: make(map[string]workloadinterface.IMetadata),
Report: &reporthandlingv2.PostureReport{},
Frameworks: frameworks,
K8SResources: k8sResources,
AllResources: make(map[string]workloadinterface.IMetadata),
ResourcesResult: make(map[string]resourcesresults.Result),
PostureReport: &reporthandling.PostureReport{
ClusterName: ClusterName,
CustomerGUID: CustomerGUID,
@@ -32,9 +38,10 @@ func NewOPASessionObj(frameworks []reporthandling.Framework, k8sResources *K8SRe
func NewOPASessionObjMock() *OPASessionObj {
return &OPASessionObj{
Frameworks: nil,
K8SResources: nil,
AllResources: make(map[string]workloadinterface.IMetadata),
Frameworks: nil,
K8SResources: nil,
AllResources: make(map[string]workloadinterface.IMetadata),
ResourcesResult: make(map[string]resourcesresults.Result),
PostureReport: &reporthandling.PostureReport{
ClusterName: "",
CustomerGUID: "",
@@ -60,3 +67,8 @@ type RegoInputData struct {
// ClusterName string `json:"clusterName"`
// K8sConfig RegoK8sConfig `json:"k8sconfig"`
}
type Policies struct {
Frameworks []string
Controls map[string]reporthandling.Control // map[<control ID>]<control>
}
+52 -15
View File
@@ -1,26 +1,63 @@
package cautils
import (
"encoding/json"
pkgcautils "github.com/armosec/utils-go/utils"
"github.com/open-policy-agent/opa/storage"
"github.com/open-policy-agent/opa/storage/inmem"
"github.com/open-policy-agent/opa/util"
"github.com/armosec/opa-utils/reporthandling"
)
func (data *RegoInputData) SetControlsInputs(controlsInputs map[string][]string) {
data.PostureControlInputs = controlsInputs
func NewPolicies() *Policies {
return &Policies{
Frameworks: make([]string, 0),
Controls: make(map[string]reporthandling.Control),
}
}
func (data *RegoInputData) TOStorage() (storage.Store, error) {
var jsonObj map[string]interface{}
bytesData, err := json.Marshal(*data)
if err != nil {
return nil, err
func (policies *Policies) Set(frameworks []reporthandling.Framework, version string) {
for i := range frameworks {
policies.Frameworks = append(policies.Frameworks, frameworks[i].Name)
for j := range frameworks[i].Controls {
compatibleRules := []reporthandling.PolicyRule{}
for r := range frameworks[i].Controls[j].Rules {
if !ruleWithArmoOpaDependency(frameworks[i].Controls[j].Rules[r].Attributes) && isRuleKubescapeVersionCompatible(frameworks[i].Controls[j].Rules[r].Attributes, version) {
compatibleRules = append(compatibleRules, frameworks[i].Controls[j].Rules[r])
}
}
frameworks[i].Controls[j].Rules = compatibleRules
policies.Controls[frameworks[i].Controls[j].ControlID] = frameworks[i].Controls[j]
}
}
// glog.Infof("RegoDependenciesData: %s", bytesData)
if err := util.UnmarshalJSON(bytesData, &jsonObj); err != nil {
return nil, err
}
func ruleWithArmoOpaDependency(attributes map[string]interface{}) bool {
if attributes == nil {
return false
}
return inmem.NewFromObject(jsonObj), nil
if s, ok := attributes["armoOpa"]; ok { // TODO - make global
return pkgcautils.StringToBool(s.(string))
}
return false
}
// Checks that kubescape version is in range of use for this rule
// In local build (BuildNumber = ""):
// returns true only if rule doesn't have the "until" attribute
func isRuleKubescapeVersionCompatible(attributes map[string]interface{}, version string) bool {
if from, ok := attributes["useFromKubescapeVersion"]; ok && from != nil {
if version != "" {
if from.(string) > BuildNumber {
return false
}
}
}
if until, ok := attributes["useUntilKubescapeVersion"]; ok && until != nil {
if version != "" {
if until.(string) <= BuildNumber {
return false
}
} else {
return false
}
}
return true
}
+93 -110
View File
@@ -8,7 +8,8 @@ import (
"github.com/armosec/kubescape/cautils"
"github.com/armosec/opa-utils/objectsenvelopes"
"github.com/armosec/opa-utils/reporthandling"
"github.com/armosec/opa-utils/score"
"github.com/armosec/opa-utils/reporthandling/results/v1/resourcesresults"
"github.com/open-policy-agent/opa/storage"
"github.com/golang/glog"
@@ -58,41 +59,51 @@ func (opaHandler *OPAProcessorHandler) ProcessRulesListenner() {
opaSessionObj := <-*opaHandler.processedPolicy
opap := NewOPAProcessor(opaSessionObj, opaHandler.regoDependenciesData)
initializeSummaryDetails(&opap.Report.SummaryDetails, opap.Frameworks)
policies := ConvertFrameworksToPolicies(opap.Frameworks, cautils.BuildNumber)
// process
if err := opap.Process(); err != nil {
if err := opap.Process(policies); err != nil {
// fmt.Println(err)
}
// edit results
opap.updateResults()
// update score
scoreutil := score.NewScore(opaSessionObj.AllResources)
scoreutil.Calculate(opaSessionObj.PostureReport.FrameworkReports)
// report
*opaHandler.reportResults <- opaSessionObj
}
}
func (opap *OPAProcessor) Process() error {
func (opap *OPAProcessor) Process(policies *cautils.Policies) error {
// glog.Infof(fmt.Sprintf("Starting 'Process'. reportID: %s", opap.PostureReport.ReportID))
cautils.ProgressTextDisplay(fmt.Sprintf("Scanning cluster %s", cautils.ClusterName))
cautils.StartSpinner()
frameworkReports := []reporthandling.FrameworkReport{}
var errs error
for i := range opap.Frameworks {
frameworkReport, err := opap.processFramework(&opap.Frameworks[i])
for _, control := range policies.Controls {
resourcesAssociatedControl, err := opap.processControl(&control)
if err != nil {
appendError(&errs, err)
}
frameworkReports = append(frameworkReports, *frameworkReport)
// update resources with latest results
if len(resourcesAssociatedControl) != 0 {
for resourceID, controlResult := range resourcesAssociatedControl {
if _, ok := opap.ResourcesResult[resourceID]; !ok {
opap.ResourcesResult[resourceID] = resourcesresults.Result{ResourceID: resourceID}
}
t := opap.ResourcesResult[resourceID]
t.AssociatedControls = append(t.AssociatedControls, controlResult)
opap.ResourcesResult[resourceID] = t
}
}
}
opap.PostureReport.FrameworkReports = frameworkReports
opap.PostureReport.ReportID = uuid.NewV4().String()
opap.PostureReport.ReportGenerationTime = time.Now().UTC()
// glog.Infof(fmt.Sprintf("Done 'Process'. reportID: %s", opap.PostureReport.ReportID))
opap.Report.ReportID = uuid.NewV4().String()
opap.Report.ReportGenerationTime = time.Now().UTC()
cautils.StopSpinner()
cautils.SuccessTextDisplay(fmt.Sprintf("Done scanning cluster %s", cautils.ClusterName))
return errs
@@ -108,62 +119,46 @@ func appendError(errs *error, err error) {
*errs = fmt.Errorf("%v\n%s", *errs, err.Error())
}
}
func (opap *OPAProcessor) processFramework(framework *reporthandling.Framework) (*reporthandling.FrameworkReport, error) {
func (opap *OPAProcessor) processControl(control *reporthandling.Control) (map[string]resourcesresults.ResourceAssociatedControl, error) {
var errs error
frameworkReport := reporthandling.FrameworkReport{}
frameworkReport.Name = framework.Name
resourcesAssociatedControl := make(map[string]resourcesresults.ResourceAssociatedControl)
controlReports := []reporthandling.ControlReport{}
for i := range framework.Controls {
controlReport, err := opap.processControl(&framework.Controls[i])
if err != nil {
appendError(&errs, err)
// errs = fmt.Errorf("%v\n%s", errs, err.Error())
}
if controlReport != nil {
controlReports = append(controlReports, *controlReport)
}
}
frameworkReport.ControlReports = controlReports
return &frameworkReport, errs
}
controlResult := resourcesresults.ResourceAssociatedControl{}
controlResult.SetID(control.ControlID)
func (opap *OPAProcessor) processControl(control *reporthandling.Control) (*reporthandling.ControlReport, error) {
var errs error
controlReport := reporthandling.ControlReport{}
controlReport.PortalBase = control.PortalBase
controlReport.ControlID = control.ControlID
controlReport.BaseScore = control.BaseScore
controlReport.Control_ID = control.Control_ID // TODO: delete when 'id' is deprecated
controlReport.Name = control.Name
controlReport.Description = control.Description
controlReport.Remediation = control.Remediation
ruleReports := []reporthandling.RuleReport{}
// ruleResults := make(map[string][]resourcesresults.ResourceAssociatedRule)
for i := range control.Rules {
ruleReport, err := opap.processRule(&control.Rules[i])
resourceAssociatedRule, err := opap.processRule(&control.Rules[i])
if err != nil {
appendError(&errs, err)
}
if ruleReport != nil {
ruleReports = append(ruleReports, *ruleReport)
// append failed rules to controls
if len(resourceAssociatedRule) != 0 {
for resourceID, ruleResponse := range resourceAssociatedRule {
if _, ok := resourcesAssociatedControl[resourceID]; ok {
controlResult.ResourceAssociatedRules = resourcesAssociatedControl[resourceID].ResourceAssociatedRules
}
if ruleResponse != nil {
controlResult.ResourceAssociatedRules = append(controlResult.ResourceAssociatedRules, *ruleResponse)
}
resourcesAssociatedControl[resourceID] = controlResult
}
}
}
if len(ruleReports) == 0 {
return nil, nil
}
controlReport.RuleReports = ruleReports
return &controlReport, errs
return resourcesAssociatedControl, errs
}
func (opap *OPAProcessor) processRule(rule *reporthandling.PolicyRule) (*reporthandling.RuleReport, error) {
if ruleWithArmoOpaDependency(rule.Attributes) || !isRuleKubescapeVersionCompatible(rule) {
return nil, nil
}
func (opap *OPAProcessor) processRule(rule *reporthandling.PolicyRule) (map[string]*resourcesresults.ResourceAssociatedRule, error) {
postureControlInputs := opap.regoDependenciesData.GetFilteredPostureControlInputs(rule.ConfigInputs) // get store
ruleResult := resourcesresults.ResourceAssociatedRule{}
ruleResult.SetName(rule.Name)
ruleResult.ControlConfigurations = postureControlInputs
inputResources, err := reporthandling.RegoResourcesAggregator(rule, getAllSupportedObjects(opap.K8SResources, opap.AllResources, rule))
if err != nil {
@@ -172,98 +167,80 @@ func (opap *OPAProcessor) processRule(rule *reporthandling.PolicyRule) (*reporth
inputRawResources := workloadinterface.ListMetaToMap(inputResources)
ruleReport, err := opap.runOPAOnSingleRule(rule, inputRawResources, ruleData)
if err != nil {
// ruleReport.RuleStatus.Status = reporthandling.StatusFailed
ruleReport.RuleStatus.Status = "failure"
ruleReport.RuleStatus.Message = err.Error()
glog.Error(err)
} else {
ruleReport.RuleStatus.Status = reporthandling.StatusPassed
}
resources := map[string]*resourcesresults.ResourceAssociatedRule{}
// the failed resources are a subgroup of the enumeratedData, so we store the enumeratedData like it was the input data
enumeratedData, err := opap.enumerateData(rule, inputRawResources)
if err != nil {
return nil, err
}
inputResources = objectsenvelopes.ListMapToMeta(enumeratedData)
ruleReport.ListInputKinds = workloadinterface.ListMetaIDs(inputResources)
for i := range inputResources {
opap.AllResources[inputResources[i].GetID()] = inputResources[i]
resources[inputResources[i].GetID()] = nil
}
failedResources := objectsenvelopes.ListMapToMeta(ruleReport.GetFailedResources())
for i := range failedResources {
if r, ok := opap.AllResources[failedResources[i].GetID()]; !ok {
opap.AllResources[failedResources[i].GetID()] = r
}
}
warningResources := objectsenvelopes.ListMapToMeta(ruleReport.GetWarnignResources())
for i := range warningResources {
if r, ok := opap.AllResources[warningResources[i].GetID()]; !ok {
opap.AllResources[warningResources[i].GetID()] = r
ruleResponses, err := opap.runOPAOnSingleRule(rule, inputRawResources, ruleData, postureControlInputs)
if err != nil {
// TODO - Handle error
glog.Error(err)
} else {
// ruleResponse to ruleResult
for i := range ruleResponses {
ruleResult.FailedPaths = ruleResponses[i].FailedPaths
failedResources := objectsenvelopes.ListMapToMeta(ruleResponses[i].GetFailedResources())
for j := range failedResources {
resources[failedResources[j].GetID()] = &ruleResult
}
}
}
// remove all data from responses, leave only the metadata
keepFields := []string{"kind", "apiVersion", "metadata"}
keepMetadataFields := []string{"name", "namespace", "labels"}
ruleReport.RemoveData(keepFields, keepMetadataFields)
return &ruleReport, err
return resources, err
}
func (opap *OPAProcessor) runOPAOnSingleRule(rule *reporthandling.PolicyRule, k8sObjects []map[string]interface{}, getRuleData func(*reporthandling.PolicyRule) string) (reporthandling.RuleReport, error) {
func (opap *OPAProcessor) runOPAOnSingleRule(rule *reporthandling.PolicyRule, k8sObjects []map[string]interface{}, getRuleData func(*reporthandling.PolicyRule) string, postureControlInputs map[string][]string) ([]reporthandling.RuleResponse, error) {
switch rule.RuleLanguage {
case reporthandling.RegoLanguage, reporthandling.RegoLanguage2:
return opap.runRegoOnK8s(rule, k8sObjects, getRuleData)
return opap.runRegoOnK8s(rule, k8sObjects, getRuleData, postureControlInputs)
default:
return reporthandling.RuleReport{}, fmt.Errorf("rule: '%s', language '%v' not supported", rule.Name, rule.RuleLanguage)
return nil, fmt.Errorf("rule: '%s', language '%v' not supported", rule.Name, rule.RuleLanguage)
}
}
func (opap *OPAProcessor) runRegoOnK8s(rule *reporthandling.PolicyRule, k8sObjects []map[string]interface{}, getRuleData func(*reporthandling.PolicyRule) string) (reporthandling.RuleReport, error) {
func (opap *OPAProcessor) runRegoOnK8s(rule *reporthandling.PolicyRule, k8sObjects []map[string]interface{}, getRuleData func(*reporthandling.PolicyRule) string, postureControlInputs map[string][]string) ([]reporthandling.RuleResponse, error) {
var errs error
ruleReport := reporthandling.RuleReport{
Name: rule.Name,
}
// compile modules
modules, err := getRuleDependencies()
if err != nil {
return ruleReport, fmt.Errorf("rule: '%s', %s", rule.Name, err.Error())
return nil, fmt.Errorf("rule: '%s', %s", rule.Name, err.Error())
}
modules[rule.Name] = getRuleData(rule)
compiled, err := ast.CompileModules(modules)
if err != nil {
return ruleReport, fmt.Errorf("in 'runRegoOnSingleRule', failed to compile rule, name: %s, reason: %s", rule.Name, err.Error())
return nil, fmt.Errorf("in 'runRegoOnSingleRule', failed to compile rule, name: %s, reason: %s", rule.Name, err.Error())
}
store, err := resources.TOStorage(postureControlInputs)
if err != nil {
return nil, err
}
// Eval
results, err := opap.regoEval(k8sObjects, compiled)
results, err := opap.regoEval(k8sObjects, compiled, &store)
if err != nil {
errs = fmt.Errorf("rule: '%s', %s", rule.Name, err.Error())
}
if results != nil {
ruleReport.RuleResponses = append(ruleReport.RuleResponses, results...)
}
return ruleReport, errs
return results, errs
}
func (opap *OPAProcessor) regoEval(inputObj []map[string]interface{}, compiledRego *ast.Compiler) ([]reporthandling.RuleResponse, error) {
store, err := opap.regoDependenciesData.TOStorage() // get store
if err != nil {
return nil, err
}
func (opap *OPAProcessor) regoEval(inputObj []map[string]interface{}, compiledRego *ast.Compiler, store *storage.Store) ([]reporthandling.RuleResponse, error) {
// opap.regoDependenciesData.PostureControlInputs
rego := rego.New(
rego.Query("data.armo_builtins"), // get package name from rule
rego.Compiler(compiledRego),
rego.Input(inputObj),
rego.Store(store),
rego.Store(*store),
)
// Run evaluation
@@ -284,9 +261,15 @@ func (opap *OPAProcessor) enumerateData(rule *reporthandling.PolicyRule, k8sObje
if ruleEnumeratorData(rule) == "" {
return k8sObjects, nil
}
ruleReport, err := opap.runOPAOnSingleRule(rule, k8sObjects, ruleEnumeratorData)
postureControlInputs := opap.regoDependenciesData.GetFilteredPostureControlInputs(rule.ConfigInputs)
ruleResponse, err := opap.runOPAOnSingleRule(rule, k8sObjects, ruleEnumeratorData, postureControlInputs)
if err != nil {
return nil, err
}
return ruleReport.GetFailedResources(), nil
failedResources := []map[string]interface{}{}
for _, ruleResponse := range ruleResponse {
failedResources = append(failedResources, ruleResponse.GetFailedResources()...)
}
return failedResources, nil
}
+3 -1
View File
@@ -30,11 +30,13 @@ func TestProcess(t *testing.T) {
// set opaSessionObj
opaSessionObj := cautils.NewOPASessionObjMock()
opaSessionObj.Frameworks = []reporthandling.Framework{*reporthandling.MockFrameworkA()}
policies := ConvertFrameworksToPolicies(opaSessionObj.Frameworks, "")
opaSessionObj.K8SResources = &k8sResources
opaSessionObj.AllResources = allResources
opap := NewOPAProcessor(opaSessionObj, resources.NewRegoDependenciesDataMock())
opap.Process()
opap.Process(policies)
opap.updateResults()
for _, f := range opap.PostureReport.FrameworkReports {
for _, c := range f.ControlReports {
+32 -8
View File
@@ -7,29 +7,53 @@ import (
"github.com/armosec/k8s-interface/k8sinterface"
"github.com/armosec/k8s-interface/workloadinterface"
"github.com/armosec/opa-utils/exceptions"
"github.com/armosec/opa-utils/reporthandling"
resources "github.com/armosec/opa-utils/resources"
"github.com/golang/glog"
)
// updateResults update the results objects and report objects. This is a critical function - DO NOT CHANGE
func (opap *OPAProcessor) updateResults() {
// remove data from all objects
for i := range opap.AllResources {
removeData(opap.AllResources[i])
}
for f := range opap.PostureReport.FrameworkReports {
// set exceptions
exceptions.SetFrameworkExceptions(&opap.PostureReport.FrameworkReports[f], opap.Exceptions, cautils.ClusterName)
// set exceptions
for i := range opap.ResourcesResult {
// set counters
reporthandling.SetUniqueResourcesCounter(&opap.PostureReport.FrameworkReports[f])
t := opap.ResourcesResult[i]
// set default score
// reporthandling.SetDefaultScore(&opap.PostureReport.FrameworkReports[f])
// first set exceptions
if resource, ok := opap.AllResources[i]; ok {
t.SetExceptions(resource, opap.Exceptions, cautils.ClusterName)
}
// summarize the resources
opap.Report.AppendResourceResultToSummary(&t)
// Add score
// TODO
// save changes
opap.ResourcesResult[i] = t
}
// set result summary
opap.Report.SummaryDetails.InitResourcesSummary()
// for f := range opap.PostureReport.FrameworkReports {
// // set exceptions
// exceptions.SetFrameworkExceptions(&opap.PostureReport.FrameworkReports[f], opap.Exceptions, cautils.ClusterName)
// // set counters
// reporthandling.SetUniqueResourcesCounter(&opap.PostureReport.FrameworkReports[f])
// // set default score
// // reporthandling.SetDefaultScore(&opap.PostureReport.FrameworkReports[f])
// }
}
func getAllSupportedObjects(k8sResources *cautils.K8SResources, allResources map[string]workloadinterface.IMetadata, rule *reporthandling.PolicyRule) []workloadinterface.IMetadata {
+36
View File
@@ -0,0 +1,36 @@
package opaprocessor
import (
"github.com/armosec/kubescape/cautils"
"github.com/armosec/opa-utils/reporthandling"
"github.com/armosec/opa-utils/reporthandling/results/v1/reportsummary"
)
// ConvertFrameworksToPolicies convert list of frameworks to list of policies
func ConvertFrameworksToPolicies(frameworks []reporthandling.Framework, version string) *cautils.Policies {
policies := cautils.NewPolicies()
policies.Set(frameworks, version)
return policies
}
// initializeReport initialize the summary details for the report object
func initializeSummaryDetails(summaryDetails *reportsummary.SummaryDetails, frameworks []reporthandling.Framework) {
for i := range frameworks {
controls := map[string]reportsummary.ControlSummary{}
for j := range frameworks[i].Controls {
id := frameworks[i].Controls[j].ControlID
c := reportsummary.ControlSummary{
Name: frameworks[i].Controls[j].Name,
}
controls[frameworks[i].Controls[j].ControlID] = c
summaryDetails.Controls[id] = c
}
summaryDetails.Frameworks = append(summaryDetails.Frameworks, reportsummary.FrameworkSummary{
Name: frameworks[i].Name,
Controls: controls,
})
}
// opap.Report.GenerateSummary()
}
+95
View File
@@ -7,6 +7,8 @@ import (
"github.com/armosec/kubescape/resultshandling/printer"
"github.com/armosec/kubescape/resultshandling/reporter"
"github.com/armosec/opa-utils/reporthandling"
v1 "github.com/armosec/opa-utils/reporthandling/helpers/v1"
"github.com/armosec/opa-utils/score"
)
type ResultsHandler struct {
@@ -27,6 +29,8 @@ func (resultsHandler *ResultsHandler) HandleResults(scanInfo *cautils.ScanInfo)
opaSessionObj := <-*resultsHandler.opaSessionObj
resultsHandler.reportV2ToV1(opaSessionObj)
resultsHandler.printerObj.ActionPrint(opaSessionObj)
if err := resultsHandler.reporterObj.ActionSendReport(opaSessionObj); err != nil {
@@ -55,3 +59,94 @@ func CalculatePostureScore(postureReport *reporthandling.PostureReport) float32
return (float32(len(allResources)) - float32(len(failedResources))) / float32(len(allResources))
}
func (resultsHandler *ResultsHandler) reportV2ToV1(opaSessionObj *cautils.OPASessionObj) {
opaSessionObj.PostureReport.ReportID = opaSessionObj.Report.ReportID
opaSessionObj.PostureReport.CustomerGUID = opaSessionObj.Report.CustomerGUID
opaSessionObj.PostureReport.ClusterCloudProvider = opaSessionObj.Report.ClusterCloudProvider
opaSessionObj.PostureReport.ClusterName = opaSessionObj.Report.ClusterName
frameworks := []reporthandling.FrameworkReport{}
fwv1 := reporthandling.FrameworkReport{}
for _, fwv2 := range opaSessionObj.Report.SummaryDetails.Frameworks {
fwv1.Name = fwv2.GetName()
fwv1.Score = fwv2.GetScore()
fwv1.WarningResources = fwv2.NumberOf().Excluded()
fwv1.FailedResources = fwv2.NumberOf().Failed()
fwv1.TotalResources = fwv2.NumberOf().All()
crv1 := reporthandling.ControlReport{}
for _, crv2 := range fwv2.Controls {
crv1.ControlID = crv2.GetID()
crv1.Name = crv2.GetName()
crv1.Score = crv2.GetScore()
crv1.WarningResources = crv2.NumberOf().Excluded()
crv1.FailedResources = crv2.NumberOf().Failed()
crv1.TotalResources = crv2.NumberOf().All()
// TODO - add fields
// crv1.Description
// crv1.GUID
// crv1.Remediation
rulesv1 := map[string]reporthandling.RuleReport{} // ruleName: rules
for _, resourceID := range crv2.List().All() {
if resource, ok := opaSessionObj.ResourcesResult[resourceID]; ok {
for _, rulev2 := range resource.ListRules() {
if _, ok := rulesv1[rulev2.GetName()]; !ok {
rulesv1[rulev2.GetName()] = reporthandling.RuleReport{}
}
rulev1 := reporthandling.RuleReport{}
rulev1.Name = rulev2.GetName()
// rulev1.Remediation
rulev1.ResourceUniqueCounter.TotalResources++
if rulev2.GetStatus(&v1.Filters{FrameworkNames: []string{fwv2.GetName()}}).IsFailed() {
rulev1.ResourceUniqueCounter.FailedResources++
} else if rulev2.GetStatus(&v1.Filters{FrameworkNames: []string{fwv2.GetName()}}).IsExcluded() {
rulev1.ResourceUniqueCounter.WarningResources++
}
ruleResponse := reporthandling.RuleResponse{}
ruleResponse.Rulename = rulev2.GetName()
ruleResponse.FailedPaths = rulev2.FailedPaths
ruleResponse.RuleStatus = string(rulev2.GetStatus(&v1.Filters{FrameworkNames: []string{fwv2.GetName()}}).Status())
if len(rulev2.Exception) > 0 {
ruleResponse.Exception = &rulev2.Exception[0]
}
if fullRessource, ok := opaSessionObj.AllResources[resourceID]; ok {
ruleResponse.AlertObject.K8SApiObjects = append(ruleResponse.AlertObject.K8SApiObjects, fullRessource.GetObject())
}
rulev1.RuleResponses = append(rulev1.RuleResponses, ruleResponse)
rulev1.ListInputKinds = append(rulev1.ListInputKinds, resourceID)
crv1.RuleReports = append(crv1.RuleReports, rulev1)
}
}
}
// rulev1.ListInputKinds
}
fwv1.ControlReports = append(fwv1.ControlReports, crv1)
frameworks = append(frameworks, fwv1)
}
for f := range frameworks {
// // set exceptions
// exceptions.SetFrameworkExceptions(&opap.PostureReport.FrameworkReports[f], opap.Exceptions, cautils.ClusterName)
// // set counters
// reporthandling.SetUniqueResourcesCounter(&opap.PostureReport.FrameworkReports[f])
// set default score
reporthandling.SetDefaultScore(&frameworks[f])
}
// update score
scoreutil := score.NewScore(opaSessionObj.AllResources)
scoreutil.Calculate(frameworks)
opaSessionObj.PostureReport.FrameworkReports = frameworks
}