diff --git a/httphandler/handlerequests/v1/prometheus.go b/httphandler/handlerequests/v1/prometheus.go index c0fdef21..b655b667 100644 --- a/httphandler/handlerequests/v1/prometheus.go +++ b/httphandler/handlerequests/v1/prometheus.go @@ -6,6 +6,7 @@ import ( "net/http" "os" "path/filepath" + "strings" "github.com/google/uuid" "github.com/kubescape/go-logger" @@ -75,12 +76,35 @@ func getPrometheusDefaultScanCommand(scanID, resultsFile string) *cautils.ScanIn scanInfo.Local = true // do not submit results every scan scanInfo.FrameworkScan = true scanInfo.HostSensorEnabled.SetBool(false) // disable host scanner - scanInfo.ScanAll = true // scan all available frameworks (including CIS) scanInfo.ScanID = scanID // scan ID scanInfo.FailThreshold = 100 // Do not fail scanning scanInfo.ComplianceThreshold = 0 // Do not fail scanning scanInfo.Output = resultsFile // results output scanInfo.Format = envToString("KS_FORMAT", "prometheus") // default output should be json - // Framework identifiers will be set dynamically by the scan process when ScanAll is true + + // Check if specific frameworks are requested via environment variable + frameworksEnv := envToString("KS_METRICS_FRAMEWORKS", "") + if frameworksEnv != "" { + // Scan specific frameworks (comma-separated list) + frameworks := splitAndTrim(frameworksEnv, ",") + scanInfo.SetPolicyIdentifiers(frameworks, utilsapisv1.KindFramework) + } else { + // Default: scan all available frameworks (including CIS) + scanInfo.ScanAll = true + // Framework identifiers will be set dynamically by the scan process when ScanAll is true + } + return scanInfo } + +// splitAndTrim splits a string by delimiter and trims whitespace from each element +func splitAndTrim(s, sep string) []string { + parts := strings.Split(s, sep) + result := make([]string, 0, len(parts)) + for _, part := range parts { + if trimmed := strings.TrimSpace(part); trimmed != "" { + result = append(result, trimmed) + } + } + return result +} diff --git a/httphandler/handlerequests/v1/prometheus_test.go b/httphandler/handlerequests/v1/prometheus_test.go index a25b37c4..21e541b0 100644 --- a/httphandler/handlerequests/v1/prometheus_test.go +++ b/httphandler/handlerequests/v1/prometheus_test.go @@ -1,6 +1,7 @@ package v1 import ( + "os" "path/filepath" "testing" @@ -9,17 +10,95 @@ import ( ) func TestGetPrometheusDefaultScanCommand(t *testing.T) { - scanID := "1234" - outputFile := filepath.Join(OutputDir, scanID) - scanInfo := getPrometheusDefaultScanCommand(scanID, outputFile) + t.Run("default behavior - scan all frameworks", func(t *testing.T) { + // Ensure environment variable is not set + os.Unsetenv("KS_METRICS_FRAMEWORKS") + + scanID := "1234" + outputFile := filepath.Join(OutputDir, scanID) + scanInfo := getPrometheusDefaultScanCommand(scanID, outputFile) - assert.Equal(t, scanID, scanInfo.ScanID) - assert.Equal(t, outputFile, scanInfo.Output) - assert.Equal(t, "prometheus", scanInfo.Format) - assert.False(t, scanInfo.Submit) - assert.True(t, scanInfo.Local) - assert.True(t, scanInfo.FrameworkScan) - assert.True(t, scanInfo.ScanAll) // Changed to true to scan all available frameworks - assert.False(t, scanInfo.HostSensorEnabled.GetBool()) - assert.Equal(t, getter.DefaultLocalStore, scanInfo.UseArtifactsFrom) + assert.Equal(t, scanID, scanInfo.ScanID) + assert.Equal(t, outputFile, scanInfo.Output) + assert.Equal(t, "prometheus", scanInfo.Format) + assert.False(t, scanInfo.Submit) + assert.True(t, scanInfo.Local) + assert.True(t, scanInfo.FrameworkScan) + assert.True(t, scanInfo.ScanAll) // Scan all available frameworks by default + assert.False(t, scanInfo.HostSensorEnabled.GetBool()) + assert.Equal(t, getter.DefaultLocalStore, scanInfo.UseArtifactsFrom) + }) + + t.Run("specific frameworks via environment variable", func(t *testing.T) { + // Set environment variable to scan specific frameworks + os.Setenv("KS_METRICS_FRAMEWORKS", "nsa,mitre,cis-v1.10.0") + defer os.Unsetenv("KS_METRICS_FRAMEWORKS") + + scanID := "5678" + outputFile := filepath.Join(OutputDir, scanID) + scanInfo := getPrometheusDefaultScanCommand(scanID, outputFile) + + assert.Equal(t, scanID, scanInfo.ScanID) + assert.Equal(t, outputFile, scanInfo.Output) + assert.Equal(t, "prometheus", scanInfo.Format) + assert.False(t, scanInfo.Submit) + assert.True(t, scanInfo.Local) + assert.True(t, scanInfo.FrameworkScan) + assert.False(t, scanInfo.ScanAll) // Don't scan all when specific frameworks are set + assert.False(t, scanInfo.HostSensorEnabled.GetBool()) + assert.Equal(t, getter.DefaultLocalStore, scanInfo.UseArtifactsFrom) + + // Verify specific frameworks are set + assert.Len(t, scanInfo.PolicyIdentifier, 3) + assert.Equal(t, "nsa", scanInfo.PolicyIdentifier[0].Identifier) + assert.Equal(t, "mitre", scanInfo.PolicyIdentifier[1].Identifier) + assert.Equal(t, "cis-v1.10.0", scanInfo.PolicyIdentifier[2].Identifier) + }) +} + +func TestSplitAndTrim(t *testing.T) { + tests := []struct { + name string + input string + sep string + expected []string + }{ + { + name: "comma-separated with spaces", + input: "nsa, mitre, cis-v1.10.0", + sep: ",", + expected: []string{"nsa", "mitre", "cis-v1.10.0"}, + }, + { + name: "no spaces", + input: "nsa,mitre,cis-v1.10.0", + sep: ",", + expected: []string{"nsa", "mitre", "cis-v1.10.0"}, + }, + { + name: "single item", + input: "nsa", + sep: ",", + expected: []string{"nsa"}, + }, + { + name: "empty string", + input: "", + sep: ",", + expected: []string{}, + }, + { + name: "whitespace only", + input: " , , ", + sep: ",", + expected: []string{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := splitAndTrim(tt.input, tt.sep) + assert.Equal(t, tt.expected, result) + }) + } }