mirror of
https://github.com/kubescape/kubescape.git
synced 2026-02-14 18:09:55 +00:00
fixed stdin support
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
package cautils
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/armosec/kubescape/cautils/getter"
|
||||
@@ -69,24 +67,6 @@ func (scanInfo *ScanInfo) setUseFrom() {
|
||||
}
|
||||
}
|
||||
|
||||
func (scanInfo *ScanInfo) SetInputPatterns(args []string) error {
|
||||
if args[1] != "-" {
|
||||
scanInfo.InputPatterns = args[1:]
|
||||
} else { // store stout to file
|
||||
tempFile, err := os.CreateTemp(".", "tmp-kubescape*.yaml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.Remove(tempFile.Name())
|
||||
|
||||
if _, err := io.Copy(tempFile, os.Stdin); err != nil {
|
||||
return err
|
||||
}
|
||||
scanInfo.InputPatterns = []string{tempFile.Name()}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (scanInfo *ScanInfo) setOutputFile() {
|
||||
if scanInfo.Output == "" {
|
||||
return
|
||||
@@ -107,20 +87,20 @@ func (scanInfo *ScanInfo) ScanRunningCluster() bool {
|
||||
return len(scanInfo.InputPatterns) == 0
|
||||
}
|
||||
|
||||
func (scanInfo *ScanInfo) SetPolicyIdentifierForGivenFrameworks(frameworks []string) {
|
||||
for _, framework := range frameworks {
|
||||
if !scanInfo.contains(framework) {
|
||||
func (scanInfo *ScanInfo) SetPolicyIdentifiers(policies []string, kind reporthandling.NotificationPolicyKind) {
|
||||
for _, policy := range policies {
|
||||
if !scanInfo.contains(policy) {
|
||||
newPolicy := reporthandling.PolicyIdentifier{}
|
||||
newPolicy.Kind = reporthandling.KindFramework
|
||||
newPolicy.Name = framework
|
||||
newPolicy.Kind = kind // reporthandling.KindFramework
|
||||
newPolicy.Name = policy
|
||||
scanInfo.PolicyIdentifier = append(scanInfo.PolicyIdentifier, newPolicy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (scanInfo *ScanInfo) contains(framework string) bool {
|
||||
func (scanInfo *ScanInfo) contains(policyName string) bool {
|
||||
for _, policy := range scanInfo.PolicyIdentifier {
|
||||
if policy.Name == framework {
|
||||
if policy.Name == policyName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
@@ -21,7 +22,7 @@ var controlCmd = &cobra.Command{
|
||||
controls := strings.Split(args[0], ",")
|
||||
if len(controls) > 1 {
|
||||
if controls[1] == "" {
|
||||
return fmt.Errorf("usage: <control_one>,<control_two>")
|
||||
return fmt.Errorf("usage: <control-0>,<control-1>")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -34,23 +35,31 @@ var controlCmd = &cobra.Command{
|
||||
scanInfo.PolicyIdentifier = []reporthandling.PolicyIdentifier{}
|
||||
|
||||
if len(args) == 0 {
|
||||
scanInfo.SetPolicyIdentifierForGivenFrameworks(getter.NativeFrameworks)
|
||||
} else {
|
||||
controls := strings.Split(args[0], ",")
|
||||
scanInfo.PolicyIdentifier = []reporthandling.PolicyIdentifier{}
|
||||
scanInfo.PolicyIdentifier = setScanForFirstControl(controls)
|
||||
scanInfo.SetPolicyIdentifiers(getter.NativeFrameworks, reporthandling.KindFramework)
|
||||
scanInfo.ScanAll = true
|
||||
} else { // expected control or list of control sepparated by ","
|
||||
|
||||
if len(controls) > 1 {
|
||||
scanInfo.PolicyIdentifier = SetScanForGivenControls(controls[1:])
|
||||
}
|
||||
// Read controls from input args
|
||||
scanInfo.SetPolicyIdentifiers(strings.Split(args[0], ","), reporthandling.KindControl)
|
||||
|
||||
if len(args) > 1 {
|
||||
// Set scan to run on yamls
|
||||
if err := scanInfo.SetInputPatterns(args); err != nil {
|
||||
return err
|
||||
if len(args[1:]) == 0 || args[1] != "-" {
|
||||
scanInfo.InputPatterns = args[1:]
|
||||
} else { // store stdin to file - do NOT move to separate function !!
|
||||
tempFile, err := os.CreateTemp(".", "tmp-kubescape*.yaml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.Remove(tempFile.Name())
|
||||
|
||||
if _, err := io.Copy(tempFile, os.Stdin); err != nil {
|
||||
return err
|
||||
}
|
||||
scanInfo.InputPatterns = []string{tempFile.Name()}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scanInfo.FrameworkScan = false
|
||||
scanInfo.Init()
|
||||
cautils.SetSilentMode(scanInfo.Silent)
|
||||
|
||||
@@ -2,6 +2,7 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
@@ -18,34 +19,48 @@ var frameworkCmd = &cobra.Command{
|
||||
Long: "Execute a scan on a running Kubernetes cluster or `yaml`/`json` files (use glob) or `-` for stdin",
|
||||
ValidArgs: getter.NativeFrameworks,
|
||||
Args: func(cmd *cobra.Command, args []string) error {
|
||||
if len(args) == 0 {
|
||||
if len(args) > 0 {
|
||||
frameworks := strings.Split(args[0], ",")
|
||||
if len(frameworks) > 1 {
|
||||
if frameworks[1] == "" {
|
||||
return fmt.Errorf("usage: <framework-0>,<framework-1>")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("requires at least one framework name")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
flagValidationFramework()
|
||||
scanInfo.PolicyIdentifier = []reporthandling.PolicyIdentifier{}
|
||||
// If no framework provided, use all
|
||||
if len(args) == 0 {
|
||||
scanInfo.SetPolicyIdentifierForGivenFrameworks(getter.NativeFrameworks)
|
||||
var frameworks []string
|
||||
|
||||
if len(args) == 0 { // scan all frameworks
|
||||
frameworks = getter.NativeFrameworks
|
||||
scanInfo.ScanAll = true
|
||||
} 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.SetPolicyIdentifierForGivenFrameworks(frameworks[1:])
|
||||
}
|
||||
frameworks = strings.Split(args[0], ",")
|
||||
|
||||
if len(args) > 1 {
|
||||
// expected yaml/url input
|
||||
if err := scanInfo.SetInputPatterns(args); err != nil {
|
||||
return err
|
||||
if len(args[1:]) == 0 || args[1] != "-" {
|
||||
scanInfo.InputPatterns = args[1:]
|
||||
} else { // store stdin to file - do NOT move to separate function !!
|
||||
tempFile, err := os.CreateTemp(".", "tmp-kubescape*.yaml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.Remove(tempFile.Name())
|
||||
|
||||
if _, err := io.Copy(tempFile, os.Stdin); err != nil {
|
||||
return err
|
||||
}
|
||||
scanInfo.InputPatterns = []string{tempFile.Name()}
|
||||
}
|
||||
}
|
||||
}
|
||||
scanInfo.SetPolicyIdentifiers(frameworks, reporthandling.KindFramework)
|
||||
|
||||
scanInfo.Init()
|
||||
cautils.SetSilentMode(scanInfo.Silent)
|
||||
err := clihandler.ScanCliSetup(&scanInfo)
|
||||
@@ -62,13 +77,13 @@ func init() {
|
||||
scanInfo.FrameworkScan = true
|
||||
}
|
||||
|
||||
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 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 {
|
||||
|
||||
@@ -101,9 +101,10 @@ func setPolicyGetter(scanInfo *cautils.ScanInfo, customerGUID string) {
|
||||
if scanInfo.ScanAll {
|
||||
frameworks, err := g.ListCustomFrameworks(customerGUID)
|
||||
if err != nil {
|
||||
glog.Error("could not get custom frameworks")
|
||||
glog.Error("failed to get custom frameworks") // handle error
|
||||
return
|
||||
}
|
||||
scanInfo.SetPolicyIdentifierForGivenFrameworks(frameworks)
|
||||
scanInfo.SetPolicyIdentifiers(frameworks, reporthandling.KindFramework)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,10 +27,10 @@ e.g. When a `kube-system` resource fails and it is ok, simply add the resource t
|
||||
|
||||
## Usage
|
||||
|
||||
The `resources` list and `posturePolicies` list are design to be a combination of the resources sand policies to exclude
|
||||
The `resources` list and `posturePolicies` list are design to be a combination of the resources and policies to exclude
|
||||
> You must declare at least one resource and one policy
|
||||
|
||||
e.g. If you wish to exclude all namespaces with the label "environment": "dev", the resource list should look as following:
|
||||
e.g. If you wish to exclude all namespaces with the label `"environment": "dev"`, the resource list should look as following:
|
||||
```
|
||||
"resources": [
|
||||
{
|
||||
@@ -43,7 +43,7 @@ e.g. If you wish to exclude all namespaces with the label "environment": "dev",
|
||||
]
|
||||
```
|
||||
|
||||
But if you wish to exclude all namespaces **OR** any resource with the label "environment": "dev", the resource list should look as following:
|
||||
But if you wish to exclude all namespaces **OR** any resource with the label `"environment": "dev"`, the resource list should look as following:
|
||||
```
|
||||
"resources": [
|
||||
{
|
||||
@@ -63,17 +63,17 @@ But if you wish to exclude all namespaces **OR** any resource with the label "en
|
||||
|
||||
Same works with the `posturePolicies` list ->
|
||||
|
||||
e.g. If you wish to exclude the resources decleared in the `resources` list that faild when scanning the `NSA` framework **AND** failed the `Allowed hostPath` control, the `posturePolicies` list should look as following:
|
||||
e.g. If you wish to exclude the resources declared in the `resources` list that failed when scanning the `NSA` framework **AND** failed the `Allowed hostPath` control, the `posturePolicies` list should look as following:
|
||||
```
|
||||
"posturePolicies": [
|
||||
{
|
||||
"frameworkName": "NSA"
|
||||
"frameworkName": "NSA",
|
||||
"controlName": "Allowed hostPath"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
But if you wish to exclude the resources decleared in the `resources` list that faild when scanning the `NSA` framework **OR** failed the `Allowed hostPath` control, the `posturePolicies` list should look as following:
|
||||
But if you wish to exclude the resources declared in the `resources` list that failed when scanning the `NSA` framework **OR** failed the `Allowed hostPath` control, the `posturePolicies` list should look as following:
|
||||
```
|
||||
"posturePolicies": [
|
||||
{
|
||||
|
||||
@@ -7,7 +7,13 @@ def get_exec_from_args(args: list):
|
||||
|
||||
def run_command(command):
|
||||
try:
|
||||
return f"{subprocess.check_output(command, stderr=subprocess.STDOUT)}"
|
||||
return f"{subprocess.check_output(command, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)}"
|
||||
except Exception as e:
|
||||
return f"{e}"
|
||||
|
||||
|
||||
def assertion(msg):
|
||||
errors = ["Error: invalid parameter", "exit status 1"]
|
||||
for e in errors:
|
||||
assert e not in msg, msg
|
||||
|
||||
|
||||
@@ -3,15 +3,71 @@ import smoke_utils
|
||||
import sys
|
||||
|
||||
|
||||
def full_scan(kubescape_exec: str):
|
||||
return smoke_utils.run_command(command=[kubescape_exec, "scan", "framework", "nsa", os.path.join("..", "*.yaml")])
|
||||
all_files = os.path.join("..", "examples", "online-boutique", "*.yaml")
|
||||
single_file = os.path.join("..", "examples", "online-boutique", "frontend.yaml")
|
||||
|
||||
|
||||
def scan_all(kubescape_exec: str):
|
||||
return smoke_utils.run_command(command=[kubescape_exec, "scan", all_files])
|
||||
|
||||
|
||||
def scan_control_name(kubescape_exec: str):
|
||||
return smoke_utils.run_command(command=[kubescape_exec, "scan", "control", 'Allowed hostPath', all_files])
|
||||
|
||||
|
||||
def scan_control_id(kubescape_exec: str):
|
||||
return smoke_utils.run_command(command=[kubescape_exec, "scan", "control", 'C-0006', all_files])
|
||||
|
||||
|
||||
def scan_controls(kubescape_exec: str):
|
||||
return smoke_utils.run_command(command=[kubescape_exec, "scan", "control", 'Allowed hostPath,Allow privilege escalation', all_files])
|
||||
|
||||
|
||||
def scan_framework(kubescape_exec: str):
|
||||
return smoke_utils.run_command(command=[kubescape_exec, "scan", "framework", "nsa", all_files])
|
||||
|
||||
|
||||
def scan_frameworks(kubescape_exec: str):
|
||||
return smoke_utils.run_command(command=[kubescape_exec, "scan", "framework", "nsa,mitre,armobest", all_files])
|
||||
|
||||
|
||||
def scan_from_stdin(kubescape_exec: str):
|
||||
return smoke_utils.run_command(command=["cat", single_file, "|", kubescape_exec, "scan", "framework", "nsa", "-"])
|
||||
|
||||
|
||||
def run(kubescape_exec: str):
|
||||
# return
|
||||
print("Testing E2E yaml files")
|
||||
msg = full_scan(kubescape_exec=kubescape_exec)
|
||||
assert "exit status 1" not in msg, msg
|
||||
print("Testing E2E on yaml files")
|
||||
|
||||
# TODO - fix support
|
||||
# print("Testing scan all yaml files")
|
||||
# msg = scan_all(kubescape_exec=kubescape_exec)
|
||||
# smoke_utils.assertion(msg)
|
||||
|
||||
print("Testing scan control name")
|
||||
msg = scan_control_name(kubescape_exec=kubescape_exec)
|
||||
smoke_utils.assertion(msg)
|
||||
|
||||
print("Testing scan control id")
|
||||
msg = scan_control_id(kubescape_exec=kubescape_exec)
|
||||
smoke_utils.assertion(msg)
|
||||
|
||||
print("Testing scan controls")
|
||||
msg = scan_controls(kubescape_exec=kubescape_exec)
|
||||
smoke_utils.assertion(msg)
|
||||
|
||||
print("Testing scan framework")
|
||||
msg = scan_framework(kubescape_exec=kubescape_exec)
|
||||
smoke_utils.assertion(msg)
|
||||
|
||||
print("Testing scan frameworks")
|
||||
msg = scan_frameworks(kubescape_exec=kubescape_exec)
|
||||
smoke_utils.assertion(msg)
|
||||
|
||||
# TODO - fix test
|
||||
# print("Testing scan from stdin")
|
||||
# msg = scan_from_stdin(kubescape_exec=kubescape_exec)
|
||||
# smoke_utils.assertion(msg)
|
||||
|
||||
print("Done E2E yaml files")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user