Update posture report flag and cluster name

This commit is contained in:
Daniel-GrunbergerCA
2021-09-12 18:13:24 +03:00
parent 4171d110a4
commit 9fc455bcec
8 changed files with 104 additions and 41 deletions
+28 -6
View File
@@ -3,8 +3,10 @@ package cautils
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/url"
"os"
"github.com/armosec/kubescape/cautils/getter"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -31,9 +33,9 @@ func (co *ConfigObj) Json() []byte {
}
type IClusterConfig interface {
SetCustomerGUID()
GetCustomerGUID()
GenerateURL() string
SetCustomerGUID() error
GetCustomerGUID() string
GenerateURL()
}
type ClusterConfig struct {
@@ -43,18 +45,37 @@ type ClusterConfig struct {
configObj *ConfigObj
}
type EmptyConfig struct {
}
func (c *EmptyConfig) GenerateURL() {
}
func (c *EmptyConfig) SetCustomerGUID() error {
return nil
}
func (c *EmptyConfig) GetCustomerGUID() string {
return ""
}
func NewEmptyConfig() *EmptyConfig {
return &EmptyConfig{}
}
func NewClusterConfig(k8s *k8sinterface.KubernetesApi, armoAPI *getter.ArmoAPI) *ClusterConfig {
return &ClusterConfig{
k8s: k8s,
armoAPI: armoAPI,
defaultNS: "default", // TODO - load default namespace from k8s api
defaultNS: k8sinterface.GetDefaultNamespace(),
}
}
func (c *ClusterConfig) update(configObj *ConfigObj) {
c.configObj = configObj
ioutil.WriteFile(getter.GetDefaultPath(configFileName+".json"), c.configObj.Json(), 0664)
}
func (c *ClusterConfig) GenerateURL() string {
func (c *ClusterConfig) GenerateURL() {
u := url.URL{}
u.Scheme = "https"
u.Host = getter.ArmoFEURL
@@ -64,8 +85,9 @@ func (c *ClusterConfig) GenerateURL() string {
q.Add("customerGUID", c.configObj.CustomerGUID)
u.RawQuery = q.Encode()
fmt.Println("To view all controls and get remediations visit:")
InfoTextDisplay(os.Stdout, u.String()+"\n")
return u.String()
}
func (c *ClusterConfig) GetCustomerGUID() string {
+47 -10
View File
@@ -6,20 +6,20 @@ import (
"os"
"strings"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
// DO NOT REMOVE - load cloud providers auth
_ "k8s.io/client-go/plugin/pkg/client/auth"
"sigs.k8s.io/controller-runtime/pkg/client/config"
)
var ConnectedToCluster = true
// K8SConfig pointer to k8s config
var K8SConfig *restclient.Config
var K8SCmdConfig clientcmd.ClientConfig
// KubernetesApi -
type KubernetesApi struct {
@@ -30,8 +30,15 @@ type KubernetesApi struct {
// NewKubernetesApi -
func NewKubernetesApi() *KubernetesApi {
var kubernetesClient *kubernetes.Clientset
var err error
kubernetesClient, err := kubernetes.NewForConfig(GetK8sConfig())
if !IsConnectedToCluster() {
fmt.Println(fmt.Errorf("failed to load kubernetes config: no configuration has been provided, try setting KUBECONFIG environment variable"))
os.Exit(1)
}
kubernetesClient, err = kubernetes.NewForConfig(GetK8sConfig())
if err != nil {
fmt.Printf("Failed to load config file, reason: %s", err.Error())
os.Exit(1)
@@ -54,7 +61,6 @@ var RunningIncluster bool
// LoadK8sConfig load config from local file or from cluster
func LoadK8sConfig() error {
kubeconfig, err := config.GetConfig()
if err != nil {
return fmt.Errorf("failed to load kubernetes config: %s", strings.ReplaceAll(err.Error(), "KUBERNETES_MASTER", "KUBECONFIG"))
@@ -69,11 +75,42 @@ func LoadK8sConfig() error {
// GetK8sConfig get config. load if not loaded yet
func GetK8sConfig() *restclient.Config {
if K8SConfig == nil {
if err := LoadK8sConfig(); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
if !IsConnectedToCluster() {
return nil
}
return K8SConfig
}
func IsConnectedToCluster() bool {
if K8SConfig == nil {
if err := LoadK8sConfig(); err != nil {
ConnectedToCluster = false
}
}
return ConnectedToCluster
}
func GetClusterName() string {
if !ConnectedToCluster {
return ""
}
kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(clientcmd.NewDefaultClientConfigLoadingRules(), &clientcmd.ConfigOverrides{})
config, err := kubeConfig.RawConfig()
if err != nil {
return ""
}
// TODO - Handle if empty
return config.CurrentContext
}
func GetDefaultNamespace() string {
clientCfg, err := clientcmd.NewDefaultClientConfigLoadingRules().Load()
if err != nil {
return "default"
}
namespace := clientCfg.Contexts[clientCfg.CurrentContext].Namespace
if namespace == "" {
namespace = "default"
}
return namespace
}
+6
View File
@@ -19,6 +19,7 @@ type ScanInfo struct {
InputPatterns []string
Silent bool
FailThreshold uint16
DoNotSendResults bool
}
type Getters struct {
@@ -80,3 +81,8 @@ func (scanInfo *ScanInfo) setOutputFile() {
func (scanInfo *ScanInfo) ScanRunningCluster() bool {
return len(scanInfo.InputPatterns) == 0
}
// func (scanInfo *ScanInfo) ConnectedToCluster(k8s k8sinterface.) bool {
// _, err := k8s.KubernetesClient.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
// return err == nil
// }
+13 -24
View File
@@ -5,7 +5,6 @@ import (
"fmt"
"io"
"io/ioutil"
"math/rand"
"os"
"strings"
@@ -95,7 +94,7 @@ func init() {
frameworkCmd.Flags().StringVarP(&scanInfo.Output, "output", "o", "", "Output file. print output to file and not stdout")
frameworkCmd.Flags().BoolVarP(&scanInfo.Silent, "silent", "s", false, "Silent progress messages")
frameworkCmd.Flags().Uint16VarP(&scanInfo.FailThreshold, "fail-threshold", "t", 0, "Failure threshold is the percent bellow which the command fails and returns exit code -1")
frameworkCmd.Flags().BoolVarP(&scanInfo.DoNotSendResults, "results-locally", "", false, "Kubescape sends scan results to its backend to allow users to control exceptions and maintain chronological scan results. Use results-locally if you do not wish to use these features")
}
func CliSetup() error {
@@ -107,7 +106,9 @@ func CliSetup() error {
}
var k8s *k8sinterface.KubernetesApi
if scanInfo.ScanRunningCluster() {
if !scanInfo.ScanRunningCluster() {
k8sinterface.ConnectedToCluster = false
} else {
k8s = k8sinterface.NewKubernetesApi()
}
@@ -118,12 +119,18 @@ func CliSetup() error {
policyHandler := policyhandler.NewPolicyHandler(&processNotification, k8s)
// load cluster config
clusterConfig := cautils.NewClusterConfig(k8s, getter.NewArmoAPI())
var clusterConfig cautils.IClusterConfig
if !scanInfo.DoNotSendResults && k8sinterface.ConnectedToCluster {
clusterConfig = cautils.NewClusterConfig(k8s, getter.NewArmoAPI())
} else {
clusterConfig = cautils.NewEmptyConfig()
}
if err := clusterConfig.SetCustomerGUID(); err != nil {
fmt.Println(err)
}
cautils.CustomerGUID = clusterConfig.GetCustomerGUID()
cautils.ClusterName = generateClusterName()
cautils.ClusterName = k8sinterface.GetClusterName()
// cli handler setup
go func() {
@@ -144,7 +151,7 @@ func CliSetup() error {
score := resultsHandling.HandleResults()
// print report url
fmt.Println(clusterConfig.GenerateURL())
clusterConfig.GenerateURL()
adjustedFailThreshold := float32(scanInfo.FailThreshold) / 100
if score < adjustedFailThreshold {
@@ -181,21 +188,3 @@ func (clihandler *CLIHandler) Scan() error {
}
return nil
}
func generateClusterName() string {
name := fmt.Sprintf("%d", rand.Int())
if k8sinterface.K8SConfig == nil {
return name
}
if k8sinterface.K8SConfig.Host != "" {
name = k8sinterface.K8SConfig.Host
} else if k8sinterface.K8SConfig.ServerName != "" {
name = k8sinterface.K8SConfig.ServerName
}
name = strings.ReplaceAll(name, ".", "-")
name = strings.ReplaceAll(name, " ", "-")
name = strings.ReplaceAll(name, "https://", "")
name = strings.ReplaceAll(name, ":", "-")
return name
}
+4
View File
@@ -221,6 +221,10 @@ func (opap *OPAProcessor) regoEval(inputObj []map[string]interface{}, compiledRe
func (opap *OPAProcessor) updateScore() {
if !k8sinterface.ConnectedToCluster {
return
}
// calculate score
s := score.NewScore(k8sinterface.NewKubernetesApi(), ScoreConfigPath)
s.Calculate(opap.PostureReport.FrameworkReports)
+1 -1
View File
@@ -79,7 +79,7 @@ func (policyHandler *PolicyHandler) getPolicies(notification *opapolicy.PolicyNo
func (policyHandler *PolicyHandler) getResources(notification *opapolicy.PolicyNotification, opaSessionObj *cautils.OPASessionObj, scanInfo *cautils.ScanInfo) (*cautils.K8SResources, error) {
var k8sResources *cautils.K8SResources
var err error
if scanInfo.ScanRunningCluster() {
if k8sinterface.ConnectedToCluster {
k8sResources, err = policyHandler.getK8sResources(opaSessionObj.Frameworks, &notification.Designators, scanInfo.ExcludedNamespaces)
} else {
k8sResources, err = policyHandler.loadResources(opaSessionObj.Frameworks, scanInfo)
+4
View File
@@ -178,6 +178,10 @@ func (printer *Printer) printResult(controlName string, controlSummary *ControlS
}
func (printer *Printer) PrintUrl(url string) {
cautils.InfoTextDisplay(printer.writer, url)
}
func generateRow(control string, cs ControlSummary) []string {
row := []string{control}
row = append(row, cs.ToSlice()...)
@@ -28,6 +28,7 @@ func (report *ReportEventReceiver) ActionSendReportListenner(opaSessionObj *caut
if cautils.CustomerGUID == "" {
return
}
//Add score
opaSessionObj.PostureReport.RemoveData()
if err := report.Send(opaSessionObj.PostureReport); err != nil {
fmt.Println(err)