Compare commits

...

1 Commits

Author SHA1 Message Date
Matthias Bertschy
2156677e04 add kubectl plugin with krew 2023-01-16 11:37:26 +01:00
20 changed files with 193 additions and 134 deletions

View File

@@ -89,14 +89,14 @@ jobs:
env: env:
RELEASE: ${{ inputs.release }} RELEASE: ${{ inputs.release }}
KUBESCAPE_SKIP_UPDATE_CHECK: "true" KUBESCAPE_SKIP_UPDATE_CHECK: "true"
run: python3 smoke_testing/init.py ${PWD}/build/${{ matrix.os }}/kubescape run: python3 smoke_testing/init.py ${PWD}/build/${{ matrix.os }}/kubescape-${{ matrix.os }}
if: matrix.os != 'ubuntu-20.04' if: matrix.os != 'ubuntu-20.04'
- name: Smoke Testing (Linux) - name: Smoke Testing (Linux)
env: env:
RELEASE: ${{ inputs.release }} RELEASE: ${{ inputs.release }}
KUBESCAPE_SKIP_UPDATE_CHECK: "true" KUBESCAPE_SKIP_UPDATE_CHECK: "true"
run: python3 smoke_testing/init.py ${PWD}/build/ubuntu-latest/kubescape run: python3 smoke_testing/init.py ${PWD}/build/ubuntu-latest/kubescape-ubuntu-latest
if: matrix.os == 'ubuntu-20.04' if: matrix.os == 'ubuntu-20.04'
- name: golangci-lint - name: golangci-lint

View File

