diff --git a/reporthandling/apis/statuses.go b/reporthandling/apis/statuses.go index 43ac3e65..0941200b 100644 --- a/reporthandling/apis/statuses.go +++ b/reporthandling/apis/statuses.go @@ -30,6 +30,7 @@ const ( // IStatus interface handling status type IStatus interface { Status() ScanningStatus + GetSubStatus() ScanningSubStatus Info() string IsPassed() bool IsFailed() bool diff --git a/reporthandling/apis/statuses_test.go b/reporthandling/apis/statuses_test.go index d8647cac..26bc4f2b 100644 --- a/reporthandling/apis/statuses_test.go +++ b/reporthandling/apis/statuses_test.go @@ -17,6 +17,7 @@ func TestCompare(t *testing.T) { assert.Equal(t, StatusFailed, Compare(StatusPassed, StatusFailed)) assert.Equal(t, StatusSkipped, Compare(StatusSkipped, StatusPassed)) assert.Equal(t, StatusPassed, Compare(StatusPassed, StatusPassed)) + assert.Equal(t, StatusUnknown, Compare(StatusUnknown, StatusUnknown)) } func TestCompareStatusAndSubStatus(t *testing.T) { @@ -29,3 +30,42 @@ func TestCompareStatusAndSubStatus(t *testing.T) { assert.Equal(t, makeIS(StatusSkipped, SubStatusManualReview), makeIS(CompareStatusAndSubStatus(StatusPassed, StatusSkipped, SubStatusUnknown, SubStatusManualReview))) assert.Equal(t, makeIS(StatusSkipped, SubStatusRequiresReview), makeIS(CompareStatusAndSubStatus(StatusPassed, StatusSkipped, SubStatusUnknown, SubStatusRequiresReview))) } + +func TestConvertStatusToNewStatus(t *testing.T) { + tests := []struct { + name string + status ScanningStatus + expected ScanningStatus + sub ScanningSubStatus + }{ + { + name: "StatusExcluded", + status: StatusExcluded, + expected: StatusPassed, + sub: SubStatusException, + }, + { + name: "StatusIrrelevant", + status: StatusIrrelevant, + expected: StatusPassed, + sub: SubStatusIrrelevant, + }, + { + name: "StatusPassed", + status: StatusPassed, + expected: StatusPassed, + sub: SubStatusUnknown, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + actualStatus, actualSub := ConvertStatusToNewStatus(test.status) + if actualStatus != test.expected { + t.Errorf("Expected status %s, but got %s", test.expected, actualStatus) + } + if actualSub != test.sub { + t.Errorf("Expected sub status %s, but got %s", test.sub, actualSub) + } + }) + } +} diff --git a/reporthandling/apis/statusinfo.go b/reporthandling/apis/statusinfo.go index 379c3608..b7ecc1e9 100644 --- a/reporthandling/apis/statusinfo.go +++ b/reporthandling/apis/statusinfo.go @@ -1,8 +1,13 @@ package apis type StatusInfo struct { - InnerStatus ScanningStatus `json:"status,omitempty"` - InnerInfo string `json:"info,omitempty"` + InnerStatus ScanningStatus `json:"status,omitempty"` + SubStatus ScanningSubStatus `json:"subStatus,omitempty"` + InnerInfo string `json:"info,omitempty"` +} + +func (s *StatusInfo) GetSubStatus() ScanningSubStatus { + return s.SubStatus } func (s *StatusInfo) Status() ScanningStatus { diff --git a/reporthandling/apis/statusinfo_test.go b/reporthandling/apis/statusinfo_test.go new file mode 100644 index 00000000..31a1a583 --- /dev/null +++ b/reporthandling/apis/statusinfo_test.go @@ -0,0 +1,46 @@ +package apis + +import "testing" + +func TestIsPassed(t *testing.T) { + s := &StatusInfo{InnerStatus: StatusPassed} + if !s.IsPassed() { + t.Fatalf("Expected status to be passed, got %v", s.InnerStatus) + } +} + +func TestIsFailed(t *testing.T) { + s := &StatusInfo{InnerStatus: StatusFailed} + if !s.IsFailed() { + t.Fatalf("Expected status to be failed, got %v", s.InnerStatus) + } +} + +func TestIsSkipped(t *testing.T) { + s := &StatusInfo{InnerStatus: StatusSkipped} + if !s.IsSkipped() { + t.Fatalf("Expected status to be skipped, got %v", s.InnerStatus) + } +} + +func TestGetSubStatus(t *testing.T) { + s := &StatusInfo{SubStatus: SubStatusException} + if s.GetSubStatus() != SubStatusException { + t.Fatalf("Expected sub-status to be %v, got %v", SubStatusException, s.GetSubStatus()) + } +} + +func TestStatus(t *testing.T) { + s := &StatusInfo{InnerStatus: StatusPassed} + if s.Status() != StatusPassed { + t.Fatalf("Expected status to be %v, got %v", StatusPassed, s.Status()) + } +} + +func TestInfo(t *testing.T) { + info := "Test info" + s := &StatusInfo{InnerInfo: info} + if s.Info() != info { + t.Fatalf("Expected info to be %v, got %v", info, s.Info()) + } +} diff --git a/reporthandling/helpers/v1/status.go b/reporthandling/helpers/v1/status.go index 7c3700f7..2d92f3d7 100644 --- a/reporthandling/helpers/v1/status.go +++ b/reporthandling/helpers/v1/status.go @@ -3,20 +3,25 @@ package v1 import "github.com/kubescape/opa-utils/reporthandling/apis" type Status struct { - status apis.ScanningStatus + status apis.ScanningStatus + subStatus apis.ScanningSubStatus } func NewStatus(status apis.ScanningStatus) *Status { return &Status{status: status} } -func NewStatusInfo(status apis.ScanningStatus, info string) *apis.StatusInfo { +func NewStatusInfo(status apis.ScanningStatus, subStatus apis.ScanningSubStatus, info string) *apis.StatusInfo { return &apis.StatusInfo{ InnerStatus: status, + SubStatus: subStatus, InnerInfo: info, } } +func (s *Status) GetSubStatus() apis.ScanningSubStatus { + return s.subStatus +} func (s *Status) Status() apis.ScanningStatus { return s.status } diff --git a/reporthandling/helpers/v1/status_test.go b/reporthandling/helpers/v1/status_test.go new file mode 100644 index 00000000..f94d4117 --- /dev/null +++ b/reporthandling/helpers/v1/status_test.go @@ -0,0 +1,135 @@ +package v1 + +import ( + "testing" + + "github.com/kubescape/opa-utils/reporthandling/apis" +) + +func TestNewStatus(t *testing.T) { + tests := []struct { + name string + status apis.ScanningStatus + want apis.ScanningStatus + }{ + { + name: "Test passed status", + status: apis.StatusPassed, + want: apis.StatusPassed, + }, + { + name: "Test failed status", + status: apis.StatusFailed, + want: apis.StatusFailed, + }, + { + name: "Test skipped status", + status: apis.StatusSkipped, + want: apis.StatusSkipped, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := NewStatus(tt.status) + if got := s.Status(); got != tt.want { + t.Errorf("NewStatus().Status() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestNewStatusInfo(t *testing.T) { + tests := []struct { + name string + status apis.ScanningStatus + subStatus apis.ScanningSubStatus + info string + wantStatus apis.ScanningStatus + wantSubStatus apis.ScanningSubStatus + wantInfo string + }{ + { + name: "Test passed status with ignore sub status and info", + status: apis.StatusPassed, + subStatus: apis.SubStatusException, + info: string(apis.SubStatusConfigurationInfo), + wantStatus: apis.StatusPassed, + wantSubStatus: apis.SubStatusException, + wantInfo: string(apis.SubStatusConfigurationInfo), + }, + { + name: "Test failed status and info", + status: apis.StatusFailed, + subStatus: "", + info: string(apis.SubStatusManualReviewInfo), + wantStatus: apis.StatusFailed, + wantSubStatus: "", + wantInfo: string(apis.SubStatusManualReviewInfo), + }, + { + name: "Test skipped status with irrelevant sub status without info", + status: apis.StatusSkipped, + subStatus: apis.SubStatusConfiguration, + info: "", + wantStatus: apis.StatusSkipped, + wantSubStatus: apis.SubStatusConfiguration, + wantInfo: "", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := NewStatusInfo(tt.status, tt.subStatus, tt.info) + if got := s.Status(); got != tt.wantStatus { + t.Errorf("NewStatusInfo().Status() = %v, want %v", got, tt.wantStatus) + } + if got := s.GetSubStatus(); got != tt.wantSubStatus { + t.Errorf("NewStatusInfo().GetSubStatus() = %v, want %v", got, tt.wantSubStatus) + } + if got := s.Info(); got != tt.wantInfo { + t.Errorf("NewStatusInfo().Info() = %v, want %v", got, tt.wantInfo) + } + }) + } +} + +func TestGetSubStatus(t *testing.T) { + status := &Status{subStatus: apis.SubStatusIntegration} + if status.GetSubStatus() != apis.SubStatusIntegration { + t.Errorf("Expected subStatus to be %s, got %s", apis.SubStatusIntegration, status.GetSubStatus()) + } +} + +func TestStatus(t *testing.T) { + status := &Status{status: apis.StatusFailed} + if status.Status() != apis.StatusFailed { + t.Errorf("Expected status to be %s, got %s", apis.StatusFailed, status.Status()) + } +} + +func TestInfo(t *testing.T) { + status := &Status{} + if status.Info() != "" { + t.Errorf("Expected Info to be empty string, got %s", status.Info()) + } +} + +func TestIsPassed(t *testing.T) { + status := &Status{status: apis.StatusPassed} + if !status.IsPassed() { + t.Errorf("Expected IsPassed to be true, got false") + } +} + +func TestIsFailed(t *testing.T) { + status := &Status{status: apis.StatusFailed} + if !status.IsFailed() { + t.Errorf("Expected IsFailed to be true, got false") + } +} + +func TestIsSkipped(t *testing.T) { + status := &Status{status: apis.StatusSkipped} + if !status.IsSkipped() { + t.Errorf("Expected IsSkipped to be true, got false") + } +} diff --git a/reporthandling/results/v1/reportsummary/controlsummarymethods.go b/reporthandling/results/v1/reportsummary/controlsummarymethods.go index 57780aaf..8415c717 100644 --- a/reporthandling/results/v1/reportsummary/controlsummarymethods.go +++ b/reporthandling/results/v1/reportsummary/controlsummarymethods.go @@ -28,12 +28,12 @@ func (controlSummary *ControlSummary) SetStatus(statusInfo *apis.StatusInfo) { } func (controlSummary *ControlSummary) SetSubStatus(subStatus apis.ScanningSubStatus) { - controlSummary.SubStatus = subStatus + controlSummary.StatusInfo.SubStatus = subStatus } // GetSubStatus get the control sub status. returns an apis.StatusInfo object func (controlSummary *ControlSummary) GetSubStatus() apis.ScanningSubStatus { - return controlSummary.SubStatus + return controlSummary.StatusInfo.SubStatus } func (controlSummary *ControlSummary) CalculateStatus() { @@ -42,37 +42,38 @@ func (controlSummary *ControlSummary) CalculateStatus() { // calculateStatus set the control status based on the resource counters and the sub status based on the subStatus parameter func (controlSummary *ControlSummary) calculateStatus(subStatus apis.ScanningSubStatus) { - controlSummary.StatusInfo.InnerStatus = calculateStatus(&controlSummary.ResourceCounters) + controlSummary.StatusInfo.InnerStatus = calculateStatus(&controlSummary.StatusCounters) + // Statuses should be the same - controlSummary.Status = controlSummary.StatusInfo.Status() + controlSummary.Status = controlSummary.StatusInfo.Status() // backward compatibility - controlSummary.CalculateSubStatus(subStatus) + controlSummary.calculateNSetSubStatus(subStatus) } // CalculateSubStatus set the control sub status based on the resource associated control sub status -func (controlSummary *ControlSummary) CalculateSubStatus(subStatus apis.ScanningSubStatus) { +func (controlSummary *ControlSummary) calculateNSetSubStatus(subStatus apis.ScanningSubStatus) { switch controlSummary.Status { case apis.StatusPassed: - if subStatus == apis.SubStatusIrrelevant || controlSummary.SubStatus == apis.SubStatusIrrelevant || controlSummary.ResourceCounters.All() == 0 { - controlSummary.SubStatus = apis.SubStatusIrrelevant + if subStatus == apis.SubStatusIrrelevant || controlSummary.StatusInfo.SubStatus == apis.SubStatusIrrelevant || controlSummary.StatusCounters.All() == 0 { + controlSummary.StatusInfo.SubStatus = apis.SubStatusIrrelevant controlSummary.StatusInfo.InnerInfo = "" - } else if subStatus == apis.SubStatusException || controlSummary.SubStatus == apis.SubStatusException { - controlSummary.SubStatus = apis.SubStatusException + } else if subStatus == apis.SubStatusException || controlSummary.StatusInfo.SubStatus == apis.SubStatusException { + controlSummary.StatusInfo.SubStatus = apis.SubStatusException controlSummary.StatusInfo.InnerInfo = "" } case apis.StatusSkipped: - if subStatus == apis.SubStatusConfiguration || controlSummary.SubStatus == apis.SubStatusConfiguration { - controlSummary.SubStatus = apis.SubStatusConfiguration + if subStatus == apis.SubStatusConfiguration || controlSummary.StatusInfo.SubStatus == apis.SubStatusConfiguration { + controlSummary.StatusInfo.SubStatus = apis.SubStatusConfiguration controlSummary.StatusInfo.InnerInfo = string(apis.SubStatusConfigurationInfo) - } else if subStatus == apis.SubStatusManualReview || controlSummary.SubStatus == apis.SubStatusManualReview { - controlSummary.SubStatus = apis.SubStatusManualReview + } else if subStatus == apis.SubStatusManualReview || controlSummary.StatusInfo.SubStatus == apis.SubStatusManualReview { + controlSummary.StatusInfo.SubStatus = apis.SubStatusManualReview controlSummary.StatusInfo.InnerInfo = string(apis.SubStatusManualReviewInfo) - } else if subStatus == apis.SubStatusRequiresReview || controlSummary.SubStatus == apis.SubStatusRequiresReview { - controlSummary.SubStatus = apis.SubStatusRequiresReview + } else if subStatus == apis.SubStatusRequiresReview || controlSummary.StatusInfo.SubStatus == apis.SubStatusRequiresReview { + controlSummary.StatusInfo.SubStatus = apis.SubStatusRequiresReview controlSummary.StatusInfo.InnerInfo = string(apis.SubStatusRequiresReviewInfo) } case apis.StatusFailed: - controlSummary.SubStatus = apis.SubStatusUnknown + controlSummary.StatusInfo.SubStatus = apis.SubStatusUnknown controlSummary.StatusInfo.InnerInfo = "" } } @@ -82,14 +83,21 @@ func (controlSummary *ControlSummary) ListResourcesIDs() *helpersv1.AllLists { return &controlSummary.ResourceIDs } -// NumberOf get the number of resources +// Deprecated use 'ResourcesCounters' instead +// NumberOfResources get the status counters func (controlSummary *ControlSummary) NumberOfResources() ICounters { - return &controlSummary.ResourceCounters + return &controlSummary.StatusCounters +} + +// NumberOfResources get the status counters +func (controlSummary *ControlSummary) StatusesCounters() (ICounters, ISubCounters) { + return &controlSummary.StatusCounters, &controlSummary.SubStatusCounters } // Increase increases the counter based on the status func (controlSummary *ControlSummary) increase(status apis.IStatus) { - controlSummary.ResourceCounters.Increase(status) + controlSummary.StatusCounters.Increase(status) + controlSummary.SubStatusCounters.Increase(status) } // Append increases the counter based on the status @@ -98,7 +106,7 @@ func (controlSummary *ControlSummary) Append(status apis.IStatus, ids ...string) controlSummary.ResourceIDs.Append(status.Status(), ids[i]) controlSummary.increase(status) } - controlSummary.ResourceIDs.ToUniqueResources() + controlSummary.ResourceIDs.ToUniqueResources() // TODO: check if it is needed } // =================================== Score ============================================ diff --git a/reporthandling/results/v1/reportsummary/datastructures.go b/reporthandling/results/v1/reportsummary/datastructures.go index 169f77c2..a1a18ea5 100644 --- a/reporthandling/results/v1/reportsummary/datastructures.go +++ b/reporthandling/results/v1/reportsummary/datastructures.go @@ -19,42 +19,46 @@ type SummaryDetails struct { Frameworks []FrameworkSummary `json:"frameworks"` ResourcesSeverityCounters SeverityCounters `json:"resourcesSeverityCounters,omitempty"` ControlsSeverityCounters SeverityCounters `json:"controlsSeverityCounters,omitempty"` - ResourceCounters ResourceCounters `json:",inline"` + StatusCounters StatusCounters `json:",inline"` Score float32 `json:"score"` } // FrameworkSummary summary of scanning from a single framework perspective type FrameworkSummary struct { - Controls ControlSummaries `json:"controls,omitempty"` // mapping of control - map[] - Name string `json:"name"` // framework name - Status apis.ScanningStatus `json:"status"` - Version string `json:"version"` - ResourceCounters ResourceCounters `json:",inline"` - Score float32 `json:"score"` + Controls ControlSummaries `json:"controls,omitempty"` // mapping of control - map[] + Name string `json:"name"` // framework name + Status apis.ScanningStatus `json:"status"` + Version string `json:"version"` + StatusCounters StatusCounters `json:",inline"` + Score float32 `json:"score"` } // ControlSummary summary of scanning from a single control perspective type ControlSummary struct { - StatusInfo apis.StatusInfo `json:"statusInfo,omitempty"` - ControlID string `json:"controlID"` - Name string `json:"name"` - Status apis.ScanningStatus `json:"status"` - SubStatus apis.ScanningSubStatus `json:"subStatus"` - Description string `json:"-"` - Remediation string `json:"-"` - ResourceIDs helpersv1.AllLists `json:"resourceIDs"` - ResourceCounters ResourceCounters `json:",inline"` - Score float32 `json:"score"` - ScoreFactor float32 `json:"scoreFactor"` + StatusInfo apis.StatusInfo `json:"statusInfo,omitempty"` + ControlID string `json:"controlID"` + Name string `json:"name"` + Status apis.ScanningStatus `json:"status"` // backward compatibility + Description string `json:"-"` + Remediation string `json:"-"` + ResourceIDs helpersv1.AllLists `json:"resourceIDs"` + StatusCounters StatusCounters `json:",inline"` + SubStatusCounters SubStatusCounters `json:",inline"` + Score float32 `json:"score"` + ScoreFactor float32 `json:"scoreFactor"` } -type ResourceCounters struct { +type StatusCounters struct { PassedResources int `json:"passedResources"` FailedResources int `json:"failedResources"` SkippedResources int `json:"skippedResources"` ExcludedResources int `json:"excludedResources"` // Deprecated } +type SubStatusCounters struct { + IgnoredResources int `json:"ignoredResources"` +} + type SeverityCounters struct { CriticalSeverityCounter int `json:"criticalSeverity"` HighSeverityCounter int `json:"highSeverity"` diff --git a/reporthandling/results/v1/reportsummary/datastructures_mock.go b/reporthandling/results/v1/reportsummary/datastructures_mock.go index 5eada695..9948b6d9 100644 --- a/reporthandling/results/v1/reportsummary/datastructures_mock.go +++ b/reporthandling/results/v1/reportsummary/datastructures_mock.go @@ -16,8 +16,8 @@ func mockSummaryDetailsStatusIrrelevant() *SummaryDetails { Controls: map[string]ControlSummary{ "C-0001": *mockControlSummaryStatusIrrelevant(), }, - ResourceCounters: *mockResourceCountersSkippedFailPass(), - Status: apis.StatusFailed, + StatusCounters: *mockStatusCountersSkippedFailPass(), + Status: apis.StatusFailed, } } @@ -29,8 +29,8 @@ func mockSummaryDetailsNoInnerStatus() *SummaryDetails { Controls: map[string]ControlSummary{ "C-0001": *mockControlSummaryNoInnerStatus(), }, - ResourceCounters: *mockResourceCountersSkippedFailPass(), - Status: apis.StatusFailed, + StatusCounters: *mockStatusCountersSkippedFailPass(), + Status: apis.StatusFailed, } } @@ -42,8 +42,8 @@ func mockSummaryDetailsStatusEmpty() *SummaryDetails { Controls: map[string]ControlSummary{ "C-0001": *mockControlSummaryStatusEmpty(), }, - ResourceCounters: *mockResourceCountersSkippedFailPass(), - Status: apis.StatusFailed, + StatusCounters: *mockStatusCountersSkippedFailPass(), + Status: apis.StatusFailed, } } @@ -55,8 +55,8 @@ func mockSummaryDetailsStatusSkipped() *SummaryDetails { Controls: map[string]ControlSummary{ "C-0001": *mockControlSummaryStatusSkipped(), }, - ResourceCounters: *mockResourceCountersSkippedFailPass(), - Status: apis.StatusFailed, + StatusCounters: *mockStatusCountersSkippedFailPass(), + Status: apis.StatusFailed, } } @@ -73,8 +73,8 @@ func mockSummaryDetailsFailed() *SummaryDetails { "C-0003": *mockControlSummaryExceptionPass(), "C-0004": *mockControlSummaryPass(), }, - ResourceCounters: *mockResourceCountersSkippedFailPass(), - Status: apis.StatusFailed, + StatusCounters: *mockStatusCountersSkippedFailPass(), + Status: apis.StatusFailed, } } func mockSummaryDetailsPassed() *SummaryDetails { @@ -82,7 +82,7 @@ func mockSummaryDetailsPassed() *SummaryDetails { Controls: map[string]ControlSummary{ "C-0004": *mockControlSummaryPass(), }, - ResourceCounters: *mockResourceCountersPass(), + StatusCounters: *mockStatusCountersPass(), } } func mockSummaryDetailsException() *SummaryDetails { @@ -93,16 +93,16 @@ func mockSummaryDetailsException() *SummaryDetails { Controls: map[string]ControlSummary{ "C-0003": *mockControlSummaryExceptionPass(), }, - ResourceCounters: *mockResourceCountersExceptions(), + StatusCounters: *mockStatusCountersExceptions(), } } func mockFrameworkSummaryPassException() *FrameworkSummary { return &FrameworkSummary{ - Name: "fw-pass-exclude", - Score: 0, - Status: apis.StatusPassed, - Version: "utnitest", - ResourceCounters: *mockResourceCountersExceptionPass(), + Name: "fw-pass-exclude", + Score: 0, + Status: apis.StatusPassed, + Version: "utnitest", + StatusCounters: *mockStatusCountersExceptionPass(), Controls: map[string]ControlSummary{ "C-0003": *mockControlSummaryExceptionPass(), }, @@ -110,11 +110,11 @@ func mockFrameworkSummaryPassException() *FrameworkSummary { } func mockFrameworkSummaryFailException() *FrameworkSummary { return &FrameworkSummary{ - Name: "fw-failed", - Score: 0, - Status: apis.StatusFailed, - Version: "utnitest", - ResourceCounters: *mockResourceCountersSkippedFailPass(), + Name: "fw-failed", + Score: 0, + Status: apis.StatusFailed, + Version: "utnitest", + StatusCounters: *mockStatusCountersSkippedFailPass(), Controls: map[string]ControlSummary{ "C-0001": *mockControlSummaryFailPass(), "C-0002": *mockControlSummaryFailPassException(), @@ -123,11 +123,11 @@ func mockFrameworkSummaryFailException() *FrameworkSummary { } func mockFrameworkSummaryFailPass() *FrameworkSummary { return &FrameworkSummary{ - Name: "fw-failed", - Score: 0, - Status: apis.StatusFailed, - Version: "utnitest", - ResourceCounters: *mockResourceCountersFailPass(), + Name: "fw-failed", + Score: 0, + Status: apis.StatusFailed, + Version: "utnitest", + StatusCounters: *mockStatusCountersFailPass(), Controls: map[string]ControlSummary{ "C-0001": *mockControlSummaryFailPass(), "C-0003": *mockControlSummaryExceptionPass(), @@ -137,41 +137,41 @@ func mockFrameworkSummaryFailPass() *FrameworkSummary { } func mockControlSummaryExceptionPass() *ControlSummary { return &ControlSummary{ - Name: "control-exclude-pass", - Score: 0, - Status: apis.StatusPassed, - SubStatus: apis.SubStatusException, - ResourceCounters: *mockResourceCountersExceptionPass(), - ResourceIDs: *helpersv1.MockAllListsForIntegration(), + Name: "control-exclude-pass", + Score: 0, + Status: apis.StatusPassed, + StatusInfo: *helpersv1.NewStatusInfo(apis.StatusPassed, apis.SubStatusException, ""), + StatusCounters: *mockStatusCountersExceptionPass(), + ResourceIDs: *helpersv1.MockAllListsForIntegration(), } } func mockControlSummaryPass() *ControlSummary { return &ControlSummary{ - Name: "control-pass", - Score: 0, - Status: apis.StatusPassed, - ResourceCounters: *mockResourceCountersPass(), - ResourceIDs: *helpersv1.MockAllListsForIntegration(), + Name: "control-pass", + Score: 0, + Status: apis.StatusPassed, + StatusCounters: *mockStatusCountersPass(), + ResourceIDs: *helpersv1.MockAllListsForIntegration(), } } func mockControlSummaryFailPass() *ControlSummary { return &ControlSummary{ - Name: "control-fail-pass", - Score: 0, - Status: apis.StatusFailed, - ResourceCounters: *mockResourceCountersFailPass(), - ResourceIDs: *helpersv1.MockAllListsForIntegration(), + Name: "control-fail-pass", + Score: 0, + Status: apis.StatusFailed, + StatusCounters: *mockStatusCountersFailPass(), + ResourceIDs: *helpersv1.MockAllListsForIntegration(), } } func mockControlSummaryFailPassException() *ControlSummary { return &ControlSummary{ - Name: "control-fail-pass-exclude", - Status: apis.StatusFailed, - Score: 0, - ResourceCounters: *mockResourceCountersSkippedFailPass(), - ResourceIDs: *helpersv1.MockAllListsForIntegration(), + Name: "control-fail-pass-exclude", + Status: apis.StatusFailed, + Score: 0, + StatusCounters: *mockStatusCountersSkippedFailPass(), + ResourceIDs: *helpersv1.MockAllListsForIntegration(), } } func mockControlSummaryStatusSkipped() *ControlSummary { @@ -189,9 +189,8 @@ func mockControlSummaryStatusSkipped() *ControlSummary { func mockControlSummaryNoInnerStatus() *ControlSummary { return &ControlSummary{ Name: "control-irrelevant", + StatusInfo: *helpersv1.NewStatusInfo(apis.StatusSkipped, apis.SubStatusIntegration, ""), Status: apis.StatusSkipped, - SubStatus: apis.SubStatusIntegration, - StatusInfo: apis.StatusInfo{}, Score: 0, } } @@ -205,52 +204,48 @@ func mockControlSummaryStatusEmpty() *ControlSummary { func mockControlSummaryStatusIrrelevant() *ControlSummary { return &ControlSummary{ - Name: "control-irrelevant", - Status: apis.StatusPassed, - SubStatus: apis.SubStatusIrrelevant, - StatusInfo: apis.StatusInfo{ - InnerStatus: apis.StatusPassed, - InnerInfo: "no k8s dashboard in cluster", - }, - Score: 0, + Name: "control-irrelevant", + Status: apis.StatusPassed, + StatusInfo: *helpersv1.NewStatusInfo(apis.StatusPassed, apis.SubStatusIrrelevant, "no k8s dashboard in cluster"), + Score: 0, } } -func mockResourceCountersFailPass() *ResourceCounters { - return &ResourceCounters{ +func mockStatusCountersFailPass() *StatusCounters { + return &StatusCounters{ PassedResources: 5, FailedResources: 6, } } -func mockResourceCountersExceptionPass() *ResourceCounters { - return &ResourceCounters{ +func mockStatusCountersExceptionPass() *StatusCounters { + return &StatusCounters{ PassedResources: 4, } } -func mockResourceCountersSkippedFailPass() *ResourceCounters { - return &ResourceCounters{ +func mockStatusCountersSkippedFailPass() *StatusCounters { + return &StatusCounters{ PassedResources: 4, SkippedResources: 3, FailedResources: 5, } } -func mockResourceCountersPass() *ResourceCounters { - return &ResourceCounters{ +func mockStatusCountersPass() *StatusCounters { + return &StatusCounters{ PassedResources: 4, } } -func mockResourceCountersSkipped() *ResourceCounters { - return &ResourceCounters{ +func mockStatusCountersSkipped() *StatusCounters { + return &StatusCounters{ SkippedResources: 4, } } -func mockResourceCountersExceptions() *ResourceCounters { - return &ResourceCounters{ +func mockStatusCountersExceptions() *StatusCounters { + return &StatusCounters{ PassedResources: 4, } } diff --git a/reporthandling/results/v1/reportsummary/frameworksummarymethods.go b/reporthandling/results/v1/reportsummary/frameworksummarymethods.go index 993de72b..c23c88cd 100644 --- a/reporthandling/results/v1/reportsummary/frameworksummarymethods.go +++ b/reporthandling/results/v1/reportsummary/frameworksummarymethods.go @@ -17,19 +17,19 @@ func (frameworkSummary *FrameworkSummary) GetStatus() apis.IStatus { // SetStatus set the framework status based on the resource counters func (frameworkSummary *FrameworkSummary) CalculateStatus() { - frameworkSummary.Status = calculateStatus(&frameworkSummary.ResourceCounters) + frameworkSummary.Status = calculateStatus(&frameworkSummary.StatusCounters) } // =================================== Counters ============================================ // NumberOfExcluded get the number of excluded resources func (frameworkSummary *FrameworkSummary) NumberOfResources() ICounters { - return &frameworkSummary.ResourceCounters + return &frameworkSummary.StatusCounters } // Increase increases the counter based on the status func (frameworkSummary *FrameworkSummary) Increase(status apis.IStatus) { - frameworkSummary.ResourceCounters.Increase(status) + frameworkSummary.StatusCounters.Increase(status) } // List resources IDs @@ -58,7 +58,7 @@ func (frameworkSummary *FrameworkSummary) initResourcesSummary(controlInfoMap ma frameworkSummary.Controls[k] = control } - frameworkSummary.ResourceCounters.Set(frameworkSummary.ListResourcesIDs()) + frameworkSummary.StatusCounters.Set(frameworkSummary.ListResourcesIDs()) frameworkSummary.CalculateStatus() } diff --git a/reporthandling/results/v1/reportsummary/frameworksummarymethods_test.go b/reporthandling/results/v1/reportsummary/frameworksummarymethods_test.go index 7aeface4..573d5736 100644 --- a/reporthandling/results/v1/reportsummary/frameworksummarymethods_test.go +++ b/reporthandling/results/v1/reportsummary/frameworksummarymethods_test.go @@ -46,7 +46,7 @@ func TestStatusEmpty(t *testing.T) { f := mockSummaryDetailsStatusEmpty() for _, v := range f.Controls { v.Status = apis.StatusPassed - v.SubStatus = apis.SubStatusIrrelevant + v.StatusInfo.SubStatus = apis.SubStatusIrrelevant status := v.GetStatus() subStatus := v.GetSubStatus() assert.Equal(t, reflect.TypeOf(status), reflect.TypeOf(&apis.StatusInfo{})) @@ -91,6 +91,7 @@ func TestStatusIrrelevant(t *testing.T) { func TestFrameworkControlsSummariesCounters(t *testing.T) { f := mockFrameworkSummaryFailPass() assert.Equal(t, len(f.Controls), f.GetControls().NumberOfControls().All(), "invalid total control count") + // assert.Equal(t, len(f.GetControls().NumberOfControls().), f.GetControls().NumberOfControls().Failed(), "invalid total failed control count") assert.Equal(t, len(f.GetControls().ListControlsIDs().Failed()), f.GetControls().NumberOfControls().Failed(), "invalid total failed control count") assert.Equal(t, len(f.GetControls().ListControlsIDs().Passed()), f.GetControls().NumberOfControls().Passed(), "invalid total passed control count") assert.Equal(t, len(f.GetControls().ListControlsIDs().Skipped()), f.GetControls().NumberOfControls().Skipped(), "invalid total skipped control count") diff --git a/reporthandling/results/v1/reportsummary/interface.go b/reporthandling/results/v1/reportsummary/interface.go index eb7adbb4..498d41d1 100644 --- a/reporthandling/results/v1/reportsummary/interface.go +++ b/reporthandling/results/v1/reportsummary/interface.go @@ -45,6 +45,8 @@ type IControlSummary interface { // Get SubStatus() get control sub status GetSubStatus() apis.ScanningSubStatus + + StatusesCounters() (ICounters, ISubCounters) } type IControlsSummaries interface { @@ -54,6 +56,7 @@ type IControlsSummaries interface { ListControlsIDs() *helpersv1.AllLists ListResourcesIDs() *helpersv1.AllLists } + type IPolicies interface { GetStatus() apis.IStatus CalculateStatus() diff --git a/reporthandling/results/v1/reportsummary/posturecounters.go b/reporthandling/results/v1/reportsummary/posturecounters.go index 87e83eda..e766334c 100644 --- a/reporthandling/results/v1/reportsummary/posturecounters.go +++ b/reporthandling/results/v1/reportsummary/posturecounters.go @@ -19,6 +19,11 @@ func (pcounter *PostureCounters) Failed() int { return pcounter.FailedCounter } +// deprecated +func (pcounter *PostureCounters) Excluded() int { + return pcounter.ExcludedCounter +} + func (pcounter *PostureCounters) All() int { return pcounter.Passed() + pcounter.Skipped() + pcounter.Failed() } diff --git a/reporthandling/results/v1/reportsummary/resourcecounters_test.go b/reporthandling/results/v1/reportsummary/resourcecounters_test.go deleted file mode 100644 index 9d36eebe..00000000 --- a/reporthandling/results/v1/reportsummary/resourcecounters_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package reportsummary - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -var resourcesCounter = ResourceCounters{} - -// =================================== Counters ============================================ - -func setResourcesCountersMock() { - resourcesCounter.PassedResources = 7 - resourcesCounter.FailedResources = 15 - resourcesCounter.SkippedResources = 5 -} - -func TestSet(t *testing.T) { - rc := ResourceCounters{} - summaryDetails := MockSummaryDetails() - rc.Set(summaryDetails.ListResourcesIDs()) - assert.Equal(t, 1, rc.SkippedResources) - assert.Equal(t, 1, rc.PassedResources) - assert.Equal(t, 2, rc.FailedResources) -} - -// Excluded get the number of skipped resources -func TestExcluded(t *testing.T) { - setResourcesCountersMock() - assert.Equal(t, 5, resourcesCounter.Skipped()) -} - -// Passed get the number of passed resources -func TestPassed(t *testing.T) { - setResourcesCountersMock() - assert.Equal(t, 7, resourcesCounter.Passed()) -} - -// Failed get the number of failed resources -func TestFailed(t *testing.T) { - setResourcesCountersMock() - assert.Equal(t, 15, resourcesCounter.Failed()) -} - -// NumberOfAll get the number of all resources -func TestNumberOfAll(t *testing.T) { - setResourcesCountersMock() - assert.Equal(t, 27, resourcesCounter.All()) -} diff --git a/reporthandling/results/v1/reportsummary/resourceids.go b/reporthandling/results/v1/reportsummary/resourceids.go deleted file mode 100644 index 181143da..00000000 --- a/reporthandling/results/v1/reportsummary/resourceids.go +++ /dev/null @@ -1 +0,0 @@ -package reportsummary diff --git a/reporthandling/results/v1/reportsummary/resourcecounters.go b/reporthandling/results/v1/reportsummary/statuscounters.go similarity index 55% rename from reporthandling/results/v1/reportsummary/resourcecounters.go rename to reporthandling/results/v1/reportsummary/statuscounters.go index 685bb153..278a2876 100644 --- a/reporthandling/results/v1/reportsummary/resourcecounters.go +++ b/reporthandling/results/v1/reportsummary/statuscounters.go @@ -9,42 +9,63 @@ type ICounters interface { Passed() int Skipped() int Failed() int + Excluded() int // deprecated All() int } +type ISubCounters interface { + All() int + Ignored() int +} + // =================================== Counters ============================================ // NumberOfExcluded get the number of excluded resources -func (resourceCounters *ResourceCounters) Set(allLists *helpersv1.AllLists) { +func (resourceCounters *StatusCounters) Set(allLists *helpersv1.AllLists) { resourceCounters.FailedResources = len(allLists.Failed()) resourceCounters.PassedResources = len(allLists.Passed()) resourceCounters.SkippedResources = len(allLists.Skipped()) } // NumberOfPassed get the number of passed resources -func (resourceCounters *ResourceCounters) Passed() int { +func (resourceCounters *StatusCounters) Passed() int { return resourceCounters.PassedResources + resourceCounters.ExcludedResources } // NumberOfSkipped get the number of skipped resources -func (resourceCounters *ResourceCounters) Skipped() int { +func (resourceCounters *StatusCounters) Skipped() int { return resourceCounters.SkippedResources } // NumberOfFailed get the number of failed resources -func (resourceCounters *ResourceCounters) Failed() int { +func (resourceCounters *StatusCounters) Failed() int { return resourceCounters.FailedResources } +// deprecated +func (resourceCounters *StatusCounters) Excluded() int { + return resourceCounters.ExcludedResources +} + // NumberOfAll get the number of all resources -func (resourceCounters *ResourceCounters) All() int { +func (resourceCounters *StatusCounters) All() int { return resourceCounters.Failed() + resourceCounters.Passed() + resourceCounters.Skipped() } +// =================================== SubCounters ============================================ + +func (subStatusCounters *SubStatusCounters) All() int { + return subStatusCounters.Ignored() +} + +func (subStatusCounters *SubStatusCounters) Ignored() int { + return subStatusCounters.IgnoredResources +} + // =================================== Setters ============================================ // Increase increases the counter based on the status -func (resourceCounters *ResourceCounters) Increase(status apis.IStatus) { +func (resourceCounters *StatusCounters) Increase(status apis.IStatus) { switch status.Status() { case apis.StatusFailed: resourceCounters.FailedResources++ @@ -54,3 +75,10 @@ func (resourceCounters *ResourceCounters) Increase(status apis.IStatus) { resourceCounters.SkippedResources++ } } + +// Increase increases the counter based on the status +func (subStatusCounters *SubStatusCounters) Increase(status apis.IStatus) { + if status.IsPassed() && status.GetSubStatus() == apis.SubStatusException { + subStatusCounters.IgnoredResources++ + } +} diff --git a/reporthandling/results/v1/reportsummary/statuscounters_test.go b/reporthandling/results/v1/reportsummary/statuscounters_test.go new file mode 100644 index 00000000..b02560fd --- /dev/null +++ b/reporthandling/results/v1/reportsummary/statuscounters_test.go @@ -0,0 +1,153 @@ +package reportsummary + +import ( + "testing" + + "github.com/kubescape/opa-utils/reporthandling/apis" + "github.com/stretchr/testify/assert" +) + +var resourcesCounter = StatusCounters{} + +// =================================== Counters ============================================ + +func setResourcesCountersMock() { + resourcesCounter.PassedResources = 7 + resourcesCounter.FailedResources = 15 + resourcesCounter.SkippedResources = 5 +} + +func TestSet(t *testing.T) { + rc := StatusCounters{} + summaryDetails := MockSummaryDetails() + rc.Set(summaryDetails.ListResourcesIDs()) + assert.Equal(t, 1, rc.SkippedResources) + assert.Equal(t, 1, rc.PassedResources) + assert.Equal(t, 2, rc.FailedResources) +} + +// Excluded get the number of skipped resources +func TestExcluded(t *testing.T) { + setResourcesCountersMock() + assert.Equal(t, 5, resourcesCounter.Skipped()) +} + +// Passed get the number of passed resources +func TestPassed(t *testing.T) { + setResourcesCountersMock() + assert.Equal(t, 7, resourcesCounter.Passed()) +} + +// Failed get the number of failed resources +func TestFailed(t *testing.T) { + setResourcesCountersMock() + assert.Equal(t, 15, resourcesCounter.Failed()) +} + +// NumberOfAll get the number of all resources +func TestNumberOfAll(t *testing.T) { + setResourcesCountersMock() + assert.Equal(t, 27, resourcesCounter.All()) +} + +func TestStatusCounters_Increase(t *testing.T) { + tests := []struct { + resourceCounters *StatusCounters + name string + status apis.ScanningStatus + expectedPassed int + expectedFailed int + expectedSkipped int + expectedExcluded int + }{ + { + name: "Test passed status", + status: apis.StatusPassed, + resourceCounters: &StatusCounters{ + FailedResources: 1, + SkippedResources: 2, + PassedResources: 3, + }, + expectedFailed: 1, + expectedSkipped: 2, + expectedPassed: 4, + }, + { + name: "Test failed status", + status: apis.StatusFailed, + resourceCounters: &StatusCounters{ + FailedResources: 1, + SkippedResources: 2, + PassedResources: 3, + }, + expectedFailed: 2, + expectedSkipped: 2, + expectedPassed: 3, + }, + { + name: "Test skipped status", + status: apis.StatusSkipped, + resourceCounters: &StatusCounters{ + FailedResources: 1, + SkippedResources: 2, + PassedResources: 3, + }, + expectedFailed: 1, + expectedSkipped: 3, + expectedPassed: 3, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + status := &apis.StatusInfo{InnerStatus: test.status} + test.resourceCounters.Increase(status) + if test.resourceCounters.PassedResources != test.expectedPassed { + t.Errorf("Expected PassedResources to be %d, but got %d", test.expectedPassed, test.resourceCounters.PassedResources) + } + if test.resourceCounters.FailedResources != test.expectedFailed { + t.Errorf("Expected FailedResources to be %d, but got %d", test.expectedFailed, test.resourceCounters.FailedResources) + } + if test.resourceCounters.SkippedResources != test.expectedSkipped { + t.Errorf("Expected SkippedResources to be %d, but got %d", test.expectedSkipped, test.resourceCounters.SkippedResources) + } + }) + } +} + +func TestSubStatusCounters_Increase(t *testing.T) { + tests := []struct { + subStatusCounters *SubStatusCounters + name string + status apis.ScanningStatus + subStatus apis.ScanningSubStatus + expectedIgnored int + }{ + { + name: "Test ignored and passed status", + status: apis.StatusPassed, + subStatus: apis.SubStatusException, + subStatusCounters: &SubStatusCounters{ + IgnoredResources: 1, + }, + expectedIgnored: 2, + }, + { + name: "Test ignored and failed status", + status: apis.StatusFailed, + subStatus: apis.SubStatusException, + subStatusCounters: &SubStatusCounters{ + IgnoredResources: 1, + }, + expectedIgnored: 1, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + status := &apis.StatusInfo{InnerStatus: test.status, SubStatus: test.subStatus} + test.subStatusCounters.Increase(status) + if test.subStatusCounters.IgnoredResources != test.expectedIgnored { + t.Errorf("Expected IgnoredResources to be %d, but got %d", test.expectedIgnored, test.subStatusCounters.IgnoredResources) + } + }) + } +} diff --git a/reporthandling/results/v1/reportsummary/summarydetails.go b/reporthandling/results/v1/reportsummary/summarydetails.go index bfd2858d..8bfeb274 100644 --- a/reporthandling/results/v1/reportsummary/summarydetails.go +++ b/reporthandling/results/v1/reportsummary/summarydetails.go @@ -23,19 +23,19 @@ func (summaryDetails *SummaryDetails) GetScore() float32 { // SetStatus set the framework status based on the resource counters func (summaryDetails *SummaryDetails) CalculateStatus() { - summaryDetails.Status = calculateStatus(&summaryDetails.ResourceCounters) + summaryDetails.Status = calculateStatus(&summaryDetails.StatusCounters) } // =================================== Counters ============================================ // NumberOfExcluded get the number of excluded resources func (summaryDetails *SummaryDetails) NumberOfResources() ICounters { - return &summaryDetails.ResourceCounters + return &summaryDetails.StatusCounters } // Increase increases the counter based on the status func (summaryDetails *SummaryDetails) Increase(status apis.IStatus) { - summaryDetails.ResourceCounters.Increase(status) + summaryDetails.StatusCounters.Increase(status) } // InitResourcesSummary must run this AFTER initializing the controls @@ -59,7 +59,7 @@ func (summaryDetails *SummaryDetails) InitResourcesSummary(controlInfoMap map[st } } - summaryDetails.ResourceCounters.Set(summaryDetails.ListResourcesIDs()) + summaryDetails.StatusCounters.Set(summaryDetails.ListResourcesIDs()) summaryDetails.CalculateStatus() } diff --git a/reporthandling/results/v1/reportsummary/summarydetails_test.go b/reporthandling/results/v1/reportsummary/summarydetails_test.go index 70052c19..b0074077 100644 --- a/reporthandling/results/v1/reportsummary/summarydetails_test.go +++ b/reporthandling/results/v1/reportsummary/summarydetails_test.go @@ -67,6 +67,37 @@ func TestUpdateControlsSummaryCountersFailed(t *testing.T) { assert.Equal(t, 0, v.NumberOfResources().Skipped()) } + for _, v := range controls { + statuses, subStatuses := v.StatusesCounters() + assert.Equal(t, 1, statuses.All()) + assert.Equal(t, 1, statuses.Failed()) + assert.Equal(t, 0, statuses.Passed()) + assert.Equal(t, 0, statuses.Skipped()) + assert.Equal(t, 0, subStatuses.All()) + assert.Equal(t, 0, subStatuses.Ignored()) + } + +} + +func TestUpdateControlsSummaryCountersExcluded(t *testing.T) { + controls := map[string]ControlSummary{} + + passedControls := mockResultsFailed.ListControlsIDs(nil).Passed() + for i := range passedControls { + controls[passedControls[i]] = ControlSummary{} + } + + updateControlsSummaryCounters(&mockResultsException, controls, nil) + for _, v := range controls { + statuses, subStatuses := v.StatusesCounters() + assert.Equal(t, 1, statuses.All()) + assert.Equal(t, 0, statuses.Failed()) + assert.Equal(t, 1, statuses.Passed()) + assert.Equal(t, 0, statuses.Skipped()) + assert.Equal(t, 1, subStatuses.All()) + assert.Equal(t, 1, subStatuses.Ignored()) + } + } func TestUpdateControlsSummaryCountersPassed(t *testing.T) { controls := map[string]ControlSummary{} diff --git a/reporthandling/results/v1/reportsummary/utils.go b/reporthandling/results/v1/reportsummary/utils.go index eb8813e1..36fb2e58 100644 --- a/reporthandling/results/v1/reportsummary/utils.go +++ b/reporthandling/results/v1/reportsummary/utils.go @@ -4,7 +4,7 @@ import ( "github.com/kubescape/opa-utils/reporthandling/apis" ) -func calculateStatus(counters *ResourceCounters) apis.ScanningStatus { +func calculateStatus(counters *StatusCounters) apis.ScanningStatus { if counters.Failed() != 0 { return apis.StatusFailed diff --git a/reporthandling/results/v1/reportsummary/utils_test.go b/reporthandling/results/v1/reportsummary/utils_test.go index b3ae35f4..e38a2d6e 100644 --- a/reporthandling/results/v1/reportsummary/utils_test.go +++ b/reporthandling/results/v1/reportsummary/utils_test.go @@ -8,9 +8,9 @@ import ( ) func TestCalculateStatus(t *testing.T) { - passed := mockResourceCountersPass() - failed := mockResourceCountersFailPass() - skipped := mockResourceCountersSkipped() + passed := mockStatusCountersPass() + failed := mockStatusCountersFailPass() + skipped := mockStatusCountersSkipped() assert.Equal(t, apis.StatusPassed, calculateStatus(passed)) assert.Equal(t, apis.StatusFailed, calculateStatus(failed)) diff --git a/reporthandling/results/v1/resourcesresults/controls.go b/reporthandling/results/v1/resourcesresults/controls.go index 5ff5a4ec..b564be5c 100644 --- a/reporthandling/results/v1/resourcesresults/controls.go +++ b/reporthandling/results/v1/resourcesresults/controls.go @@ -60,7 +60,7 @@ func (control *ResourceAssociatedControl) GetSubStatus() apis.ScanningSubStatus } return subStatus } - return control.SubStatus + return control.Status.SubStatus } // SetStatus set control status and sub status @@ -83,7 +83,7 @@ func (control *ResourceAssociatedControl) SetStatus(c reporthandling.Control) { actionRequiredStr := c.GetActionRequiredAttribute() if actionRequiredStr == "" { control.Status.InnerStatus = status - control.SubStatus = subStatus + control.Status.SubStatus = subStatus return } @@ -111,7 +111,7 @@ func (control *ResourceAssociatedControl) SetStatus(c reporthandling.Control) { control.Status.InnerStatus = status control.Status.InnerInfo = statusInfo - control.SubStatus = subStatus + control.Status.SubStatus = subStatus } diff --git a/reporthandling/results/v1/resourcesresults/datastructures.go b/reporthandling/results/v1/resourcesresults/datastructures.go index a12d82b3..c1124aac 100644 --- a/reporthandling/results/v1/resourcesresults/datastructures.go +++ b/reporthandling/results/v1/resourcesresults/datastructures.go @@ -13,7 +13,6 @@ type Result struct { PrioritizedResource *prioritization.PrioritizedResource `json:"prioritizedResource,omitempty"` ResourceID string `json:"resourceID"` // /// AssociatedControls []ResourceAssociatedControl `json:"controls,omitempty"` - *resultOptions } @@ -22,7 +21,6 @@ type ResourceAssociatedControl struct { ControlID string `json:"controlID"` Name string `json:"name"` Status apis.StatusInfo `json:"status"` - SubStatus apis.ScanningSubStatus `json:"subStatus"` ResourceAssociatedRules []ResourceAssociatedRule `json:"rules,omitempty"` } diff --git a/reporthandling/results/v1/resourcesresults/datastructures_mock.go b/reporthandling/results/v1/resourcesresults/datastructures_mock.go index bbd8eb9c..fd52a1e5 100644 --- a/reporthandling/results/v1/resourcesresults/datastructures_mock.go +++ b/reporthandling/results/v1/resourcesresults/datastructures_mock.go @@ -95,8 +95,7 @@ func mockResourceAssociatedControlException() *ResourceAssociatedControl { return &ResourceAssociatedControl{ ControlID: "C-0089", Name: "0089", - Status: apis.StatusInfo{InnerStatus: apis.StatusPassed}, - SubStatus: apis.SubStatusException, + Status: apis.StatusInfo{InnerStatus: apis.StatusPassed, SubStatus: apis.SubStatusException}, ResourceAssociatedRules: []ResourceAssociatedRule{ *mockResourceAssociatedRuleException(), }, @@ -136,8 +135,7 @@ func mockResourceAssociatedControl0087Failed() *ResourceAssociatedControl { return &ResourceAssociatedControl{ ControlID: "C-0087", Name: "0087", - Status: apis.StatusInfo{InnerStatus: apis.StatusFailed}, - SubStatus: apis.SubStatusUnknown, + Status: apis.StatusInfo{InnerStatus: apis.StatusFailed, SubStatus: apis.SubStatusUnknown}, ResourceAssociatedRules: []ResourceAssociatedRule{ *mockResourceAssociatedRuleA(), *mockResourceAssociatedRuleB(), @@ -159,8 +157,7 @@ func mockResourceAssociatedControl0088Failed() *ResourceAssociatedControl { return &ResourceAssociatedControl{ ControlID: "C-0088", Name: "0088", - Status: apis.StatusInfo{InnerStatus: apis.StatusFailed}, - SubStatus: apis.SubStatusUnknown, + Status: apis.StatusInfo{InnerStatus: apis.StatusFailed, SubStatus: apis.SubStatusUnknown}, ResourceAssociatedRules: []ResourceAssociatedRule{ *mockResourceAssociatedRuleB(), }, @@ -171,8 +168,7 @@ func mockResourceAssociatedControl0089Passed() *ResourceAssociatedControl { return &ResourceAssociatedControl{ ControlID: "C-0089", Name: "0089", - Status: apis.StatusInfo{InnerStatus: apis.StatusPassed}, - SubStatus: apis.SubStatusUnknown, + Status: apis.StatusInfo{InnerStatus: apis.StatusPassed, SubStatus: apis.SubStatusUnknown}, ResourceAssociatedRules: []ResourceAssociatedRule{ *mockResourceAssociatedRulePassed(), }, diff --git a/reporthandling/results/v1/resourcesresults/testdata/new_resource_associated_controls.json b/reporthandling/results/v1/resourcesresults/testdata/new_resource_associated_controls.json index 19e713da..63d16ae2 100644 --- a/reporthandling/results/v1/resourcesresults/testdata/new_resource_associated_controls.json +++ b/reporthandling/results/v1/resourcesresults/testdata/new_resource_associated_controls.json @@ -3,9 +3,9 @@ "controlID": "C-0053", "name": "Access container service account", "status": { - "status": "passed" + "status": "passed", + "subStatus": "w/exceptions" }, - "subStatus": "w/exceptions", "rules": [ { "name": "access-container-service-account-v1", @@ -47,9 +47,9 @@ "controlID": "C-0014", "name": "Access Kubernetes dashboard", "status": { + "subStatus": "", "status": "passed" }, - "subStatus": "", "rules": [ { "name": "rule-access-dashboard-subject-v1", @@ -62,9 +62,9 @@ "controlID": "C-0212", "name": "CIS-5.7.4 The default namespace should not be used", "status": { + "subStatus": "", "status": "failed" }, - "subStatus": "", "rules": [ { "name": "resources-notpods-in-default-namespace", diff --git a/reporthandling/v2/datastructures_test.go b/reporthandling/v2/datastructures_test.go index 9d831941..d3c585d2 100644 --- a/reporthandling/v2/datastructures_test.go +++ b/reporthandling/v2/datastructures_test.go @@ -66,7 +66,7 @@ func GetPostureReportMock() *PostureReport { Controls: map[string]reportsummary.ControlSummary{ "C-0045": { Score: 68, - ResourceCounters: reportsummary.ResourceCounters{ + StatusCounters: reportsummary.StatusCounters{ PassedResources: 17, FailedResources: 5, SkippedResources: 0, @@ -78,7 +78,7 @@ func GetPostureReportMock() *PostureReport { Controls: map[string]reportsummary.ControlSummary{ "C-0045": { Score: 68, - ResourceCounters: reportsummary.ResourceCounters{ + StatusCounters: reportsummary.StatusCounters{ PassedResources: 17, FailedResources: 5, SkippedResources: 0,