Compare commits

..

2 Commits
v2.0.3 ... dev

Author SHA1 Message Date
Vlad Klokun
c717a9233b Merge pull request #1046 from fredbi/fix/1040-empty-framework-name
fix ListFrameworks (could return an empty element)
2023-01-20 17:16:31 +02:00
Frédéric BIDON
e37f47de3a fix ListFrameworks (could return an empty element)
Signed-off-by: Frédéric BIDON <fredbi@yahoo.com>
2023-01-20 14:06:51 +01:00
32 changed files with 475 additions and 392 deletions

64
.github/workflows/01-golang-lint.yaml vendored Normal file
View File

@@ -0,0 +1,64 @@
name: golangci-lint
on:
push:
branches:
- dev
pull_request:
types: [ edited, opened, synchronize, reopened ]
branches:
- 'master'
- 'main'
- 'dev'
paths-ignore:
- '**.yaml'
- '**.md'
- '**.sh'
- 'website/*'
- 'examples/*'
- 'docs/*'
- 'build/*'
- '.github/*'
permissions:
contents: read
# Optional: allow read access to pull request. Use with `only-new-issues` option.
pull-requests: read
jobs:
golangci:
name: lint
runs-on: ubuntu-20.04
steps:
- uses: actions/setup-go@v3
with:
go-version: 1.19
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Install libgit2
run: make libgit2
- name: golangci-lint
continue-on-error: true
uses: golangci/golangci-lint-action@v3
with:
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
version: latest
# Optional: working directory, useful for monorepos
# working-directory: somedir
# Optional: golangci-lint command line arguments.
# args: --issues-exit-code=0
args: --timeout 10m --build-tags=static
#--new-from-rev dev
# Optional: show only new issues if it's a pull request. The default value is `false`.
only-new-issues: true
# Optional: if set to true then the all caching functionality will be complete disabled,
# takes precedence over all other caching options.
# skip-cache: true
# Optional: if set to true then the action don't cache or restore ~/go/pkg.
# skip-pkg-cache: true
# Optional: if set to true then the action don't cache or restore ~/.cache/go-build.
# skip-build-cache: true

View File

