mirror of
https://github.com/kubescape/kubescape.git
synced 2026-02-14 18:09:55 +00:00
add wlid annotation to workloadconfigurationscans and summaries
Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>
This commit is contained in:
@@ -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
3
go.mod
@@ -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
6
go.sum
@@ -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=
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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=
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user