mirror of
https://github.com/kubescape/kubescape.git
synced 2026-03-03 02:00:27 +00:00
151 lines
5.3 KiB
Go
151 lines
5.3 KiB
Go
package resourcehandler
|
|
|
|
import (
|
|
"github.com/armosec/k8s-interface/k8sinterface"
|
|
"github.com/armosec/k8s-interface/workloadinterface"
|
|
"github.com/armosec/kubescape/cautils"
|
|
"github.com/armosec/kubescape/cautils/getter"
|
|
"github.com/armosec/kubescape/cautils/logger"
|
|
"github.com/armosec/kubescape/cautils/logger/helpers"
|
|
armosecadaptorv1 "github.com/armosec/kubescape/registryadaptors/armosec/v1"
|
|
"github.com/armosec/kubescape/registryadaptors/registryvulnerabilities"
|
|
"github.com/armosec/opa-utils/shared"
|
|
)
|
|
|
|
const (
|
|
ImagevulnerabilitiesObjectGroup = "image.vulnscan.com"
|
|
ImagevulnerabilitiesObjectVersion = "v1"
|
|
ImagevulnerabilitiesObjectKind = "ImageVulnerabilities"
|
|
)
|
|
|
|
type RegistryAdaptors struct {
|
|
adaptors []registryvulnerabilities.IContainerImageVulnerabilityAdaptor
|
|
}
|
|
|
|
func NewRegistryAdaptors() (*RegistryAdaptors, error) {
|
|
// list supported adaptors
|
|
registryAdaptors := &RegistryAdaptors{}
|
|
adaptors, err := listAdaptores()
|
|
if err != nil {
|
|
return registryAdaptors, err
|
|
}
|
|
registryAdaptors.adaptors = adaptors
|
|
return registryAdaptors, nil
|
|
}
|
|
|
|
func (registryAdaptors *RegistryAdaptors) collectImagesVulnerabilities(k8sResourcesMap *cautils.K8SResources, allResources map[string]workloadinterface.IMetadata) error {
|
|
logger.L().Debug("Collecting images vulnerabilities")
|
|
|
|
// list cluster images
|
|
images := listImagesTags(k8sResourcesMap, allResources)
|
|
imagesIdentifiers := imageTagsToContainerImageIdentifier(images)
|
|
|
|
imagesVulnerability := map[string][]registryvulnerabilities.Vulnerability{}
|
|
for i := range registryAdaptors.adaptors { // login and and get vulnerabilities
|
|
|
|
if err := registryAdaptors.adaptors[i].Login(); err != nil {
|
|
logger.L().Error("failed to login", helpers.Error(err))
|
|
continue
|
|
}
|
|
vulnerabilities, err := registryAdaptors.adaptors[i].GetImagesVulnerabilities(imagesIdentifiers)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for j := range vulnerabilities {
|
|
imagesVulnerability[vulnerabilities[j].ImageID.Tag] = vulnerabilities[j].Vulnerabilities
|
|
}
|
|
}
|
|
|
|
// convert result to IMetadata object
|
|
metaObjs := vulnerabilitiesToIMetadata(imagesVulnerability)
|
|
|
|
// save in resources map
|
|
for i := range metaObjs {
|
|
allResources[metaObjs[i].GetID()] = metaObjs[i]
|
|
}
|
|
(*k8sResourcesMap)[k8sinterface.JoinResourceTriplets(ImagevulnerabilitiesObjectGroup, ImagevulnerabilitiesObjectVersion, ImagevulnerabilitiesObjectKind)] = workloadinterface.ListMetaIDs(metaObjs)
|
|
|
|
return nil
|
|
}
|
|
|
|
func vulnerabilitiesToIMetadata(vulnerabilities map[string][]registryvulnerabilities.Vulnerability) []workloadinterface.IMetadata {
|
|
objs := []workloadinterface.IMetadata{}
|
|
for i := range vulnerabilities {
|
|
objs = append(objs, vulnerabilityToIMetadata(i, vulnerabilities[i]))
|
|
}
|
|
return objs
|
|
}
|
|
|
|
func vulnerabilityToIMetadata(imageTag string, vulnerabilities []registryvulnerabilities.Vulnerability) workloadinterface.IMetadata {
|
|
obj := map[string]interface{}{}
|
|
metadata := map[string]interface{}{}
|
|
metadata["name"] = imageTag // store image tag as object name
|
|
obj["kind"] = ImagevulnerabilitiesObjectKind
|
|
obj["apiVersion"] = k8sinterface.JoinGroupVersion(ImagevulnerabilitiesObjectGroup, ImagevulnerabilitiesObjectVersion)
|
|
obj["data"] = vulnerabilities
|
|
obj["metadata"] = metadata
|
|
|
|
return workloadinterface.NewWorkloadObj(obj)
|
|
}
|
|
|
|
// list all images tags
|
|
func listImagesTags(k8sResourcesMap *cautils.K8SResources, allResources map[string]workloadinterface.IMetadata) []string {
|
|
images := []string{}
|
|
for _, resources := range *k8sResourcesMap {
|
|
for j := range resources {
|
|
if resource, ok := allResources[resources[j]]; ok {
|
|
if resource.GetObjectType() == workloadinterface.TypeWorkloadObject {
|
|
workload := workloadinterface.NewWorkloadObj(resource.GetObject())
|
|
if contianers, err := workload.GetContainers(); err == nil {
|
|
for i := range contianers {
|
|
images = append(images, contianers[i].Image)
|
|
}
|
|
}
|
|
if contianers, err := workload.GetInitContainers(); err == nil {
|
|
for i := range contianers {
|
|
images = append(images, contianers[i].Image)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return shared.SliceStringToUnique(images)
|
|
}
|
|
|
|
func imageTagsToContainerImageIdentifier(images []string) []registryvulnerabilities.ContainerImageIdentifier {
|
|
imagesIdentifiers := make([]registryvulnerabilities.ContainerImageIdentifier, len(images))
|
|
for i := range images {
|
|
imageIdentifier := registryvulnerabilities.ContainerImageIdentifier{
|
|
Tag: images[i],
|
|
}
|
|
// splitted := strings.Split(images[i], "/")
|
|
// if len(splitted) == 1 {
|
|
// imageIdentifier.Tag = splitted[0]
|
|
// } else if len(splitted) == 2 {
|
|
// imageIdentifier.Registry = splitted[0]
|
|
// imageIdentifier.Tag = splitted[1]
|
|
// } else if len(splitted) >= 3 {
|
|
// imageIdentifier.Registry = splitted[0]
|
|
// imageIdentifier.Repository = strings.Join(splitted[1:len(splitted)-1], "/")
|
|
// imageIdentifier.Tag = splitted[len(splitted)-1]
|
|
// }
|
|
imagesIdentifiers[i] = imageIdentifier
|
|
}
|
|
return imagesIdentifiers
|
|
}
|
|
func listAdaptores() ([]registryvulnerabilities.IContainerImageVulnerabilityAdaptor, error) {
|
|
|
|
adaptors := []registryvulnerabilities.IContainerImageVulnerabilityAdaptor{}
|
|
|
|
armoAPI := getter.GetArmoAPIConnector()
|
|
if armoAPI != nil {
|
|
if armoAPI.GetSecretKey() != "" && armoAPI.GetClientID() != "" && armoAPI.GetAccountID() != "" {
|
|
adaptors = append(adaptors, armosecadaptorv1.NewArmoAdaptor(getter.GetArmoAPIConnector()))
|
|
}
|
|
}
|
|
|
|
return adaptors, nil
|
|
}
|