Skip to content

Commit

Permalink
Merge pull request #139 from kubescape/store-summary-CR-objects
Browse files Browse the repository at this point in the history
Store summary cr objects
  • Loading branch information
rcohencyberarmor committed Aug 16, 2023
2 parents c086e93 + 178fe93 commit a33e2c9
Show file tree
Hide file tree
Showing 4 changed files with 315 additions and 28 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ require (
github.com/kinbiko/jsonassert v1.1.1
github.com/kubescape/go-logger v0.0.13
github.com/kubescape/k8s-interface v0.0.127
github.com/kubescape/storage v0.0.8
github.com/kubescape/storage v0.0.16
github.com/spdx/tools-golang v0.5.0-rc1
github.com/spf13/viper v1.16.0
github.com/stretchr/testify v1.8.3
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -689,8 +689,8 @@ github.com/kubescape/go-logger v0.0.13 h1:Rio+grBhpcdExZIVT+HcBVcgbvwrU/aVSV99iK
github.com/kubescape/go-logger v0.0.13/go.mod h1:Tod++iNn5kofkhjpfwjUrqie2YHkLZNoH0Pq0+KldMo=
github.com/kubescape/k8s-interface v0.0.127 h1:9H4TxbUliliQe4eY+jsZDOaYRWMEK/jriMBj4cMX73A=
github.com/kubescape/k8s-interface v0.0.127/go.mod h1:ENpA9SkkS6E3PIT+AaMu/JGkuyE04aUamY+a7WLqsJQ=
github.com/kubescape/storage v0.0.8 h1:QnFdBASsiner/TY0lKpimEk/dbxMDHPnPyzCVJKCuW0=
github.com/kubescape/storage v0.0.8/go.mod h1:LDJDA+AxRosIer/1Ma/HSf2SvXgxCH8bYQ9eejAAv8s=
github.com/kubescape/storage v0.0.16 h1:4BR4h8oSE+Q9w5O7ZwzJeGO8a4j2p/QAfx4nFEKO0dI=
github.com/kubescape/storage v0.0.16/go.mod h1:LDJDA+AxRosIer/1Ma/HSf2SvXgxCH8bYQ9eejAAv8s=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 h1:bqDmpDG49ZRnB5PcgP0RXtQvnMSgIF14M7CBd2shtXs=
Expand Down
148 changes: 124 additions & 24 deletions repositories/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import (
"strconv"
"time"

"github.com/armosec/utils-k8s-go/wlid"
"github.com/kubescape/go-logger"
"github.com/kubescape/go-logger/helpers"
"github.com/kubescape/k8s-interface/instanceidhandler/v1"
v1 "github.com/kubescape/k8s-interface/instanceidhandler/v1"
"github.com/kubescape/k8s-interface/k8sinterface"
"github.com/kubescape/kubevuln/core/domain"
"github.com/kubescape/kubevuln/core/ports"
"github.com/kubescape/storage/pkg/apis/softwarecomposition/v1beta1"
Expand All @@ -22,6 +24,10 @@ import (
"k8s.io/client-go/util/retry"
)

const (
vulnerabilityManifestSummaryKindPlural string = "vulnerabilitymanifests"
)

// APIServerStore implements both CVERepository and SBOMRepository with in-cluster storage (apiserver) to be used for production
type APIServerStore struct {
StorageClient spdxv1beta1.SpdxV1beta1Interface
Expand Down Expand Up @@ -175,39 +181,132 @@ func (a *APIServerStore) storeCVEWithFullContent(ctx context.Context, cve domain
return nil
}

func parseSeverities(cve domain.CVEManifest) v1beta1.SeveritySummary {
func parseVulnerabilitiesComponents(name, namespace string, withRelevancy bool) v1beta1.VulnerabilitiesComponents {
vulComp := v1beta1.VulnerabilitiesComponents{}

if withRelevancy {
vulComp.WorkloadVulnerabilitiesObj.Name = name
vulComp.WorkloadVulnerabilitiesObj.Kind = vulnerabilityManifestSummaryKindPlural
vulComp.WorkloadVulnerabilitiesObj.Namespace = namespace
} else {
vulComp.ImageVulnerabilitiesObj.Name = name
vulComp.ImageVulnerabilitiesObj.Kind = vulnerabilityManifestSummaryKindPlural
vulComp.ImageVulnerabilitiesObj.Namespace = namespace
}
return vulComp
}

func parseSeverities(cve domain.CVEManifest, withRelevancy bool) v1beta1.SeveritySummary {
critical := 0
criticalRelevant := 0
high := 0
highRelevant := 0
medium := 0
mediumRelevant := 0
low := 0
lowRelevant := 0
negligible := 0
negligibleRelevant := 0
unknown := 0
unknownRelevant := 0

for i := range cve.Content.Matches {
switch cve.Content.Matches[i].Vulnerability.Severity {
case domain.CriticalSeverity:
critical += 1
if withRelevancy {
criticalRelevant += 1
} else {
critical += 1
}
case domain.HighSeverity:
high += 1
if withRelevancy {
highRelevant += 1
} else {
high += 1
}
case domain.MediumSeverity:
medium += 1
if withRelevancy {
mediumRelevant += 1
} else {
medium += 1
}
case domain.LowSeverity:
low += 1
if withRelevancy {
lowRelevant += 1
} else {
low += 1
}
case domain.NegligibleSeverity:
negligible += 1
if withRelevancy {
negligibleRelevant += 1
} else {
negligible += 1
}
case domain.UnknownSeverity:
unknown += 1
if withRelevancy {
unknownRelevant += 1
} else {
unknown += 1
}
}
}

return v1beta1.SeveritySummary{
Critical: v1beta1.VulnerabilityCounters{All: critical},
High: v1beta1.VulnerabilityCounters{All: high},
Medium: v1beta1.VulnerabilityCounters{All: medium},
Low: v1beta1.VulnerabilityCounters{All: low},
Negligible: v1beta1.VulnerabilityCounters{All: negligible},
Unknown: v1beta1.VulnerabilityCounters{All: unknown},
Critical: v1beta1.VulnerabilityCounters{All: critical, Relevant: criticalRelevant},
High: v1beta1.VulnerabilityCounters{All: high, Relevant: highRelevant},
Medium: v1beta1.VulnerabilityCounters{All: medium, Relevant: mediumRelevant},
Low: v1beta1.VulnerabilityCounters{All: low, Relevant: lowRelevant},
Negligible: v1beta1.VulnerabilityCounters{All: negligible, Relevant: negligibleRelevant},
Unknown: v1beta1.VulnerabilityCounters{All: unknown, Relevant: unknownRelevant},
}
}

func enrichSummaryManifestObjectAnnotations(ctx context.Context, annotations map[string]string) (map[string]string, error) {
if annotations == nil {
annotations = make(map[string]string)
}
enrichedAnnotations := annotations

workload, ok := ctx.Value(domain.WorkloadKey{}).(domain.ScanCommand)
if !ok {
return nil, domain.ErrMissingWorkload
}
enrichedAnnotations[v1.WlidMetadataKey] = workload.Wlid
enrichedAnnotations[v1.ContainerNameMetadataKey] = workload.ContainerName

return enrichedAnnotations, nil
}

func enrichSummaryManifestObjectLabels(ctx context.Context, labels map[string]string, withRelevancy bool) (map[string]string, error) {
if labels == nil {
labels = make(map[string]string)
}
if withRelevancy {
labels[v1.ContextMetadataKey] = v1.ContextMetadataKeyFiltered
} else {
labels[v1.ContextMetadataKey] = v1.ContextMetadataKeyNonFiltered
}
enrichedLabels := labels

workload, ok := ctx.Value(domain.WorkloadKey{}).(domain.ScanCommand)
if !ok {
return nil, domain.ErrMissingWorkload
}

workloadKind := wlid.GetKindFromWlid(workload.Wlid)
groupVersionScheme, err := k8sinterface.GetGroupVersionResource(workloadKind)
if err != nil {
return nil, err
}

enrichedLabels[v1.ApiGroupMetadataKey] = groupVersionScheme.Group
enrichedLabels[v1.ApiVersionMetadataKey] = groupVersionScheme.Version
enrichedLabels[v1.KindMetadataKey] = workloadKind
enrichedLabels[v1.NameMetadataKey] = wlid.GetNameFromWlid(workload.Wlid)
enrichedLabels[v1.NamespaceMetadataKey] = wlid.GetNamespaceFromWlid(workload.Wlid)
enrichedLabels[v1.ContainerNameMetadataKey] = workload.ContainerName

return enrichedLabels, nil
}

func (a *APIServerStore) storeCVESummary(ctx context.Context, cve domain.CVEManifest, withRelevancy bool) error {
Expand All @@ -219,27 +318,28 @@ func (a *APIServerStore) storeCVESummary(ctx context.Context, cve domain.CVEMani
helpers.String("relevant", strconv.FormatBool(withRelevancy)))
return nil
}
if cve.Labels == nil {
cve.Labels = make(map[string]string)
}

if withRelevancy {
cve.Labels[v1.ContextMetadataKey] = v1.ContextMetadataKeyFiltered
} else {
cve.Labels[v1.ContextMetadataKey] = v1.ContextMetadataKeyNonFiltered
annotations, err := enrichSummaryManifestObjectAnnotations(ctx, cve.Annotations)
if err != nil {
return err
}
labels, err := enrichSummaryManifestObjectLabels(ctx, cve.Labels, withRelevancy)
if err != nil {
return err
}

manifest := v1beta1.VulnerabilityManifestSummary{
ObjectMeta: metav1.ObjectMeta{
Name: cve.Name,
Annotations: cve.Annotations,
Labels: cve.Labels,
Annotations: annotations,
Labels: labels,
},
Spec: v1beta1.VulnerabilityManifestSummarySpec{
Severities: parseSeverities(cve),
Severities: parseSeverities(cve, withRelevancy),
Vulnerabilities: parseVulnerabilitiesComponents(cve.Name, a.Namespace, withRelevancy),
},
}
_, err := a.StorageClient.VulnerabilityManifestSummaries(a.Namespace).Create(context.Background(), &manifest, metav1.CreateOptions{})
_, err = a.StorageClient.VulnerabilityManifestSummaries(a.Namespace).Create(context.Background(), &manifest, metav1.CreateOptions{})
switch {
case errors.IsAlreadyExists(err):
retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
Expand Down
Loading

0 comments on commit a33e2c9

Please sign in to comment.