Skip to content

Commit

Permalink
Merge pull request #88 from kubescape/labels
Browse files Browse the repository at this point in the history
ensure proper labels and annotations on objects
  • Loading branch information
dwertent committed Mar 30, 2023
2 parents dd379b8 + b0c251e commit 2c40e73
Show file tree
Hide file tree
Showing 13 changed files with 98 additions and 20 deletions.
2 changes: 2 additions & 0 deletions adapters/mockcve.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ func (m MockCVEAdapter) ScanSBOM(ctx context.Context, sbom domain.SBOM) (domain.
SBOMCreatorVersion: sbom.SBOMCreatorVersion,
CVEScannerVersion: m.Version(ctx),
CVEDBVersion: m.DBVersion(ctx),
Annotations: sbom.Annotations,
Labels: sbom.Labels,
Content: &v1beta1.GrypeDocument{},
}, nil
}
Expand Down
6 changes: 6 additions & 0 deletions adapters/mocksbom.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import (
"time"

"github.com/kubescape/go-logger"
"github.com/kubescape/k8s-interface/instanceidhandler/v1"
"github.com/kubescape/kubevuln/core/domain"
"github.com/kubescape/kubevuln/core/ports"
"github.com/kubescape/kubevuln/internal/tools"
"github.com/kubescape/storage/pkg/apis/softwarecomposition/v1beta1"
)

