add wlid annotation to workloadconfigurationscans and summaries

Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>
This commit is contained in:
Matthias Bertschy
2023-12-06 16:05:14 +01:00
parent e27237047e
commit e29e6a5e8a
8 changed files with 46 additions and 56 deletions

View File

@@ -57,7 +57,7 @@ func Test_GetRequestPayload(t *testing.T) {
Commands: []apis.Command{
{
CommandName: apis.TypeScanImages,
WildWlid: "wlid://cluster-any",
WildWlid: "wlid://cluster-any/namespace-",
},
},
},

3
go.mod
View File

@@ -9,7 +9,7 @@ require (
github.com/anchore/syft v0.86.1
github.com/armosec/armoapi-go v0.0.256
github.com/armosec/utils-go v0.0.40
github.com/armosec/utils-k8s-go v0.0.18
github.com/armosec/utils-k8s-go v0.0.23
github.com/briandowns/spinner v1.23.0
github.com/chainguard-dev/git-urls v1.0.2
github.com/distribution/distribution v2.8.3+incompatible
@@ -309,6 +309,7 @@ require (
github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 // indirect
github.com/nwaples/rardecode v1.1.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/olvrng/ujson v1.1.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc4 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect

6
go.sum
View File

@@ -627,8 +627,8 @@ github.com/armosec/gojay v1.2.15 h1:sSB2vnAvacUNkw9nzUYZKcPzhJOyk6/5LK2JCNdmoZY=
github.com/armosec/gojay v1.2.15/go.mod h1:vzVAaay2TWJAngOpxu8aqLbye9jMgoKleuAOK+xsOts=
github.com/armosec/utils-go v0.0.40 h1:FdH8TxRG0SH3heKLrZ0Mj0eq5dNgk5go8/mteSCg2wY=
github.com/armosec/utils-go v0.0.40/go.mod h1:pDaq3SNKQ8wliAAOq4B8re9MWmT0bX9di2Jn1jZI7lE=
github.com/armosec/utils-k8s-go v0.0.18 h1:SBmj+j/5JrROVQVLjlHsoMcPZKK/AKWEK1SMMf3hd1U=
github.com/armosec/utils-k8s-go v0.0.18/go.mod h1:FJRG/MRz7jT4ExSEYHIFsilVsAF11M+GJRhLl4PFZ4s=
github.com/armosec/utils-k8s-go v0.0.23 h1:+nPV0NL2lYPwSFdXGymytNvrtMMgFjA+Ia5Efwg9ZiQ=
github.com/armosec/utils-k8s-go v0.0.23/go.mod h1:CXgkHFgY8xlKN+wiQ8TyjwNj0+VSgj6NolB3itZ2lY8=
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
@@ -1581,6 +1581,8 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olvrng/ujson v1.1.0 h1:8xVUzVlqwdMVWh5d1UHBtLQ1D50nxoPuPEq9Wozs8oA=
github.com/olvrng/ujson v1.1.0/go.mod h1:Mz4G3RODTUfbkKyvi0lgmPx/7vd3Saksk+1jgk8s9xo=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=

View File

@@ -7,6 +7,7 @@ replace github.com/kubescape/kubescape/v3 => ../
require (
github.com/armosec/armoapi-go v0.0.256
github.com/armosec/utils-go v0.0.40
github.com/armosec/utils-k8s-go v0.0.23
github.com/go-openapi/runtime v0.26.0
github.com/google/uuid v1.3.1
github.com/gorilla/mux v1.8.0
@@ -112,7 +113,6 @@ require (
github.com/aquasecurity/trivy v0.44.1 // indirect
github.com/aquasecurity/trivy-db v0.0.0-20230726112157-167ba4f2faeb // indirect
github.com/armosec/gojay v1.2.15 // indirect
github.com/armosec/utils-k8s-go v0.0.18 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/aws/aws-sdk-go v1.44.312 // indirect
github.com/aws/aws-sdk-go-v2 v1.20.0 // indirect
@@ -312,6 +312,7 @@ require (
github.com/nwaples/rardecode v1.1.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/olekukonko/tablewriter v0.0.6-0.20230417144759-edd1a71a5576 // indirect
github.com/olvrng/ujson v1.1.0 // indirect
github.com/open-policy-agent/opa v0.55.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc4 // indirect

View File

@@ -627,8 +627,8 @@ github.com/armosec/gojay v1.2.15 h1:sSB2vnAvacUNkw9nzUYZKcPzhJOyk6/5LK2JCNdmoZY=
github.com/armosec/gojay v1.2.15/go.mod h1:vzVAaay2TWJAngOpxu8aqLbye9jMgoKleuAOK+xsOts=
github.com/armosec/utils-go v0.0.40 h1:FdH8TxRG0SH3heKLrZ0Mj0eq5dNgk5go8/mteSCg2wY=
github.com/armosec/utils-go v0.0.40/go.mod h1:pDaq3SNKQ8wliAAOq4B8re9MWmT0bX9di2Jn1jZI7lE=
github.com/armosec/utils-k8s-go v0.0.18 h1:SBmj+j/5JrROVQVLjlHsoMcPZKK/AKWEK1SMMf3hd1U=
github.com/armosec/utils-k8s-go v0.0.18/go.mod h1:FJRG/MRz7jT4ExSEYHIFsilVsAF11M+GJRhLl4PFZ4s=
github.com/armosec/utils-k8s-go v0.0.23 h1:+nPV0NL2lYPwSFdXGymytNvrtMMgFjA+Ia5Efwg9ZiQ=
github.com/armosec/utils-k8s-go v0.0.23/go.mod h1:CXgkHFgY8xlKN+wiQ8TyjwNj0+VSgj6NolB3itZ2lY8=
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
@@ -1585,6 +1585,8 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olvrng/ujson v1.1.0 h1:8xVUzVlqwdMVWh5d1UHBtLQ1D50nxoPuPEq9Wozs8oA=
github.com/olvrng/ujson v1.1.0/go.mod h1:Mz4G3RODTUfbkKyvi0lgmPx/7vd3Saksk+1jgk8s9xo=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=

View File

@@ -54,13 +54,13 @@ func main() {
initializeLoggerName()
initializeLoggerLevel()
initializeSaaSEnv()
initializeStorage(cfg)
initializeStorage(clusterName, cfg)
// traces will be created by otelmux.Middleware in SetupHTTPListener()
logger.L().Ctx(ctx).Fatal(listener.SetupHTTPListener().Error())
}
func initializeStorage(cfg config.Config) {
func initializeStorage(clusterName string, cfg config.Config) {
if !cfg.ContinuousPostureScan {
logger.L().Debug("continuous posture scan - skipping storage initialization")
return
@@ -80,7 +80,7 @@ func initializeStorage(cfg config.Config) {
}
}
s, err := storage.NewAPIServerStorage(namespace, config)
s, err := storage.NewAPIServerStorage(clusterName, namespace, config)
if err != nil {
logger.L().Fatal("storage initialization error", helpers.Error(err))
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"github.com/armosec/utils-k8s-go/wlid"
"github.com/kubescape/go-logger"
"github.com/kubescape/go-logger/helpers"
v1 "github.com/kubescape/k8s-interface/instanceidhandler/v1"
@@ -40,6 +41,7 @@ type PostureRepository interface {
// APIServerStore implements both PostureRepository with in-cluster storage (apiserver) to be used for production
type APIServerStore struct {
StorageClient spdxv1beta1.SpdxV1beta1Interface
clusterName string
namespace string
}
@@ -54,7 +56,7 @@ func GetStorage() *APIServerStore {
}
// NewAPIServerStorage initializes the APIServerStore struct
func NewAPIServerStorage(namespace string, config *rest.Config) (*APIServerStore, error) {
func NewAPIServerStorage(clusterName string, namespace string, config *rest.Config) (*APIServerStore, error) {
// disable rate limiting
config.QPS = 0
config.RateLimiter = nil
@@ -64,6 +66,7 @@ func NewAPIServerStorage(namespace string, config *rest.Config) (*APIServerStore
}
return &APIServerStore{
StorageClient: clientset.SpdxV1beta1(),
clusterName: clusterName,
namespace: namespace,
}, nil
}
@@ -156,7 +159,7 @@ func (a *APIServerStore) StoreWorkloadConfigurationScanResult(ctx context.Contex
return nil, err
}
namespace := a.getResourceNamespace(resource, relatedObjects)
labels, annotations, err := getManifestObjectLabelsAndAnnotations(ctx, resource, relatedObjects)
labels, annotations, err := getManifestObjectLabelsAndAnnotations(a.clusterName, resource, relatedObjects)
if err != nil {
return nil, err
}
@@ -323,22 +326,24 @@ func (a *APIServerStore) StoreWorkloadConfigurationScanResultSummary(ctx context
return &manifest, nil
}
func updateLabelsAndAnnotationsMapFromRelatedObjects(m map[string]string, relatedObjects []workloadinterface.IMetadata) error {
m[v1.RbacResourceMetadataKey] = "true"
func updateLabelsAndAnnotationsMapFromRelatedObjects(clusterName string, labels map[string]string, annotations map[string]string, relatedObjects []workloadinterface.IMetadata) error {
labels[v1.RbacResourceMetadataKey] = "true"
for i := range relatedObjects {
relatedObject := relatedObjects[i]
switch relatedObject.GetKind() {
case "Role":
m[v1.RoleNameMetadataKey] = relatedObject.GetName()
m[v1.RoleNamespaceMetadataKey] = relatedObject.GetNamespace()
labels[v1.RoleNameMetadataKey] = relatedObject.GetName()
labels[v1.RoleNamespaceMetadataKey] = relatedObject.GetNamespace()
case "RoleBinding":
m[v1.RoleBindingNameMetadataKey] = relatedObject.GetName()
m[v1.RoleBindingNamespaceMetadataKey] = relatedObject.GetNamespace()
labels[v1.RoleBindingNameMetadataKey] = relatedObject.GetName()
labels[v1.RoleBindingNamespaceMetadataKey] = relatedObject.GetNamespace()
annotations[v1.WlidMetadataKey] = wlid.GetK8sWLID(clusterName, relatedObject.GetNamespace(), relatedObject.GetKind(), relatedObject.GetName())
case "ClusterRole":
m[v1.ClusterRoleNameMetadataKey] = relatedObject.GetName()
labels[v1.ClusterRoleNameMetadataKey] = relatedObject.GetName()
case "ClusterRoleBinding":
m[v1.ClusterRoleBindingNameMetadataKey] = relatedObject.GetName()
labels[v1.ClusterRoleBindingNameMetadataKey] = relatedObject.GetName()
annotations[v1.WlidMetadataKey] = wlid.GetK8sWLID(clusterName, "", relatedObject.GetKind(), relatedObject.GetName())
default:
return fmt.Errorf("unknown related object kind %s", relatedObject.GetKind())
}
@@ -346,24 +351,24 @@ func updateLabelsAndAnnotationsMapFromRelatedObjects(m map[string]string, relate
return nil
}
func getManifestObjectLabelsAndAnnotations(ctx context.Context, resource workloadinterface.IMetadata, relatedObjects []workloadinterface.IMetadata) (labels map[string]string, annotations map[string]string, err error) {
m := make(map[string]string)
m[v1.ApiGroupMetadataKey], m[v1.ApiVersionMetadataKey] = k8sinterface.SplitApiVersion(resource.GetApiVersion())
m[v1.KindMetadataKey] = resource.GetKind()
m[v1.NameMetadataKey] = resource.GetName()
func getManifestObjectLabelsAndAnnotations(clusterName string, resource workloadinterface.IMetadata, relatedObjects []workloadinterface.IMetadata) (map[string]string, map[string]string, error) {
annotations := map[string]string{
v1.WlidMetadataKey: wlid.GetK8sWLID(clusterName, resource.GetNamespace(), resource.GetKind(), resource.GetName()),
}
labels := make(map[string]string)
labels[v1.ApiGroupMetadataKey], labels[v1.ApiVersionMetadataKey] = k8sinterface.SplitApiVersion(resource.GetApiVersion())
labels[v1.KindMetadataKey] = resource.GetKind()
labels[v1.NameMetadataKey] = resource.GetName()
if k8sinterface.IsResourceInNamespaceScope(resource.GetKind()) {
m[v1.NamespaceMetadataKey] = resource.GetNamespace()
labels[v1.NamespaceMetadataKey] = resource.GetNamespace()
}
if len(relatedObjects) > 0 {
if err := updateLabelsAndAnnotationsMapFromRelatedObjects(m, relatedObjects); err != nil {
if err := updateLabelsAndAnnotationsMapFromRelatedObjects(clusterName, labels, annotations, relatedObjects); err != nil {
return nil, nil, err
}
}
annotations = m
labels = make(map[string]string)
maps.Copy(labels, m)
names.SanitizeLabelValues(labels)
return labels, annotations, nil

View File

@@ -306,11 +306,7 @@ func TestGetManifestObjectLabelsAndAnnotations(t *testing.T) {
"kubescape.io/workload-namespace": "test-namespace",
},
expectedAnnotations: map[string]string{
"kubescape.io/workload-api-group": "",
"kubescape.io/workload-api-version": "v1",
"kubescape.io/workload-kind": "Pod",
"kubescape.io/workload-name": "test-pod",
"kubescape.io/workload-namespace": "test-namespace",
"kubescape.io/wlid": "wlid://cluster-minikube/namespace-test-namespace/pod-test-pod",
},
},
{
@@ -348,20 +344,11 @@ func TestGetManifestObjectLabelsAndAnnotations(t *testing.T) {
"kubescape.io/rolebinding-namespace": "test-namespace",
},
expectedAnnotations: map[string]string{
"kubescape.io/workload-api-group": "",
"kubescape.io/workload-api-version": "v1",
"kubescape.io/workload-kind": "Pod",
"kubescape.io/workload-name": "test-pod",
"kubescape.io/workload-namespace": "test-namespace",
"kubescape.io/rbac-resource": "true",
"kubescape.io/role-name": "test-role",
"kubescape.io/role-namespace": "test-namespace",
"kubescape.io/rolebinding-name": "test-role-binding",
"kubescape.io/rolebinding-namespace": "test-namespace",
"kubescape.io/wlid": "wlid://cluster-minikube/namespace-test-namespace/rolebinding-test-role-binding",
},
},
{
name: "with related objects (role, rolebinding)",
name: "with related objects (clusterrole, clusterrolebinding)",
resource: &FakeMetadata{
Namespace: "test-namespace",
ApiVersion: "v1",
@@ -391,22 +378,14 @@ func TestGetManifestObjectLabelsAndAnnotations(t *testing.T) {
"kubescape.io/clusterrolebinding-name": "test-role-binding",
},
expectedAnnotations: map[string]string{
"kubescape.io/workload-api-group": "",
"kubescape.io/workload-api-version": "v1",
"kubescape.io/workload-kind": "Pod",
"kubescape.io/workload-name": "test-pod",
"kubescape.io/workload-namespace": "test-namespace",
"kubescape.io/rbac-resource": "true",
"kubescape.io/clusterrole-name": "test-role",
"kubescape.io/clusterrolebinding-name": "test-role-binding",
"kubescape.io/wlid": "wlid://cluster-minikube/namespace-/clusterrolebinding-test-role-binding",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := context.Background()
labels, annotations, err := getManifestObjectLabelsAndAnnotations(ctx, tt.resource, tt.relatedObjects)
labels, annotations, err := getManifestObjectLabelsAndAnnotations("minikube", tt.resource, tt.relatedObjects)
assert.NoError(t, err)
assert.Equal(t, tt.expectedLabels, labels)
assert.Equal(t, tt.expectedAnnotations, annotations)