mirror of
https://github.com/kubescape/kubescape.git
synced 2026-04-15 06:58:11 +00:00
integrate host sensor into k8s IMetadata resource map
This commit is contained in:
+22
-2
@@ -42,7 +42,6 @@ func initHostSensor(scanInfo *cautils.ScanInfo, k8s *k8sinterface.KubernetesApi)
|
||||
glog.Errorf("failed to create host sensor: %v", err)
|
||||
return &hostsensorutils.HostSensorHandlerMock{}
|
||||
}
|
||||
scanInfo.ExcludedNamespaces = fmt.Sprintf("%s,%s", scanInfo.ExcludedNamespaces, hostSensorHandler.DaemonSet.Namespace)
|
||||
return hostSensorHandler
|
||||
} else {
|
||||
fmt.Printf("Skipping nodes scanning\n")
|
||||
@@ -55,6 +54,7 @@ func getInterfaces(scanInfo *cautils.ScanInfo) componentInterfaces {
|
||||
var hostSensorHandler hostsensorutils.IHostSensor
|
||||
var tenantConfig cautils.ITenantConfig
|
||||
|
||||
hostSensorHandler = &hostsensorutils.HostSensorHandlerMock{}
|
||||
// scanning environment
|
||||
scanningTarget := scanInfo.GetScanningEnvironment()
|
||||
switch scanningTarget {
|
||||
@@ -108,13 +108,33 @@ func ScanCliSetup(scanInfo *cautils.ScanInfo) error {
|
||||
interfaces.report.SetClusterName(interfaces.tenantConfig.GetClusterName())
|
||||
interfaces.report.SetCustomerGUID(interfaces.tenantConfig.GetCustomerGUID())
|
||||
|
||||
if err := interfaces.hostSensorHandler.Init(); err != nil {
|
||||
errMsg := "failed to init host sensor"
|
||||
if scanInfo.VerboseMode {
|
||||
errMsg = fmt.Sprintf("%s: %v", errMsg, err)
|
||||
}
|
||||
cautils.ErrorDisplay(errMsg)
|
||||
} else if len(scanInfo.IncludeNamespaces) == 0 && interfaces.hostSensorHandler.GetNamespace() != "" {
|
||||
scanInfo.ExcludedNamespaces = fmt.Sprintf("%s,%s", scanInfo.ExcludedNamespaces, interfaces.hostSensorHandler)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err := interfaces.hostSensorHandler.TearDown(); err != nil {
|
||||
errMsg := "failed to tear down host sensor"
|
||||
if scanInfo.VerboseMode {
|
||||
errMsg = fmt.Sprintf("%s: %v", errMsg, err)
|
||||
}
|
||||
cautils.ErrorDisplay(errMsg)
|
||||
}
|
||||
}()
|
||||
|
||||
// set policy getter only after setting the customerGUID
|
||||
setPolicyGetter(scanInfo, interfaces.tenantConfig.GetCustomerGUID())
|
||||
|
||||
// cli handler setup
|
||||
go func() {
|
||||
// policy handler setup
|
||||
policyHandler := policyhandler.NewPolicyHandler(&processNotification, interfaces.resourceHandler)
|
||||
policyHandler := policyhandler.NewPolicyHandler(&processNotification, interfaces.resourceHandler, interfaces.hostSensorHandler)
|
||||
|
||||
if err := Scan(policyHandler, scanInfo); err != nil {
|
||||
fmt.Println(err)
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
type HostSensorDataEnvelope struct {
|
||||
schema.GroupVersionKind
|
||||
schema.GroupVersionResource
|
||||
NodeName string `json:"nodeName"`
|
||||
Data json.RawMessage `json:"data"`
|
||||
}
|
||||
@@ -22,7 +22,7 @@ func (hsde *HostSensorDataEnvelope) SetName(val string) {
|
||||
}
|
||||
|
||||
func (hsde *HostSensorDataEnvelope) SetKind(val string) {
|
||||
hsde.Kind = val
|
||||
hsde.Resource = val
|
||||
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ func (hsde *HostSensorDataEnvelope) GetName() string {
|
||||
}
|
||||
|
||||
func (hsde *HostSensorDataEnvelope) GetKind() string {
|
||||
return hsde.Kind
|
||||
return hsde.Resource
|
||||
}
|
||||
|
||||
func (hsde *HostSensorDataEnvelope) GetApiVersion() string {
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/armosec/k8s-interface/k8sinterface"
|
||||
"github.com/armosec/kubescape/cautils"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -18,22 +19,15 @@ import (
|
||||
)
|
||||
|
||||
type HostSensorHandler struct {
|
||||
HostSensorNamespace string
|
||||
HostSensorPort int32
|
||||
HostSensorDaemonSetName string
|
||||
HostSensorPodNames map[string]string //map from pod names to node names
|
||||
IsReady <-chan bool //readonly chan
|
||||
k8sObj *k8sinterface.KubernetesApi
|
||||
DaemonSet *appsv1.DaemonSet
|
||||
podListLock sync.RWMutex
|
||||
HostSensorPort int32
|
||||
HostSensorPodNames map[string]string //map from pod names to node names
|
||||
IsReady <-chan bool //readonly chan
|
||||
k8sObj *k8sinterface.KubernetesApi
|
||||
DaemonSet *appsv1.DaemonSet
|
||||
podListLock sync.RWMutex
|
||||
}
|
||||
|
||||
func NewHostSensorHandler(k8sObj *k8sinterface.KubernetesApi) (*HostSensorHandler, error) {
|
||||
// deploy the YAML
|
||||
// store namespace + port
|
||||
// store pod names
|
||||
// make sure all pods are running, after X seconds treat has running anyway, and log an error on the pods not running yet
|
||||
// return the object
|
||||
|
||||
if k8sObj == nil {
|
||||
return nil, fmt.Errorf("nil k8s interface received")
|
||||
@@ -54,6 +48,13 @@ func NewHostSensorHandler(k8sObj *k8sinterface.KubernetesApi) (*HostSensorHandle
|
||||
}
|
||||
|
||||
func (hsh *HostSensorHandler) Init() error {
|
||||
// deploy the YAML
|
||||
// store namespace + port
|
||||
// store pod names
|
||||
// make sure all pods are running, after X seconds treat has running anyway, and log an error on the pods not running yet
|
||||
cautils.ProgressTextDisplay("Installing host sensor")
|
||||
cautils.StartSpinner()
|
||||
defer cautils.StopSpinner()
|
||||
if err := hsh.applyYAML(); err != nil {
|
||||
return fmt.Errorf("in HostSensorHandler init failed to apply YAML: %v", err)
|
||||
}
|
||||
@@ -77,13 +78,14 @@ func (hsh *HostSensorHandler) applyYAML() error {
|
||||
if err := yaml.Unmarshal(singleYAMLBytes, namespaceAC); err != nil {
|
||||
return fmt.Errorf("failed to Unmarshal YAML of namespace: %v", err)
|
||||
}
|
||||
namespaceName := ""
|
||||
|
||||
if ns, err := hsh.k8sObj.KubernetesClient.CoreV1().Namespaces().Apply(hsh.k8sObj.Context, namespaceAC, metav1.ApplyOptions{
|
||||
FieldManager: "kubescape",
|
||||
}); err != nil {
|
||||
return fmt.Errorf("failed to apply YAML of namespace: %v", err)
|
||||
} else {
|
||||
hsh.HostSensorNamespace = ns.Name
|
||||
namespaceName = ns.Name
|
||||
}
|
||||
// apply deamonset
|
||||
deamonAC := &appsapplyv1.DaemonSetApplyConfiguration{}
|
||||
@@ -96,13 +98,12 @@ func (hsh *HostSensorHandler) applyYAML() error {
|
||||
if err := yaml.Unmarshal(singleYAMLBytes, deamonAC); err != nil {
|
||||
return fmt.Errorf("failed to Unmarshal YAML of deamonset: %v", err)
|
||||
}
|
||||
deamonAC.Namespace = &hsh.HostSensorNamespace
|
||||
if ds, err := hsh.k8sObj.KubernetesClient.AppsV1().DaemonSets(hsh.HostSensorNamespace).Apply(hsh.k8sObj.Context, deamonAC, metav1.ApplyOptions{
|
||||
deamonAC.Namespace = &namespaceName
|
||||
if ds, err := hsh.k8sObj.KubernetesClient.AppsV1().DaemonSets(namespaceName).Apply(hsh.k8sObj.Context, deamonAC, metav1.ApplyOptions{
|
||||
FieldManager: "kubescape",
|
||||
}); err != nil {
|
||||
return fmt.Errorf("failed to apply YAML of deamonset: %v", err)
|
||||
} else {
|
||||
hsh.HostSensorDaemonSetName = ds.Name
|
||||
hsh.HostSensorPort = ds.Spec.Template.Spec.Containers[0].Ports[0].ContainerPort
|
||||
hsh.DaemonSet = ds
|
||||
}
|
||||
@@ -171,10 +172,10 @@ func (hsh *HostSensorHandler) updatePodInListAtomic(eventType watch.EventType, p
|
||||
func (hsh *HostSensorHandler) TearDown() error {
|
||||
// remove the namespace
|
||||
gracePeriod := int64(15)
|
||||
if err := hsh.k8sObj.KubernetesClient.AppsV1().DaemonSets(hsh.HostSensorNamespace).Delete(hsh.k8sObj.Context, hsh.HostSensorDaemonSetName, metav1.DeleteOptions{GracePeriodSeconds: &gracePeriod}); err != nil {
|
||||
if err := hsh.k8sObj.KubernetesClient.AppsV1().DaemonSets(hsh.GetNamespace()).Delete(hsh.k8sObj.Context, hsh.DaemonSet.Name, metav1.DeleteOptions{GracePeriodSeconds: &gracePeriod}); err != nil {
|
||||
return fmt.Errorf("failed to delete host-sensor daemonset: %v", err)
|
||||
}
|
||||
if err := hsh.k8sObj.KubernetesClient.CoreV1().Namespaces().Delete(hsh.k8sObj.Context, hsh.HostSensorNamespace,
|
||||
if err := hsh.k8sObj.KubernetesClient.CoreV1().Namespaces().Delete(hsh.k8sObj.Context, hsh.GetNamespace(),
|
||||
metav1.DeleteOptions{GracePeriodSeconds: &gracePeriod}); err != nil {
|
||||
return fmt.Errorf("failed to delete host-sensor namespace: %v", err)
|
||||
}
|
||||
@@ -182,3 +183,7 @@ func (hsh *HostSensorHandler) TearDown() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hsh *HostSensorHandler) GetNamespace() string {
|
||||
return hsh.DaemonSet.Namespace
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"github.com/armosec/kubescape/cautils"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
@@ -93,20 +94,26 @@ func (hsh *HostSensorHandler) GetKubeletConfigurations() ([]HostSensorDataEnvelo
|
||||
continue
|
||||
}
|
||||
res[resIdx].Data = jsonBytes
|
||||
kindDet := schema.GroupVersionKind{}
|
||||
kindDet := metav1.TypeMeta{}
|
||||
if err = json.Unmarshal(jsonBytes, &kindDet); err != nil {
|
||||
fmt.Printf("In GetKubeletConfigurations failed to Unmarshal GroupVersionKind: %v;\n%v", err, jsonBytes)
|
||||
continue
|
||||
}
|
||||
res[resIdx].GroupVersionKind = kindDet
|
||||
res[resIdx].GroupVersionResource.Resource = kindDet.Kind
|
||||
res[resIdx].GroupVersionResource.Group = kindDet.GroupVersionKind().Group
|
||||
res[resIdx].GroupVersionResource.Version = kindDet.GroupVersionKind().Version
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (hsh *HostSensorHandler) CollectResources() ([]HostSensorDataEnvelope, error) {
|
||||
cautils.ProgressTextDisplay("Accessing host sensor")
|
||||
cautils.StartSpinner()
|
||||
defer cautils.StopSpinner()
|
||||
kcData, err := hsh.GetKubeletConfigurations()
|
||||
if err != nil {
|
||||
return kcData, err
|
||||
}
|
||||
cautils.SuccessTextDisplay("Read host information from host sensor")
|
||||
return kcData, nil
|
||||
}
|
||||
|
||||
@@ -4,4 +4,5 @@ type IHostSensor interface {
|
||||
Init() error
|
||||
TearDown() error
|
||||
CollectResources() ([]HostSensorDataEnvelope, error)
|
||||
GetNamespace() string
|
||||
}
|
||||
|
||||
@@ -14,3 +14,7 @@ func (hshm *HostSensorHandlerMock) TearDown() error {
|
||||
func (hshm *HostSensorHandlerMock) CollectResources() ([]HostSensorDataEnvelope, error) {
|
||||
return []HostSensorDataEnvelope{}, nil
|
||||
}
|
||||
|
||||
func (hshm *HostSensorHandlerMock) GetNamespace() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -3,24 +3,29 @@ package policyhandler
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/armosec/k8s-interface/k8sinterface"
|
||||
"github.com/armosec/k8s-interface/workloadinterface"
|
||||
"github.com/armosec/kubescape/cautils"
|
||||
"github.com/armosec/kubescape/hostsensorutils"
|
||||
"github.com/armosec/kubescape/resourcehandler"
|
||||
"github.com/armosec/opa-utils/reporthandling"
|
||||
)
|
||||
|
||||
// PolicyHandler -
|
||||
type PolicyHandler struct {
|
||||
resourceHandler resourcehandler.IResourceHandler
|
||||
resourceHandler resourcehandler.IResourceHandler
|
||||
hostSensorHandler hostsensorutils.IHostSensor
|
||||
// we are listening on this chan in opaprocessor/processorhandler.go/ProcessRulesListenner func
|
||||
processPolicy *chan *cautils.OPASessionObj
|
||||
getters *cautils.Getters
|
||||
}
|
||||
|
||||
// CreatePolicyHandler Create ws-handler obj
|
||||
func NewPolicyHandler(processPolicy *chan *cautils.OPASessionObj, resourceHandler resourcehandler.IResourceHandler) *PolicyHandler {
|
||||
func NewPolicyHandler(processPolicy *chan *cautils.OPASessionObj, resourceHandler resourcehandler.IResourceHandler, hostSensorHandler hostsensorutils.IHostSensor) *PolicyHandler {
|
||||
return &PolicyHandler{
|
||||
resourceHandler: resourceHandler,
|
||||
processPolicy: processPolicy,
|
||||
resourceHandler: resourceHandler,
|
||||
processPolicy: processPolicy,
|
||||
hostSensorHandler: hostSensorHandler,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,5 +57,25 @@ func (policyHandler *PolicyHandler) HandleNotificationRequest(notification *repo
|
||||
func (policyHandler *PolicyHandler) getResources(notification *reporthandling.PolicyNotification, opaSessionObj *cautils.OPASessionObj, scanInfo *cautils.ScanInfo) (*cautils.K8SResources, error) {
|
||||
|
||||
opaSessionObj.PostureReport.ClusterAPIServerInfo = policyHandler.resourceHandler.GetClusterAPIServerInfo()
|
||||
return policyHandler.resourceHandler.GetResources(opaSessionObj.Frameworks, ¬ification.Designators)
|
||||
resourcesMap, err := policyHandler.resourceHandler.GetResources(opaSessionObj.Frameworks, ¬ification.Designators)
|
||||
if err != nil {
|
||||
return resourcesMap, err
|
||||
}
|
||||
hostResources, err := policyHandler.hostSensorHandler.CollectResources()
|
||||
if err != nil {
|
||||
return resourcesMap, err
|
||||
}
|
||||
for rscIdx := range hostResources {
|
||||
groupResources := k8sinterface.ResourceGroupToString(hostResources[rscIdx].Group, hostResources[rscIdx].GetApiVersion(), hostResources[rscIdx].GetKind())
|
||||
for _, groupResource := range groupResources {
|
||||
grpReasorceList, ok := (*resourcesMap)[groupResource]
|
||||
if !ok {
|
||||
grpReasorceList = make([]workloadinterface.IMetadata, 0)
|
||||
}
|
||||
grpReasorceList = append(grpReasorceList, &hostResources[rscIdx])
|
||||
(*resourcesMap)[groupResource] = grpReasorceList
|
||||
}
|
||||
}
|
||||
cautils.SuccessTextDisplay("Let’s start!!!")
|
||||
return resourcesMap, nil
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ func (k8sHandler *K8sResourceHandler) GetResources(frameworks []reporthandling.F
|
||||
return k8sResourcesMap, err
|
||||
}
|
||||
|
||||
cautils.SuccessTextDisplay("Accessed successfully to Kubernetes objects, let’s start!!!")
|
||||
cautils.SuccessTextDisplay("Accessed successfully to Kubernetes objects")
|
||||
return k8sResourcesMap, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user