Expand Down Expand Up @@ -37,6 +39,10 @@ func (m MockSBOMAdapter) CreateSBOM(ctx context.Context, imageID string, _ domai
sbom := domain.SBOM{
ID: imageID,
SBOMCreatorVersion: m.Version(),
Annotations: map[string]string{
instanceidhandler.ImageTagAnnotationKey: imageID,
},
Labels: tools.LabelsFromImageID(imageID),
Content: &v1beta1.Document{
CreationInfo: &v1beta1.CreationInfo{
Created: time.Now().Format(time.RFC3339),
Expand Down
6 changes: 3 additions & 3 deletions adapters/mocksbom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ import (

func TestMockSBOMAdapter_CreateSBOM(t *testing.T) {
m := NewMockSBOMAdapter(false, false)
sbom, _ := m.CreateSBOM(context.TODO(), "imageID", domain.RegistryOptions{})
sbom, _ := m.CreateSBOM(context.TODO(), "image", domain.RegistryOptions{})
assert.Assert(t, sbom.Content != nil)
}

func TestMockSBOMAdapter_CreateSBOM_Error(t *testing.T) {
m := NewMockSBOMAdapter(true, false)
_, err := m.CreateSBOM(context.TODO(), "imageID", domain.RegistryOptions{})
_, err := m.CreateSBOM(context.TODO(), "image", domain.RegistryOptions{})
assert.Assert(t, err != nil)
}

func TestMockSBOMAdapter_CreateSBOM_Timeout(t *testing.T) {
m := NewMockSBOMAdapter(false, true)
sbom, _ := m.CreateSBOM(context.TODO(), "imageID", domain.RegistryOptions{})
sbom, _ := m.CreateSBOM(context.TODO(), "image", domain.RegistryOptions{})
assert.Assert(t, sbom.Status == domain.SBOMStatusTimedOut)
}

Expand Down
2 changes: 2 additions & 0 deletions adapters/v1/grype.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ func (g *GrypeAdapter) ScanSBOM(ctx context.Context, sbom domain.SBOM) (domain.C
SBOMCreatorVersion: sbom.SBOMCreatorVersion,
CVEScannerVersion: g.Version(ctx),
CVEDBVersion: g.DBVersion(ctx),
Annotations: sbom.Annotations,
Labels: sbom.Labels,
Content: vulnerabilityResults,
}, nil
}
Expand Down
5 changes: 5 additions & 0 deletions adapters/v1/syft.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/eapache/go-resiliency/deadline"
"github.com/kubescape/go-logger"
"github.com/kubescape/go-logger/helpers"
"github.com/kubescape/k8s-interface/instanceidhandler/v1"
"github.com/kubescape/kubevuln/core/domain"
"github.com/kubescape/kubevuln/core/ports"
"github.com/kubescape/kubevuln/internal/tools"
Expand Down Expand Up @@ -45,6 +46,10 @@ func (s *SyftAdapter) CreateSBOM(ctx context.Context, imageID string, options do
domainSBOM := domain.SBOM{
ID: imageID,
SBOMCreatorVersion: s.Version(),
Annotations: map[string]string{
instanceidhandler.ImageTagAnnotationKey: imageID,
},
Labels: tools.LabelsFromImageID(imageID),
}
// translate business models into Syft models
sourceInput, err := source.ParseInput(imageID, "", true)
Expand Down
1 change: 1 addition & 0 deletions core/domain/cve.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ type CVEManifest struct {
CVEScannerVersion string
CVEDBVersion string
Content *v1beta1.GrypeDocument
Annotations map[string]string
Labels map[string]string
}
1 change: 1 addition & 0 deletions core/domain/sbom.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type SBOM struct {
SBOMCreatorVersion string
Status string
Content *v1beta1.Document
Annotations map[string]string
Labels map[string]string
}

Expand Down
1 change: 0 additions & 1 deletion core/services/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ func (s *ScanService) ScanCVE(ctx context.Context) error {
}
// store CVE'
if s.storage {
cvep.Labels = sbomp.Labels
cvep.Wlid = workload.Wlid
err = s.cveRepository.StoreCVE(ctx, cvep, true)
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/anchore/grype v0.59.1
github.com/anchore/stereoscope v0.0.0-20230317134707-7928713c391e
github.com/anchore/syft v0.75.0
github.com/aquilax/truncate v1.0.0
github.com/armosec/armoapi-go v0.0.176
github.com/armosec/cluster-container-scanner-api v0.0.52
github.com/armosec/logger-go v0.0.14
Expand All @@ -22,7 +23,7 @@ require (
github.com/hashicorp/go-multierror v1.1.1
github.com/kinbiko/jsonassert v1.1.1
github.com/kubescape/go-logger v0.0.11
github.com/kubescape/k8s-interface v0.0.116
github.com/kubescape/k8s-interface v0.0.118
github.com/kubescape/storage v0.2.0
github.com/spdx/tools-golang v0.5.0-rc1
github.com/spf13/viper v1.15.0
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,8 @@ github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/aquilax/truncate v1.0.0 h1:UgIGS8U/aZ4JyOJ2h3xcF5cSQ06+gGBnjxH2RUHJe0U=
github.com/aquilax/truncate v1.0.0/go.mod h1:BeMESIDMlvlS3bmg4BVvBbbZUNwWtS8uzYPAKXwwhLw=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
Expand Down Expand Up @@ -673,8 +675,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kubescape/go-logger v0.0.11 h1:oucpq2S7+DT7O+UclG5IrmHado/tj6+IkYf9czVk/aY=
github.com/kubescape/go-logger v0.0.11/go.mod h1:yGiKBJ2lhq/kxzY/MVYDREL9fLV3RGD6gv+UFjslaew=
github.com/kubescape/k8s-interface v0.0.116 h1:Sn76gsMLAArc5kbHZVoRMS6QlM4mOz9Dolpym9BOul8=
github.com/kubescape/k8s-interface v0.0.116/go.mod h1:ENpA9SkkS6E3PIT+AaMu/JGkuyE04aUamY+a7WLqsJQ=
github.com/kubescape/k8s-interface v0.0.118 h1:w5RyIPp/agXMQcBoQ67KfxFRqfYnFle4mGMUyYjIydM=
github.com/kubescape/k8s-interface v0.0.118/go.mod h1:ENpA9SkkS6E3PIT+AaMu/JGkuyE04aUamY+a7WLqsJQ=
github.com/kubescape/storage v0.2.0 h1:WZXy4Dyjf5ltEMtk0SOD9RFL1haS9ffFPGfs1gUV1aM=
github.com/kubescape/storage v0.2.0/go.mod h1:sPE749pFNoxoskBn6JTpNQyguF2rv/u2kYqzRd3MvXw=
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
Expand Down
27 changes: 27 additions & 0 deletions internal/tools/tools.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package tools

import (
"regexp"
"runtime/debug"
"testing"

"github.com/aquilax/truncate"
"github.com/distribution/distribution/reference"
"github.com/kubescape/k8s-interface/instanceidhandler/v1"
"gotest.tools/v3/assert"
"k8s.io/apimachinery/pkg/util/validation"
)

func EnsureSetup(t *testing.T, errored bool) {
Expand All @@ -22,3 +27,25 @@ func PackageVersion(name string) string {
}
return "unknown"
}

var offendingChars = regexp.MustCompile("[@:/ .]")

func sanitize(s string) string {
return truncate.Truncate(offendingChars.ReplaceAllString(s, "-"), 63, "", truncate.PositionEnd)
}

// LabelsFromImageID returns a map of labels from an image ID.
// Each label is sanitized and verified to be a valid DNS1123 label.
func LabelsFromImageID(imageID string) map[string]string {
labels := map[string]string{}
match := reference.ReferenceRegexp.FindStringSubmatch(imageID)
labels[instanceidhandler.ImageNameAnnotationKey] = sanitize(match[1])
labels[instanceidhandler.ImageTagAnnotationKey] = sanitize(match[2])
// prune invalid labels
for key, value := range labels {
if errs := validation.IsDNS1123Label(value); len(errs) != 0 {
delete(labels, key)
}
}
return labels
}
37 changes: 37 additions & 0 deletions internal/tools/tools_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package tools

import (
"reflect"
"testing"

"github.com/kubescape/k8s-interface/instanceidhandler/v1"
"gotest.tools/v3/assert"
)

Expand All @@ -13,3 +15,38 @@ func TestEnsureSetup(t *testing.T) {
func TestPackageVersion(t *testing.T) {
assert.Assert(t, PackageVersion("github.com/anchore/syft") == "unknown") // only works on compiled binaries
}

func TestLabelsFromImageID(t *testing.T) {
tests := []struct {
imageID string
want map[string]string
}{
{
imageID: "myapp",
want: map[string]string{instanceidhandler.ImageNameAnnotationKey: "myapp"},
},
{
imageID: "registry.com:8080/myapp",
want: map[string]string{instanceidhandler.ImageNameAnnotationKey: "registry-com-8080-myapp"},
},
{
imageID: "registry.com:8080/myapp:tag",
want: map[string]string{instanceidhandler.ImageNameAnnotationKey: "registry-com-8080-myapp", instanceidhandler.ImageTagAnnotationKey: "tag"},
},
{
imageID: "registry.com:8080/myapp@sha256:be178c0543eb17f5f3043021c9e5fcf30285e557a4fc309cce97ff9ca6182912",
want: map[string]string{instanceidhandler.ImageNameAnnotationKey: "registry-com-8080-myapp"},
},
{
imageID: "registry.com:8080/myapp:tag2@sha256:be178c0543eb17f5f3043021c9e5fcf30285e557a4fc309cce97ff9ca6182912",
want: map[string]string{instanceidhandler.ImageNameAnnotationKey: "registry-com-8080-myapp", instanceidhandler.ImageTagAnnotationKey: "tag2"},
},
}
for _, tt := range tests {
t.Run(tt.imageID, func(t *testing.T) {
if got := LabelsFromImageID(tt.imageID); !reflect.DeepEqual(got, tt.want) {
t.Errorf("LabelsFromImageID() = %v, want %v", got, tt.want)
}
})
}
}
21 changes: 8 additions & 13 deletions repositories/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,17 +106,10 @@ func (a *APIServerStore) StoreCVE(ctx context.Context, cve domain.CVEManifest, w
return nil
}
name := hashFromImageID(cve.ID)
annotations := make(map[string]string)
if withRelevancy {
annotations[instanceidhandler.InstanceIDAnnotationKey] = cve.ID
annotations[instanceidhandler.WlidAnnotationKey] = cve.Wlid
} else {
annotations[instanceidhandler.ImageTagAnnotationKey] = cve.ID
}
manifest := v1beta1.VulnerabilityManifest{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Annotations: annotations,
Annotations: cve.Annotations,
Labels: cve.Labels,
},
Spec: v1beta1.VulnerabilityManifestSpec{
Expand Down Expand Up @@ -238,11 +231,9 @@ func (a *APIServerStore) StoreSBOM(ctx context.Context, sbom domain.SBOM) error
}
manifest := v1beta1.SBOMSPDXv2p3{
ObjectMeta: metav1.ObjectMeta{
Name: hashFromImageID(sbom.ID),
Annotations: map[string]string{
instanceidhandler.ImageTagAnnotationKey: sbom.ID,
instanceidhandler.StatusAnnotationKey: sbom.Status,
},
Name: hashFromImageID(sbom.ID),
Annotations: sbom.Annotations,
Labels: sbom.Labels,
},
Spec: v1beta1.SBOMSPDXv2p3Spec{
Metadata: v1beta1.SPDXMeta{
Expand All @@ -255,6 +246,10 @@ func (a *APIServerStore) StoreSBOM(ctx context.Context, sbom domain.SBOM) error
},
Status: v1beta1.SBOMSPDXv2p3Status{}, // TODO move timeout information here
}
if manifest.Annotations == nil {
manifest.Annotations = map[string]string{}
}
manifest.Annotations[instanceidhandler.StatusAnnotationKey] = sbom.Status // for the moment stored as an annotation
created, err := time.Parse(time.RFC3339, sbom.Content.CreationInfo.Created)
if err != nil {
manifest.Spec.Metadata.Report.CreatedAt.Time = created
Expand Down

0 comments on commit 2c40e73

Please sign in to comment.