@@ -1,71 +0,0 @@
name: publish-artifacts
on:
workflow_call:
inputs:
upload_url:
description: 'upload url'
required: true
type: string
release:
description: 'release tag'
required: true
type: string
jobs:
publish-artifacts:
name: Build and publish artifacts
runs-on: ${{ matrix.os }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
strategy:
matrix:
os: [ubuntu-20.04, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.19
- name: Install MSYS2 & libgit2 (Windows)
shell: cmd
run: .\build.bat all
if: matrix.os == 'windows-latest'
- name: Install libgit2 (Linux/macOS)
run: make libgit2
if: matrix.os != 'windows-latest'
- name: Build
env:
RELEASE: ${{ inputs.release }}
CLIENT: release
CGO_ENABLED: 1
run: python3 --version && python3 build.py
- name: Upload release assets (Windows / MacOS)
id: upload-release-asset-win-macos
uses: shogo82148/actions-upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ inputs.upload_url }}
asset_path: build/${{ matrix.os }}/*
if: matrix.os != 'ubuntu-20.04'
- name: Upload release assets (Linux)
id: upload-release-asset-linux
uses: shogo82148/actions-upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ inputs.upload_url }}
asset_path: build/ubuntu-latest/*
if: matrix.os == 'ubuntu-20.04'
- name: Update new version in krew-index
uses: rajatjindal/krew-release-bot@v0.0.43

View File

@@ -1,52 +0,0 @@
# Kubescape workflows
Tag terminology: `v<major>.<minor>.<patch>`
## Developing process
Kubescape's main branch is `main`, any PR will be opened against the main branch.
### Opening a PR
When a user opens a PR, this will trigger some basic tests (units, license, etc.)
### Reviewing a PR
The reviewer/maintainer of a PR will decide whether the PR introduces changes that require running the E2E system tests. If so, the reviewer will add the `trigger-integration-test` label.
### Approving a PR
Once a maintainer approves the PR, if the `trigger-integration-test` label was added to the PR, the GitHub actions will trigger the system test. The PR will be merged only after the system tests passed successfully. If the label was not added, the PR can be merged.
### Merging a PR
The code is merged, no other actions are needed
## Release process
Every two weeks, we will create a new tag by bumping the minor version, this will create the release and publish the artifacts.
If we are introducing breaking changes, we will update the `major` version instead.
When we wish to push a hot-fix/feature within the two weeks, we will bump the `patch`.
### Creating a new tag
Every two weeks or upon the decision of the maintainers, a maintainer can create a tag.
The tag should look as follows: `v<A>.<B>.<C>-rc.D` (release candidate).
When creating a tag, GitHub will trigger the following actions:
1. Basic tests - unit tests, license, etc.
2. System tests (integration tests). If the tests fail, the actions will stop here.
3. Create a new tag: `v<A>.<B>.<C>` (same tag just without the `rc` suffix)
4. Create a release
5. Publish artifacts
6. Build and publish the docker image (this is meanwhile until we separate the microservice code from the LCI codebase)
## Additional Information
The "callers" have the alphabetic prefix and the "executes" have the numeric prefix
## Screenshot
<img width="1469" alt="image" src="https://user-images.githubusercontent.com/64066841/212532727-e82ec9e7-263d-408b-b4b0-a8c943f0109a.png">

View File

@@ -1,4 +1,4 @@
name: 03-publish-image
name: build
on:
workflow_call:

124
.github/workflows/build.yaml vendored Normal file
View File

@@ -0,0 +1,124 @@
name: build
on:
push:
branches:
- 'master'
- 'main'
paths-ignore:
- '**.yaml'
- '**.md'
- '**.sh'
- 'website/*'
- 'examples/*'
- 'docs/*'
- 'build/*'
- '.github/*'
jobs:
test:
uses: ./.github/workflows/test.yaml
with:
release: "v2.0.${{ github.run_number }}"
client: test
create-release:
uses: ./.github/workflows/release.yaml
needs: test
with:
release_name: "Release v2.0.${{ github.run_number }}"
tag_name: "v2.0.${{ github.run_number }}"
secrets: inherit
publish-artifacts:
name: Build and publish artifacts
needs: create-release
runs-on: ${{ matrix.os }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
strategy:
matrix:
os: [ubuntu-20.04, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.19
- name: Install MSYS2 & libgit2 (Windows)
shell: cmd
run: .\build.bat all
if: matrix.os == 'windows-latest'
- name: Install libgit2 (Linux/macOS)
run: make libgit2
if: matrix.os != 'windows-latest'
- name: Build
env:
RELEASE: v2.0.${{ github.run_number }}
CLIENT: release
CGO_ENABLED: 1
run: python3 --version && python3 build.py
- name: Upload release binaries (Windows / MacOS)
id: upload-release-asset-win-macos
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-release.outputs.upload_url }}
asset_path: build/${{ matrix.os }}/kubescape
asset_name: kubescape-${{ matrix.os }}
asset_content_type: application/octet-stream
if: matrix.os != 'ubuntu-20.04'
- name: Upload release binaries (Linux)
id: upload-release-asset-linux
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-release.outputs.upload_url }}
asset_path: build/ubuntu-latest/kubescape
asset_name: kubescape-ubuntu-latest
asset_content_type: application/octet-stream
if: matrix.os == 'ubuntu-20.04'
- name: Upload release hash (Windows / MacOS)
id: upload-release-hash-win-macos
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-release.outputs.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: ${{ needs.create-release.outputs.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'
publish-image:
uses: ./.github/workflows/build-image.yaml
needs: create-release
with:
client: "image-release"
image_name: "quay.io/${{ github.repository_owner }}/kubescape"
image_tag: "v2.0.${{ github.run_number }}"
support_platforms: true
cosign: true
secrets: inherit

31
.github/workflows/build_dev.yaml vendored Normal file
View File

@@ -0,0 +1,31 @@
name: build-dev
on:
push:
branches: [ dev ]
paths-ignore:
- '**.yaml'
- '**.md'
- '**.sh'
- 'website/*'
- 'examples/*'
- 'docs/*'
- 'build/*'
- '.github/*'
jobs:
test:
uses: ./.github/workflows/test.yaml
with:
release: "v2.0.${{ github.run_number }}"
client: test
# publish-dev-image:
# uses: ./.github/workflows/build-image.yaml
# needs: test
# with:
# client: "image-dev"
# image_name: "quay.io/${{ github.repository_owner }}/kubescape"
# image_tag: "dev-v2.0.${{ github.run_number }}"
# support_platforms: true
# cosign: true
# secrets: inherit

View File

@@ -1,47 +0,0 @@
name: release
on:
push:
tags:
# - 'v*.*.*-rc.*' # Comment out since the re-tagging process is not yet implemented
- 'v*.*.*'
jobs:
test:
uses: ./.github/workflows/00-test.yaml
with:
release: ${{ github.ref_name}}
client: test
# integration-test:
# if: ${{ label == e2e-tests }}
# re-tag:
# # if tests passed, create new tag without `rc`
create-release:
uses: ./.github/workflows/01-create-release.yaml
needs: test
with:
release_name: "Release ${{ github.ref_name}}"
tag: ${{ github.ref_name}}
secrets: inherit
publish-artifacts:
uses: ./.github/workflows/02-publish-artifacts.yaml
needs: create-release
with:
upload_url: ${{ needs.create-release.outputs.upload_url }}
release: "${{ github.ref_name}}"
secrets: inherit
publish-image:
uses: ./.github/workflows/03-publish-image.yaml
needs: create-release
with:
client: "image-release"
image_name: "quay.io/${{ github.repository_owner }}/kubescape"
image_tag: "${{ github.ref_name}}"
support_platforms: true
cosign: true
secrets: inherit

View File

@@ -18,7 +18,7 @@ on:
- '.github/*'
jobs:
test:
uses: ./.github/workflows/00-test.yaml
uses: ./.github/workflows/test.yaml
with:
release: ${{ github.ref_name}}
release: "v2.0.${{ github.run_number }}"
client: test

View File

@@ -1,4 +1,4 @@
name: 01-create-release
name: build
on:
workflow_call:
@@ -7,7 +7,7 @@ on:
description: 'release'
required: true
type: string
tag:
tag_name:
description: 'tag'
required: true
type: string
@@ -34,8 +34,8 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ inputs.tag_name }}
release_name: ${{ inputs.release_name }}
tag_name: ${{ inputs.tag }}
draft: ${{ inputs.draft }}
prerelease: false

View File

@@ -1,4 +1,4 @@
name: 00-test
name: test
on:
workflow_call:
@@ -12,7 +12,7 @@ on:
required: true
type: string
jobs:
basic-tests:
build:
name: Create cross-platform build
runs-on: ${{ matrix.os }}
env:
@@ -89,41 +89,12 @@ jobs:
env:
RELEASE: ${{ inputs.release }}
KUBESCAPE_SKIP_UPDATE_CHECK: "true"
run: python3 smoke_testing/init.py ${PWD}/build/${{ matrix.os }}/kubescape-${{ matrix.os }}
run: python3 smoke_testing/init.py ${PWD}/build/${{ matrix.os }}/kubescape
if: matrix.os != 'ubuntu-20.04'
- name: Smoke Testing (Linux)
env:
RELEASE: ${{ inputs.release }}
KUBESCAPE_SKIP_UPDATE_CHECK: "true"
run: python3 smoke_testing/init.py ${PWD}/build/ubuntu-latest/kubescape-ubuntu-latest
if: matrix.os == 'ubuntu-20.04'
- name: golangci-lint
if: matrix.os == 'ubuntu-20.04'
continue-on-error: true
uses: golangci/golangci-lint-action@v3
with:
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
version: latest
# Optional: working directory, useful for monorepos
# working-directory: somedir
# Optional: golangci-lint command line arguments.
# args: --issues-exit-code=0
args: --timeout 10m --build-tags=static
#--new-from-rev dev
# Optional: show only new issues if it's a pull request. The default value is `false`.
only-new-issues: true
# Optional: if set to true then the all caching functionality will be complete disabled,
# takes precedence over all other caching options.
# skip-cache: true
# Optional: if set to true then the action don't cache or restore ~/go/pkg.
# skip-pkg-cache: true
# Optional: if set to true then the action don't cache or restore ~/.cache/go-build.
# skip-build-cache: true
run: python3 smoke_testing/init.py ${PWD}/build/ubuntu-latest/kubescape
if: matrix.os == 'ubuntu-20.04'

View File

@@ -1,36 +0,0 @@
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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -13,19 +13,19 @@ import (
)
var (
listExample = fmt.Sprintf(`
listExample = `
# List default supported frameworks names
%[1]s list frameworks
kubescape list frameworks
# List all supported frameworks names
%[1]s list frameworks --account <account id>
kubescape list frameworks --account <account id>
# List all supported controls names with ids
%[1]s list controls
kubescape list controls
Control documentation:
https://hub.armosec.io/docs/controls
`, cautils.ExecName())
`
)
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.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().MarkDeprecated("id", "Control ID's are included in list outputs")
listCmd.PersistentFlags().MarkDeprecated("id", "Control ID's are included in list outpus")
return listCmd
}

View File

@@ -26,19 +26,19 @@ import (
var rootInfo cautils.RootInfo
var ksExamples = fmt.Sprintf(`
var ksExamples = `
# Scan command
%[1]s scan
kubescape scan
# List supported frameworks
%[1]s list frameworks
kubescape list frameworks
# Download artifacts (air-gapped environment support)
%[1]s download artifacts
kubescape download artifacts
# View cached configurations
%[1]s config view
`, cautils.ExecName())
kubescape config view
`
func NewDefaultKubescapeCommand() *cobra.Command {
ks := core.NewKubescape()
@@ -53,16 +53,6 @@ func getRootCmd(ks meta.IKubescape) *cobra.Command {
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.KSCloudBEURLs, "env", "", envFlagUsage)
rootCmd.PersistentFlags().MarkDeprecated("environment", "use 'env' instead")

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -160,7 +160,7 @@ func (lp *LoadPolicy) ListFrameworks() ([]string, error) {
continue
}
if contains(frameworkNames, framework.Name) {
if framework.Name == "" || contains(frameworkNames, framework.Name) {
continue
}

View File

@@ -179,6 +179,29 @@ func TestLoadPolicy(t *testing.T) {
require.Equal(t, extraFramework, fws[1])
})
t.Run("should not return an empty framework", func(t *testing.T) {
t.Parallel()
const (
extraFramework = "NSA"
attackTracks = "attack-tracks"
controlsInputs = "controls-inputs"
)
p := NewLoadPolicy([]string{
testFrameworkFile(testFramework),
testFrameworkFile(extraFramework),
testFrameworkFile(attackTracks), // should be ignored
testFrameworkFile(controlsInputs), // should be ignored
})
fws, err := p.ListFrameworks()
require.NoError(t, err)
require.Len(t, fws, 2)
require.NotContains(t, fws, "")
require.Equal(t, testFramework, fws[0])
require.Equal(t, extraFramework, fws[1])
})
t.Run("should fail on file error", func(t *testing.T) {
t.Parallel()

View File

@@ -0,0 +1,125 @@
{
"publicRegistries": [],
"untrustedRegistries": [],
"listOfDangerousArtifacts": [
"bin/bash",
"sbin/sh",
"bin/ksh",
"bin/tcsh",
"bin/zsh",
"usr/bin/scsh",
"bin/csh",
"bin/busybox",
"usr/bin/busybox"
],
"sensitiveKeyNames": [
"aws_access_key_id",
"aws_secret_access_key",
"azure_batchai_storage_account",
"azure_batchai_storage_key",
"azure_batch_account",
"azure_batch_key",
"secret",
"key",
"password",
"pwd",
"token",
"jwt",
"bearer",
"credential"
],
"servicesNames": [
"nifi-service",
"argo-server",
"minio",
"postgres",
"workflow-controller-metrics",
"weave-scope-app",
"kubernetes-dashboard"
],
"memory_limit_max": [],
"cpu_request_min": [],
"wlKnownNames": [
"coredns",
"kube-proxy",
"event-exporter-gke",
"kube-dns",
"17-default-backend",
"metrics-server",
"ca-audit",
"ca-dashboard-aggregator",
"ca-notification-server",
"ca-ocimage",
"ca-oracle",
"ca-posture",
"ca-rbac",
"ca-vuln-scan",
"ca-webhook",
"ca-websocket",
"clair-clair"
],
"sensitiveInterfaces": [
"nifi",
"argo-server",
"weave-scope-app",
"kubeflow",
"kubernetes-dashboard",
"jenkins",
"prometheus-deployment"
],
"max_high_vulnerabilities": [
"10"
],
"sensitiveValues": [
"BEGIN \\w+ PRIVATE KEY",
"PRIVATE KEY",
"eyJhbGciO",
"JWT",
"Bearer",
"_key_",
"_secret_"
],
"memory_request_max": [],
"memory_request_min": [],
"cpu_request_max": [],
"cpu_limit_max": [],
"cpu_limit_min": [],
"insecureCapabilities": [
"SETPCAP",
"NET_ADMIN",
"NET_RAW",
"SYS_MODULE",
"SYS_RAWIO",
"SYS_PTRACE",
"SYS_ADMIN",
"SYS_BOOT",
"MAC_OVERRIDE",
"MAC_ADMIN",
"PERFMON",
"ALL",
"BPF"
],
"max_critical_vulnerabilities": [
"5"
],
"sensitiveValuesAllowed": [],
"memory_limit_min": [],
"recommendedLabels": [
"app",
"tier",
"phase",
"version",
"owner",
"env"
],
"k8sRecommendedLabels": [
"app.kubernetes.io/name",
"app.kubernetes.io/instance",
"app.kubernetes.io/version",
"app.kubernetes.io/component",
"app.kubernetes.io/part-of",
"app.kubernetes.io/managed-by",
"app.kubernetes.io/created-by"
],
"imageRepositoryAllowList": []
}

View File

@@ -1,20 +0,0 @@
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-")
}