Implementing capability to print out the "print" statements of the rego

Signed-off-by: Ben <ben@armosec.io>
This commit is contained in:
Ben
2024-11-20 00:10:18 +02:00
parent a9ac880356
commit 4f3ef49f99
6 changed files with 24 additions and 8 deletions

View File

@@ -15,12 +15,12 @@ import (
) )
var scanCmdExamples = fmt.Sprintf(` var scanCmdExamples = fmt.Sprintf(`
Scan command is for scanning an existing cluster or kubernetes manifest files based on pre-defined frameworks Scan command is for scanning an existing cluster or kubernetes manifest files based on pre-defined frameworks
# Scan current cluster # Scan current cluster
%[1]s scan %[1]s scan
# Scan kubernetes manifest files # Scan kubernetes manifest files
%[1]s scan . %[1]s scan .
# Scan and save the results in the JSON format # Scan and save the results in the JSON format
@@ -29,7 +29,7 @@ var scanCmdExamples = fmt.Sprintf(`
# Display all resources # Display all resources
%[1]s scan --verbose %[1]s scan --verbose
# Scan different clusters from the kubectl context # Scan different clusters from the kubectl context
%[1]s scan --kube-context <kubernetes context> %[1]s scan --kube-context <kubernetes context>
`, cautils.ExecName()) `, cautils.ExecName())
@@ -89,6 +89,7 @@ func GetScanCommand(ks meta.IKubescape) *cobra.Command {
scanCmd.PersistentFlags().BoolVarP(&scanInfo.Submit, "submit", "", false, "Submit the scan results to Kubescape SaaS where you can see the results in a user-friendly UI, choose your preferred compliance framework, check risk results history and trends, manage exceptions, get remediation recommendations and much more. By default the results are not submitted") scanCmd.PersistentFlags().BoolVarP(&scanInfo.Submit, "submit", "", false, "Submit the scan results to Kubescape SaaS where you can see the results in a user-friendly UI, choose your preferred compliance framework, check risk results history and trends, manage exceptions, get remediation recommendations and much more. By default the results are not submitted")
scanCmd.PersistentFlags().BoolVarP(&scanInfo.OmitRawResources, "omit-raw-resources", "", false, "Omit raw resources from the output. By default the raw resources are included in the output") scanCmd.PersistentFlags().BoolVarP(&scanInfo.OmitRawResources, "omit-raw-resources", "", false, "Omit raw resources from the output. By default the raw resources are included in the output")
scanCmd.PersistentFlags().BoolVarP(&scanInfo.PrintAttackTree, "print-attack-tree", "", false, "Print attack tree") scanCmd.PersistentFlags().BoolVarP(&scanInfo.PrintAttackTree, "print-attack-tree", "", false, "Print attack tree")
scanCmd.PersistentFlags().BoolVarP(&scanInfo.EnableRegoPrint, "enable-rego-prints", "", false, "Enable sending to rego prints to the logs (use with debug log level: -l debug)")
scanCmd.PersistentFlags().BoolVarP(&scanInfo.ScanImages, "scan-images", "", false, "Scan resources images") scanCmd.PersistentFlags().BoolVarP(&scanInfo.ScanImages, "scan-images", "", false, "Scan resources images")
scanCmd.PersistentFlags().MarkDeprecated("fail-threshold", "use '--compliance-threshold' flag instead. Flag will be removed at 1.Dec.2023") scanCmd.PersistentFlags().MarkDeprecated("fail-threshold", "use '--compliance-threshold' flag instead. Flag will be removed at 1.Dec.2023")

View File

@@ -132,6 +132,7 @@ type ScanInfo struct {
ScanAll bool // true if scan all frameworks ScanAll bool // true if scan all frameworks
OmitRawResources bool // true if omit raw resources from the output OmitRawResources bool // true if omit raw resources from the output
PrintAttackTree bool // true if print attack tree PrintAttackTree bool // true if print attack tree
EnableRegoPrint bool // true if print rego
ScanObject *objectsenvelopes.ScanObject // identifies a single resource (k8s object) to be scanned ScanObject *objectsenvelopes.ScanObject // identifies a single resource (k8s object) to be scanned
IsDeletedScanObject bool // indicates whether the ScanObject is a deleted K8S resource IsDeletedScanObject bool // indicates whether the ScanObject is a deleted K8S resource
ScanType ScanTypes ScanType ScanTypes

View File

@@ -182,7 +182,7 @@ func (ks *Kubescape) Scan(ctx context.Context, scanInfo *cautils.ScanInfo) (*res
defer spanOpa.End() defer spanOpa.End()
deps := resources.NewRegoDependenciesData(k8sinterface.GetK8sConfig(), interfaces.tenantConfig.GetContextName()) deps := resources.NewRegoDependenciesData(k8sinterface.GetK8sConfig(), interfaces.tenantConfig.GetContextName())
reportResults := opaprocessor.NewOPAProcessor(scanData, deps, interfaces.tenantConfig.GetContextName(), scanInfo.ExcludedNamespaces, scanInfo.IncludeNamespaces) reportResults := opaprocessor.NewOPAProcessor(scanData, deps, interfaces.tenantConfig.GetContextName(), scanInfo.ExcludedNamespaces, scanInfo.IncludeNamespaces, scanInfo.EnableRegoPrint)
if err = reportResults.ProcessRulesListener(ctxOpa, cautils.NewProgressHandler("")); err != nil { if err = reportResults.ProcessRulesListener(ctxOpa, cautils.NewProgressHandler("")); err != nil {
// TODO - do something // TODO - do something
return resultsHandling, fmt.Errorf("%w", err) return resultsHandling, fmt.Errorf("%w", err)

View File

@@ -21,6 +21,7 @@ import (
"github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/ast"
"github.com/open-policy-agent/opa/rego" "github.com/open-policy-agent/opa/rego"
"github.com/open-policy-agent/opa/storage" "github.com/open-policy-agent/opa/storage"
opaprint "github.com/open-policy-agent/opa/topdown/print"
"go.opentelemetry.io/otel" "go.opentelemetry.io/otel"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
) )
@@ -41,9 +42,10 @@ type OPAProcessor struct {
opaRegisterOnce sync.Once opaRegisterOnce sync.Once
excludeNamespaces []string excludeNamespaces []string
includeNamespaces []string includeNamespaces []string
printEnabled bool
} }
func NewOPAProcessor(sessionObj *cautils.OPASessionObj, regoDependenciesData *resources.RegoDependenciesData, clusterName string, excludeNamespaces string, includeNamespaces string) *OPAProcessor { func NewOPAProcessor(sessionObj *cautils.OPASessionObj, regoDependenciesData *resources.RegoDependenciesData, clusterName string, excludeNamespaces string, includeNamespaces string, enableRegoPrint bool) *OPAProcessor {
if regoDependenciesData != nil && sessionObj != nil { if regoDependenciesData != nil && sessionObj != nil {
regoDependenciesData.PostureControlInputs = sessionObj.RegoInputData.PostureControlInputs regoDependenciesData.PostureControlInputs = sessionObj.RegoInputData.PostureControlInputs
regoDependenciesData.DataControlInputs = sessionObj.RegoInputData.DataControlInputs regoDependenciesData.DataControlInputs = sessionObj.RegoInputData.DataControlInputs
@@ -55,6 +57,7 @@ func NewOPAProcessor(sessionObj *cautils.OPASessionObj, regoDependenciesData *re
clusterName: clusterName, clusterName: clusterName,
excludeNamespaces: split(excludeNamespaces), excludeNamespaces: split(excludeNamespaces),
includeNamespaces: split(includeNamespaces), includeNamespaces: split(includeNamespaces),
printEnabled: enableRegoPrint,
} }
} }
@@ -319,7 +322,9 @@ func (opap *OPAProcessor) runRegoOnK8s(ctx context.Context, rule *reporthandling
modules[rule.Name] = getRuleData(rule) modules[rule.Name] = getRuleData(rule)
// NOTE: OPA module compilation is the most resource-intensive operation. // NOTE: OPA module compilation is the most resource-intensive operation.
compiled, err := ast.CompileModules(modules) compiled, err := ast.CompileModulesWithOpt(modules, ast.CompileOpts{
EnablePrintStatements: opap.printEnabled,
})
if err != nil { if err != nil {
return nil, fmt.Errorf("in 'runRegoOnK8s', failed to compile rule, name: %s, reason: %w", rule.Name, err) return nil, fmt.Errorf("in 'runRegoOnK8s', failed to compile rule, name: %s, reason: %w", rule.Name, err)
} }
@@ -338,12 +343,20 @@ func (opap *OPAProcessor) runRegoOnK8s(ctx context.Context, rule *reporthandling
return results, nil return results, nil
} }
func (opap *OPAProcessor) Print(ctx opaprint.Context, str string) error {
msg := fmt.Sprintf("opa-print: {%v} - %s", ctx.Location, str)
logger.L().Ctx(ctx.Context).Debug(msg)
return nil
}
func (opap *OPAProcessor) regoEval(ctx context.Context, inputObj []map[string]interface{}, compiledRego *ast.Compiler, store *storage.Store) ([]reporthandling.RuleResponse, error) { func (opap *OPAProcessor) regoEval(ctx context.Context, inputObj []map[string]interface{}, compiledRego *ast.Compiler, store *storage.Store) ([]reporthandling.RuleResponse, error) {
rego := rego.New( rego := rego.New(
rego.Query("data.armo_builtins"), // get package name from rule rego.Query("data.armo_builtins"), // get package name from rule
rego.Compiler(compiledRego), rego.Compiler(compiledRego),
rego.Input(inputObj), rego.Input(inputObj),
rego.Store(*store), rego.Store(*store),
rego.EnablePrintStatements(opap.printEnabled),
rego.PrintHook(opap),
) )
// Run evaluation // Run evaluation

View File

@@ -197,7 +197,7 @@ func TestProcessResourcesResult(t *testing.T) {
opaSessionObj.K8SResources = k8sResources opaSessionObj.K8SResources = k8sResources
opaSessionObj.AllResources[deployment.GetID()] = deployment opaSessionObj.AllResources[deployment.GetID()] = deployment
opap := NewOPAProcessor(opaSessionObj, resources.NewRegoDependenciesDataMock(), "test", "", "") opap := NewOPAProcessor(opaSessionObj, resources.NewRegoDependenciesDataMock(), "test", "", "", false)
opap.AllPolicies = policies opap.AllPolicies = policies
opap.Process(context.TODO(), policies, nil) opap.Process(context.TODO(), policies, nil)

View File

@@ -184,6 +184,7 @@ func defaultScanInfo() *cautils.ScanInfo {
scanInfo.Format = envToString("KS_FORMAT", "json") // default output should be json scanInfo.Format = envToString("KS_FORMAT", "json") // default output should be json
scanInfo.Submit = envToBool("KS_SUBMIT", false) // publish results to Kubescape SaaS scanInfo.Submit = envToBool("KS_SUBMIT", false) // publish results to Kubescape SaaS
scanInfo.Local = envToBool("KS_KEEP_LOCAL", false) // do not publish results to Kubescape SaaS scanInfo.Local = envToBool("KS_KEEP_LOCAL", false) // do not publish results to Kubescape SaaS
scanInfo.EnableRegoPrint = envToBool("KS_REGO_PRINT", false) // print rego rules
scanInfo.HostSensorEnabled.SetBool(envToBool("KS_ENABLE_HOST_SCANNER", false)) // enable host scanner scanInfo.HostSensorEnabled.SetBool(envToBool("KS_ENABLE_HOST_SCANNER", false)) // enable host scanner
if !envToBool("KS_DOWNLOAD_ARTIFACTS", false) { if !envToBool("KS_DOWNLOAD_ARTIFACTS", false) {
scanInfo.UseArtifactsFrom = getter.DefaultLocalStore // Load files from cache (this will prevent kubescape fom downloading the artifacts every time) scanInfo.UseArtifactsFrom = getter.DefaultLocalStore // Load files from cache (this will prevent kubescape fom downloading the artifacts every time)