Skip to content

Commit

Permalink
VulnerabilityReport v1alpha2 with grouped packages and webhook conver…
Browse files Browse the repository at this point in the history
…sion (#277)

* create resource VulnerabilityReport v1alpha2

* add VulnerabilityReport v1alpha2 fields

* generating clientset for vulnerabilityreport v1alpha2

* fix custom checks paths in Makefile

* parse trivy results to v1alpha2 vulnerability reports

* send v1alpha2 vulnerability reports to SaaS

* update vulnerabilityreport samples

* preserve unknown fields in .spec.vulnerabilities objects of v1alpha2 VulnerabilityReports

* deprecate VulnerabilityReport v1alpha1

* Setup VulnerabilityReport webhook conversion (#283)

* implement conversion.Hub in VulnerabilityReport v1alpha1

* move summarize function to v1alpha2 VulnerabilityReport

* implement conversion.Convertible in VulnerabilityReport v1alpha2

* set imagePullPolicy to IfNotPresent in config/manager/manager.yaml

* split install and install-crds targets in Makefile

* logging vulnerability reports conversions

* remove x-kubernetes-preserve-unknown-fields from v1alpha2 vulnerability report

* setup webhook with cert-manager

* setting TLSOpts in webhook server

* generating CRDs with kustomize for applying webhook patch

* installing yq in local binaries directory

* fix CRD generation

* updating CRD annotations

* annotate CRD for injecting conversion

* inject webhook conversion in annotated CRDs

* add flag for enabling/disabling conversion

* update helm chart for generating and mounting certificates if webhook is enabled

* set annotation with jq instead of kustomize

* remove unnecessary base64 encoding

* bump chart version to 0.8.5-rc3

* move NAMESPACE var in Makefile

* delete unused cert-manager files in config/ directory

* remove logs from vulnerabilityreport_conversion.go

* using certificates from existing secret if it already exists (#284)

* Add fields `totalPackages` and `totalUniquePackages` in VulnerabilityReport (#285)

* add fields `totalPackages` and `totalUniquePackages` in v1alpha2 VulnerabilityReport

* bump chart version to 0.8.5-rc4

* remove TODO
  • Loading branch information
matheusfm authored Jun 3, 2024
1 parent 03041da commit e7e761c
Show file tree
Hide file tree
Showing 47 changed files with 3,431 additions and 1,050 deletions.
20 changes: 16 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ help: ## Display this help.
##@ Development

.PHONY: manifests
manifests: controller-gen addlicense ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
manifests: controller-gen addlicense yq ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
$(YQ) -i '.metadata.annotations."zora.undistro.io/inject-conversion" = "true"' config/crd/bases/zora.undistro.io_vulnerabilityreports.yaml
@cp -r config/crd/bases/*.yaml charts/zora/crds/
$(ADDLICENSE) -c "Undistro Authors" -l "apache" -ignore ".github/**" -ignore ".idea/**" -ignore "dist/**" -ignore "site/**" -ignore "config/**" -ignore "docs/overrides/**" -ignore "docs/stylesheets/**" .

Expand Down Expand Up @@ -146,15 +147,19 @@ ifndef ignore-not-found
ignore-not-found = false
endif

.PHONY: install-crds
install-crds: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f -

NAMESPACE ?= zora-system
.PHONY: install
install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f -
install: install-crds ## Install CRs (plugins, custom checks, cluster, and scan) into the K8s cluster specified in ~/.kube/config.
@$(KUBECTL) create namespace $(NAMESPACE) || true
@$(KUBECTL) apply -f config/samples/zora_v1alpha1_plugin_popeye_all.yaml -n $(NAMESPACE)
@$(KUBECTL) apply -f config/samples/zora_v1alpha1_plugin_marvin.yaml -n $(NAMESPACE)
@$(KUBECTL) apply -f config/samples/zora_v1alpha1_plugin_trivy.yaml -n $(NAMESPACE)
@$(KUBECTL) apply -f config/samples/zora_v1alpha1_customcheck_labels.yaml -n $(NAMESPACE)
@$(KUBECTL) apply -f config/samples/zora_v1alpha1_customcheck_replicas.yaml -n $(NAMESPACE)
@$(KUBECTL) apply -f config/samples/zora_v1alpha2_customcheck_labels.yaml -n $(NAMESPACE)
@$(KUBECTL) apply -f config/rbac/zora_plugins_role.yaml
@$(KUBECTL) create -f config/rbac/zora_plugins_role_binding.yaml || true
@$(KUBECTL) apply -f config/samples/zora_v1alpha1_cluster.yaml -n $(NAMESPACE)
Expand Down Expand Up @@ -206,6 +211,7 @@ GOLANGCI_LINT = $(LOCALBIN)/golangci-lint-$(GOLANGCI_LINT_VERSION)
ADDLICENSE ?= $(LOCALBIN)/addlicense-$(ADDLICENSE_VERSION)
HELM_DOCS ?= $(LOCALBIN)/helm-docs-$(HELM_DOCS_VERSION)
KIND ?= $(LOCALBIN)/kind-$(KIND_VERSION)
YQ ?= $(LOCALBIN)/yq-$(YQ_VERSION)

## Tool Versions
KUSTOMIZE_VERSION ?= v5.3.0
Expand All @@ -215,6 +221,7 @@ GOLANGCI_LINT_VERSION ?= v1.54.2
HELM_DOCS_VERSION ?= v1.13.1
ADDLICENSE_VERSION ?= v1.1.1
KIND_VERSION ?= v0.22.0
YQ_VERSION ?= v4.43.1

.PHONY: kustomize
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.
Expand Down Expand Up @@ -251,6 +258,11 @@ kind: $(KIND) ## Download kind locally if necessary
$(KIND): $(LOCALBIN)
$(call go-install-tool,$(KIND),sigs.k8s.io/kind,${KIND_VERSION})

.PHONY: yq
yq: $(YQ) ## Download yq locally if necessary
$(YQ): $(LOCALBIN)
$(call go-install-tool,$(YQ),github.com/mikefarah/yq/v4,${YQ_VERSION})

# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist
# $1 - target path with name of binary (ideally with version)
# $2 - package url which can be installed
Expand Down
11 changes: 11 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ resources:
kind: VulnerabilityReport
path: github.com/undistro/zora/api/zora/v1alpha1
version: v1alpha1
webhooks:
conversion: true
webhookVersion: v1
- api:
crdVersion: v1
namespaced: true
Expand All @@ -68,4 +71,12 @@ resources:
kind: CustomCheck
path: github.com/undistro/zora/api/zora/v1alpha2
version: v1alpha2
- api:
crdVersion: v1
namespaced: true
domain: undistro.io
group: zora
kind: VulnerabilityReport
path: github.com/undistro/zora/api/zora/v1alpha2
version: v1alpha2
version: "3"
89 changes: 57 additions & 32 deletions api/zora/v1alpha1/vulnerabilityreport_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,53 @@
package v1alpha1

import (
"fmt"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// VulnerabilityReportSpec defines the desired state of VulnerabilityReport
type VulnerabilityReportSpec struct {
Cluster string `json:"cluster"`
Image string `json:"image"`
Digest string `json:"digest"`
Tags []string `json:"tags,omitempty"`
Architecture string `json:"architecture,omitempty"`
OS string `json:"os,omitempty"`
Distro *Distro `json:"distro,omitempty"`

TotalResources int `json:"totalResources"`
Resources map[string][]string `json:"resources"`
Vulnerabilities []Vulnerability `json:"vulnerabilities"`

Summary VulnerabilitySummary `json:"summary"`
VulnerabilityReportCommon `json:",inline"`
Vulnerabilities []Vulnerability `json:"vulnerabilities"`
}

type VulnerabilityReportCommon struct {
Cluster string `json:"cluster"`
Image string `json:"image"`
Digest string `json:"digest"`
Tags []string `json:"tags,omitempty"`
Architecture string `json:"architecture,omitempty"`
OS string `json:"os,omitempty"`
Distro *Distro `json:"distro,omitempty"`
TotalResources int `json:"totalResources"`
Resources map[string][]string `json:"resources"`
Summary VulnerabilitySummary `json:"summary"`
}

type Vulnerability struct {
VulnerabilityCommon `json:",inline"`
Package `json:",inline"`
}

type Package struct {
Package string `json:"package"`
Version string `json:"version"`
FixVersion string `json:"fixVersion,omitempty"`
Status string `json:"status,omitempty"`
Type string `json:"type,omitempty"`
}

func (r *Package) String() string {
return fmt.Sprintf("Package=%s, Version=%s, FixVersion=%s, Status=%s, Type=%s", r.Package, r.Version, r.FixVersion, r.Status, r.Type)
}

type VulnerabilityCommon struct {
ID string `json:"id"`
Severity string `json:"severity"`
Title string `json:"title"`
Description string `json:"description,omitempty"`
Package string `json:"package"`
Version string `json:"version"`
FixVersion string `json:"fixVersion,omitempty"`
URL string `json:"url,omitempty"`
Status string `json:"status,omitempty"`
Type string `json:"type,omitempty"`
Score string `json:"score,omitempty"`
PublishedDate *metav1.Time `json:"publishedDate,omitempty"`
LastModifiedDate *metav1.Time `json:"lastModifiedDate,omitempty"`
Expand All @@ -66,25 +82,31 @@ type VulnerabilitySummary struct {
Unknown int `json:"unknown"`
}

func (in *VulnerabilityReportSpec) Summarize() {
s := &VulnerabilitySummary{}
for _, v := range in.Vulnerabilities {
s.Total++
switch v.Severity {
case "CRITICAL":
s.Critical++
case "HIGH":
s.High++
case "MEDIUM":
s.Medium++
case "LOW":
s.Low++
default:
s.Unknown++
}
}
in.Summary = *s
}

// VulnerabilityReportStatus defines the observed state of VulnerabilityReport
type VulnerabilityReportStatus struct {
Status `json:",inline"`
}

func (in *VulnerabilityReport) SetSaaSStatus(status metav1.ConditionStatus, reason, msg string) {
in.Status.SetCondition(metav1.Condition{
Type: "SaaS",
Status: status,
ObservedGeneration: in.Generation,
Reason: reason,
Message: msg,
})
}

func (in *VulnerabilityReport) SaaSStatusIsTrue() bool {
return in.Status.ConditionIsTrue("SaaS")
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:shortName={vuln,vulns,vulnerabilities}
Expand All @@ -97,6 +119,7 @@ func (in *VulnerabilityReport) SaaSStatusIsTrue() bool {
//+kubebuilder:printcolumn:name="Low",type="string",JSONPath=".spec.summary.low",priority=1
//+kubebuilder:printcolumn:name="Unknown",type="string",JSONPath=".spec.summary.unknown",priority=1
//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",priority=0
//+kubebuilder:deprecatedversion:warning="The v1alpha1 version of VulnerabilityReport has been deprecated. Please use v1alpha2 instead."

// VulnerabilityReport is the Schema for the vulnerabilityreports API
// +genclient
Expand All @@ -108,6 +131,8 @@ type VulnerabilityReport struct {
Status VulnerabilityReportStatus `json:"status,omitempty"`
}

func (in *VulnerabilityReport) Hub() {}

//+kubebuilder:object:root=true

// VulnerabilityReportList contains a list of VulnerabilityReport
Expand Down
26 changes: 26 additions & 0 deletions api/zora/v1alpha1/vulnerabilityreport_webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2024 Undistro Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package v1alpha1

import (
ctrl "sigs.k8s.io/controller-runtime"
)

// SetupWebhookWithManager will setup the manager to manage the webhooks
func (r *VulnerabilityReport) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr).
For(r).
Complete()
}
108 changes: 78 additions & 30 deletions api/zora/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit e7e761c

Please sign in to comment.