Merge pull request #975 from kooomix/dev

control scan and download only by id
This commit is contained in:
David Wertenteil
2022-12-22 16:56:40 +02:00
committed by GitHub
13 changed files with 62 additions and 55 deletions

View File

@@ -24,8 +24,8 @@ var (
# Download the NSA framework. Run 'kubescape list frameworks' for all frameworks names
kubescape download framework nsa
# Download the "HostPath mount" control. Run 'kubescape list controls' for all controls names
kubescape download control "HostPath mount"
# Download the "C-0001" control. Run 'kubescape list controls --id' for all controls ids
kubescape download control "C-0001"
# Download the "C-0001" control. Run 'kubescape list controls --id' for all controls ids
kubescape download control C-0001
@@ -70,7 +70,9 @@ func GeDownloadCmd(ks meta.IKubescape) *cobra.Command {
}
downloadInfo.Target = args[0]
if len(args) >= 2 {
downloadInfo.Name = args[1]
downloadInfo.Identifier = args[1]
}
if err := ks.Download(&downloadInfo); err != nil {
logger.L().Fatal(err.Error())

View File

@@ -25,11 +25,11 @@ func NewDownloadReleasedPolicy() *DownloadReleasedPolicy {
}
}
func (drp *DownloadReleasedPolicy) GetControl(policyName string) (*reporthandling.Control, error) {
func (drp *DownloadReleasedPolicy) GetControl(ID string) (*reporthandling.Control, error) {
var control *reporthandling.Control
var err error
control, err = drp.gs.GetOPAControl(policyName)
control, err = drp.gs.GetOPAControlByID(ID)
if err != nil {
return nil, err
}

View File

@@ -9,7 +9,7 @@ import (
type IPolicyGetter interface {
GetFramework(name string) (*reporthandling.Framework, error)
GetFrameworks() ([]reporthandling.Framework, error)
GetControl(name string) (*reporthandling.Control, error)
GetControl(ID string) (*reporthandling.Control, error)
ListFrameworks() ([]string, error)
ListControls() ([]string, error)

View File

@@ -192,7 +192,7 @@ func (api *KSCloudAPI) GetFrameworks() ([]reporthandling.Framework, error) {
return frameworks, err
}
func (api *KSCloudAPI) GetControl(policyName string) (*reporthandling.Control, error) {
func (api *KSCloudAPI) GetControl(ID string) (*reporthandling.Control, error) {
return nil, fmt.Errorf("control api is not public")
}

View File

@@ -37,7 +37,7 @@ func NewLoadPolicy(filePaths []string) *LoadPolicy {
}
// Return control from file
func (lp *LoadPolicy) GetControl(controlName string) (*reporthandling.Control, error) {
func (lp *LoadPolicy) GetControl(controlID string) (*reporthandling.Control, error) {
control := &reporthandling.Control{}
filePath := lp.filePath()
@@ -49,13 +49,13 @@ 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) {
if controlID != "" && !strings.EqualFold(controlID, control.ControlID) && !strings.EqualFold(controlID, control.ControlID) {
framework, err := lp.GetFramework(control.Name)
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) {
if strings.EqualFold(ctrl.ControlID, controlID) || strings.EqualFold(ctrl.ControlID, controlID) {
control = &ctrl
break
}

View File

@@ -94,7 +94,7 @@ const (
)
type PolicyIdentifier struct {
Name string // policy name e.g. nsa,mitre,c-0012
Identifier string // policy Identifier e.g. c-0012 for control, nsa,mitre for frameworks
Kind apisv1.NotificationPolicyKind // policy kind e.g. Framework,Control,Rule
Designators armotypes.PortalDesignator
}
@@ -182,7 +182,7 @@ func (scanInfo *ScanInfo) setUseArtifactsFrom() {
func (scanInfo *ScanInfo) setUseFrom() {
if scanInfo.UseDefault {
for _, policy := range scanInfo.PolicyIdentifier {
scanInfo.UseFrom = append(scanInfo.UseFrom, getter.GetDefaultPath(policy.Name+".json"))
scanInfo.UseFrom = append(scanInfo.UseFrom, getter.GetDefaultPath(policy.Identifier+".json"))
}
}
}
@@ -202,7 +202,7 @@ func (scanInfo *ScanInfo) SetPolicyIdentifiers(policies []string, kind apisv1.No
if !scanInfo.contains(policy) {
newPolicy := PolicyIdentifier{}
newPolicy.Kind = kind
newPolicy.Name = policy
newPolicy.Identifier = policy
scanInfo.PolicyIdentifier = append(scanInfo.PolicyIdentifier, newPolicy)
}
}
@@ -210,7 +210,7 @@ func (scanInfo *ScanInfo) SetPolicyIdentifiers(policies []string, kind apisv1.No
func (scanInfo *ScanInfo) contains(policyName string) bool {
for _, policy := range scanInfo.PolicyIdentifier {
if policy.Name == policyName {
if policy.Identifier == policyName {
return true
}
}
@@ -238,7 +238,7 @@ func scanInfoToScanMetadata(scanInfo *ScanInfo) *reporthandlingv2.Metadata {
}
// append frameworks
for _, policy := range scanInfo.PolicyIdentifier {
metadata.ScanMetadata.TargetNames = append(metadata.ScanMetadata.TargetNames, policy.Name)
metadata.ScanMetadata.TargetNames = append(metadata.ScanMetadata.TargetNames, policy.Identifier)
}
metadata.ScanMetadata.KubescapeVersion = BuildNumber

View File

@@ -13,13 +13,22 @@ import (
metav1 "github.com/kubescape/kubescape/v2/core/meta/datastructures/v1"
)
const (
TargetControlsInputs = "controls-inputs"
TargetExceptions = "exceptions"
TargetControl = "control"
TargetFramework = "framework"
TargetArtifacts = "artifacts"
TargetAttackTracks = "attack-tracks"
)
var downloadFunc = map[string]func(*metav1.DownloadInfo) error{
"controls-inputs": downloadConfigInputs,
"exceptions": downloadExceptions,
"control": downloadControl,
"framework": downloadFramework,
"artifacts": downloadArtifacts,
"attack-tracks": downloadAttackTracks,
TargetControlsInputs: downloadConfigInputs,
TargetExceptions: downloadExceptions,
TargetControl: downloadControl,
TargetFramework: downloadFramework,
TargetArtifacts: downloadArtifacts,
TargetAttackTracks: downloadAttackTracks,
}
func DownloadSupportCommands() []string {
@@ -84,7 +93,7 @@ func downloadArtifacts(downloadInfo *metav1.DownloadInfo) error {
func downloadConfigInputs(downloadInfo *metav1.DownloadInfo) error {
tenant := getTenantConfig(&downloadInfo.Credentials, "", "", getKubernetesApi())
controlsInputsGetter := getConfigInputsGetter(downloadInfo.Name, tenant.GetAccountID(), nil)
controlsInputsGetter := getConfigInputsGetter(downloadInfo.Identifier, tenant.GetAccountID(), nil)
controlInputs, err := controlsInputsGetter.GetControlsInputs(tenant.GetContextName())
if err != nil {
return err
@@ -158,7 +167,7 @@ func downloadFramework(downloadInfo *metav1.DownloadInfo) error {
g := getPolicyGetter(nil, tenant.GetTenantEmail(), true, nil)
if downloadInfo.Name == "" {
if downloadInfo.Identifier == "" {
// if framework name not specified - download all frameworks
frameworks, err := g.GetFrameworks()
if err != nil {
@@ -175,9 +184,9 @@ func downloadFramework(downloadInfo *metav1.DownloadInfo) error {
// return fmt.Errorf("missing framework name")
} else {
if downloadInfo.FileName == "" {
downloadInfo.FileName = fmt.Sprintf("%s.json", downloadInfo.Name)
downloadInfo.FileName = fmt.Sprintf("%s.json", downloadInfo.Identifier)
}
framework, err := g.GetFramework(downloadInfo.Name)
framework, err := g.GetFramework(downloadInfo.Identifier)
if err != nil {
return err
}
@@ -200,25 +209,25 @@ func downloadControl(downloadInfo *metav1.DownloadInfo) error {
g := getPolicyGetter(nil, tenant.GetTenantEmail(), false, nil)
if downloadInfo.Name == "" {
if downloadInfo.Identifier == "" {
// TODO - support
return fmt.Errorf("missing control name")
return fmt.Errorf("missing control ID")
}
if downloadInfo.FileName == "" {
downloadInfo.FileName = fmt.Sprintf("%s.json", downloadInfo.Name)
downloadInfo.FileName = fmt.Sprintf("%s.json", downloadInfo.Identifier)
}
controls, err := g.GetControl(downloadInfo.Name)
controls, err := g.GetControl(downloadInfo.Identifier)
if err != nil {
return err
return fmt.Errorf("failed to download control id '%s', %s", downloadInfo.Identifier, err.Error())
}
if controls == nil {
return fmt.Errorf("failed to download control - received an empty objects")
return fmt.Errorf("failed to download control id '%s' - received an empty objects", downloadInfo.Identifier)
}
downloadTo := filepath.Join(downloadInfo.Path, downloadInfo.FileName)
err = getter.SaveInFile(controls, downloadTo)
if err != nil {
return err
}
logger.L().Success("Downloaded", helpers.String("artifact", downloadInfo.Target), helpers.String("name", downloadInfo.Name), helpers.String("path", downloadTo))
logger.L().Success("Downloaded", helpers.String("artifact", downloadInfo.Target), helpers.String("ID", downloadInfo.Identifier), helpers.String("path", downloadTo))
return nil
}

View File

@@ -125,18 +125,18 @@ func getFieldSelector(scanInfo *cautils.ScanInfo) resourcehandler.IFieldSelector
return &resourcehandler.EmptySelector{}
}
func policyIdentifierNames(pi []cautils.PolicyIdentifier) string {
policiesNames := ""
func policyIdentifierIdentities(pi []cautils.PolicyIdentifier) string {
policiesIdentities := ""
for i := range pi {
policiesNames += pi[i].Name
policiesIdentities += pi[i].Identifier
if i+1 < len(pi) {
policiesNames += ","
policiesIdentities += ","
}
}
if policiesNames == "" {
policiesNames = "all"
if policiesIdentities == "" {
policiesIdentities = "all"
}
return policiesNames
return policiesIdentities
}
// setSubmitBehavior - Setup the desired cluster behavior regarding submitting to the Kubescape Cloud BE

View File

@@ -64,7 +64,7 @@ func getInterfaces(scanInfo *cautils.ScanInfo) componentInterfaces {
// ================== version testing ======================================
v := cautils.NewIVersionCheckHandler()
v.CheckLatestVersion(cautils.NewVersionCheckRequest(cautils.BuildNumber, policyIdentifierNames(scanInfo.PolicyIdentifier), "", cautils.ScanningContextToScanningScope(scanInfo.GetScanningContext())))
v.CheckLatestVersion(cautils.NewVersionCheckRequest(cautils.BuildNumber, policyIdentifierIdentities(scanInfo.PolicyIdentifier), "", cautils.ScanningContextToScanningScope(scanInfo.GetScanningContext())))
// ================== setup host scanner object ======================================

View File

@@ -6,6 +6,6 @@ type DownloadInfo struct {
Path string // directory to save artifact. Default is "~/.kubescape/"
FileName string // can be empty
Target string // type of artifact to download
Name string // name of artifact to download
Identifier string // identifier of artifact to download
Credentials cautils.Credentials
}

View File

@@ -56,7 +56,7 @@ func (policyHandler *PolicyHandler) getScanPolicies(policyIdentifier []cautils.P
switch getScanKind(policyIdentifier) {
case apisv1.KindFramework: // Download frameworks
for _, rule := range policyIdentifier {
receivedFramework, err := policyHandler.getters.PolicyGetter.GetFramework(rule.Name)
receivedFramework, err := policyHandler.getters.PolicyGetter.GetFramework(rule.Identifier)
if err != nil {
return frameworks, policyDownloadError(err)
}
@@ -65,7 +65,7 @@ func (policyHandler *PolicyHandler) getScanPolicies(policyIdentifier []cautils.P
}
if receivedFramework != nil {
frameworks = append(frameworks, *receivedFramework)
cache := getter.GetDefaultPath(rule.Name + ".json")
cache := getter.GetDefaultPath(rule.Identifier + ".json")
if err := getter.SaveInFile(receivedFramework, cache); err != nil {
logger.L().Warning("failed to cache file", helpers.String("file", cache), helpers.Error(err))
}
@@ -75,15 +75,15 @@ func (policyHandler *PolicyHandler) getScanPolicies(policyIdentifier []cautils.P
f := reporthandling.Framework{}
var receivedControl *reporthandling.Control
var err error
for _, rule := range policyIdentifier {
receivedControl, err = policyHandler.getters.PolicyGetter.GetControl(rule.Name)
for _, policy := range policyIdentifier {
receivedControl, err = policyHandler.getters.PolicyGetter.GetControl(policy.Identifier)
if err != nil {
return frameworks, policyDownloadError(err)
}
if receivedControl != nil {
f.Controls = append(f.Controls, *receivedControl)
cache := getter.GetDefaultPath(rule.Name + ".json")
cache := getter.GetDefaultPath(policy.Identifier + ".json")
if err := getter.SaveInFile(receivedControl, cache); err != nil {
logger.L().Warning("failed to cache file", helpers.String("file", cache), helpers.Error(err))
}
@@ -100,7 +100,7 @@ func (policyHandler *PolicyHandler) getScanPolicies(policyIdentifier []cautils.P
func policyIdentifierToSlice(rules []cautils.PolicyIdentifier) []string {
s := []string{}
for i := range rules {
s = append(s, fmt.Sprintf("%s: %s", rules[i].Kind, rules[i].Name))
s = append(s, fmt.Sprintf("%s: %s", rules[i].Kind, rules[i].Identifier))
}
return s
}

View File

@@ -32,9 +32,9 @@ func TestToScanInfo(t *testing.T) {
assert.False(t, s.Submit)
assert.False(t, s.ScanAll)
assert.True(t, s.FrameworkScan)
assert.Equal(t, "nsa", s.PolicyIdentifier[0].Name)
assert.Equal(t, "nsa", s.PolicyIdentifier[0].Identifier)
assert.Equal(t, apisv1.KindFramework, s.PolicyIdentifier[0].Kind)
assert.Equal(t, "mitre", s.PolicyIdentifier[1].Name)
assert.Equal(t, "mitre", s.PolicyIdentifier[1].Identifier)
assert.Equal(t, apisv1.KindFramework, s.PolicyIdentifier[1].Kind)
}
{
@@ -49,7 +49,7 @@ func TestToScanInfo(t *testing.T) {
assert.Equal(t, "kube-system,kube-public", s.IncludeNamespaces)
assert.Equal(t, "", s.ExcludedNamespaces)
assert.Equal(t, 1, len(s.PolicyIdentifier))
assert.Equal(t, "c-0001", s.PolicyIdentifier[0].Name)
assert.Equal(t, "c-0001", s.PolicyIdentifier[0].Identifier)
assert.Equal(t, apisv1.KindControl, s.PolicyIdentifier[0].Kind)
}
{

View File

@@ -21,7 +21,7 @@ def scan_control_id(kubescape_exec: str):
def scan_controls(kubescape_exec: str):
return smoke_utils.run_command(command=[kubescape_exec, "scan", "control", 'HostPath mount,Allow privilege escalation', all_files, "--enable-host-scan=false"])
return smoke_utils.run_command(command=[kubescape_exec, "scan", "control", 'C-0048,C-0016', all_files, "--enable-host-scan=false"])
def scan_framework(kubescape_exec: str):
@@ -48,10 +48,6 @@ def run(kubescape_exec: str):
# 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)