@@ -25,7 +25,7 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
submodules: recursive submodules: recursive
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v3 uses: actions/setup-go@v3
with: with:
@@ -46,53 +46,26 @@ jobs:
CLIENT: release CLIENT: release
CGO_ENABLED: 1 CGO_ENABLED: 1
run: python3 --version && python3 build.py run: python3 --version && python3 build.py
- name: Upload release binaries (Windows / MacOS) - name: Upload release assets (Windows / MacOS)
id: upload-release-asset-win-macos id: upload-release-asset-win-macos
uses: actions/upload-release-asset@v1 uses: shogo82148/actions-upload-release-asset@v1
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: with:
upload_url: ${{ inputs.upload_url }} upload_url: ${{ inputs.upload_url }}
asset_path: build/${{ matrix.os }}/kubescape asset_path: build/${{ matrix.os }}/*
asset_name: kubescape-${{ matrix.os }}
asset_content_type: application/octet-stream
if: matrix.os != 'ubuntu-20.04' if: matrix.os != 'ubuntu-20.04'
- name: Upload release binaries (Linux) - name: Upload release assets (Linux)
id: upload-release-asset-linux id: upload-release-asset-linux
uses: actions/upload-release-asset@v1 uses: shogo82148/actions-upload-release-asset@v1
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: with:
upload_url: ${{ inputs.upload_url }} upload_url: ${{ inputs.upload_url }}
asset_path: build/ubuntu-latest/kubescape asset_path: build/ubuntu-latest/*
asset_name: kubescape-ubuntu-latest
asset_content_type: application/octet-stream
if: matrix.os == 'ubuntu-20.04' if: matrix.os == 'ubuntu-20.04'
- name: Upload release hash (Windows / MacOS) - name: Update new version in krew-index
id: upload-release-hash-win-macos uses: rajatjindal/krew-release-bot@v0.0.43
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ inputs.upload_url }}
asset_path: build/${{ matrix.os }}/kubescape.sha256
asset_name: kubescape-${{ matrix.os }}-sha256
asset_content_type: application/octet-stream
if: matrix.os != 'ubuntu-20.04'
- name: Upload release hash (Linux)
id: upload-release-hash-linux
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ inputs.upload_url }}
asset_path: build/ubuntu-latest/kubescape.sha256
asset_name: kubescape-ubuntu-latest-sha256
asset_content_type: application/octet-stream
if: matrix.os == 'ubuntu-20.04'

36
.krew.yaml Normal file
View File

@@ -0,0 +1,36 @@
apiVersion: krew.googlecontainertools.github.com/v1alpha2
kind: Plugin
metadata:
name: kubescape
spec:
homepage: https://kubescape.io/
shortDescription: An open-source Kubernetes security platform for your IDE, CI/CD pipelines, and clusters
version: {{ .TagName }}
description: |
Kubescape is an open-source Kubernetes security platform.
It includes risk analysis, security compliance, and misconfiguration scanning.
Targeted at the DevSecOps practitioner or platform engineer,
it offers an easy-to-use CLI interface, flexible output formats, and automated scanning capabilities.
It saves Kubernetes users and admins precious time, effort, and resources.
Kubescape was created by [ARMO](https://www.armosec.io/?utm_source=github&utm_medium=repository)
and is a [Cloud Native Computing Foundation (CNCF) sandbox project](https://www.cncf.io/sandbox-projects/).
platforms:
- selector:
matchLabels:
os: darwin
arch: amd64
{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/{{ .TagName }}/kubescape-macos-latest" .TagName }}
bin: kubectl-kubescape
- selector:
matchLabels:
os: linux
arch: amd64
{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/{{ .TagName }}/kubescape-ubuntu-latest" .TagName }}
bin: kubectl-kubescape
- selector:
matchLabels:
os: windows
arch: amd64
{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/{{ .TagName }}/kubescape-windows-latest" .TagName }}
bin: kubectl-kubescape.exe

View File

@@ -1,4 +1,5 @@
[![Version](https://img.shields.io/github/v/release/kubescape/kubescape)](releases) [![Version](https://img.shields.io/github/v/release/kubescape/kubescape)](releases)
[![build](https://github.com/kubescape/kubescape/actions/workflows/build.yaml/badge.svg)](https://github.com/kubescape/kubescape/actions/workflows/build.yaml) [![build](https://github.com/kubescape/kubescape/actions/workflows/build.yaml/badge.svg)](https://github.com/kubescape/kubescape/actions/workflows/build.yaml)
[![Go Report Card](https://goreportcard.com/badge/github.com/kubescape/kubescape)](https://goreportcard.com/report/github.com/kubescape/kubescape) [![Go Report Card](https://goreportcard.com/badge/github.com/kubescape/kubescape)](https://goreportcard.com/report/github.com/kubescape/kubescape)
[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/kubescape/kubescape) [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/kubescape/kubescape)

View File

@@ -3,9 +3,16 @@ import sys
import hashlib import hashlib
import platform import platform
import subprocess import subprocess
import tarfile
BASE_GETTER_CONST = "github.com/kubescape/kubescape/v2/core/cautils/getter" BASE_GETTER_CONST = "github.com/kubescape/kubescape/v2/core/cautils/getter"
platformSuffixes = {
"Windows": "windows-latest",
"Linux": "ubuntu-latest",
"Darwin": "macos-latest",
}
def check_status(status, msg): def check_status(status, msg):
if status != 0: if status != 0:
sys.stderr.write(msg) sys.stderr.write(msg)
@@ -14,20 +21,18 @@ def check_status(status, msg):
def get_build_dir(): def get_build_dir():
current_platform = platform.system() current_platform = platform.system()
build_dir = ""
if current_platform == "Windows": build_dir = "windows-latest" if current_platform not in platformSuffixes: raise OSError("Platform %s is not supported!" % (current_platform))
elif current_platform == "Linux": build_dir = "ubuntu-latest"
elif current_platform == "Darwin": build_dir = "macos-latest"
else: raise OSError("Platform %s is not supported!" % (current_platform))
return os.path.join("build", build_dir) return os.path.join("build", platformSuffixes[current_platform])
def get_package_name(): def get_package_name():
package_name = "kubescape" current_platform = platform.system()
return package_name if current_platform not in platformSuffixes: raise OSError("Platform %s is not supported!" % (current_platform))
return "kubescape-" + platformSuffixes[current_platform]
def main(): def main():
@@ -46,6 +51,7 @@ def main():
ks_file = os.path.join(build_dir, package_name) ks_file = os.path.join(build_dir, package_name)
hash_file = ks_file + ".sha256" hash_file = ks_file + ".sha256"
tar_file = ks_file + ".tar.gz"
if not os.path.isdir(build_dir): if not os.path.isdir(build_dir):
os.makedirs(build_dir) os.makedirs(build_dir)
@@ -73,6 +79,9 @@ def main():
print("kubescape hash: {}, file: {}".format(hash, hash_file)) print("kubescape hash: {}, file: {}".format(hash, hash_file))
kube_sha.write(sha256.hexdigest()) kube_sha.write(sha256.hexdigest())
with tarfile.open(tar_file, 'w:gz') as archive:
archive.add(ks_file, "kubescape")
print("Build Done") print("Build Done")

View File

@@ -31,7 +31,7 @@ RUN ls -ltr build/ubuntu-latest
WORKDIR /work WORKDIR /work
RUN python build.py RUN python build.py
RUN /work/build/ubuntu-latest/kubescape download artifacts -o /work/artifacts RUN /work/build/ubuntu-latest/kubescape-ubuntu-latest download artifacts -o /work/artifacts
FROM alpine:3.16.2 FROM alpine:3.16.2
@@ -45,7 +45,7 @@ USER ks
WORKDIR /home/ks WORKDIR /home/ks
COPY --from=builder /work/httphandler/build/ubuntu-latest/kubescape /usr/bin/ksserver COPY --from=builder /work/httphandler/build/ubuntu-latest/kubescape-ubuntu-latest /usr/bin/ksserver
COPY --from=builder /work/build/ubuntu-latest/kubescape /usr/bin/kubescape COPY --from=builder /work/build/ubuntu-latest/kubescape-ubuntu-latest /usr/bin/kubescape
ENTRYPOINT ["ksserver"] ENTRYPOINT ["ksserver"]

View File

@@ -1,23 +1,23 @@
package completion package completion
import ( import (
"fmt"
"os" "os"
"strings" "strings"
"github.com/kubescape/kubescape/v2/core/cautils"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var completionCmdExamples = ` var completionCmdExamples = fmt.Sprintf(`
# Enable BASH shell autocompletion # Enable BASH shell autocompletion
$ source <(kubescape completion bash) $ source <(%[1]s completion bash)
$ echo 'source <(kubescape completion bash)' >> ~/.bashrc $ echo 'source <(%[1]s completion bash)' >> ~/.bashrc
# Enable ZSH shell autocompletion # Enable ZSH shell autocompletion
$ source <(kubectl completion zsh) $ source <(kubectl completion zsh)
$ echo 'source <(kubectl completion zsh)' >> "${fpath[1]}/_kubectl" $ echo 'source <(kubectl completion zsh)' >> "${fpath[1]}/_kubectl"
`, cautils.ExecName())
`
func GetCompletionCmd() *cobra.Command { func GetCompletionCmd() *cobra.Command {
completionCmd := &cobra.Command{ completionCmd := &cobra.Command{

View File

@@ -1,34 +1,37 @@
package config package config
import ( import (
"fmt"
"github.com/kubescape/kubescape/v2/core/cautils"
"github.com/kubescape/kubescape/v2/core/meta" "github.com/kubescape/kubescape/v2/core/meta"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var ( var (
configExample = ` configExample = fmt.Sprintf(`
# View cached configurations # View cached configurations
kubescape config view %[1]s config view
# Delete cached configurations # Delete cached configurations
kubescape config delete %[1]s config delete
# Set cached configurations # Set cached configurations
kubescape config set --help %[1]s config set --help
` `, cautils.ExecName())
setConfigExample = ` setConfigExample = fmt.Sprintf(`
# Set account id # Set account id
kubescape config set accountID <account id> %[1]s config set accountID <account id>
# Set client id # Set client id
kubescape config set clientID <client id> %[1]s config set clientID <client id>
# Set access key # Set access key
kubescape config set secretKey <access key> %[1]s config set secretKey <access key>
# Set cloudAPIURL # Set cloudAPIURL
kubescape config set cloudAPIURL <cloud API URL> %[1]s config set cloudAPIURL <cloud API URL>
` `, cautils.ExecName())
) )
func GetConfigCmd(ks meta.IKubescape) *cobra.Command { func GetConfigCmd(ks meta.IKubescape) *cobra.Command {

View File

@@ -1,18 +1,21 @@
package delete package delete
import ( import (
"fmt"
"github.com/kubescape/kubescape/v2/core/cautils"
"github.com/kubescape/kubescape/v2/core/meta" "github.com/kubescape/kubescape/v2/core/meta"
v1 "github.com/kubescape/kubescape/v2/core/meta/datastructures/v1" v1 "github.com/kubescape/kubescape/v2/core/meta/datastructures/v1"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var deleteExceptionsExamples = ` var deleteExceptionsExamples = fmt.Sprintf(`
# Delete single exception # Delete single exception
kubescape delete exceptions "exception name" %[1]s delete exceptions "exception name"
# Delete multiple exceptions # Delete multiple exceptions
kubescape delete exceptions "first exception;second exception;third exception" %[1]s delete exceptions "first exception;second exception;third exception"
` `, cautils.ExecName())
func GetDeleteCmd(ks meta.IKubescape) *cobra.Command { func GetDeleteCmd(ks meta.IKubescape) *cobra.Command {
var deleteInfo v1.Delete var deleteInfo v1.Delete

View File

@@ -5,6 +5,7 @@ import (
"strings" "strings"
logger "github.com/kubescape/go-logger" logger "github.com/kubescape/go-logger"
"github.com/kubescape/kubescape/v2/core/cautils"
"github.com/kubescape/kubescape/v2/core/meta" "github.com/kubescape/kubescape/v2/core/meta"
v1 "github.com/kubescape/kubescape/v2/core/meta/datastructures/v1" v1 "github.com/kubescape/kubescape/v2/core/meta/datastructures/v1"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@@ -13,7 +14,7 @@ import (
func getExceptionsCmd(ks meta.IKubescape, deleteInfo *v1.Delete) *cobra.Command { func getExceptionsCmd(ks meta.IKubescape, deleteInfo *v1.Delete) *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "exceptions <exception name>", Use: "exceptions <exception name>",
Short: "Delete exceptions from Kubescape SaaS version. Run 'kubescape list exceptions' for all exceptions names", Short: fmt.Sprintf("Delete exceptions from Kubescape SaaS version. Run '%[1]s list exceptions' for all exceptions names", cautils.ExecName()),
Example: deleteExceptionsExamples, Example: deleteExceptionsExamples,
Args: func(cmd *cobra.Command, args []string) error { Args: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 { if len(args) != 1 {

View File

@@ -14,31 +14,31 @@ import (
) )
var ( var (
downloadExample = ` downloadExample = fmt.Sprintf(`
# Download all artifacts and save them in the default path (~/.kubescape) # Download all artifacts and save them in the default path (~/.kubescape)
kubescape download artifacts %[1]s download artifacts
# Download all artifacts and save them in /tmp path # Download all artifacts and save them in /tmp path
kubescape download artifacts --output /tmp %[1]s download artifacts --output /tmp
# Download the NSA framework. Run 'kubescape list frameworks' for all frameworks names # Download the NSA framework. Run '%[1]s list frameworks' for all frameworks names
kubescape download framework nsa %[1]s download framework nsa
# Download the "C-0001" control. Run 'kubescape list controls --id' for all controls ids # Download the "C-0001" control. Run '%[1]s list controls --id' for all controls ids
kubescape download control "C-0001" %[1]s download control "C-0001"
# Download the "C-0001" control. Run 'kubescape list controls --id' for all controls ids # Download the "C-0001" control. Run '%[1]s list controls --id' for all controls ids
kubescape download control C-0001 %[1]s download control C-0001
# Download the configured exceptions # Download the configured exceptions
kubescape download exceptions %[1]s download exceptions
# Download the configured controls-inputs # Download the configured controls-inputs
kubescape download controls-inputs %[1]s download controls-inputs
# Download the attack tracks # Download the attack tracks
kubescape download attack-tracks %[1]s download attack-tracks
` `, cautils.ExecName())
) )
func GeDownloadCmd(ks meta.IKubescape) *cobra.Command { func GeDownloadCmd(ks meta.IKubescape) *cobra.Command {

View File

@@ -13,19 +13,19 @@ import (
) )
var ( var (
listExample = ` listExample = fmt.Sprintf(`
# List default supported frameworks names # List default supported frameworks names
kubescape list frameworks %[1]s list frameworks
# List all supported frameworks names # List all supported frameworks names
kubescape list frameworks --account <account id> %[1]s list frameworks --account <account id>
# List all supported controls names with ids # List all supported controls names with ids
kubescape list controls %[1]s list controls
Control documentation: Control documentation:
https://hub.armosec.io/docs/controls https://hub.armosec.io/docs/controls
` `, cautils.ExecName())
) )
func GetListCmd(ks meta.IKubescape) *cobra.Command { func GetListCmd(ks meta.IKubescape) *cobra.Command {
@@ -65,7 +65,7 @@ func GetListCmd(ks meta.IKubescape) *cobra.Command {
listCmd.PersistentFlags().StringVarP(&listPolicies.Credentials.ClientID, "client-id", "", "", "Kubescape SaaS client ID. Default will load client ID from cache, read more - https://hub.armosec.io/docs/authentication") listCmd.PersistentFlags().StringVarP(&listPolicies.Credentials.ClientID, "client-id", "", "", "Kubescape SaaS client ID. Default will load client ID from cache, read more - https://hub.armosec.io/docs/authentication")
listCmd.PersistentFlags().StringVarP(&listPolicies.Credentials.SecretKey, "secret-key", "", "", "Kubescape SaaS secret key. Default will load secret key from cache, read more - https://hub.armosec.io/docs/authentication") listCmd.PersistentFlags().StringVarP(&listPolicies.Credentials.SecretKey, "secret-key", "", "", "Kubescape SaaS secret key. Default will load secret key from cache, read more - https://hub.armosec.io/docs/authentication")
listCmd.PersistentFlags().StringVar(&listPolicies.Format, "format", "pretty-print", "output format. supported: 'pretty-print'/'json'") listCmd.PersistentFlags().StringVar(&listPolicies.Format, "format", "pretty-print", "output format. supported: 'pretty-print'/'json'")
listCmd.PersistentFlags().MarkDeprecated("id", "Control ID's are included in list outpus") listCmd.PersistentFlags().MarkDeprecated("id", "Control ID's are included in list outputs")
return listCmd return listCmd
} }

View File

@@ -26,19 +26,19 @@ import (
var rootInfo cautils.RootInfo var rootInfo cautils.RootInfo
var ksExamples = ` var ksExamples = fmt.Sprintf(`
# Scan command # Scan command
kubescape scan %[1]s scan
# List supported frameworks # List supported frameworks
kubescape list frameworks %[1]s list frameworks
# Download artifacts (air-gapped environment support) # Download artifacts (air-gapped environment support)
kubescape download artifacts %[1]s download artifacts
# View cached configurations # View cached configurations
kubescape config view %[1]s config view
` `, cautils.ExecName())
func NewDefaultKubescapeCommand() *cobra.Command { func NewDefaultKubescapeCommand() *cobra.Command {
ks := core.NewKubescape() ks := core.NewKubescape()
@@ -53,6 +53,16 @@ func getRootCmd(ks meta.IKubescape) *cobra.Command {
Example: ksExamples, Example: ksExamples,
} }
if cautils.IsKrewPlugin() {
// Invoked as a kubectl plugin.
// Cobra doesn't have a way to specify a two word command (i.e. "kubectl kubescape"), so set a custom usage template
// with kubectl in it. Cobra will use this template for the root and all child commands.
oldUsageTemplate := rootCmd.UsageTemplate()
newUsageTemplate := strings.NewReplacer("{{.UseLine}}", "kubectl {{.UseLine}}", "{{.CommandPath}}", "kubectl {{.CommandPath}}").Replace(oldUsageTemplate)
rootCmd.SetUsageTemplate(newUsageTemplate)
}
rootCmd.PersistentFlags().StringVar(&rootInfo.KSCloudBEURLsDep, "environment", "", envFlagUsage) rootCmd.PersistentFlags().StringVar(&rootInfo.KSCloudBEURLsDep, "environment", "", envFlagUsage)
rootCmd.PersistentFlags().StringVar(&rootInfo.KSCloudBEURLs, "env", "", envFlagUsage) rootCmd.PersistentFlags().StringVar(&rootInfo.KSCloudBEURLs, "env", "", envFlagUsage)
rootCmd.PersistentFlags().MarkDeprecated("environment", "use 'env' instead") rootCmd.PersistentFlags().MarkDeprecated("environment", "use 'env' instead")

View File

@@ -18,28 +18,28 @@ import (
) )
var ( var (
controlExample = ` controlExample = fmt.Sprintf(`
# Scan the 'privileged container' control # Scan the 'privileged container' control
kubescape scan control "privileged container" %[1]s scan control "privileged container"
# Scan list of controls separated with a comma # Scan list of controls separated with a comma
kubescape scan control "privileged container","HostPath mount" %[1]s scan control "privileged container","HostPath mount"
# Scan list of controls using the control ID separated with a comma # Scan list of controls using the control ID separated with a comma
kubescape scan control C-0058,C-0057 %[1]s scan control C-0058,C-0057
Run 'kubescape list controls' for the list of supported controls Run '%[1]s list controls' for the list of supported controls
Control documentation: Control documentation:
https://hub.armosec.io/docs/controls https://hub.armosec.io/docs/controls
` `, cautils.ExecName())
) )
// controlCmd represents the control command // controlCmd represents the control command
func getControlCmd(ks meta.IKubescape, scanInfo *cautils.ScanInfo) *cobra.Command { func getControlCmd(ks meta.IKubescape, scanInfo *cautils.ScanInfo) *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "control <control names list>/<control ids list>", Use: "control <control names list>/<control ids list>",
Short: "The controls you wish to use. Run 'kubescape list controls' for the list of supported controls", Short: fmt.Sprintf("The controls you wish to use. Run '%[1]s list controls' for the list of supported controls", cautils.ExecName()),
Example: controlExample, Example: controlExample,
Args: func(cmd *cobra.Command, args []string) error { Args: func(cmd *cobra.Command, args []string) error {
if len(args) > 0 { if len(args) > 0 {
@@ -67,7 +67,7 @@ func getControlCmd(ks meta.IKubescape, scanInfo *cautils.ScanInfo) *cobra.Comman
if len(args) == 0 { if len(args) == 0 {
scanInfo.ScanAll = true scanInfo.ScanAll = true
} else { // expected control or list of control sepparated by "," } else { // expected control or list of control separated by ","
// Read controls from input args // Read controls from input args
scanInfo.SetPolicyIdentifiers(strings.Split(args[0], ","), apisv1.KindControl) scanInfo.SetPolicyIdentifiers(strings.Split(args[0], ","), apisv1.KindControl)

View File

@@ -20,24 +20,24 @@ import (
) )
var ( var (
frameworkExample = ` frameworkExample = fmt.Sprintf(`
# Scan all frameworks # Scan all frameworks
kubescape scan framework all %[1]s scan framework all
# Scan the NSA framework # Scan the NSA framework
kubescape scan framework nsa %[1]s scan framework nsa
# Scan the NSA and MITRE framework # Scan the NSA and MITRE framework
kubescape scan framework nsa,mitre %[1]s scan framework nsa,mitre
# Scan all frameworks # Scan all frameworks
kubescape scan framework all %[1]s scan framework all
# Scan kubernetes YAML manifest files (single file or glob) # Scan kubernetes YAML manifest files (single file or glob)
kubescape scan framework nsa . %[1]s scan framework nsa .
Run 'kubescape list frameworks' for the list of supported frameworks Run '%[1]s list frameworks' for the list of supported frameworks
` `, cautils.ExecName())
ErrUnknownSeverity = errors.New("unknown severity") ErrUnknownSeverity = errors.New("unknown severity")
) )
@@ -46,7 +46,7 @@ func getFrameworkCmd(ks meta.IKubescape, scanInfo *cautils.ScanInfo) *cobra.Comm
return &cobra.Command{ return &cobra.Command{
Use: "framework <framework names list> [`<glob pattern>`/`-`] [flags]", Use: "framework <framework names list> [`<glob pattern>`/`-`] [flags]",
Short: "The framework you wish to use. Run 'kubescape list frameworks' for the list of supported frameworks", Short: fmt.Sprintf("The framework you wish to use. Run '%[1]s list frameworks' for the list of supported frameworks", cautils.ExecName()),
Example: frameworkExample, Example: frameworkExample,
Long: "Execute a scan on a running Kubernetes cluster or `yaml`/`json` files (use glob) or `-` for stdin", Long: "Execute a scan on a running Kubernetes cluster or `yaml`/`json` files (use glob) or `-` for stdin",
Args: func(cmd *cobra.Command, args []string) error { Args: func(cmd *cobra.Command, args []string) error {

View File

@@ -10,25 +10,24 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var scanCmdExamples = ` var scanCmdExamples = fmt.Sprintf(`
Scan command is for scanning an existing cluster or kubernetes manifest files based on pre-defined frameworks Scan command is for scanning an existing cluster or kubernetes manifest files based on pre-defined frameworks
# Scan current cluster with all frameworks # Scan current cluster with all frameworks
kubescape scan --enable-host-scan --verbose %[1]s scan --enable-host-scan --verbose
# Scan kubernetes YAML manifest files # Scan kubernetes YAML manifest files
kubescape scan . %[1]s scan .
# Scan and save the results in the JSON format # Scan and save the results in the JSON format
kubescape scan --format json --output results.json --format-version=v2 %[1]s scan --format json --output results.json --format-version=v2
# Display all resources # Display all resources
kubescape scan --verbose %[1]s scan --verbose
# Scan different clusters from the kubectl context # Scan different clusters from the kubectl context
kubescape scan --kube-context <kubernetes context> %[1]s scan --kube-context <kubernetes context>
`, cautils.ExecName())
`
func GetScanCommand(ks meta.IKubescape) *cobra.Command { func GetScanCommand(ks meta.IKubescape) *cobra.Command {
var scanInfo cautils.ScanInfo var scanInfo cautils.ScanInfo

View File

@@ -19,13 +19,13 @@ import (
) )
var ( var (
rbacExamples = ` rbacExamples = fmt.Sprintf(`
# Submit cluster's Role-Based Access Control(RBAC) # Submit cluster's Role-Based Access Control(RBAC)
kubescape submit rbac %[1]s submit rbac
# Submit cluster's Role-Based Access Control(RBAC) with account ID # Submit cluster's Role-Based Access Control(RBAC) with account ID
kubescape submit rbac --account <account-id> %[1]s submit rbac --account <account-id>
` `, cautils.ExecName())
) )
// getRBACCmd represents the RBAC command // getRBACCmd represents the RBAC command
@@ -36,7 +36,7 @@ func getRBACCmd(ks meta.IKubescape, submitInfo *v1.Submit) *cobra.Command {
Example: rbacExamples, Example: rbacExamples,
Short: "Submit cluster's Role-Based Access Control(RBAC)", Short: "Submit cluster's Role-Based Access Control(RBAC)",
Long: ``, Long: ``,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(_ *cobra.Command, args []string) error {
if err := flagValidationSubmit(submitInfo); err != nil { if err := flagValidationSubmit(submitInfo); err != nil {
return err return err
@@ -51,7 +51,7 @@ func getRBACCmd(ks meta.IKubescape, submitInfo *v1.Submit) *cobra.Command {
} }
if clusterConfig.GetAccountID() == "" { if clusterConfig.GetAccountID() == "" {
return fmt.Errorf("account ID is not set, run 'kubescape submit rbac --account <account-id>'") return fmt.Errorf("account ID is not set, run '%[1]s submit rbac --account <account-id>'", cautils.ExecName())
} }
// list RBAC // list RBAC

View File

@@ -6,6 +6,7 @@ import (
"os" "os"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/kubescape/kubescape/v2/core/cautils"
reporthandlingv2 "github.com/kubescape/opa-utils/reporthandling/v2" reporthandlingv2 "github.com/kubescape/opa-utils/reporthandling/v2"
logger "github.com/kubescape/go-logger" logger "github.com/kubescape/go-logger"
@@ -50,7 +51,7 @@ func (resultsObject *ResultsObject) ListAllResources() (map[string]workloadinter
func getResultsCmd(ks meta.IKubescape, submitInfo *v1.Submit) *cobra.Command { func getResultsCmd(ks meta.IKubescape, submitInfo *v1.Submit) *cobra.Command {
var resultsCmd = &cobra.Command{ var resultsCmd = &cobra.Command{
Use: "results <json file>\nExample:\n$ kubescape submit results path/to/results.json --format-version v2", Use: fmt.Sprintf("results <json file>\nExample:\n$ %[1]s submit results path/to/results.json --format-version v2", cautils.ExecName()),
Short: "Submit a pre scanned results file. The file must be in json format", Short: "Submit a pre scanned results file. The file must be in json format",
Long: ``, Long: ``,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
@@ -87,7 +88,7 @@ func getResultsCmd(ks meta.IKubescape, submitInfo *v1.Submit) *cobra.Command {
return nil return nil
}, },
} }
resultsCmd.PersistentFlags().StringVar(&formatVersion, "format-version", "v1", "Output object can be differnet between versions, this is for maintaining backward and forward compatibility. Supported:'v1'/'v2'") resultsCmd.PersistentFlags().StringVar(&formatVersion, "format-version", "v1", "Output object can be different between versions, this is for maintaining backward and forward compatibility. Supported:'v1'/'v2'")
return resultsCmd return resultsCmd
} }

View File

@@ -1,18 +1,21 @@
package submit package submit
import ( import (
"fmt"
"github.com/kubescape/kubescape/v2/core/cautils"
"github.com/kubescape/kubescape/v2/core/meta" "github.com/kubescape/kubescape/v2/core/meta"
metav1 "github.com/kubescape/kubescape/v2/core/meta/datastructures/v1" metav1 "github.com/kubescape/kubescape/v2/core/meta/datastructures/v1"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var submitCmdExamples = ` var submitCmdExamples = fmt.Sprintf(`
# Submit Kubescape scan results file # Submit Kubescape scan results file
kubescape submit results %[1]s submit results
# Submit exceptions file to Kubescape SaaS # Submit exceptions file to Kubescape SaaS
kubescape submit exceptions %[1]s submit exceptions
` `, cautils.ExecName())
func GetSubmitCmd(ks meta.IKubescape) *cobra.Command { func GetSubmitCmd(ks meta.IKubescape) *cobra.Command {
var submitInfo metav1.Submit var submitInfo metav1.Submit

20
core/cautils/krewutils.go Normal file
View File

@@ -0,0 +1,20 @@
package cautils
import (
"os"
"path/filepath"
"strings"
)
// ExecName returns the correct name to use in examples depending on how kubescape is invoked
func ExecName() string {
n := "kubescape"
if IsKrewPlugin() {
return "kubectl " + n
}
return n
}
func IsKrewPlugin() bool {
return strings.HasPrefix(filepath.Base(os.Args[0]), "kubectl-")
}