Merge pull request #380 from dwertent/master

Hot fix
This commit is contained in:
David Wertenteil
2022-02-10 14:07:34 +02:00
committed by GitHub
18 changed files with 84 additions and 53 deletions
+1 -1
View File
@@ -87,7 +87,7 @@ jobs:
run: echo '::set-output name=IMAGE_NAME::quay.io/${{ github.repository_owner }}/kubescape'
- name: Build the Docker image
run: docker build . --file build/Dockerfile --tag ${{ steps.image-name.outputs.IMAGE_NAME }}:${{ steps.image-version.outputs.IMAGE_VERSION }} --build-arg run_number=${{ github.run_number }}
run: docker build . --file build/Dockerfile --tag ${{ steps.image-name.outputs.IMAGE_NAME }}:${{ steps.image-version.outputs.IMAGE_VERSION }} --build-arg image_version=${{ steps.image-version.outputs.IMAGE_VERSION }}
- name: Re-Tag Image to latest
run: docker tag ${{ steps.image-name.outputs.IMAGE_NAME }}:${{ steps.image-version.outputs.IMAGE_VERSION }} ${{ steps.image-name.outputs.IMAGE_NAME }}:latest
+1 -1
View File
@@ -65,7 +65,7 @@ jobs:
run: echo '::set-output name=IMAGE_NAME::quay.io/${{ github.repository_owner }}/kubescape'
- name: Build the Docker image
run: docker build . --file build/Dockerfile --tag ${{ steps.image-name.outputs.IMAGE_NAME }}:${{ steps.image-version.outputs.IMAGE_VERSION }} --build-arg run_number=${{ github.run_number }}
run: docker build . --file build/Dockerfile --tag ${{ steps.image-name.outputs.IMAGE_NAME }}:${{ steps.image-version.outputs.IMAGE_VERSION }} --build-arg image_version=${{ steps.image-version.outputs.IMAGE_VERSION }}
- name: Login to Quay.io
env:
+21 -19
View File
@@ -195,38 +195,40 @@ helm template bitnami/mysql --generate-name --dry-run | kubescape scan -
```
### Offline Support
### Offline/Air-gaped Environment Support
[Video tutorial](https://youtu.be/IGXL9s37smM)
It is possible to run Kubescape offline!
First download the framework and then scan with `--use-from` flag
1. Download and save in file, if file name not specified, will save in `~/.kubescape/<framework name>.json`
```
kubescape download framework nsa --output nsa.json
```
2. Scan using the downloaded framework
```
kubescape scan framework nsa --use-from nsa.json
```
You can also download all artifacts to a local path and then load them using `--use-artifacts-from` flag
#### Download all artifacts
1. Download and save in local directory, if path not specified, will save all in `~/.kubescape`
```
kubescape download artifacts --output path/to/local/dir
```
2. Copy the downloaded artifacts to the air-gaped/offline environment
2. Scan using the downloaded artifacts
3. Scan using the downloaded artifacts
```
kubescape scan framework nsa --use-artifacts-from path/to/local/dir
kubescape scan --use-artifacts-from path/to/local/dir
```
#### Download a single artifacts
You can also download a single artifacts and scan with the `--use-from` flag
1. Download and save in file, if file name not specified, will save in `~/.kubescape/<framework name>.json`
```
kubescape download framework nsa --output /path/nsa.json
```
2. Copy the downloaded artifacts to the air-gaped/offline environment
3. Scan using the downloaded framework
```
kubescape scan framework nsa --use-from /path/nsa.json
```
## Scan Periodically using Helm - Contributed by [@yonahd](https://github.com/yonahd)
[Please follow the instructions here](https://hub.armo.cloud/docs/installation-of-armo-in-cluster)
[helm chart repo](https://github.com/armosec/armo-helm)
+2 -2
View File
@@ -1,9 +1,9 @@
FROM golang:1.17-alpine as builder
#ENV GOPROXY=https://goproxy.io,direct
ARG run_number
ARG image_version
ENV RELEASE=v1.0.${run_number}
ENV RELEASE=image_version
ENV GO111MODULE=
+5 -2
View File
@@ -57,7 +57,10 @@ func (pl *PrettyLogger) print(level helpers.Level, msg string, details ...helper
if !level.Skip(pl.level) {
pl.mutex.Lock()
prefix(level)(pl.writer, "[%s] ", level.String())
message(pl.writer, fmt.Sprintf("%s. %s\n", msg, detailsToString(details)))
if d := detailsToString(details); d != "" {
msg = fmt.Sprintf("%s. %s", msg, d)
}
message(pl.writer, fmt.Sprintf("%s\n", msg))
pl.mutex.Unlock()
}
@@ -68,7 +71,7 @@ func detailsToString(details []helpers.IDetails) string {
for i := range details {
s += fmt.Sprintf("%s: %s", details[i].Key(), details[i].Value())
if i < len(details)-1 {
s += ";"
s += "; "
}
}
return s
+8 -1
View File
@@ -2,6 +2,7 @@ package cmd
import (
"fmt"
"path/filepath"
"strings"
"github.com/armosec/kubescape/cautils"
@@ -65,10 +66,16 @@ var downloadCmd = &cobra.Command{
}
func init() {
// cobra.OnInitialize(initConfig)
cobra.OnInitialize(initDownload)
rootCmd.AddCommand(downloadCmd)
downloadCmd.PersistentFlags().StringVarP(&downloadInfo.Account, "account", "", "", "Armo portal account ID. Default will load account ID from configMap or config file")
downloadCmd.Flags().StringVarP(&downloadInfo.Path, "output", "o", "", "Output file. If not specified, will save in `~/.kubescape/<policy name>.json`")
}
func initDownload() {
if filepath.Ext(downloadInfo.Path) == ".json" {
downloadInfo.Path, downloadInfo.FileName = filepath.Split(downloadInfo.Path)
}
}
+4 -2
View File
@@ -1,8 +1,10 @@
package cmd
import (
"fmt"
"os"
"github.com/armosec/kubescape/cautils"
"github.com/armosec/kubescape/cautils/logger"
"github.com/spf13/cobra"
)
@@ -13,7 +15,7 @@ var versionCmd = &cobra.Command{
RunE: func(cmd *cobra.Command, args []string) error {
v := cautils.NewIVersionCheckHandler()
v.CheckLatestVersion(cautils.NewVersionCheckRequest(cautils.BuildNumber, "", "", "version"))
logger.L().Info("Your current version is: " + cautils.BuildNumber)
fmt.Fprintln(os.Stdout, "Your current version is: "+cautils.BuildNumber)
return nil
},
}
+18 -3
View File
@@ -36,6 +36,7 @@ type componentInterfaces struct {
func getInterfaces(scanInfo *cautils.ScanInfo) componentInterfaces {
// ================== setup k8s interface object ======================================
var k8s *k8sinterface.KubernetesApi
if scanInfo.GetScanningEnvironment() == cautils.ScanCluster {
k8s = getKubernetesApi()
@@ -44,11 +45,20 @@ func getInterfaces(scanInfo *cautils.ScanInfo) componentInterfaces {
}
}
// ================== setup tenant object ======================================
tenantConfig := getTenantConfig(scanInfo.Account, scanInfo.KubeContext, k8s)
// Set submit behavior AFTER loading tenant config
setSubmitBehavior(scanInfo, tenantConfig)
// ================== version testing ======================================
v := cautils.NewIVersionCheckHandler()
v.CheckLatestVersion(cautils.NewVersionCheckRequest(cautils.BuildNumber, policyIdentifierNames(scanInfo.PolicyIdentifier), "", scanInfo.GetScanningEnvironment()))
// ================== setup host sensor object ======================================
hostSensorHandler := getHostSensorHandler(scanInfo, k8s)
if err := hostSensorHandler.Init(); err != nil {
logger.L().Error("failed to init host sensor", helpers.Error(err))
@@ -59,24 +69,29 @@ func getInterfaces(scanInfo *cautils.ScanInfo) componentInterfaces {
scanInfo.ExcludedNamespaces = fmt.Sprintf("%s,%s", scanInfo.ExcludedNamespaces, hostSensorHandler.GetNamespace())
}
// ================== setup registry adaptors ======================================
registryAdaptors, err := resourcehandler.NewRegistryAdaptors()
if err != nil {
logger.L().Error("failed to initialize registry adaptors", helpers.Error(err))
}
// ================== setup resource collector object ======================================
resourceHandler := getResourceHandler(scanInfo, tenantConfig, k8s, hostSensorHandler, registryAdaptors)
// ================== setup reporter & printer objects ======================================
// reporting behavior - setup reporter
reportHandler := getReporter(tenantConfig, scanInfo.Submit)
v := cautils.NewIVersionCheckHandler()
v.CheckLatestVersion(cautils.NewVersionCheckRequest(cautils.BuildNumber, policyIdentifierNames(scanInfo.PolicyIdentifier), "", scanInfo.GetScanningEnvironment()))
// setup printer
printerHandler := printerv1.GetPrinter(scanInfo.Format, scanInfo.VerboseMode)
// printerHandler = printerv2.GetPrinter(scanInfo.Format, scanInfo.VerboseMode)
printerHandler.SetWriter(scanInfo.Output)
// ================== return interface ======================================
return componentInterfaces{
tenantConfig: tenantConfig,
resourceHandler: resourceHandler,
+3 -1
View File
@@ -8,6 +8,7 @@ import (
"github.com/armosec/kubescape/cautils"
"github.com/armosec/kubescape/cautils/getter"
"github.com/armosec/kubescape/cautils/logger"
"github.com/armosec/kubescape/cautils/logger/helpers"
"github.com/armosec/kubescape/hostsensorutils"
"github.com/armosec/kubescape/resourcehandler"
"github.com/armosec/kubescape/resultshandling/reporter"
@@ -58,6 +59,7 @@ func getReporter(tenantConfig cautils.ITenantConfig, submit bool) reporter.IRepo
func getResourceHandler(scanInfo *cautils.ScanInfo, tenantConfig cautils.ITenantConfig, k8s *k8sinterface.KubernetesApi, hostSensorHandler hostsensorutils.IHostSensor, registryAdaptors *resourcehandler.RegistryAdaptors) resourcehandler.IResourceHandler {
if len(scanInfo.InputPatterns) > 0 || k8s == nil {
// scanInfo.HostSensor.SetBool(false)
return resourcehandler.NewFileResourceHandler(scanInfo.InputPatterns, registryAdaptors)
}
getter.GetArmoAPIConnector()
@@ -197,7 +199,7 @@ func getConfigInputsGetter(ControlsInputs string, accountID string, downloadRele
func getDownloadReleasedPolicy(downloadReleasedPolicy *getter.DownloadReleasedPolicy) getter.IPolicyGetter {
if err := downloadReleasedPolicy.SetRegoObjects(); err != nil { // if failed to pull policy, fallback to cache
cautils.WarningDisplay(os.Stderr, "Warning: failed to get policies from github release, loading policies from cache\n")
logger.L().Warning("failed to get policies from github release, loading policies from cache", helpers.Error(err))
return getter.NewLoadPolicy(getDefaultFrameworksPaths())
} else {
return downloadReleasedPolicy
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 70 KiB

+1 -1
View File
@@ -5,7 +5,7 @@ go 1.17
require (
github.com/armosec/armoapi-go v0.0.49
github.com/armosec/k8s-interface v0.0.60
github.com/armosec/opa-utils v0.0.107
github.com/armosec/opa-utils v0.0.110
github.com/armosec/rbac-utils v0.0.14
github.com/armosec/utils-go v0.0.3
github.com/armosec/utils-k8s-go v0.0.1
+2 -2
View File
@@ -93,8 +93,8 @@ github.com/armosec/k8s-interface v0.0.50/go.mod h1:vHxGWqD/uh6+GQb9Sqv7OGMs+Rvc2
github.com/armosec/k8s-interface v0.0.60 h1:jTCiO15QQbHVuxFQ928rp4srf1rQoUzeybfcbv/cuss=
github.com/armosec/k8s-interface v0.0.60/go.mod h1:g0jv/fG+VqpT5ivO6D2gJcJ/w68BiffDz+PcU9YFbL4=
github.com/armosec/opa-utils v0.0.64/go.mod h1:6tQP8UDq2EvEfSqh8vrUdr/9QVSCG4sJfju1SXQOn4c=
github.com/armosec/opa-utils v0.0.107 h1:P+SACquUDMbXcOYIbQ+uzwcdJlrguXOTI42PHEJG2NU=
github.com/armosec/opa-utils v0.0.107/go.mod h1:Wc1P4gkB6UQeGW8I76zCuitGGl15Omp0bKw7N0tR9dk=
github.com/armosec/opa-utils v0.0.110 h1:qncGcbnYjiGULP3yK+4geRNNpRoWqKXQL+Xg+iXc1cM=
github.com/armosec/opa-utils v0.0.110/go.mod h1:Wc1P4gkB6UQeGW8I76zCuitGGl15Omp0bKw7N0tR9dk=
github.com/armosec/rbac-utils v0.0.1/go.mod h1:pQ8CBiij8kSKV7aeZm9FMvtZN28VgA7LZcYyTWimq40=
github.com/armosec/rbac-utils v0.0.14 h1:CKYKcgqJEXWF2Hen/B1pVGtS3nDAG1wp9dDv6oNtq90=
github.com/armosec/rbac-utils v0.0.14/go.mod h1:Ex/IdGWhGv9HZq6Hs8N/ApzCKSIvpNe/ETqDfnuyah0=
+2 -2
View File
@@ -157,7 +157,7 @@ func (hsh *HostSensorHandler) CollectResources() ([]hostsensor.HostSensorDataEnv
return res, nil
}
logger.L().Info("Accessing host sensor")
logger.L().Debug("Accessing host sensor")
cautils.StartSpinner()
defer cautils.StopSpinner()
kcData, err := hsh.GetKubeletConfigurations()
@@ -197,6 +197,6 @@ func (hsh *HostSensorHandler) CollectResources() ([]hostsensor.HostSensorDataEnv
res = append(res, kcData...)
// finish
logger.L().Success("Read host information from host sensor")
logger.L().Debug("Done reading information from host sensor")
return res, nil
}
+1 -1
View File
@@ -54,6 +54,6 @@ echo -e "\033[0m"
$KUBESCAPE_EXEC version
echo
echo -e "\033[35mUsage: $ $KUBESCAPE_EXEC scan --submit"
echo -e "\033[35mUsage: $ $KUBESCAPE_EXEC scan --submit --enable-host-scan"
echo -e "\033[0m"
+9 -7
View File
@@ -58,15 +58,18 @@ func NewEKSProviderContext() *EKSProviderContext {
}
func (eksProviderContext *EKSProviderContext) getKubeClusterName() string {
cluster := k8sinterface.GetCurrentContext().Cluster
var splittedCluster []string
context := k8sinterface.GetCurrentContext()
if context == nil {
return ""
}
cluster := context.Cluster
if cluster != "" {
splittedCluster = strings.Split(cluster, ".")
splittedCluster := strings.Split(cluster, ".")
if len(splittedCluster) > 1 {
return splittedCluster[0]
}
}
splittedCluster = strings.Split(k8sinterface.GetClusterName(), ".")
splittedCluster := strings.Split(k8sinterface.GetClusterName(), ".")
if len(splittedCluster) > 1 {
return splittedCluster[0]
}
@@ -78,9 +81,8 @@ func (eksProviderContext *EKSProviderContext) getKubeCluster() string {
if context == nil {
return ""
}
cluster := context.Cluster
if cluster != "" {
return cluster
if context.Cluster != "" {
return context.Cluster
}
return k8sinterface.GetClusterName()
}
+3 -5
View File
@@ -89,8 +89,7 @@ func (gkeProviderContext *GKEProviderContext) getKubeClusterName() string {
if len(parsedName) < 3 {
return ""
}
clusterName = parsedName[3]
return clusterName
return parsedName[3]
}
func (gkeProviderContext *GKEProviderContext) getKubeCluster() string {
@@ -98,9 +97,8 @@ func (gkeProviderContext *GKEProviderContext) getKubeCluster() string {
if context == nil {
return ""
}
cluster := context.Cluster
if cluster != "" {
return cluster
if context.Cluster != "" {
return context.Cluster
}
return k8sinterface.GetClusterName()
+1 -1
View File
@@ -80,7 +80,7 @@ func (k8sHandler *K8sResourceHandler) GetResources(frameworks []reporthandling.F
}
cautils.StopSpinner()
logger.L().Success("Accessed successfully to Kubernetes objects")
logger.L().Success("Accessed to Kubernetes objects")
return k8sResourcesMap, allResources, nil
}
+2 -2
View File
@@ -28,11 +28,11 @@ func listUrls(patterns []string) []string {
urls := []string{}
for i := range patterns {
if strings.HasPrefix(patterns[i], "http") {
if !isYaml(patterns[i]) || !isJson(patterns[i]) { // if url of repo
if !isYaml(patterns[i]) && !isJson(patterns[i]) { // if url of repo
if yamls, err := ScanRepository(patterns[i], ""); err == nil { // TODO - support branch
urls = append(urls, yamls...)
} else {
fmt.Print(err) // TODO - handle errors
logger.L().Error(err.Error())
}
} else { // url of single file
urls = append(urls, patterns[i])