mirror of
https://github.com/kubescape/kubescape.git
synced 2026-04-15 06:58:11 +00:00
add download json option
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
package cautils
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/armosec/kubescape/cautils/getter"
|
||||
)
|
||||
|
||||
type DownloadInfo struct {
|
||||
Path string
|
||||
FrameworkName string
|
||||
}
|
||||
|
||||
func GetDefaultPath(frameworkName string) string {
|
||||
if homeDir, err := os.UserHomeDir(); err == nil {
|
||||
return filepath.Join(homeDir, getter.DefaultLocalStore, frameworkName+".json")
|
||||
}
|
||||
return filepath.Join(getter.DefaultLocalStore, frameworkName+".json")
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/armosec/kubescape/cautils/opapolicy"
|
||||
@@ -12,6 +13,8 @@ import (
|
||||
|
||||
const DefaultLocalStore = ".kubescape"
|
||||
|
||||
var path string
|
||||
|
||||
type IPolicyGetter interface {
|
||||
GetFramework(name string) (*opapolicy.Framework, error)
|
||||
}
|
||||
@@ -33,6 +36,15 @@ func NewDownloadReleasedPolicy() *DownloadReleasedPolicy {
|
||||
}
|
||||
}
|
||||
|
||||
func SaveFrameworkInFile(framework *opapolicy.Framework, path string) error {
|
||||
encodedData, _ := json.Marshal(framework)
|
||||
err := os.WriteFile(path, []byte(fmt.Sprintf("%v", string(encodedData))), 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (drp *DownloadReleasedPolicy) GetFramework(name string) (*opapolicy.Framework, error) {
|
||||
drp.setURL(name)
|
||||
respStr, err := HttpGetter(drp.httpClient, drp.hostURL)
|
||||
@@ -42,13 +54,56 @@ func (drp *DownloadReleasedPolicy) GetFramework(name string) (*opapolicy.Framewo
|
||||
|
||||
framework := &opapolicy.Framework{}
|
||||
err = JSONDecoder(respStr).Decode(framework)
|
||||
// SaveFrameworkInFile(framework)
|
||||
// store in file
|
||||
//
|
||||
|
||||
/*
|
||||
|
||||
1. Public save framework function (framework, path) error
|
||||
2. Call the function from Download And GetFramework
|
||||
3. export to function: os.Join($HOME, getter.DefaultLocalStore, <name>.json)
|
||||
|
||||
*/
|
||||
return framework, err
|
||||
}
|
||||
|
||||
func (drp *DownloadReleasedPolicy) setURL(frameworkName string) {
|
||||
// requestURI := "v1/armoFrameworks"
|
||||
func (drp *DownloadReleasedPolicy) setURL(frameworkName string) error {
|
||||
|
||||
resp, err := http.Get("https://api.github.com/repos/armosec/regolibrary/releases/latest")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode < 200 || 301 < resp.StatusCode {
|
||||
return fmt.Errorf("failed to download file, status code: %s", resp.Status)
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var data map[string]interface{}
|
||||
err = json.Unmarshal(body, &data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if assets, ok := data["assets"].([]interface{}); ok {
|
||||
for i := range assets {
|
||||
if asset, ok := assets[i].(map[string]interface{}); ok {
|
||||
if name, ok := asset["name"].(string); ok {
|
||||
if name == frameworkName {
|
||||
if url, ok := asset["browser_download_url"].(string); ok {
|
||||
drp.hostURL = url
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
// drp.hostURL = URLEncoder(fmt.Sprintf("%s/%s", drp.hostURL, requestURI))
|
||||
}
|
||||
|
||||
// =======================================================================================================================
|
||||
|
||||
+25
-2
@@ -10,6 +10,8 @@ import (
|
||||
type ScanInfo struct {
|
||||
PolicyGetter getter.IPolicyGetter
|
||||
PolicyIdentifier opapolicy.PolicyIdentifier
|
||||
UseFrom string
|
||||
UseDefault bool
|
||||
Format string
|
||||
Output string
|
||||
ExcludedNamespaces string
|
||||
@@ -19,13 +21,34 @@ type ScanInfo struct {
|
||||
|
||||
func (scanInfo *ScanInfo) Init() {
|
||||
// scanInfo.setSilentMode()
|
||||
scanInfo.setUseFrom()
|
||||
scanInfo.setOutputFile()
|
||||
scanInfo.setGetter()
|
||||
|
||||
}
|
||||
func (scanInfo *ScanInfo) setGetter() {
|
||||
scanInfo.PolicyGetter = getter.NewArmoAPI()
|
||||
func (scanInfo *ScanInfo) setUseFrom() {
|
||||
if scanInfo.UseFrom != "" {
|
||||
return
|
||||
}
|
||||
if scanInfo.UseDefault {
|
||||
scanInfo.UseFrom = GetDefaultPath(scanInfo.PolicyIdentifier.Name)
|
||||
}
|
||||
|
||||
}
|
||||
func (scanInfo *ScanInfo) setGetter() {
|
||||
|
||||
// // get from armo backend
|
||||
// scanInfo.PolicyGetter = getter.NewArmoAPI()
|
||||
|
||||
if scanInfo.UseFrom != "" {
|
||||
// load from file
|
||||
scanInfo.PolicyGetter = getter.NewLoadPolicy(scanInfo.UseFrom)
|
||||
} else {
|
||||
scanInfo.PolicyGetter = getter.NewDownloadReleasedPolicy()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (scanInfo *ScanInfo) setSilentMode() {
|
||||
if scanInfo.Format == "json" || scanInfo.Format == "junit" {
|
||||
scanInfo.Silent = true
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/armosec/kubescape/cautils"
|
||||
"github.com/armosec/kubescape/cautils/getter"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var downloadInfo cautils.DownloadInfo
|
||||
|
||||
var downloadCmd = &cobra.Command{
|
||||
Use: "download framework <framework-name>",
|
||||
Short: "Download framework controls",
|
||||
Long: ``,
|
||||
Args: func(cmd *cobra.Command, args []string) error {
|
||||
if len(args) != 2 {
|
||||
return fmt.Errorf("requires two arguments : framework <framework-name>")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
downloadInfo.FrameworkName = args[1]
|
||||
g := getter.NewDownloadReleasedPolicy()
|
||||
if !(cmd.Flags().Lookup("output").Changed) {
|
||||
downloadInfo.Path = cautils.GetDefaultPath(downloadInfo.FrameworkName)
|
||||
} else {
|
||||
currPath, err := os.Getwd()
|
||||
if err != nil {
|
||||
downloadInfo.Path = filepath.Join(downloadInfo.Path)
|
||||
} else {
|
||||
downloadInfo.Path = filepath.Join(currPath, downloadInfo.Path)
|
||||
}
|
||||
|
||||
}
|
||||
frameworks, err := g.GetFramework(downloadInfo.FrameworkName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = getter.SaveFrameworkInFile(frameworks, downloadInfo.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(downloadCmd)
|
||||
downloadInfo = cautils.DownloadInfo{}
|
||||
downloadCmd.Flags().StringVarP(&downloadInfo.Path, "output", "o", "", "Output file.")
|
||||
}
|
||||
+6
-2
@@ -33,7 +33,7 @@ var frameworkCmd = &cobra.Command{
|
||||
Long: "Execute a scan on a running Kubernetes cluster or `yaml`/`json` files (use glob) or `-` for stdin",
|
||||
ValidArgs: supportedFrameworks,
|
||||
Args: func(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
if len(args) < 1 && !(cmd.Flags().Lookup("use-from").Changed) {
|
||||
return fmt.Errorf("requires at least one argument")
|
||||
}
|
||||
if !isValidFramework(args[0]) {
|
||||
@@ -44,8 +44,10 @@ var frameworkCmd = &cobra.Command{
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
scanInfo.PolicyIdentifier = opapolicy.PolicyIdentifier{}
|
||||
scanInfo.PolicyIdentifier.Kind = opapolicy.KindFramework
|
||||
scanInfo.PolicyIdentifier.Name = args[0]
|
||||
|
||||
if !(cmd.Flags().Lookup("use-from").Changed) {
|
||||
scanInfo.PolicyIdentifier.Name = args[0]
|
||||
}
|
||||
if len(args[1:]) == 0 || args[1] != "-" {
|
||||
scanInfo.InputPatterns = args[1:]
|
||||
} else { // store stout to file
|
||||
@@ -75,6 +77,8 @@ func isValidFramework(framework string) bool {
|
||||
func init() {
|
||||
scanCmd.AddCommand(frameworkCmd)
|
||||
scanInfo = cautils.ScanInfo{}
|
||||
frameworkCmd.Flags().StringVarP(&scanInfo.UseFrom, "use-from", "", "", "Path to load framework from")
|
||||
frameworkCmd.Flags().BoolVarP(&scanInfo.UseDefault, "use-default", "", false, "Load framework from default path")
|
||||
frameworkCmd.Flags().StringVarP(&scanInfo.ExcludedNamespaces, "exclude-namespaces", "e", "", "Namespaces to exclude from check")
|
||||
frameworkCmd.Flags().StringVarP(&scanInfo.Format, "format", "f", "pretty-printer", `Output format. supported formats: "pretty-printer"/"json"/"junit"`)
|
||||
frameworkCmd.Flags().StringVarP(&scanInfo.Output, "output", "o", "", "Output file. print output to file and not stdout")
|
||||
|
||||
+25
-1
@@ -50,6 +50,18 @@ kubescape scan framework nsa https://raw.githubusercontent.com/GoogleCloudPlatfo
|
||||
helm template [CHART] [flags] --generate-name --dry-run | kubescape scan framework nsa -
|
||||
```
|
||||
|
||||
### Scan on-prem (offline)
|
||||
|
||||
* Scan using a framework from the local file system
|
||||
```
|
||||
kubescape scan framework --use-from <path>
|
||||
```
|
||||
|
||||
* Scan using the framework from the default location in file system
|
||||
```
|
||||
kubescape scan framework --use-default
|
||||
```
|
||||
|
||||
## Output formats
|
||||
|
||||
By default, the output is user friendly.
|
||||
@@ -64,4 +76,16 @@ kubescape scan framework nsa --format json --output results.json
|
||||
* Output in `junit xml` format <img src="new-feature.svg">
|
||||
```
|
||||
kubescape scan framework nsa --format junit --output results.xml
|
||||
```
|
||||
```
|
||||
|
||||
## Download
|
||||
|
||||
* Download and save in file <img src="new-feature.svg">
|
||||
```
|
||||
kubescape download framework nsa --output nsa.json
|
||||
```
|
||||
|
||||
* Download and save in default file (`~/.kubescape/<framework name>.json`)
|
||||
```
|
||||
kubescape download framework nsa
|
||||
```
|
||||
|
||||
@@ -25,7 +25,7 @@ func (policyHandler *PolicyHandler) GetPoliciesFromBackend(notification *opapoli
|
||||
}
|
||||
|
||||
default:
|
||||
err := fmt.Errorf("Missing rule kind, expected: %s", opapolicy.KindFramework)
|
||||
err := fmt.Errorf("missing rule kind, expected: %s", opapolicy.KindFramework)
|
||||
errs = fmt.Errorf("%s", err.Error())
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user