Skip to content

Commit

Permalink
UD-1129: Update reconciliation of misconfigurations and vulnerabiliti…
Browse files Browse the repository at this point in the history
…es to check for deltas before sending to SaaS

Signed-off-by: Kevin Conner <kev.conner@getupcloud.com>
  • Loading branch information
knrc committed Jan 19, 2024
1 parent 3402c2d commit 8d2aa2e
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 0 deletions.
8 changes: 8 additions & 0 deletions api/zora/v1alpha1/clusterscan_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ func (in *PluginReference) PluginKey(defaultNamespace string) types.NamespacedNa
return types.NamespacedName{Name: in.Name, Namespace: ns}
}

type PluginScanProcessedResources map[string]string

// ClusterScanStatus defines the observed state of ClusterScan
type ClusterScanStatus struct {
Status `json:",inline"`
Expand Down Expand Up @@ -104,6 +106,12 @@ type ClusterScanStatus struct {

// Total of ClusterIssues reported in the last successful scan
TotalIssues *int `json:"totalIssues,omitempty"`

// Resource versions of processed vulnerabilities
ProcessedVulnerabilities map[string]PluginScanProcessedResources `json:"processedVulnerabilities,omitempty"`

// Resource versions of processed misconfigurations
ProcessedMisconfigurations map[string]PluginScanProcessedResources `json:"processedMisconfigurations,omitempty"`
}

// GetPluginStatus returns a PluginScanStatus of a plugin
Expand Down
57 changes: 57 additions & 0 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.

14 changes: 14 additions & 0 deletions charts/zora/crds/zora.undistro.io_clusterscans.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,20 @@ spec:
type: object
description: Information of the last scans of plugins
type: object
processedMisconfigurations:
additionalProperties:
additionalProperties:
type: string
type: object
description: Resource versions of processed misconfigurations
type: object
processedVulnerabilities:
additionalProperties:
additionalProperties:
type: string
type: object
description: Resource versions of processed vulnerabilities
type: object
suspend:
description: Suspend field value from ClusterScan spec
type: boolean
Expand Down
14 changes: 14 additions & 0 deletions config/crd/bases/zora.undistro.io_clusterscans.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,20 @@ spec:
type: object
description: Information of the last scans of plugins
type: object
processedMisconfigurations:
additionalProperties:
additionalProperties:
type: string
type: object
description: Resource versions of processed misconfigurations
type: object
processedVulnerabilities:
additionalProperties:
additionalProperties:
type: string
type: object
description: Resource versions of processed vulnerabilities
type: object
suspend:
description: Suspend field value from ClusterScan spec
type: boolean
Expand Down
63 changes: 63 additions & 0 deletions internal/saas/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@ package saas
import (
"context"
"errors"
"fmt"
"reflect"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
ctrlClient "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"

"github.com/undistro/zora/api/zora/v1alpha1"
)
Expand Down Expand Up @@ -107,6 +110,13 @@ func pushMisconfigs(saasClient Client, c ctrlClient.Client, ctx context.Context,
return err
}

pluginProcessedResources := getMisconfigProcessedResources(clusterScan.Status.Plugins, issueList.Items)
if reflect.DeepEqual(pluginProcessedResources, clusterScan.Status.ProcessedMisconfigurations) {
log := log.FromContext(ctx)
log.Info("Skipping misconfigurations, no changes from processed misconfigurations")
return nil
}

status := NewScanStatusWithIssues(scanList.Items, issueList.Items)
if status == nil {
return nil
Expand All @@ -120,6 +130,7 @@ func pushMisconfigs(saasClient Client, c ctrlClient.Client, ctx context.Context,
clusterScan.SetSaaSStatus(metav1.ConditionFalse, "Error", err.Error())
return err
}
clusterScan.Status.ProcessedMisconfigurations = pluginProcessedResources
clusterScan.SetSaaSStatus(metav1.ConditionTrue, "OK", "cluster scan successfully synced with SaaS")
return nil
}
Expand All @@ -142,6 +153,14 @@ func pushVulns(scl Client, cl ctrlClient.Client, ctx context.Context, cs *v1alph
if len(metaList.Items) == 0 {
return nil
}

pluginProcessedResources := getVulnerabilityProcessedResources(metaList.Items)
if reflect.DeepEqual(pluginProcessedResources, cs.Status.ProcessedVulnerabilities) {
log := log.FromContext(ctx)
log.Info("Skipping vulnerabilities, no changes from processed vulnerabilities")
return nil
}

for _, i := range metaList.Items {
vulnReport := &v1alpha1.VulnerabilityReport{}
if err := cl.Get(ctx, types.NamespacedName{Namespace: i.Namespace, Name: i.Name}, vulnReport); err != nil {
Expand All @@ -161,6 +180,7 @@ func pushVulns(scl Client, cl ctrlClient.Client, ctx context.Context, cs *v1alph
return err
}
}
cs.Status.ProcessedVulnerabilities = pluginProcessedResources
cs.SetSaaSStatus(metav1.ConditionTrue, "OK", "cluster scan successfully synced with SaaS")
return nil
}
Expand All @@ -180,3 +200,46 @@ func buildLabelSelector(clusterName string, scanIDs []string) (*ctrlClient.Match
}
return &ctrlClient.MatchingLabelsSelector{Selector: ls}, nil
}

func getMisconfigProcessedResources(pluginStatus map[string]*v1alpha1.PluginScanStatus, clusterIssues []v1alpha1.ClusterIssue) map[string]v1alpha1.PluginScanProcessedResources {
var pluginProcessedResources map[string]v1alpha1.PluginScanProcessedResources
issuePluginIncluded := false
for _, issue := range clusterIssues {
plugin := issue.Labels[v1alpha1.LabelPlugin]
if !issuePluginIncluded {
_, issuePluginIncluded = pluginStatus[plugin]
}
if pluginProcessedResources == nil {
pluginProcessedResources = map[string]v1alpha1.PluginScanProcessedResources{}
}
processedResources, ok := pluginProcessedResources[plugin]
if !ok {
processedResources = v1alpha1.PluginScanProcessedResources{}
pluginProcessedResources[plugin] = processedResources
}
processedResources[fmt.Sprintf("%s/%s", issue.Namespace, issue.Name)] = issue.ResourceVersion
}
if issuePluginIncluded {
return pluginProcessedResources
} else {
return nil
}
}

func getVulnerabilityProcessedResources(vulnerabiltiyIssues []metav1.PartialObjectMetadata) map[string]v1alpha1.PluginScanProcessedResources {
var pluginProcessedResources map[string]v1alpha1.PluginScanProcessedResources
for _, issue := range vulnerabiltiyIssues {
plugin := issue.Labels[v1alpha1.LabelPlugin]
if pluginProcessedResources == nil {
pluginProcessedResources = map[string]v1alpha1.PluginScanProcessedResources{}
}
processedResources, ok := pluginProcessedResources[plugin]
if !ok {
processedResources = v1alpha1.PluginScanProcessedResources{}
pluginProcessedResources[plugin] = processedResources
}
processedResources[fmt.Sprintf("%s/%s", issue.Namespace, issue.Name)] = issue.ResourceVersion

}
return pluginProcessedResources
}

0 comments on commit 8d2aa2e

Please sign in to comment.