mirror of
https://github.com/kubescape/kubescape.git
synced 2026-02-14 18:09:55 +00:00
Implementing capability to print out the "print" statements of the rego
Signed-off-by: Ben <ben@armosec.io>
This commit is contained in:
@@ -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")
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user