Skip to content

Commit

Permalink
Release (kubescape#844)
Browse files Browse the repository at this point in the history
* Fix issue for scanning list obj

* Fix go mod in httphandler pkg

* Broken links fix in roadmap.md 

Planning, backlog, and wishlist links were not taking to the required section.

* override infoMap only if it's not nil

* improved icon of kubescape in readme

* Support scanning several files

* gramatical improvements

* docs(readme): Star → star

* Fix issues according to review

* Handle with issues  caused by updating opa-utils

* Fix scanning ListObj following reviews

* Update core/pkg/resourcehandler/filesloader.go

Co-authored-by: Vlad Klokun <[email protected]>

* Update completion.go

* Added fixed control input

* update go.mod

* Print chart name log when fail to generate

* Change formatting to %s

* Added resource prioritization information, raw resource will be sent on the result object

* Merging typo fixes from master (kubescape#772)

* greetings

* Update aws.sh

simplified the comment

* typo: In the title and h1 element

Their was a typo in index.html file.

* punctuation changes

* docs : added gitpod badge in readme.md

* fixed typos

* � some grammar mistake is corrected inPULL_REQUEST_TEMPLATE.md file

* Updated README.md file

Added link to CONTRIBUTING.md file in a line in README.

* Added link to code of conduct file

I have added link to the code of conduct file and fixed some problems in the Readme file.

* Fixed readme

* Added alpine tag

Adding alpine tag instead of latest and removing repeating commands

* roadmap.md file is modified

* Automatically Close "Typo" labelled Issue

* build.py is modified

* modified PR template

* Fixed some typos in feature_request.md

"." at the end of the headings were missing and all the text were in same line.
Now this gives a clear and concise view of the texts.

* fixed the typo in docs/index.html

Found and fixed typo in the 'alt' attribute of img tag

* Update PULL_REQUEST_TEMPLATE.md

Co-authored-by: Krishna Agarwal <[email protected]>
Co-authored-by: Saswata Senapati <[email protected]>
Co-authored-by: Rahul Singh <[email protected]>
Co-authored-by: deepuyadav004 <[email protected]>
Co-authored-by: kartik <[email protected]>
Co-authored-by: Rounak-28 <[email protected]>
Co-authored-by: pwnb0y <[email protected]>
Co-authored-by: Ben Hirschberg <[email protected]>
Co-authored-by: Saptarshi Sarkar <[email protected]>
Co-authored-by: Rahul Surwade <[email protected]>
Co-authored-by: Suhas Gumma <[email protected]>
Co-authored-by: Kamal Nayan <[email protected]>
Co-authored-by: TarangVerma <[email protected]>
Co-authored-by: avikittu <[email protected]>

* update logger version

* update logger version (kubescape#773)

* Fixed: Kubescape fails to authenticate remote private Github repo (kubescape#721)

* grammar error fixer in CONTRIBUTING.md

* scanning private git repository is available

* giturl to gitapi

* NO TOKEN error functionality added

* Used GetToken method of giturl.IGitAPPI for auth

Co-authored-by: satyam kale <[email protected]>
Co-authored-by: Ben Hirschberg <[email protected]>

* bump opa-utils to 181

* Option to force enable color output (closes kubescape#560) (kubescape#767)

* Option to force enable color output (closes kubescape#560)

(cherry picked from commit 4f95178)

* Update go.mod

* update scanner image

* Update host scanner image  (kubescape#774)

* update logger version

* update scanner image

* remove windows exe extension

* Remove windows extension build (kubescape#775)

* update logger version

* update scanner image

* remove windows exe extension

* commened out prioritization logic

* Edit Junit output (kubescape#802)

* Edit Junit output

* Update go sum

* Following review

* update AdoptClusterName

* Print line separator only if some controls failed (kubescape#813)

* removed the extra 'download' word from the example (kubescape#810)

it was confusing to understand the download command because there was an extra 'download' mentioned

* Prioritization (kubescape#815)

* removed commented out code

* Added attack tracks information to prioritization algorithm

* bump opa-utils

* go mod tidy

* go mod tidy

* CR changes

* Issue 613 cluster name (kubescape#783)

* added --clusterName flag (kubescape#613)

Signed-off-by: Anubhav Gupta <[email protected]>

* update flag name to --cluster-name

Signed-off-by: Anubhav Gupta <[email protected]>

Signed-off-by: Anubhav Gupta <[email protected]>

* Per 307 fail on severity counters (kubescape#831)

* feat: fail on exceeding severity thresholds (kubescape#830)

- Add support for severity counters
- Add support for CLI flags that set severity thresholds
- Terminate Kubescape with an exit code 1 if scan results exceed the
  severity thresholds

* Update opa-utils pkg version

Co-authored-by: Vlad Klokun <[email protected]>

* Fix merge conflict

* typo in .gitignore file (kubescape#833)

* remove unsupported installation method

* fixed welcome message

* fixed merge

* fixed attack tracks loading logic

* add flag validation for --account-id (kubescape#605) (kubescape#793)

* add flag validation for --account-id (kubescape#605)

Signed-off-by: Anubhav Gupta <[email protected]>

* add flag validation for --client-id & --secret-key

Signed-off-by: Anubhav Gupta <[email protected]>

* Validation method should be a member function

* Adding unit tests for credentials validate

Signed-off-by: Anubhav Gupta <[email protected]>
Co-authored-by: David Wertenteil <[email protected]>

* Scan Kustomize Directory (kubescape#795)

* Scan Kustomize Files

* update 'scam Kustomize Directory' documentation in  Readme.md

* go get

* go get inside httphandler

* SourceTypeKustomizeDirectory

* Added Scan for Kustomization File

Co-authored-by: David Wertenteil <[email protected]>

* feat: unify severity threshold into one CLI flag (kubescape#838)

* feat: unify severity threshold into one CLI flag

Before this commit, severity threshold flags were separated by severity.
This commit unifies these thresholds into one flag that forces Kubescape
to terminate with an exit code 1 if there was at least one failed
control at the specified severity threshold or above.

* chore: update opa utils version

* chore: update opa-utils in httphandler

* feat: dont enforce severity by default

Previous iteration of supporting the severity threshold enforced it even
if the severity threshold was not explicitly specified.
This change enforces the severity threshold only if it has been
explicitly set.

* refactor: clarify flagValidationFramework func name

This change clarifies the meaning of the function that validates the
scan info for the `scan framework` command.
It achieves this by renaming the `flagValidationFramework` function to
`validateFrameworkScanInfo`.

* Merge branch 'master' into dev

Signed-off-by: Anubhav Gupta <[email protected]>
Co-authored-by: Moshe-Rappaport-CA <[email protected]>
Co-authored-by: Moshe Rappaport <[email protected]>
Co-authored-by: Om Raut <[email protected]>
Co-authored-by: Kamal Nayan <[email protected]>
Co-authored-by: Vlad Klokun <[email protected]>
Co-authored-by: Chirag Arora <[email protected]>
Co-authored-by: shm12 <[email protected]>
Co-authored-by: Amir Malka <[email protected]>
Co-authored-by: Krishna Agarwal <[email protected]>
Co-authored-by: Saswata Senapati <[email protected]>
Co-authored-by: Rahul Singh <[email protected]>
Co-authored-by: deepuyadav004 <[email protected]>
Co-authored-by: kartik <[email protected]>
Co-authored-by: Rounak-28 <[email protected]>
Co-authored-by: pwnb0y <[email protected]>
Co-authored-by: Ben Hirschberg <[email protected]>
Co-authored-by: Saptarshi Sarkar <[email protected]>
Co-authored-by: Rahul Surwade <[email protected]>
Co-authored-by: Suhas Gumma <[email protected]>
Co-authored-by: TarangVerma <[email protected]>
Co-authored-by: avikittu <[email protected]>
Co-authored-by: satyam kale <[email protected]>
Co-authored-by: Aditya Pratap Singh <[email protected]>
Co-authored-by: Ashray Shetty <[email protected]>
Co-authored-by: Anubhav Gupta <[email protected]>
Co-authored-by: Meyazhagan <[email protected]>
  • Loading branch information
1 parent 2916686 commit 0f3ce69
Show file tree
Hide file tree
Showing 23 changed files with 880 additions and 45 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,12 @@ kubescape scan </path/to/directory> --submit
```
> Kubescape will load the default value file
#### Scan Kustomize Directory
```
kubescape scan </path/to/directory> --submit
```
> Kubescape will generate Kubernetes Yaml Objects using 'Kustomize' file and scans them for security.
### Offline/Air-gaped Environment Support
[Video tutorial](https://youtu.be/IGXL9s37smM)
Expand Down
12 changes: 12 additions & 0 deletions cmd/delete/exceptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ func getExceptionsCmd(ks meta.IKubescape, deleteInfo *v1.Delete) *cobra.Command
return nil
},
Run: func(cmd *cobra.Command, args []string) {

if err := flagValidationDelete(deleteInfo); err != nil {
logger.L().Fatal(err.Error())
}

exceptionsNames := strings.Split(args[0], ";")
if len(exceptionsNames) == 0 {
logger.L().Fatal("missing exceptions names")
Expand All @@ -32,3 +37,10 @@ func getExceptionsCmd(ks meta.IKubescape, deleteInfo *v1.Delete) *cobra.Command
},
}
}

// Check if the flag entered are valid
func flagValidationDelete(deleteInfo *v1.Delete) error {

// Validate the user's credentials
return deleteInfo.Credentials.Validate()
}
11 changes: 11 additions & 0 deletions cmd/download/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ func GeDownloadCmd(ks meta.IKubescape) *cobra.Command {
},
RunE: func(cmd *cobra.Command, args []string) error {

if err := flagValidationDownload(&downloadInfo); err != nil {
return err
}

if filepath.Ext(downloadInfo.Path) == ".json" {
downloadInfo.Path, downloadInfo.FileName = filepath.Split(downloadInfo.Path)
}
Expand All @@ -80,3 +84,10 @@ func GeDownloadCmd(ks meta.IKubescape) *cobra.Command {

return downloadCmd
}

// Check if the flag entered are valid
func flagValidationDownload(downloadInfo *v1.DownloadInfo) error {

// Validate the user's credentials
return downloadInfo.Credentials.Validate()
}
12 changes: 12 additions & 0 deletions cmd/list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ func GetListCmd(ks meta.IKubescape) *cobra.Command {
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {

if err := flagValidationList(&listPolicies); err != nil {
return err
}

listPolicies.Target = args[0]

if err := ks.List(&listPolicies); err != nil {
Expand All @@ -67,3 +72,10 @@ func GetListCmd(ks meta.IKubescape) *cobra.Command {

return listCmd
}

// Check if the flag entered are valid
func flagValidationList(listPolicies *v1.ListPolicies) error {

// Validate the user's credentials
return listPolicies.Credentials.Validate()
}
20 changes: 19 additions & 1 deletion cmd/scan/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ func getControlCmd(ks meta.IKubescape, scanInfo *cautils.ScanInfo) *cobra.Comman
},
RunE: func(cmd *cobra.Command, args []string) error {

if err := validateFrameworkScanInfo(scanInfo); err != nil {
return err
}

// flagValidationControl(scanInfo)
scanInfo.PolicyIdentifier = []cautils.PolicyIdentifier{}

Expand Down Expand Up @@ -88,6 +92,10 @@ func getControlCmd(ks meta.IKubescape, scanInfo *cautils.ScanInfo) *cobra.Comman

scanInfo.FrameworkScan = false

if err := validateControlScanInfo(scanInfo); err != nil {
return err
}

results, err := ks.Scan(scanInfo)
if err != nil {
logger.L().Fatal(err.Error())
Expand All @@ -101,9 +109,19 @@ func getControlCmd(ks meta.IKubescape, scanInfo *cautils.ScanInfo) *cobra.Comman
if results.GetRiskScore() > float32(scanInfo.FailThreshold) {
logger.L().Fatal("scan risk-score is above permitted threshold", helpers.String("risk-score", fmt.Sprintf("%.2f", results.GetRiskScore())), helpers.String("fail-threshold", fmt.Sprintf("%.2f", scanInfo.FailThreshold)))
}
enforceSeverityThresholds(&results.GetResults().SummaryDetails.SeverityCounters, scanInfo, terminateOnExceedingSeverity)

enforceSeverityThresholds(&results.GetResults().SummaryDetails.SeverityCounters, scanInfo)
return nil
},
}
}

// validateControlScanInfo validates the ScanInfo struct for the `control` command
func validateControlScanInfo(scanInfo *cautils.ScanInfo) error {
severity := scanInfo.FailThresholdSeverity

if err := validateSeverity(severity); severity != "" && err != nil {
return err
}
return nil
}
107 changes: 80 additions & 27 deletions cmd/scan/framework.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package scan

import (
"errors"
"fmt"
"io"
"os"
"strings"

apisv1 "github.com/kubescape/opa-utils/httpserver/apis/v1"
reporthandlingapis "github.com/kubescape/opa-utils/reporthandling/apis"
"github.com/kubescape/opa-utils/reporthandling/results/v1/reportsummary"

logger "github.com/kubescape/go-logger"
Expand Down Expand Up @@ -37,6 +39,8 @@ var (
Run 'kubescape list frameworks' for the list of supported frameworks
`

ErrUnknownSeverity = errors.New("unknown severity")
)

func getFrameworkCmd(ks meta.IKubescape, scanInfo *cautils.ScanInfo) *cobra.Command {
Expand All @@ -63,7 +67,7 @@ func getFrameworkCmd(ks meta.IKubescape, scanInfo *cautils.ScanInfo) *cobra.Comm
},
RunE: func(cmd *cobra.Command, args []string) error {

if err := flagValidationFramework(scanInfo); err != nil {
if err := validateFrameworkScanInfo(scanInfo); err != nil {
return err
}
scanInfo.FrameworkScan = true
Expand Down Expand Up @@ -115,45 +119,94 @@ func getFrameworkCmd(ks meta.IKubescape, scanInfo *cautils.ScanInfo) *cobra.Comm
logger.L().Fatal("scan risk-score is above permitted threshold", helpers.String("risk-score", fmt.Sprintf("%.2f", results.GetRiskScore())), helpers.String("fail-threshold", fmt.Sprintf("%.2f", scanInfo.FailThreshold)))
}

enforceSeverityThresholds(&results.GetData().Report.SummaryDetails.SeverityCounters, scanInfo)
enforceSeverityThresholds(&results.GetData().Report.SummaryDetails.SeverityCounters, scanInfo, terminateOnExceedingSeverity)
return nil
},
}
}

// enforceSeverityThresholds ensures that the scan results are below defined severity thresholds
// countersExceedSeverityThreshold returns true if severity of failed controls exceed the set severity threshold, else returns false
func countersExceedSeverityThreshold(severityCounters reportsummary.ISeverityCounters, scanInfo *cautils.ScanInfo) (bool, error) {
targetSeverity := scanInfo.FailThresholdSeverity
if err := validateSeverity(targetSeverity); err != nil {
return false, err
}

getFailedResourcesFuncsBySeverity := []struct {
SeverityName string
GetFailedResources func() int
}{
{reporthandlingapis.SeverityLowString, severityCounters.NumberOfResourcesWithLowSeverity},
{reporthandlingapis.SeverityMediumString, severityCounters.NumberOfResourcesWithMediumSeverity},
{reporthandlingapis.SeverityHighString, severityCounters.NumberOfResourcesWithHighSeverity},
{reporthandlingapis.SeverityCriticalString, severityCounters.NumberOfResourcesWithCriticalSeverity},
}

targetSeverityIdx := 0
for idx, description := range getFailedResourcesFuncsBySeverity {
if strings.EqualFold(description.SeverityName, targetSeverity) {
targetSeverityIdx = idx
break
}
}

for _, description := range getFailedResourcesFuncsBySeverity[targetSeverityIdx:] {
failedResourcesCount := description.GetFailedResources()
if failedResourcesCount > 0 {
return true, nil
}
}

return false, nil

}

// terminateOnExceedingSeverity terminates the application on exceeding severity
func terminateOnExceedingSeverity(scanInfo *cautils.ScanInfo, l logger.ILogger) {
l.Fatal("result exceeds severity threshold", helpers.String("set severity threshold", scanInfo.FailThresholdSeverity))
}

// enforceSeverityThresholds ensures that the scan results are below the defined severity threshold
//
// The function forces the application to terminate with an exit code 1 if there are more resources with failed controls of a given severity than permitted
func enforceSeverityThresholds(severityCounters reportsummary.ISeverityCounters, scanInfo *cautils.ScanInfo) {
failedCritical := severityCounters.NumberOfResourcesWithCriticalSeverity()
failedHigh := severityCounters.NumberOfResourcesWithHighSeverity()
failedMedium := severityCounters.NumberOfResourcesWithMediumSeverity()
failedLow := severityCounters.NumberOfResourcesWithLowSeverity()

criticalExceeded := failedCritical > scanInfo.FailThresholdCritical
highExceeded := failedHigh > scanInfo.FailThresholdHigh
mediumExceeded := failedMedium > scanInfo.FailThresholdMedium
lowExceeded := failedLow > scanInfo.FailThresholdLow

resourceThresholdsExceeded := criticalExceeded || highExceeded || mediumExceeded || lowExceeded

if resourceThresholdsExceeded {
logger.L().Fatal(
"There were failed controls that exceed permitted severity thresholds",
helpers.String("critical", fmt.Sprintf("got: %d, permitted: %d", failedCritical, scanInfo.FailThresholdCritical)),
helpers.String("high", fmt.Sprintf("got: %d, permitted: %d", failedHigh, scanInfo.FailThresholdHigh)),
helpers.String("medium", fmt.Sprintf("got: %d, permitted: %d", failedMedium, scanInfo.FailThresholdMedium)),
helpers.String("low", fmt.Sprintf("got: %d, permitted: %d", failedLow, scanInfo.FailThresholdLow)),
)
// The function forces the application to terminate with an exit code 1 if at least one control failed control that exceeds the set severity threshold
func enforceSeverityThresholds(severityCounters reportsummary.ISeverityCounters, scanInfo *cautils.ScanInfo, onExceed func(*cautils.ScanInfo, logger.ILogger)) {
// If a severity threshold is not set, we don’t need to enforce it
if scanInfo.FailThresholdSeverity == "" {
return
}

if val, err := countersExceedSeverityThreshold(severityCounters, scanInfo); val && err == nil {
onExceed(scanInfo, logger.L())
} else if err != nil {
logger.L().Fatal(err.Error())
}
}

// validateSeverity returns an error if a given severity is not known, nil otherwise
func validateSeverity(severity string) error {
for _, val := range reporthandlingapis.GetSupportedSeverities() {
if strings.EqualFold(severity, val) {
return nil
}
}
return ErrUnknownSeverity

}

func flagValidationFramework(scanInfo *cautils.ScanInfo) error {
// validateFrameworkScanInfo validates the scan info struct for the `scan framework` command
func validateFrameworkScanInfo(scanInfo *cautils.ScanInfo) error {
if scanInfo.Submit && scanInfo.Local {
return fmt.Errorf("you can use `keep-local` or `submit`, but not both")
}
if 100 < scanInfo.FailThreshold || 0 > scanInfo.FailThreshold {
return fmt.Errorf("bad argument: out of range threshold")
}
return nil

severity := scanInfo.FailThresholdSeverity
if err := validateSeverity(severity); severity != "" && err != nil {
return err
}

// Validate the user's credentials
return scanInfo.Credentials.Validate()
}
7 changes: 1 addition & 6 deletions cmd/scan/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package scan

import (
"fmt"
"math"

"github.com/kubescape/k8s-interface/k8sinterface"
"github.com/kubescape/kubescape/v2/core/cautils"
Expand Down Expand Up @@ -75,11 +74,7 @@ func GetScanCommand(ks meta.IKubescape) *cobra.Command {

scanCmd.PersistentFlags().Float32VarP(&scanInfo.FailThreshold, "fail-threshold", "t", 100, "Failure threshold is the percent above which the command fails and returns exit code 1")

scanCmd.PersistentFlags().IntVar(&scanInfo.FailThresholdCritical, "threshold-critical", math.MaxInt, "Critical threshold is the amount of resources that have critical failed controls above which the command fails and returns exit code 1")
scanCmd.PersistentFlags().IntVar(&scanInfo.FailThresholdHigh, "threshold-high", math.MaxInt, "The amount of resources that have failed controls with High severity above which the command fails and returns exit code 1")
scanCmd.PersistentFlags().IntVar(&scanInfo.FailThresholdMedium, "threshold-medium", math.MaxInt, "The amount of resources that have failed controls with Medium severity above which the command fails and returns exit code 1")
scanCmd.PersistentFlags().IntVar(&scanInfo.FailThresholdLow, "threshold-low", math.MaxInt, "The amount of resources that have failed controls with Low severity above which the command fails and returns exit code 1")

scanCmd.PersistentFlags().StringVar(&scanInfo.FailThresholdSeverity, "severity-threshold", "", "Severity threshold is the severity of failed controls at which the command fails and returns exit code 1")
scanCmd.PersistentFlags().StringVarP(&scanInfo.Format, "format", "f", "pretty-printer", `Output format. Supported formats: "pretty-printer", "json", "junit", "prometheus", "pdf", "html"`)
scanCmd.PersistentFlags().StringVar(&scanInfo.IncludeNamespaces, "include-namespaces", "", "scan specific namespaces. e.g: --include-namespaces ns-a,ns-b")
scanCmd.PersistentFlags().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")
Expand Down
Loading

0 comments on commit 0f3ce69

Please sign in to comment.