diff --git a/reporthandling/results/v1/reportsummary/controlsummarymethods.go b/reporthandling/results/v1/reportsummary/controlsummarymethods.go index 8415c717..0fdb62be 100644 --- a/reporthandling/results/v1/reportsummary/controlsummarymethods.go +++ b/reporthandling/results/v1/reportsummary/controlsummarymethods.go @@ -116,6 +116,14 @@ func (controlSummary *ControlSummary) GetScore() float32 { return controlSummary.Score } +func (controlSummary *ControlSummary) GetComplianceScore() float32 { + // if ComplianceScore field is set return it, else return -1 + if controlSummary.ComplianceScore != nil { + return *controlSummary.ComplianceScore + } + return -1 +} + // GetScoreFactor return control score func (controlSummary *ControlSummary) GetScoreFactor() float32 { return controlSummary.ScoreFactor diff --git a/reporthandling/results/v1/reportsummary/datastructures.go b/reporthandling/results/v1/reportsummary/datastructures.go index 7053b181..292d3e3a 100644 --- a/reporthandling/results/v1/reportsummary/datastructures.go +++ b/reporthandling/results/v1/reportsummary/datastructures.go @@ -47,6 +47,7 @@ type ControlSummary struct { StatusCounters StatusCounters `json:"ResourceCounters"` // Backward compatibility SubStatusCounters SubStatusCounters `json:"subStatusCounters"` Score float32 `json:"score"` + ComplianceScore *float32 `json:"complianceScore,omitempty"` ScoreFactor float32 `json:"scoreFactor"` } diff --git a/reporthandling/results/v1/reportsummary/interface.go b/reporthandling/results/v1/reportsummary/interface.go index d2bdd156..8619a014 100644 --- a/reporthandling/results/v1/reportsummary/interface.go +++ b/reporthandling/results/v1/reportsummary/interface.go @@ -69,6 +69,9 @@ type IPolicies interface { // Score GetScore() float32 + // ComplianceScore + GetComplianceScore() float32 + // Name GetName() string } diff --git a/score/score.go b/score/score.go index 39f7c0ba..9a8cb5f5 100644 --- a/score/score.go +++ b/score/score.go @@ -14,6 +14,7 @@ import ( "github.com/kubescape/opa-utils/reporthandling" "github.com/kubescape/opa-utils/reporthandling/results/v1/reportsummary" v2 "github.com/kubescape/opa-utils/reporthandling/v2" + "github.com/kubescape/opa-utils/shared" "go.uber.org/zap" appsv1 "k8s.io/api/apps/v1" ) @@ -351,8 +352,7 @@ func max32(a, b float32) float32 { // SetPostureReportComplianceScores calculates and populates scores for all controls, frameworks and whole scan. func (su *ScoreUtil) SetPostureReportComplianceScores(report *v2.PostureReport) error { // call CalculatePostureReportV2 to set frameworks.score and summaryDetails.score for backward compatibility - // afterwards we will override the controls.score - // and set frameworks.complianceScore and summaryDetails.complianceScore + // afterwards we set complianceScore for frameworks, controls and summaryDetails // TODO: remove CalculatePostureReportV2 call after we deprecate frameworks.score and summaryDetails.score if err := su.CalculatePostureReportV2(report); err != nil { return err @@ -378,10 +378,9 @@ func (su *ScoreUtil) SetPostureReportComplianceScores(report *v2.PostureReport) func (su *ScoreUtil) ControlsSummariesComplianceScore(ctrls *reportsummary.ControlSummaries, frameworkName string) (sumScore float32) { for ctrlID := range *ctrls { ctrl := (*ctrls)[ctrlID] - ctrl.Score = 0 - ctrl.Score = su.GetControlComplianceScore(&ctrl, frameworkName) + ctrl.ComplianceScore = shared.Ptr(su.GetControlComplianceScore(&ctrl, frameworkName)) (*ctrls)[ctrlID] = ctrl - sumScore += ctrl.GetScore() + sumScore += ctrl.GetComplianceScore() } return sumScore } diff --git a/score/score_test.go b/score/score_test.go index 152e19bd..15673b64 100644 --- a/score/score_test.go +++ b/score/score_test.go @@ -947,20 +947,29 @@ func TestSetPostureReportComplianceScores(t *testing.T) { t.Run("assert control scores", func(t *testing.T) { require.Len(t, report.SummaryDetails.Controls, 4) for _, control := range report.SummaryDetails.Controls { - var expectedForControl float64 + var expectedComplianceScore float64 + var expectedScore float64 switch control.ControlID { case "control-1": - expectedForControl = 33.333336 + expectedComplianceScore = 33.333336 + expectedScore = 81.13208 case "control-2": - expectedForControl = 100 // passed + expectedComplianceScore = 100 // passed + expectedScore = 0 case "control-3": - expectedForControl = 50 + expectedComplianceScore = 50 + expectedScore = 66.666664 case "control-4": - expectedForControl = 100 // passed + expectedComplianceScore = 100 // passed + expectedScore = 0 } - assert.InDeltaf(t, expectedForControl, control.Score, 1e-6, + assert.InDeltaf(t, expectedComplianceScore, *control.ComplianceScore, 1e-6, + "unexpected summarized score for control %q", control.ControlID, + ) + // check that control score wasn't overridden by compliance score + assert.InDeltaf(t, expectedScore, control.Score, 1e-6, "unexpected summarized score for control %q", control.ControlID, ) } diff --git a/shared/pointer.go b/shared/pointer.go new file mode 100644 index 00000000..b6399a0f --- /dev/null +++ b/shared/pointer.go @@ -0,0 +1,5 @@ +package shared + +func Ptr[T any](v T) *T { + return &v +}