support vuln scan

This commit is contained in:
dwertent
2022-01-31 18:41:45 +02:00
parent aa2dedb76f
commit d1695b7f10
11 changed files with 420 additions and 124 deletions
+6 -1
View File
@@ -63,7 +63,12 @@ func getInterfaces(scanInfo *cautils.ScanInfo) componentInterfaces {
scanInfo.ExcludedNamespaces = fmt.Sprintf("%s,%s", scanInfo.ExcludedNamespaces, hostSensorHandler.GetNamespace())
}
resourceHandler := getResourceHandler(scanInfo, tenantConfig, k8s, hostSensorHandler)
registryAdaptors, err := resourcehandler.NewRegistryAdaptors()
if err != nil {
// display warning
}
resourceHandler := getResourceHandler(scanInfo, tenantConfig, k8s, hostSensorHandler, registryAdaptors)
// reporting behavior - setup reporter
reportHandler := getReporter(tenantConfig, scanInfo.Submit)
+4 -3
View File
@@ -55,12 +55,13 @@ func getReporter(tenantConfig cautils.ITenantConfig, submit bool) reporter.IRepo
return reporterv1.NewReportMock()
}
func getResourceHandler(scanInfo *cautils.ScanInfo, tenantConfig cautils.ITenantConfig, k8s *k8sinterface.KubernetesApi, hostSensorHandler hostsensorutils.IHostSensor) resourcehandler.IResourceHandler {
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 {
return resourcehandler.NewFileResourceHandler(scanInfo.InputPatterns)
return resourcehandler.NewFileResourceHandler(scanInfo.InputPatterns, registryAdaptors)
}
getter.GetArmoAPIConnector()
rbacObjects := getRBACHandler(tenantConfig, k8s, scanInfo.Submit)
return resourcehandler.NewK8sResourceHandler(k8s, getFieldSelector(scanInfo), hostSensorHandler, rbacObjects)
return resourcehandler.NewK8sResourceHandler(k8s, getFieldSelector(scanInfo), hostSensorHandler, rbacObjects, registryAdaptors)
}
func getHostSensorHandler(scanInfo *cautils.ScanInfo, k8s *k8sinterface.KubernetesApi) hostsensorutils.IHostSensor {
+164
View File
@@ -0,0 +1,164 @@
# Container image vulnerability adaptor interface
## High level design of Kubescape
### Layers
* Controls and Rules: that actual control logic implementation, the "tests" themselves. Implemented in rego
* OPA engine: the [OPA](https://github.com/open-policy-agent/opa) rego interpreter
* Rules processor: Kubescape component, it enumerates and runs the controls while also preparing the all the input data that the controls need for running
* Data sources: set of different modules providing data to the Rules processor so it can run the controls with them. Examples: Kubernetes objects, cloud vendor API objects and adding in this proposal the vulnerability infomration
* Cloud Image Vulnerability adaption interface: the subject of this proposal, it gives a common interface for different registry/vulnerabilty vendors to adapt to.
* CIV adaptors: specific implementation of the CIV interface, example Harbor adaption
```
-----------------------
| Controls/Rules (rego) |
-----------------------
|
-----------------------
| OPA engine |
-----------------------
|
-----------------------
| Rules processor |
-----------------------
|
-----------------------
| Data sources |
-----------------------
|
=======================
| CIV adaption interface| <- Adding this layer in this proposal
=======================
|
-----------------------
| Specific CIV adaptors | <- Will be implemented based on this proposal
-----------------------
```
## Functionalities to cover
The interface needs to cover the following functionalities:
* Authentication against the information source (abstracted login)
* Triggering image scan (if applicable, the source might store vulnerabilities for images but cannot scan alone)
* Reading image scan status (with last scan date and etc.)
* Getting vulnerability information for a given image
* Getting image information
* Image manifests
* Image BOMs (bill of material)
## Go API proposal
```
/*type ContainerImageRegistryCredentials struct {
Password string
Tag string
Hash string
}*/
type ContainerImageIdentifier struct {
Registry string
Repository string
Tag string
Hash string
}
type ContainerImageScanStatus struct {
ImageID ContainerImageIdentifier
IsScanAvailable bool
IsBomAvailable bool
LastScanDate time.Time
}
type ContainerImageVulnerabilityReport struct {
ImageID ContainerImageIdentifier
// TBD
}
type ContainerImageInformation struct {
ImageID ContainerImageIdentifier
Bom []string
ImageManifest Manifest // will use here Docker package definition
}
type IContainerImageVulnerabilityAdaptor interface {
// Credentials are coming from user input (CLI or configuration file) and they are abstracted at string to string map level
// so and example use would be like registry: "simpledockerregistry:80" and credentials like {"username":"joedoe","password":"abcd1234"}
Login(registry string, credentials map[string]string) error
// For "help" purposes
DescribeAdaptor() string
GetImagesScanStatus(imageIDs []ContainerImageIdentifier) ([]ContainerImageScanStatus, error)
GetImagesVulnerabilties(imageIDs []ContainerImageIdentifier) ([]ContainerImageVulnerabilityReport, error)
GetImagesInformation(imageIDs []ContainerImageIdentifier) ([]ContainerImageInformation, error)
}
```
# Integration
# Input
The objects received from the interface will be converted to an IMetadata compatible objects as following
```
{
"apiVersion": "image.vulnscan.com/v1",
"kind": "ImageVulnerabilities",
"metadata": {
"name": "nginx:latest"
},
"data": {
// list of vulnerabilities
}
}
```
# Output
The rego results will be a combination of the k8s artifact and the list of relevant CVEs for the control
```
{
"apiVersion": "result.vulnscan.com/v1",
"kind": "Pod",
"metadata": {
"name": "nginx"
"namespace": "default"
},
"relatedObjects": [
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "nginx"
"namespace": "default"
},
"spec": {
// podSpec
},
},
{
"apiVersion": "image.vulnscan.com/v1",
"kind": "ImageVulnerabilities",
"metadata": {
"name": "nginx:latest",
},
"data": {
// list of vulnerabilities
}
}
]
}
```
+18 -31
View File
@@ -12,20 +12,20 @@ import (
)
func NewArmoAdaptor(registry string, credentials map[string]string) (*ArmoCivAdaptor, error) {
var accountId string
var accountID string
var accessKey string
var clientId string
var clientID string
var ok bool
if accountId, ok = credentials["accountId"]; !ok {
return nil, fmt.Errorf("define accountId in credentials")
if accountID, ok = credentials["accountID"]; !ok {
return nil, fmt.Errorf("define accountID in credentials")
}
if clientId, ok = credentials["clientId"]; !ok {
return nil, fmt.Errorf("define clientId in credentials")
if clientID, ok = credentials["clientID"]; !ok {
return nil, fmt.Errorf("define clientID in credentials")
}
if accessKey, ok = credentials["accessKey"]; !ok {
return nil, fmt.Errorf("define accessKey in credentials")
}
armoCivAdaptor := ArmoCivAdaptor{registry: registry, accountId: accountId, clientId: clientId, accessKey: accessKey}
armoCivAdaptor := ArmoCivAdaptor{registry: registry, clientID: clientID, accountID: accountID, accessKey: accessKey}
err := armoCivAdaptor.initializeUrls()
if err != nil {
return nil, err
@@ -34,7 +34,7 @@ func NewArmoAdaptor(registry string, credentials map[string]string) (*ArmoCivAda
}
func (armoCivAdaptor *ArmoCivAdaptor) Login() error {
feLoginData := FeLoginData{ClientId: armoCivAdaptor.clientId, Secret: armoCivAdaptor.accessKey}
feLoginData := FeLoginData{ClientId: armoCivAdaptor.clientID, Secret: armoCivAdaptor.accessKey}
body, _ := json.Marshal(feLoginData)
authApiTokenEndpoint := fmt.Sprintf("%s/frontegg/identity/resources/auth/v1/api-token", armoCivAdaptor.armoUrls.AuthUrl)
@@ -53,11 +53,12 @@ func (armoCivAdaptor *ArmoCivAdaptor) Login() error {
return err
}
var feLoginResponse FeLoginResponse
err = json.Unmarshal(responseBody, &feLoginResponse)
armoCivAdaptor.feToken = feLoginResponse
if err != nil {
if err = json.Unmarshal(responseBody, &feLoginResponse); err != nil {
return err
}
armoCivAdaptor.feToken = feLoginResponse
/* Now we have JWT */
armoCivAdaptor.authCookie, err = armoCivAdaptor.getAuthCookie()
@@ -84,12 +85,16 @@ func (armoCivAdaptor *ArmoCivAdaptor) GetImageVulnerability(imageID *registryvul
if err != nil {
return nil, err
}
if containerScanId == "" {
return nil, fmt.Errorf("last scan ID is empty")
}
filter := []map[string]string{{"containersScanID": containerScanId}}
pageSize := 300
pageNumber := 1
request := V2ListRequest{PageSize: &pageSize, PageNum: &pageNumber, InnerFilters: filter, OrderBy: "timestamp:desc"}
requestBody, _ := json.Marshal(request)
requestUrl := fmt.Sprintf("%s/api/v1/vulnerability/scanResultsDetails?customerGUID=%s", armoCivAdaptor.armoUrls.BackendUrl, armoCivAdaptor.accountId)
requestUrl := fmt.Sprintf("%s/api/v1/vulnerability/scanResultsDetails?customerGUID=%s", armoCivAdaptor.armoUrls.BackendUrl, armoCivAdaptor.accountID)
client := &http.Client{}
httpRequest, err := http.NewRequest("POST", requestUrl, bytes.NewBuffer(requestBody))
if err != nil {
@@ -126,25 +131,7 @@ func (armoCivAdaptor *ArmoCivAdaptor) GetImageVulnerability(imageID *registryvul
return nil, err
}
vulnerabilities := make([]registryvulnerabilities.Vulnerability, len(scanDetailsResult.Response))
for i, vulnerabilityEntry := range scanDetailsResult.Response {
vulnerabilities[i].Description = vulnerabilityEntry.Description
vulnerabilities[i].Fixes = make([]registryvulnerabilities.FixedIn, len(vulnerabilityEntry.Fixes))
for j, fix := range vulnerabilityEntry.Fixes {
vulnerabilities[i].Fixes[j].ImgTag = fix.ImgTag
vulnerabilities[i].Fixes[j].Name = fix.Name
vulnerabilities[i].Fixes[j].Version = fix.Version
}
vulnerabilities[i].HealthStatus = vulnerabilityEntry.HealthStatus
vulnerabilities[i].Link = vulnerabilityEntry.Link
vulnerabilities[i].Metadata = vulnerabilityEntry.Metadata
vulnerabilities[i].Name = vulnerabilityEntry.Name
vulnerabilities[i].PackageVersion = vulnerabilityEntry.PackageVersion
vulnerabilities[i].RelatedPackageName = vulnerabilityEntry.RelatedPackageName
vulnerabilities[i].Relevancy = vulnerabilityEntry.Relevancy
vulnerabilities[i].Severity = vulnerabilityEntry.Severity
vulnerabilities[i].UrgentCount = vulnerabilityEntry.UrgentCount
}
vulnerabilities := responseObjectToVulnerabilities(scanDetailsResult.Response)
resultImageVulnerabilityReport := registryvulnerabilities.ContainerImageVulnerabilityReport{
ImageID: *imageID,
@@ -1,7 +1,6 @@
package v1
import (
"fmt"
"testing"
"github.com/armosec/kubescape/registryadaptors/registryvulnerabilities"
@@ -9,52 +8,16 @@ import (
)
func TestSum(t *testing.T) {
credentials := make(map[string]string)
credentials["clientId"] = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
credentials["accessKey"] = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
credentials["accountId"] = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
var err error
var adaptor registryvulnerabilities.IContainerImageVulnerabilityAdaptor
adaptor, err = NewArmoAdaptorMock("armoui-dev.eudev3.cyberarmorsoft.com", credentials)
adaptor, err = NewArmoAdaptorMock()
assert.NoError(t, err)
assert.NoError(t, adaptor.Login())
//fmt.Printf("Login successful: %s\n", adaptor.feToken.Token)
imageVulnerabilityReport, err := adaptor.GetImageVulnerability(&registryvulnerabilities.ContainerImageIdentifier{Tag: "gke.gcr.io/gcp-compute-persistent-disk-csi-driver:v1.3.4-gke.0"})
assert.NoError(t, err)
for _, vulnerability := range imageVulnerabilityReport.Vulnerabilities {
fmt.Printf("%s: %s\n", vulnerability.Name, vulnerability.Description)
}
assert.Equal(t, 25, len(imageVulnerabilityReport.Vulnerabilities))
}
/*
func TestSum(t *testing.T) {
credentials := make(map[string]string)
credentials["clientId"] = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
credentials["accessKey"] = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
credentials["accountId"] = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
var err error
var adaptor registryvulnerabilities.IContainerImageVulnerabilityAdaptor
adaptor, err = NewArmoAdaptorMock("armoui-dev.eudev3.cyberarmorsoft.com", credentials)
assert.NoError(t, err)
// TODO - create mock
assert.NoError(t, adaptor.Login())
//fmt.Printf("Login successful: %s\n", adaptor.feToken.Token)
imageVulnerabilityReport, err := adaptor.GetImageVulnerability(&registryvulnerabilities.ContainerImageIdentifier{Tag: "gke.gcr.io/gcp-compute-persistent-disk-csi-driver:v1.3.4-gke.0"})
assert.NoError(t, err)
for _, vulnerability := range imageVulnerabilityReport.Vulnerabilities {
fmt.Printf("%s: %s\n", vulnerability.Name, vulnerability.Description)
}
}
*/
File diff suppressed because one or more lines are too long
@@ -35,7 +35,7 @@ func (armoCivAdaptor *ArmoCivAdaptor) initializeUrls() error {
}
func (armoCivAdaptor *ArmoCivAdaptor) getAuthCookie() (string, error) {
selectCustomer := ArmoSelectCustomer{SelectedCustomerGuid: armoCivAdaptor.accountId}
selectCustomer := ArmoSelectCustomer{SelectedCustomerGuid: armoCivAdaptor.accountID}
requestBody, _ := json.Marshal(selectCustomer)
requestUrl := fmt.Sprintf("%s/api/v1/openid_customers", armoCivAdaptor.armoUrls.BackendUrl)
client := &http.Client{}
@@ -75,14 +75,18 @@ func (armoCivAdaptor *ArmoCivAdaptor) getAuthCookie() (string, error) {
}
func (armoCivAdaptor *ArmoCivAdaptor) getImageLastScanId(imageID *registryvulnerabilities.ContainerImageIdentifier) (string, error) {
filter := []map[string]string{{"imageTag": imageID.Tag}}
filter := []map[string]string{{"imageTag": imageID.Tag, "status": "Success"}}
pageSize := 1
pageNumber := 1
request := V2ListRequest{PageSize: &pageSize, PageNum: &pageNumber, InnerFilters: filter, OrderBy: "timestamp:desc"}
requestBody, _ := json.Marshal(request)
requestUrl := fmt.Sprintf("%s/api/v1/vulnerability/scanResultsSumSummary?customerGUID=%s", armoCivAdaptor.armoUrls.BackendUrl, armoCivAdaptor.accountId)
requestUrl := fmt.Sprintf("%s/api/v1/vulnerability/scanResultsSumSummary?customerGUID=%s", armoCivAdaptor.armoUrls.BackendUrl, armoCivAdaptor.accountID)
client := &http.Client{}
httpRequest, err := http.NewRequest("POST", requestUrl, bytes.NewBuffer(requestBody))
if err != nil {
return "", err
}
httpRequest.Header.Set("Content-Type", "application/json")
httpRequest.Header.Set("Authorization", fmt.Sprintf("Bearer %s", armoCivAdaptor.feToken.Token))
httpRequest.Header.Set("Cookie", fmt.Sprintf("auth=%s", armoCivAdaptor.authCookie))
@@ -120,3 +124,26 @@ func (armoCivAdaptor *ArmoCivAdaptor) getImageLastScanId(imageID *registryvulner
return scanSummartResult.Response[0].ContainerScanID, nil
}
func responseObjectToVulnerabilities(vulnerabilitiesList containerscan.VulnerabilitiesList) []registryvulnerabilities.Vulnerability {
vulnerabilities := make([]registryvulnerabilities.Vulnerability, len(vulnerabilitiesList))
for i, vulnerabilityEntry := range vulnerabilitiesList {
vulnerabilities[i].Description = vulnerabilityEntry.Description
vulnerabilities[i].Fixes = make([]registryvulnerabilities.FixedIn, len(vulnerabilityEntry.Fixes))
for j, fix := range vulnerabilityEntry.Fixes {
vulnerabilities[i].Fixes[j].ImgTag = fix.ImgTag
vulnerabilities[i].Fixes[j].Name = fix.Name
vulnerabilities[i].Fixes[j].Version = fix.Version
}
vulnerabilities[i].HealthStatus = vulnerabilityEntry.HealthStatus
vulnerabilities[i].Link = vulnerabilityEntry.Link
vulnerabilities[i].Metadata = vulnerabilityEntry.Metadata
vulnerabilities[i].Name = vulnerabilityEntry.Name
vulnerabilities[i].PackageVersion = vulnerabilityEntry.PackageVersion
vulnerabilities[i].RelatedPackageName = vulnerabilityEntry.RelatedPackageName
vulnerabilities[i].Relevancy = vulnerabilityEntry.Relevancy
vulnerabilities[i].Severity = vulnerabilityEntry.Severity
vulnerabilities[i].UrgentCount = vulnerabilityEntry.UrgentCount
}
return vulnerabilities
}
@@ -49,8 +49,8 @@ type ArmoSelectCustomer struct {
type ArmoCivAdaptor struct {
registry string
accountId string
clientId string
accountID string
clientID string
accessKey string
feToken FeLoginResponse
armoUrls ArmoBeConfiguration
+9 -3
View File
@@ -34,13 +34,15 @@ const (
// FileResourceHandler handle resources from files and URLs
type FileResourceHandler struct {
inputPatterns []string
inputPatterns []string
registryAdaptors *RegistryAdaptors
}
func NewFileResourceHandler(inputPatterns []string) *FileResourceHandler {
func NewFileResourceHandler(inputPatterns []string, registryAdaptors *RegistryAdaptors) *FileResourceHandler {
k8sinterface.InitializeMapResourcesMock() // initialize the resource map
return &FileResourceHandler{
inputPatterns: inputPatterns,
inputPatterns: inputPatterns,
registryAdaptors: registryAdaptors,
}
}
@@ -90,6 +92,10 @@ func (fileHandler *FileResourceHandler) GetResources(frameworks []reporthandling
}
}
if err := fileHandler.registryAdaptors.collectImagesVulnerabilities(k8sResources, allResources); err != nil {
cautils.WarningDisplay(os.Stderr, "Warning: failed to collect images vulnerabilities: %s\n", err.Error())
}
return k8sResources, allResources, nil
}
+8 -1
View File
@@ -30,14 +30,16 @@ type K8sResourceHandler struct {
hostSensorHandler hostsensorutils.IHostSensor
fieldSelector IFieldSelector
rbacObjectsAPI *cautils.RBACObjects
registryAdaptors *RegistryAdaptors
}
func NewK8sResourceHandler(k8s *k8sinterface.KubernetesApi, fieldSelector IFieldSelector, hostSensorHandler hostsensorutils.IHostSensor, rbacObjects *cautils.RBACObjects) *K8sResourceHandler {
func NewK8sResourceHandler(k8s *k8sinterface.KubernetesApi, fieldSelector IFieldSelector, hostSensorHandler hostsensorutils.IHostSensor, rbacObjects *cautils.RBACObjects, registryAdaptors *RegistryAdaptors) *K8sResourceHandler {
return &K8sResourceHandler{
k8s: k8s,
fieldSelector: fieldSelector,
hostSensorHandler: hostSensorHandler,
rbacObjectsAPI: rbacObjects,
registryAdaptors: registryAdaptors,
}
}
@@ -60,6 +62,11 @@ func (k8sHandler *K8sResourceHandler) GetResources(frameworks []reporthandling.F
if err := k8sHandler.pullResources(k8sResourcesMap, allResources, namespace, labels); err != nil {
return k8sResourcesMap, allResources, err
}
if err := k8sHandler.registryAdaptors.collectImagesVulnerabilities(k8sResourcesMap, allResources); err != nil {
cautils.WarningDisplay(os.Stderr, "Warning: failed to collect image vulnerabilities: %s\n", err.Error())
}
if err := k8sHandler.collectHostResources(allResources, k8sResourcesMap); err != nil {
cautils.WarningDisplay(os.Stderr, "Warning: failed to collect host sensor resources\n")
}
+147
View File
@@ -0,0 +1,147 @@
package resourcehandler
import (
"github.com/armosec/k8s-interface/k8sinterface"
"github.com/armosec/k8s-interface/workloadinterface"
"github.com/armosec/kubescape/cautils"
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 {
// 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 {
return err
}
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) {
customerGUID := " "
clientID := " "
accessKey := " "
registry := "armoui-dev.eudev3.cyberarmorsoft.com"
adaptors := []registryvulnerabilities.IContainerImageVulnerabilityAdaptor{}
armosecAdaptor, err := armosecadaptorv1.NewArmoAdaptor(registry, map[string]string{"accountID": customerGUID, "clientID": clientID, "accessKey": accessKey})
if err != nil {
return nil, err
}
adaptors = append(adaptors, armosecAdaptor)
return adaptors, nil
}