mirror of
https://github.com/kubescape/kubescape.git
synced 2026-04-15 06:58:11 +00:00
Merge remote-tracking branch 'upstream/dev'
This commit is contained in:
@@ -129,7 +129,7 @@ func (c *EmptyConfig) GetCustomerGUID() string { return "" }
|
||||
func (c *EmptyConfig) GetK8sAPI() *k8sinterface.KubernetesApi { return nil } // TODO: return mock obj
|
||||
func (c *EmptyConfig) GetDefaultNS() string { return k8sinterface.GetDefaultNamespace() }
|
||||
func (c *EmptyConfig) GetBackendAPI() getter.IBackend { return nil } // TODO: return mock obj
|
||||
func (c *EmptyConfig) GetClusterName() string { return k8sinterface.GetClusterName() }
|
||||
func (c *EmptyConfig) GetClusterName() string { return adoptClusterName(k8sinterface.GetClusterName()) }
|
||||
func (c *EmptyConfig) GenerateURL() {
|
||||
message := fmt.Sprintf("\nCheckout for more cool features: https://%s\n", getter.GetArmoAPIConnector().GetFrontendURL())
|
||||
InfoTextDisplay(os.Stdout, fmt.Sprintf("\n%s\n", message))
|
||||
@@ -243,7 +243,7 @@ func (c *ClusterConfig) setCustomerGUID(customerGUID string) {
|
||||
}
|
||||
|
||||
func (c *ClusterConfig) setClusterName(clusterName string) {
|
||||
c.configObj.ClusterName = clusterName
|
||||
c.configObj.ClusterName = adoptClusterName(clusterName)
|
||||
}
|
||||
func (c *ClusterConfig) GetClusterName() string {
|
||||
return c.configObj.ClusterName
|
||||
@@ -472,3 +472,7 @@ func DeleteConfigMap(k8s *k8sinterface.KubernetesApi) error {
|
||||
func DeleteConfigFile() error {
|
||||
return os.Remove(ConfigFileFullPath())
|
||||
}
|
||||
|
||||
func adoptClusterName(clusterName string) string {
|
||||
return strings.ReplaceAll(clusterName, "/", "-")
|
||||
}
|
||||
|
||||
@@ -17,12 +17,12 @@ const DefaultLocalStore = ".kubescape"
|
||||
|
||||
// Load policies from a local repository
|
||||
type LoadPolicy struct {
|
||||
filePath string
|
||||
filePaths []string
|
||||
}
|
||||
|
||||
func NewLoadPolicy(filePath string) *LoadPolicy {
|
||||
func NewLoadPolicy(filePaths []string) *LoadPolicy {
|
||||
return &LoadPolicy{
|
||||
filePath: filePath,
|
||||
filePaths: filePaths,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@ func NewLoadPolicy(filePath string) *LoadPolicy {
|
||||
func (lp *LoadPolicy) GetControl(controlName string) (*reporthandling.Control, error) {
|
||||
|
||||
control := &reporthandling.Control{}
|
||||
f, err := os.ReadFile(lp.filePath)
|
||||
filePath := lp.getFileForControl()
|
||||
f, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -38,35 +39,49 @@ func (lp *LoadPolicy) GetControl(controlName string) (*reporthandling.Control, e
|
||||
if err = json.Unmarshal(f, control); err != nil {
|
||||
return control, err
|
||||
}
|
||||
|
||||
if controlName != "" && !strings.EqualFold(controlName, control.Name) && !strings.EqualFold(controlName, control.ControlID) {
|
||||
return nil, fmt.Errorf("control from file not matching")
|
||||
framework, err := lp.GetFramework(controlName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("control from file not matching")
|
||||
} else {
|
||||
for _, ctrl := range framework.Controls {
|
||||
if strings.EqualFold(ctrl.Name, controlName) || strings.EqualFold(ctrl.ControlID, controlName) {
|
||||
control = &ctrl
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return control, err
|
||||
}
|
||||
|
||||
func (lp *LoadPolicy) GetFramework(frameworkName string) (*reporthandling.Framework, error) {
|
||||
|
||||
framework := &reporthandling.Framework{}
|
||||
f, err := os.ReadFile(lp.filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var err error
|
||||
for _, filePath := range lp.filePaths {
|
||||
f, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = json.Unmarshal(f, framework); err != nil {
|
||||
return framework, err
|
||||
if err = json.Unmarshal(f, framework); err != nil {
|
||||
return framework, err
|
||||
}
|
||||
if strings.EqualFold(frameworkName, framework.Name) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if frameworkName != "" && !strings.EqualFold(frameworkName, framework.Name) {
|
||||
|
||||
return nil, fmt.Errorf("framework from file not matching")
|
||||
}
|
||||
return framework, err
|
||||
}
|
||||
|
||||
func (lp *LoadPolicy) GetExceptions(customerGUID, clusterName string) ([]armotypes.PostureExceptionPolicy, error) {
|
||||
|
||||
filePath := lp.getFileForException()
|
||||
exception := []armotypes.PostureExceptionPolicy{}
|
||||
f, err := os.ReadFile(lp.filePath)
|
||||
f, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -74,3 +89,11 @@ func (lp *LoadPolicy) GetExceptions(customerGUID, clusterName string) ([]armotyp
|
||||
err = json.Unmarshal(f, &exception)
|
||||
return exception, err
|
||||
}
|
||||
|
||||
func (lp *LoadPolicy) getFileForException() string {
|
||||
return lp.filePaths[0]
|
||||
}
|
||||
|
||||
func (lp *LoadPolicy) getFileForControl() string {
|
||||
return lp.filePaths[0]
|
||||
}
|
||||
|
||||
+7
-8
@@ -9,9 +9,9 @@ import (
|
||||
|
||||
type ScanInfo struct {
|
||||
Getters
|
||||
PolicyIdentifier reporthandling.PolicyIdentifier
|
||||
PolicyIdentifier []reporthandling.PolicyIdentifier
|
||||
UseExceptions string // Load exceptions configuration
|
||||
UseFrom string // Load framework from local file (instead of download). Use when running offline
|
||||
UseFrom []string // Load framework from local file (instead of download). Use when running offline
|
||||
UseDefault bool // Load framework from cached file (instead of download). Use when running offline
|
||||
Format string // Format results (table, json, junit ...)
|
||||
Output string // Store results in an output file, Output file name
|
||||
@@ -41,22 +41,21 @@ func (scanInfo *ScanInfo) Init() {
|
||||
func (scanInfo *ScanInfo) setUseExceptions() {
|
||||
if scanInfo.UseExceptions != "" {
|
||||
// load exceptions from file
|
||||
scanInfo.ExceptionsGetter = getter.NewLoadPolicy(scanInfo.UseExceptions)
|
||||
scanInfo.ExceptionsGetter = getter.NewLoadPolicy([]string{scanInfo.UseExceptions})
|
||||
} else {
|
||||
scanInfo.ExceptionsGetter = getter.GetArmoAPIConnector()
|
||||
}
|
||||
|
||||
}
|
||||
func (scanInfo *ScanInfo) setUseFrom() {
|
||||
if scanInfo.UseFrom != "" {
|
||||
return
|
||||
}
|
||||
if scanInfo.UseDefault {
|
||||
scanInfo.UseFrom = getter.GetDefaultPath(scanInfo.PolicyIdentifier.Name + ".json")
|
||||
for _, policy := range scanInfo.PolicyIdentifier {
|
||||
scanInfo.UseFrom = append(scanInfo.UseFrom, getter.GetDefaultPath(policy.Name+".json"))
|
||||
}
|
||||
}
|
||||
}
|
||||
func (scanInfo *ScanInfo) setGetter() {
|
||||
if scanInfo.UseFrom != "" {
|
||||
if len(scanInfo.UseFrom) > 0 {
|
||||
// load from file
|
||||
scanInfo.PolicyGetter = getter.NewLoadPolicy(scanInfo.UseFrom)
|
||||
} else {
|
||||
|
||||
@@ -13,22 +13,40 @@ import (
|
||||
|
||||
// controlCmd represents the control command
|
||||
var controlCmd = &cobra.Command{
|
||||
Use: "control <control name>/<control id>",
|
||||
Use: "control <control names list>/<control ids list>.\nExamples:\n$ kubescape scan control C-0058,C-0057 [flags]\n$ kubescape scan contol C-0058 [flags]\n$ kubescape scan control 'privileged container,allowed hostpath' [flags]",
|
||||
Short: fmt.Sprintf("The control you wish to use for scan. It must be present in at least one of the folloiwng frameworks: %s", clihandler.ValidFrameworks),
|
||||
Args: func(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 && !(cmd.Flags().Lookup("use-from").Changed) {
|
||||
return fmt.Errorf("requires at least one argument")
|
||||
if len(args) > 0 {
|
||||
controls := strings.Split(args[0], ",")
|
||||
if len(controls) > 1 {
|
||||
if controls[1] == "" {
|
||||
return fmt.Errorf("usage: <control_one>,<control_two>")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("requires at least one control name")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
flagValidationControl()
|
||||
scanInfo.PolicyIdentifier = reporthandling.PolicyIdentifier{}
|
||||
if !(cmd.Flags().Lookup("use-from").Changed) {
|
||||
scanInfo.PolicyIdentifier.Name = strings.ToLower(args[0])
|
||||
scanInfo.PolicyIdentifier = []reporthandling.PolicyIdentifier{}
|
||||
|
||||
if len(args) < 1 {
|
||||
scanInfo.PolicyIdentifier = SetScanForGivenFrameworks(clihandler.SupportedFrameworks)
|
||||
} else {
|
||||
var controls []string
|
||||
if len(args) > 0 {
|
||||
controls = strings.Split(args[0], ",")
|
||||
scanInfo.PolicyIdentifier = []reporthandling.PolicyIdentifier{}
|
||||
scanInfo.PolicyIdentifier = setScanForFirstControl(controls)
|
||||
}
|
||||
|
||||
if len(controls) > 1 {
|
||||
scanInfo.PolicyIdentifier = SetScanForGivenControls(controls[1:])
|
||||
}
|
||||
}
|
||||
scanInfo.FrameworkScan = false
|
||||
scanInfo.PolicyIdentifier.Kind = reporthandling.KindControl
|
||||
scanInfo.Init()
|
||||
cautils.SetSilentMode(scanInfo.Silent)
|
||||
err := clihandler.CliSetup(&scanInfo)
|
||||
@@ -51,3 +69,22 @@ func flagValidationControl() {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func setScanForFirstControl(controls []string) []reporthandling.PolicyIdentifier {
|
||||
newPolicy := reporthandling.PolicyIdentifier{}
|
||||
newPolicy.Kind = reporthandling.KindControl
|
||||
newPolicy.Name = controls[0]
|
||||
scanInfo.PolicyIdentifier = append(scanInfo.PolicyIdentifier, newPolicy)
|
||||
return scanInfo.PolicyIdentifier
|
||||
}
|
||||
|
||||
func SetScanForGivenControls(controls []string) []reporthandling.PolicyIdentifier {
|
||||
for _, control := range controls {
|
||||
control := strings.TrimLeft(control, " ")
|
||||
newPolicy := reporthandling.PolicyIdentifier{}
|
||||
newPolicy.Kind = reporthandling.KindControl
|
||||
newPolicy.Name = control
|
||||
scanInfo.PolicyIdentifier = append(scanInfo.PolicyIdentifier, newPolicy)
|
||||
}
|
||||
return scanInfo.PolicyIdentifier
|
||||
}
|
||||
|
||||
+38
-13
@@ -9,32 +9,42 @@ import (
|
||||
"github.com/armosec/kubescape/cautils"
|
||||
"github.com/armosec/kubescape/clihandler"
|
||||
"github.com/armosec/opa-utils/reporthandling"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var frameworkCmd = &cobra.Command{
|
||||
|
||||
Use: fmt.Sprintf("framework <framework name> [`<glob pattern>`/`-`] [flags]\nSupported frameworks: %s", clihandler.ValidFrameworks),
|
||||
Use: fmt.Sprintf("framework <framework names list> [`<glob pattern>`/`-`] [flags]\nExamples:\n$ kubescape scan framework nsa [flags]\n$ kubescape scan framework mitre,nsa [flags]\n$ kubescape scan framework 'nsa, mitre' [flags]\nSupported frameworks: %s", clihandler.ValidFrameworks),
|
||||
Short: fmt.Sprintf("The framework you wish to use. Supported frameworks: %s", strings.Join(clihandler.SupportedFrameworks, ", ")),
|
||||
Long: "Execute a scan on a running Kubernetes cluster or `yaml`/`json` files (use glob) or `-` for stdin",
|
||||
ValidArgs: clihandler.SupportedFrameworks,
|
||||
Args: func(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 && !(cmd.Flags().Lookup("use-from").Changed) {
|
||||
return fmt.Errorf("requires at least one argument")
|
||||
} else if len(args) > 0 {
|
||||
if !isValidFramework(strings.ToLower(args[0])) {
|
||||
return fmt.Errorf(fmt.Sprintf("supported frameworks: %s", strings.Join(clihandler.SupportedFrameworks, ", ")))
|
||||
if len(args) > 0 {
|
||||
// "nsa, mitre" -> ["nsa", "mitre"] and nsa,mitre -> ["nsa", "mitre"]
|
||||
frameworks := strings.Split(strings.Join(strings.Fields(args[0]), ""), ",")
|
||||
for _, framework := range frameworks {
|
||||
if !isValidFramework(strings.ToLower(framework)) {
|
||||
return fmt.Errorf(fmt.Sprintf("supported frameworks: %s", strings.Join(clihandler.SupportedFrameworks, ", ")))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("requires at least one framework name")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
scanInfo.PolicyIdentifier = reporthandling.PolicyIdentifier{}
|
||||
scanInfo.PolicyIdentifier.Kind = reporthandling.KindFramework
|
||||
flagValidationFramework()
|
||||
if !(cmd.Flags().Lookup("use-from").Changed) {
|
||||
scanInfo.PolicyIdentifier.Name = strings.ToLower(args[0])
|
||||
scanInfo.PolicyIdentifier = []reporthandling.PolicyIdentifier{}
|
||||
// If no framework provided, use all
|
||||
if len(args) < 1 {
|
||||
scanInfo.PolicyIdentifier = SetScanForGivenFrameworks(clihandler.SupportedFrameworks)
|
||||
} else {
|
||||
// Read frameworks from input args
|
||||
scanInfo.PolicyIdentifier = []reporthandling.PolicyIdentifier{}
|
||||
frameworks := strings.Split(strings.Join(strings.Fields(args[0]), ""), ",")
|
||||
scanInfo.PolicyIdentifier = SetScanForFirstFramework(frameworks)
|
||||
if len(frameworks) > 1 {
|
||||
scanInfo.PolicyIdentifier = SetScanForGivenFrameworks(frameworks[1:])
|
||||
}
|
||||
}
|
||||
if len(args) > 0 {
|
||||
if len(args[1:]) == 0 || args[1] != "-" {
|
||||
@@ -74,11 +84,26 @@ func init() {
|
||||
frameworkCmd.Flags().BoolVarP(&scanInfo.Submit, "submit", "", false, "Send the scan results to Armo management portal 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")
|
||||
frameworkCmd.Flags().BoolVarP(&scanInfo.Local, "keep-local", "", false, "If you do not want your Kubescape results reported to Armo backend. Use this flag if you ran with the '--submit' flag in the past and you do not want to submit your current scan results")
|
||||
frameworkCmd.Flags().StringVarP(&scanInfo.Account, "account", "", "", "Armo portal account ID. Default will load account ID from configMap or config file")
|
||||
}
|
||||
func SetScanForGivenFrameworks(frameworks []string) []reporthandling.PolicyIdentifier {
|
||||
for _, framework := range frameworks {
|
||||
newPolicy := reporthandling.PolicyIdentifier{}
|
||||
newPolicy.Kind = reporthandling.KindFramework
|
||||
newPolicy.Name = framework
|
||||
scanInfo.PolicyIdentifier = append(scanInfo.PolicyIdentifier, newPolicy)
|
||||
}
|
||||
return scanInfo.PolicyIdentifier
|
||||
}
|
||||
|
||||
func SetScanForFirstFramework(frameworks []string) []reporthandling.PolicyIdentifier {
|
||||
newPolicy := reporthandling.PolicyIdentifier{}
|
||||
newPolicy.Kind = reporthandling.KindFramework
|
||||
newPolicy.Name = frameworks[0]
|
||||
scanInfo.PolicyIdentifier = append(scanInfo.PolicyIdentifier, newPolicy)
|
||||
return scanInfo.PolicyIdentifier
|
||||
}
|
||||
|
||||
func flagValidationFramework() {
|
||||
|
||||
if scanInfo.Submit && scanInfo.Local {
|
||||
fmt.Println("You can use `keep-local` or `submit`, but not both")
|
||||
os.Exit(1)
|
||||
|
||||
+12
-7
@@ -5,6 +5,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/armosec/kubescape/cautils"
|
||||
"github.com/armosec/kubescape/clihandler"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -16,15 +17,19 @@ var scanCmd = &cobra.Command{
|
||||
Short: "Scan the current running cluster or yaml files",
|
||||
Long: `The action you want to perform`,
|
||||
Args: func(cmd *cobra.Command, args []string) error {
|
||||
if len(args) == 0 {
|
||||
return fmt.Errorf("requires one argument: framework/control")
|
||||
}
|
||||
if !strings.EqualFold(args[0], "framework") && !strings.EqualFold(args[0], "control") {
|
||||
return fmt.Errorf("invalid parameter '%s'. Supported parameters: framework, control", args[0])
|
||||
if len(args) > 0 {
|
||||
if !strings.EqualFold(args[0], "framework") && !strings.EqualFold(args[0], "control") {
|
||||
return fmt.Errorf("invalid parameter '%s'. Supported parameters: framework, control", args[0])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) == 0 {
|
||||
frameworkArgs := []string{clihandler.ValidFrameworks}
|
||||
frameworkArgs = append(frameworkArgs, args...)
|
||||
frameworkCmd.RunE(cmd, frameworkArgs)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -35,7 +40,7 @@ func init() {
|
||||
scanCmd.PersistentFlags().StringVarP(&scanInfo.Output, "output", "o", "", "Output file. Print output to file and not stdout")
|
||||
scanCmd.PersistentFlags().BoolVarP(&scanInfo.Silent, "silent", "s", false, "Silent progress messages")
|
||||
scanCmd.PersistentFlags().Uint16VarP(&scanInfo.FailThreshold, "fail-threshold", "t", 0, "Failure threshold is the percent bellow which the command fails and returns exit code 1")
|
||||
scanCmd.PersistentFlags().StringVar(&scanInfo.UseFrom, "use-from", "", "Load local framework object from specified path. If not used will download latest")
|
||||
scanCmd.PersistentFlags().BoolVar(&scanInfo.UseDefault, "use-default", false, "Load local framework object from default path. If not used will download latest")
|
||||
scanCmd.PersistentFlags().StringSliceVar(&scanInfo.UseFrom, "use-from", nil, "Load local policy object from specified path. If not used will download latest")
|
||||
scanCmd.PersistentFlags().BoolVar(&scanInfo.UseDefault, "use-default", false, "Load local policy object from default path. If not used will download latest")
|
||||
scanCmd.PersistentFlags().StringVar(&scanInfo.UseExceptions, "exceptions", "", "Path to an exceptions obj. If not set will download exceptions from Armo management portal")
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ func GetLatestVersion() (string, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode < 200 || 301 < resp.StatusCode {
|
||||
return "unknown", fmt.Errorf("failed to download file, status code: %s", resp.Status)
|
||||
return "unknown", nil
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
|
||||
@@ -135,10 +135,8 @@ func (clihandler *CLIHandler) Scan() error {
|
||||
cautils.ScanStartDisplay()
|
||||
policyNotification := &reporthandling.PolicyNotification{
|
||||
NotificationType: reporthandling.TypeExecPostureScan,
|
||||
Rules: []reporthandling.PolicyIdentifier{
|
||||
clihandler.scanInfo.PolicyIdentifier,
|
||||
},
|
||||
Designators: armotypes.PortalDesignator{},
|
||||
Rules: clihandler.scanInfo.PolicyIdentifier,
|
||||
Designators: armotypes.PortalDesignator{},
|
||||
}
|
||||
switch policyNotification.NotificationType {
|
||||
case reporthandling.TypeExecPostureScan:
|
||||
|
||||
@@ -5,19 +5,25 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/armosec/kubescape/clihandler/cmd"
|
||||
pkgutils "github.com/armosec/utils-go/utils"
|
||||
)
|
||||
|
||||
const SKIP_VERSION_CHECK = "KUBESCAPE_SKIP_UPDATE_CHECK"
|
||||
|
||||
func main() {
|
||||
CheckLatestVersion()
|
||||
cmd.Execute()
|
||||
}
|
||||
|
||||
func CheckLatestVersion() {
|
||||
if v, ok := os.LookupEnv(SKIP_VERSION_CHECK); ok && pkgutils.StringToBool(v) {
|
||||
return
|
||||
}
|
||||
latest, err := cmd.GetLatestVersion()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||
} else if latest != cmd.BuildNumber {
|
||||
if err != nil || latest == "unknown" {
|
||||
return
|
||||
}
|
||||
if latest != cmd.BuildNumber {
|
||||
fmt.Println("Warning: You are not updated to the latest release: " + latest)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,9 +14,11 @@ func (policyHandler *PolicyHandler) GetPoliciesFromBackend(notification *reporth
|
||||
frameworks := []reporthandling.Framework{}
|
||||
exceptionPolicies := []armotypes.PostureExceptionPolicy{}
|
||||
// Get - cacli opa get
|
||||
for _, rule := range notification.Rules {
|
||||
switch rule.Kind {
|
||||
case reporthandling.KindFramework:
|
||||
rule := GetScanKind(notification)
|
||||
|
||||
switch rule.Kind {
|
||||
case reporthandling.KindFramework:
|
||||
for _, rule := range notification.Rules {
|
||||
receivedFramework, recExceptionPolicies, err := policyHandler.getFrameworkPolicies(rule.Name)
|
||||
if receivedFramework != nil {
|
||||
frameworks = append(frameworks, *receivedFramework)
|
||||
@@ -29,27 +31,32 @@ func (policyHandler *PolicyHandler) GetPoliciesFromBackend(notification *reporth
|
||||
}
|
||||
return nil, nil, fmt.Errorf("kind: %v, name: %s, error: %s", rule.Kind, rule.Name, err.Error())
|
||||
}
|
||||
case reporthandling.KindControl:
|
||||
receivedControls, recExceptionPolicies, err := policyHandler.getControl(rule.Name)
|
||||
if receivedControls != nil {
|
||||
f := reporthandling.Framework{
|
||||
Controls: receivedControls,
|
||||
}
|
||||
frameworks = append(frameworks, f)
|
||||
}
|
||||
case reporthandling.KindControl:
|
||||
f := reporthandling.Framework{}
|
||||
var receivedControl *reporthandling.Control
|
||||
var recExceptionPolicies []armotypes.PostureExceptionPolicy
|
||||
var err error
|
||||
for _, rule := range notification.Rules {
|
||||
receivedControl, recExceptionPolicies, err = policyHandler.getControl(rule.Name)
|
||||
if receivedControl != nil {
|
||||
f.Controls = append(f.Controls, *receivedControl)
|
||||
if recExceptionPolicies != nil {
|
||||
exceptionPolicies = append(exceptionPolicies, recExceptionPolicies...)
|
||||
}
|
||||
|
||||
} else if err != nil {
|
||||
if strings.Contains(err.Error(), "unsupported protocol scheme") {
|
||||
err = fmt.Errorf("failed to download from GitHub release, try running with `--use-default` flag")
|
||||
}
|
||||
return nil, nil, fmt.Errorf("error: %s", err.Error())
|
||||
}
|
||||
// TODO: add case for control from file
|
||||
default:
|
||||
err := fmt.Errorf("missing rule kind, expected: %s", reporthandling.KindFramework)
|
||||
errs = fmt.Errorf("%s", err.Error())
|
||||
}
|
||||
frameworks = append(frameworks, f)
|
||||
// TODO: add case for control from file
|
||||
default:
|
||||
err := fmt.Errorf("missing rule kind, expected: %s", reporthandling.KindFramework)
|
||||
errs = fmt.Errorf("%s", err.Error())
|
||||
}
|
||||
return frameworks, exceptionPolicies, errs
|
||||
}
|
||||
@@ -68,24 +75,30 @@ func (policyHandler *PolicyHandler) getFrameworkPolicies(policyName string) (*re
|
||||
return receivedFramework, receivedException, nil
|
||||
}
|
||||
|
||||
func GetScanKind(notification *reporthandling.PolicyNotification) *reporthandling.PolicyIdentifier {
|
||||
if len(notification.Rules) > 0 {
|
||||
return ¬ification.Rules[0]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get control by name
|
||||
func (policyHandler *PolicyHandler) getControl(policyName string) ([]reporthandling.Control, []armotypes.PostureExceptionPolicy, error) {
|
||||
func (policyHandler *PolicyHandler) getControl(policyName string) (*reporthandling.Control, []armotypes.PostureExceptionPolicy, error) {
|
||||
|
||||
controls := []reporthandling.Control{}
|
||||
|
||||
control, err := policyHandler.getters.PolicyGetter.GetControl(policyName)
|
||||
control := &reporthandling.Control{}
|
||||
var err error
|
||||
control, err = policyHandler.getters.PolicyGetter.GetControl(policyName)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return control, nil, err
|
||||
}
|
||||
if control == nil {
|
||||
return nil, nil, fmt.Errorf("control not found")
|
||||
}
|
||||
controls = append(controls, *control)
|
||||
// if control == nil {
|
||||
// return control, nil, fmt.Errorf("control not found")
|
||||
// }
|
||||
|
||||
exceptions, err := policyHandler.getters.ExceptionsGetter.GetExceptions(cautils.CustomerGUID, cautils.ClusterName)
|
||||
if err != nil {
|
||||
return controls, nil, err
|
||||
return control, nil, err
|
||||
}
|
||||
|
||||
return controls, exceptions, nil
|
||||
return control, exceptions, nil
|
||||
}
|
||||
|
||||
@@ -25,7 +25,15 @@ func (jsonPrinter *JsonPrinter) Score(score float32) {
|
||||
}
|
||||
|
||||
func (jsonPrinter *JsonPrinter) ActionPrint(opaSessionObj *cautils.OPASessionObj) {
|
||||
postureReportStr, err := json.Marshal(opaSessionObj.PostureReport.FrameworkReports[0])
|
||||
var postureReportStr []byte
|
||||
var err error
|
||||
|
||||
if len(opaSessionObj.PostureReport.FrameworkReports) == 1 {
|
||||
postureReportStr, err = json.Marshal(opaSessionObj.PostureReport.FrameworkReports[0])
|
||||
} else {
|
||||
postureReportStr, err = json.Marshal(opaSessionObj.PostureReport.FrameworkReports)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("Failed to convert posture report object!")
|
||||
os.Exit(1)
|
||||
|
||||
@@ -24,12 +24,25 @@ func NewPrettyPrinter() *PrettyPrinter {
|
||||
}
|
||||
}
|
||||
|
||||
// Initializes empty printer for new table
|
||||
func (printer *PrettyPrinter) init() *PrettyPrinter {
|
||||
printer.frameworkSummary = ControlSummary{}
|
||||
printer.summary = Summary{}
|
||||
printer.sortedControlNames = []string{}
|
||||
return printer
|
||||
}
|
||||
|
||||
func (printer *PrettyPrinter) ActionPrint(opaSessionObj *cautils.OPASessionObj) {
|
||||
// score := calculatePostureScore(opaSessionObj.PostureReport)
|
||||
|
||||
printer.summarySetup(opaSessionObj.PostureReport)
|
||||
printer.printResults()
|
||||
printer.printSummaryTable()
|
||||
for _, report := range opaSessionObj.PostureReport.FrameworkReports {
|
||||
// Print summary table together for control scan
|
||||
if report.Name != "" {
|
||||
printer = printer.init()
|
||||
}
|
||||
printer.summarySetup(report)
|
||||
printer.printResults()
|
||||
printer.printSummaryTable(report.Name)
|
||||
}
|
||||
|
||||
// return score
|
||||
}
|
||||
@@ -41,29 +54,27 @@ func (printer *PrettyPrinter) SetWriter(outputFile string) {
|
||||
func (printer *PrettyPrinter) Score(score float32) {
|
||||
}
|
||||
|
||||
func (printer *PrettyPrinter) summarySetup(postureReport *reporthandling.PostureReport) {
|
||||
for _, fr := range postureReport.FrameworkReports {
|
||||
printer.frameworkSummary = ControlSummary{
|
||||
TotalResources: fr.GetNumberOfResources(),
|
||||
TotalFailed: fr.GetNumberOfFailedResources(),
|
||||
TotalWarnign: fr.GetNumberOfWarningResources(),
|
||||
func (printer *PrettyPrinter) summarySetup(fr reporthandling.FrameworkReport) {
|
||||
printer.frameworkSummary = ControlSummary{
|
||||
TotalResources: fr.GetNumberOfResources(),
|
||||
TotalFailed: fr.GetNumberOfFailedResources(),
|
||||
TotalWarnign: fr.GetNumberOfWarningResources(),
|
||||
}
|
||||
for _, cr := range fr.ControlReports {
|
||||
if len(cr.RuleReports) == 0 {
|
||||
continue
|
||||
}
|
||||
for _, cr := range fr.ControlReports {
|
||||
if len(cr.RuleReports) == 0 {
|
||||
continue
|
||||
}
|
||||
workloadsSummary := listResultSummary(cr.RuleReports)
|
||||
workloadsSummary := listResultSummary(cr.RuleReports)
|
||||
|
||||
printer.summary[cr.Name] = ControlSummary{
|
||||
TotalResources: cr.GetNumberOfResources(),
|
||||
TotalFailed: cr.GetNumberOfFailedResources(),
|
||||
TotalWarnign: cr.GetNumberOfWarningResources(),
|
||||
FailedWorkloads: groupByNamespace(workloadsSummary, workloadSummaryFailed),
|
||||
ExcludedWorkloads: groupByNamespace(workloadsSummary, workloadSummaryExclude),
|
||||
Description: cr.Description,
|
||||
Remediation: cr.Remediation,
|
||||
ListInputKinds: cr.ListControlsInputKinds(),
|
||||
}
|
||||
printer.summary[cr.Name] = ControlSummary{
|
||||
TotalResources: cr.GetNumberOfResources(),
|
||||
TotalFailed: cr.GetNumberOfFailedResources(),
|
||||
TotalWarnign: cr.GetNumberOfWarningResources(),
|
||||
FailedWorkloads: groupByNamespace(workloadsSummary, workloadSummaryFailed),
|
||||
ExcludedWorkloads: groupByNamespace(workloadsSummary, workloadSummaryExclude),
|
||||
Description: cr.Description,
|
||||
Remediation: cr.Remediation,
|
||||
ListInputKinds: cr.ListControlsInputKinds(),
|
||||
}
|
||||
}
|
||||
printer.sortedControlNames = printer.getSortedControlsNames()
|
||||
@@ -179,7 +190,10 @@ func generateFooter(numControlers, sumFailed, sumWarning, sumTotal int) []string
|
||||
}
|
||||
return row
|
||||
}
|
||||
func (printer *PrettyPrinter) printSummaryTable() {
|
||||
func (printer *PrettyPrinter) printSummaryTable(framework string) {
|
||||
// For control scan framework will be nil
|
||||
printer.printFramework(framework)
|
||||
|
||||
summaryTable := tablewriter.NewWriter(printer.writer)
|
||||
summaryTable.SetAutoWrapText(false)
|
||||
summaryTable.SetHeader(generateHeader())
|
||||
@@ -195,6 +209,12 @@ func (printer *PrettyPrinter) printSummaryTable() {
|
||||
summaryTable.Render()
|
||||
}
|
||||
|
||||
func (printer *PrettyPrinter) printFramework(framework string) {
|
||||
if framework != "" {
|
||||
cautils.InfoTextDisplay(printer.writer, fmt.Sprintf("%s FRAMEWORK\n", framework))
|
||||
}
|
||||
}
|
||||
|
||||
func (printer *PrettyPrinter) getSortedControlsNames() []string {
|
||||
controlNames := make([]string, 0, len(printer.summary))
|
||||
for k := range printer.summary {
|
||||
|
||||
Reference in New Issue
Block a user