Skip to content

Commit

Permalink
camelCase config, removes a lot of flags, cdxjson format
Browse files Browse the repository at this point in the history
  • Loading branch information
timbastin committed Dec 26, 2024
1 parent eed4242 commit a5c6e7c
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 257 deletions.
105 changes: 25 additions & 80 deletions internal/config.go
Original file line number Diff line number Diff line change
@@ -1,91 +1,36 @@
package internal

type Config struct {
Cron string `yaml:"cron" env:"SBOM_CRON" flag:"cron"`
Format string `yaml:"format" env:"SBOM_FORMAT" flag:"format"`
Targets []string `yaml:"targets" env:"SBOM_TARGETS" flag:"targets"`
IgnoreAnnotations bool `yaml:"ignoreAnnotations" env:"SBOM_IGNORE_ANNOTATIONS" flag:"ignore-annotations"`
GitWorkingTree string `yaml:"gitWorkingTree" env:"SBOM_GIT_WORKINGTREE" flag:"git-workingtree"`
GitRepository string `yaml:"gitRepository" env:"SBOM_GIT_REPOSITORY" flag:"git-repository"`
GitBranch string `yaml:"gitBranch" env:"SBOM_GIT_BRANCH" flag:"git-branch"`
GitPath string `yaml:"gitPath" env:"SBOM_GIT_PATH" flag:"git-path"`
GitAccessToken string `yaml:"gitAccessToken" env:"SBOM_GIT_ACCESS_TOKEN" flag:"git-access-token"`
GitUserName string `yaml:"gitUserName" env:"SBOM_GIT_USERNAME" flag:"git-username"`
GitPassword string `yaml:"gitPassword" env:"SBOM_GIT_PASSWORD" flag:"git-password"`
GitAuthorName string `yaml:"gitAuthorName" env:"SBOM_GIT_AUTHOR_NAME" flag:"git-author-name"`
GitAuthorEmail string `yaml:"gitAuthorEmail" env:"SBOM_GIT_AUTHOR_EMAIL" flag:"git-author-email"`
GitHubAppId string `yaml:"githubAppId" env:"SBOM_GITHUB_APP_ID" flag:"github-app-id"`
GitHubAppInstallationId string `yaml:"githubAppInstallationId" env:"SBOM_GITHUB_APP_INSTALLATION_ID" flag:"github-app-installation-id"`
GitHubPrivateKey string `yaml:"githubAppPrivateKey" env:"SBOM_GITHUB_APP_PRIVATE_KEY"`
PodLabelSelector string `yaml:"podLabelSelector" env:"SBOM_POD_LABEL_SELECTOR" flag:"pod-label-selector"`
NamespaceLabelSelector string `yaml:"namespaceLabelSelector" env:"SBOM_NAMESPACE_LABEL_SELECTOR" flag:"namespace-label-selector"`
DeleteOrphanImages bool `yaml:"deleteOrphanImages" env:"SBOM_DELETRE_ORPHAN_IMAGES" flag:"delete-orphan-images"`
DtrackBaseUrl string `yaml:"dtrackBaseUrl" env:"SBOM_DTRACK_BASE_URL" flag:"dtrack-base-url"`
DtrackApiKey string `yaml:"dtrackApiKey" env:"SBOM_DTRACK_API_KEY" flag:"dtrack-api-key"`
DtrackLabelTagMatcher string `yaml:"dtrackLabelTagMatcher" env:"SBOM_DTRACK_LABEL_TAG_MATCHER" flag:"dtrack-label-tag-matcher"`
DtrackCaCertFile string `yaml:"dtrackCaCertFile" env:"SBOM_DTRACK_CA_CERT_FILE" flag:"dtrack-ca-cert-file"`
DtrackClientCertFile string `yaml:"dtrackClientCertFile" env:"SBOM_DTRACK_CLIENT_CERT_FILE" flag:"dtrack-client-cert-file"`
DtrackClientKeyFile string `yaml:"dtrackClientKeyFile" env:"SBOM_DTRACK_CLIENT_KEY_FILE" flag:"dtrack-client-key-file"`
DtrackParentProjectAnnotationKey string `yaml:"dtrackParentProjectAnnotationKey" env:"SBOM_DTRACK_PARENT_PROJECT_ANNOTATION_KEY" flag:"dtrack-parent-project-annotation-key"`
DtrackProjectNameAnnotationKey string `yaml:"dtrackProjectNameAnnotationKey" env:"SBOM_DTRACK_PROJECT_NAME_ANNOTATION_KEY" flag:"dtrack-project-name-annotation-key"`
KubernetesClusterId string `yaml:"kubernetesClusterId" env:"SBOM_KUBERNETES_CLUSTER_ID" flag:"kubernetes-cluster-id"`
JobImage string `yaml:"jobImage" env:"SBOM_JOB_IMAGE" flag:"job-image"`
JobImagePullSecret string `yaml:"jobImagePullSecret" env:"SBOM_JOB_IMAGE_PULL_SECRET" flag:"job-image-pull-secret"`
JobTimeout int64 `yaml:"jobTimeout" env:"SBOM_JOB_TIMEOUT" flag:"job-timeout"`
OciRegistry string `yaml:"ociRegistry" env:"SBOM_OCI_REGISTRY" flag:"oci-registry"`
OciUser string `yaml:"ociUser" env:"SBOM_OCI_USER" flag:"oci-user"`
OciToken string `yaml:"ociToken" env:"SBOM_OCI_TOKEN" flag:"oci-token"`
FallbackPullSecret string `yaml:"fallbackPullSecret" env:"SBOM_FALLBACK_PULL_SECRET" flag:"fallback-pull-secret"`
RegistryProxies []string `yaml:"registryProxy" env:"SBOM_REGISTRY_PROXY" flag:"registry-proxy"`
Verbosity string `env:"SBOM_VERBOSITY" flag:"verbosity"`
Cron string `yaml:"cron" env:"SBOM_CRON" flag:"cron"`

DevGuardToken string `yaml:"devGuardToken" env:"DEVGUARD_TOKEN" flag:"devguard-token"`
DevGuardApiURL string `yaml:"devGuardApiURL" env:"DEVGUARD_API_URL" flag:"devguard-api-url"`
DevGuardProjectID string `yaml:"devGuardProjectID" env:"DEVGUARD_PROJECT_ID" flag:"devguard-project-id"`
IgnoreAnnotations bool `yaml:"ignoreAnnotations" env:"SBOM_IGNORE_ANNOTATIONS" flag:"ignoreAnnotations"`
PodLabelSelector string `yaml:"podLabelSelector" env:"SBOM_POD_LABEL_SELECTOR" flag:"podLabelSelector"`
NamespaceLabelSelector string `yaml:"namespaceLabelSelector" env:"SBOM_NAMESPACE_LABEL_SELECTOR" flag:"namespaceLabelSelector"`

JobTimeout int64 `yaml:"jobTimeout" env:"SBOM_JOB_TIMEOUT" flag:"jobTimeout"`
FallbackPullSecret string `yaml:"fallbackPullSecret" env:"SBOM_FALLBACK_PULL_SECRET" flag:"fallbackPullSecret"`
RegistryProxies []string `yaml:"registryProxy" env:"SBOM_REGISTRY_PROXY" flag:"registryProxy"`
Verbosity string `env:"SBOM_VERBOSITY" flag:"verbosity"`

DevGuardToken string `yaml:"devGuardToken" env:"DEVGUARD_TOKEN" flag:"token"`
DevGuardApiURL string `yaml:"devGuardApiURL" env:"DEVGUARD_API_URL" flag:"apiUrl"`
DevGuardProjectID string `yaml:"devGuardProjectID" env:"DEVGUARD_PROJECT_ID" flag:"projectName"`
}

var (
ConfigKeyCron = "cron"
ConfigKeyFormat = "format"
ConfigKeyTargets = "targets"
ConfigKeyIgnoreAnnotations = "ignore-annotations"
ConfigKeyGitWorkingTree = "git-workingtree"
ConfigKeyGitRepository = "git-repository"
ConfigKeyGitBranch = "git-branch"
ConfigKeyGitPath = "git-path"
ConfigKeyGitAccessToken = "git-access-token"
ConfigKeyGitUserName = "git-username"
ConfigKeyGitPassword = "git-password"
ConfigKeyGitAuthorName = "git-author-name"
ConfigKeyGitAuthorEmail = "git-author-email"
ConfigKeyGitHubAppId = "github-app-id"
ConfigKeyGitHubAppInstallationId = "github-app-installation-id"
ConfigKeyPodLabelSelector = "pod-label-selector"
ConfigKeyNamespaceLabelSelector = "namespace-label-selector"
ConfigKeyDeleteOrphanImages = "delete-orphan-images"
ConfigKeyDependencyTrackBaseUrl = "dtrack-base-url"
/* #nosec */
ConfigKeyDependencyTrackApiKey = "dtrack-api-key"
ConfigKeyDependencyTrackLabelTagMatcher = "dtrack-label-tag-matcher"
ConfigKeyDependencyTrackCaCertFile = "dtrack-ca-cert-file"
ConfigKeyDependencyTrackClientCertFile = "dtrack-client-cert-file"
ConfigKeyDependencyTrackClientKeyFile = "dtrack-client-key-file"
ConfigKeyDependencyTrackDtrackParentProjectAnnotationKey = "dtrack-parent-project-annotation-key"
ConfigKeyDependencyTrackDtrackProjectNameAnnotationKey = "dtrack-project-name-annotation-key"
ConfigKeyKubernetesClusterId = "kubernetes-cluster-id"
ConfigKeyJobImage = "job-image"
/* #nosec */
ConfigKeyJobImagePullSecret = "job-image-pull-secret"
ConfigKeyJobTimeout = "job-timeout"
ConfigKeyOciRegistry = "oci-registry"
ConfigKeyOciUser = "oci-user"
ConfigKeyOciToken = "oci-token"
ConfigKeyFallbackPullSecret = "fallback-pull-secret"
ConfigKeyRegistryProxy = "registry-proxy"
ConfigKeyCron = "cron"

ConfigKeyIgnoreAnnotations = "ignoreAnnotations"
ConfigKeyPodLabelSelector = "podLabelSelector"
ConfigKeyNamespaceLabelSelector = "namespaceLabelSelector"

ConfigKeyJobTimeout = "jobTimeout"
ConfigKeyFallbackPullSecret = "fallbackPullSecret"
ConfigKeyRegistryProxy = "registryProxy"

ConfigDevGuardToken = "devguard-token"
ConfigDevGuardApiURL = "devguard-api-url"
ConfigDevGuardProjectID = "devguard-project-id"
ConfigDevGuardToken = "token"
ConfigDevGuardApiURL = "apiUrl"
ConfigDevGuardProjectName = "projectName"

OperatorConfig *Config
)
16 changes: 7 additions & 9 deletions internal/daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func Start(cronTime string, appVersion string) {
logrus.Debugf("Cron set to: %v", cr)

k8s := kubernetes.NewClient(internal.OperatorConfig.IgnoreAnnotations, internal.OperatorConfig.FallbackPullSecret)
sy := syft.New(internal.OperatorConfig.Format, libstandard.ToMap(internal.OperatorConfig.RegistryProxies), appVersion)
sy := syft.New(libstandard.ToMap(internal.OperatorConfig.RegistryProxies), appVersion)
processor := processor.New(k8s, sy)

cs := CronService{cron: cr, processor: processor}
Expand Down Expand Up @@ -57,15 +57,13 @@ func (c *CronService) runBackgroundService() {
running = true
logrus.Info("Execute background-service")

if !processor.HasJobImage() {
for _, t := range c.processor.Targets {
err := t.Initialize()
if err != nil {
logrus.WithError(err).Fatal("Target could not be initialized,")
}

t.LoadImages()
for _, t := range c.processor.Targets {
err := t.Initialize()
if err != nil {
logrus.WithError(err).Fatal("Target could not be initialized,")
}

t.LoadImages()
}

namespaceSelector := internal.OperatorConfig.NamespaceLabelSelector
Expand Down
148 changes: 43 additions & 105 deletions internal/processor/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (

libk8s "github.com/ckotzbauer/libk8soci/pkg/kubernetes"
"github.com/ckotzbauer/sbom-operator/internal"
"github.com/ckotzbauer/sbom-operator/internal/job"
"github.com/ckotzbauer/sbom-operator/internal/kubernetes"
"github.com/ckotzbauer/sbom-operator/internal/syft"
"github.com/ckotzbauer/sbom-operator/internal/target"
Expand All @@ -27,11 +26,7 @@ type Processor struct {
}

func New(k8s *kubernetes.KubeClient, sy *syft.Syft) *Processor {
targets := make([]target.Target, 0)
if !HasJobImage() {
logrus.Debugf("Targets set to: %v", internal.OperatorConfig.Targets)
targets = initTargets(k8s)
}
targets := initTargets(k8s)

return &Processor{K8s: k8s, sy: sy, Targets: targets, imageMap: make(map[string]bool)}
}
Expand Down Expand Up @@ -69,11 +64,7 @@ func (p *Processor) ListenForPods() {
}

func (p *Processor) ProcessAllPods(pods []libk8s.PodInfo, allImages []target.ImageInNamespace) {
if !HasJobImage() {
p.executeSyftScans(pods, allImages)
} else {
p.executeJobImage(pods)
}
p.executeSyftScans(pods, allImages)
}

func (p *Processor) scanPod(pod libk8s.PodInfo) {
Expand Down Expand Up @@ -108,19 +99,13 @@ func (p *Processor) scanPod(pod libk8s.PodInfo) {
func initTargets(k8s *kubernetes.KubeClient) []target.Target {
targets := make([]target.Target, 0)

for _, ta := range internal.OperatorConfig.Targets {
var err error
var err error

if ta == "devguard" {
t := devguard.NewDevGuardTarget(internal.OperatorConfig.DevGuardToken, internal.OperatorConfig.DevGuardApiURL, internal.OperatorConfig.DevGuardProjectID, nil)
targets = append(targets, t)
} else {
logrus.Fatalf("Unknown target %s", ta)
}
t := devguard.NewDevGuardTarget(internal.OperatorConfig.DevGuardToken, internal.OperatorConfig.DevGuardApiURL, internal.OperatorConfig.DevGuardProjectID, nil)
targets = append(targets, t)

if err != nil {
logrus.WithError(err).Fatal("Config-Validation failed!")
}
if err != nil {
logrus.WithError(err).Fatal("Config-Validation failed!")
}

if len(targets) == 0 {
Expand All @@ -130,10 +115,6 @@ func initTargets(k8s *kubernetes.KubeClient) []target.Target {
return targets
}

func HasJobImage() bool {
return internal.OperatorConfig.JobImage != ""
}

func (p *Processor) executeSyftScans(pods []libk8s.PodInfo, allImages []target.ImageInNamespace) {
for _, pod := range pods {
p.scanPod(pod)
Expand All @@ -156,50 +137,12 @@ func (p *Processor) executeSyftScans(pods []libk8s.PodInfo, allImages []target.I
}
}

if len(removableImages) > 0 && internal.OperatorConfig.DeleteOrphanImages {
if len(removableImages) > 0 {
t.Remove(removableImages)
}
}
}

func (p *Processor) executeJobImage(pods []libk8s.PodInfo) {
jobClient := job.New(
p.K8s,
internal.OperatorConfig.JobImage,
internal.OperatorConfig.JobImagePullSecret,
internal.OperatorConfig.KubernetesClusterId,
internal.OperatorConfig.JobTimeout)

filteredPods := make([]libk8s.PodInfo, 0)
for _, pod := range pods {
filteredContainers := make([]*libk8s.ContainerInfo, 0)
for _, container := range pod.Containers {
if p.K8s.HasAnnotation(pod.Annotations, container) {
logrus.Debugf("Skip image %s", container.Image.ImageID)
continue
}

filteredContainers = append(filteredContainers, container)
}

if len(filteredContainers) > 0 {
filteredPods = append(filteredPods, pod)
}
}

j, err := jobClient.StartJob(filteredPods)
if err != nil {
// Already handled from job-module
return
}

if jobClient.WaitForJob(j) {
for _, pod := range filteredPods {
p.K8s.UpdatePodAnnotation(pod)
}
}
}

func getChangedContainers(oldPod, newPod libk8s.PodInfo) ([]*libk8s.ContainerInfo, []*libk8s.ContainerInfo) {
addedContainers := make([]*libk8s.ContainerInfo, 0)
removedContainers := make([]*libk8s.ContainerInfo, 0)
Expand Down Expand Up @@ -258,9 +201,7 @@ func (p *Processor) cleanupImagesIfNeeded(namespace string, removedContainers []

if len(images) > 0 {
for _, t := range p.Targets {
if internal.OperatorConfig.DeleteOrphanImages {
t.Remove(images)
}
t.Remove(images)
}
}
}
Expand All @@ -283,12 +224,11 @@ func (p *Processor) runInformerAsync(informer cache.SharedIndexInformer) {
}()

go func() {
if !HasJobImage() {
for _, t := range p.Targets {
err := t.Initialize()
if err != nil {
logrus.WithError(err).Fatal("Target could not be initialized,")
}

for _, t := range p.Targets {
err := t.Initialize()
if err != nil {
logrus.WithError(err).Fatal("Target could not be initialized,")
}
}

Expand All @@ -299,44 +239,42 @@ func (p *Processor) runInformerAsync(informer cache.SharedIndexInformer) {
}()

go func() {
if !HasJobImage() {
logrus.Info("Wait for cache to be synced")
if !cache.WaitForCacheSync(stop, informer.HasSynced) {
logrus.Fatal("Timed out waiting for the cache to sync")
}
logrus.Info("Wait for cache to be synced")
if !cache.WaitForCacheSync(stop, informer.HasSynced) {
logrus.Fatal("Timed out waiting for the cache to sync")
}

logrus.Info("Finished cache sync")
pods := informer.GetStore().List()
missingPods := make([]libk8s.PodInfo, 0)
allImages := make([]target.ImageInNamespace, 0)
logrus.Info("Finished cache sync")
pods := informer.GetStore().List()
missingPods := make([]libk8s.PodInfo, 0)
allImages := make([]target.ImageInNamespace, 0)

for _, t := range p.Targets {
targetImages, err := t.LoadImages()
if err != nil {
logrus.WithError(err).Error("Failed to load images from target")
continue
}
for _, t := range p.Targets {
targetImages, err := t.LoadImages()
if err != nil {
logrus.WithError(err).Error("Failed to load images from target")
continue
}

for _, po := range pods {
pod := po.(*corev1.Pod)
info := p.K8s.Client.ExtractPodInfos(*pod)
for _, c := range info.Containers {
allImages = append(allImages, target.ImageInNamespace{Namespace: info.PodNamespace, Image: c.Image})
if !containsImage(targetImages, target.ImageInNamespace{
Image: c.Image,
Namespace: info.PodNamespace,
}) && !p.K8s.HasAnnotation(info.Annotations, c) {
missingPods = append(missingPods, info)
logrus.Debugf("Pod %s/%s needs to be analyzed", info.PodNamespace, info.PodName)
break
}
for _, po := range pods {
pod := po.(*corev1.Pod)
info := p.K8s.Client.ExtractPodInfos(*pod)
for _, c := range info.Containers {
allImages = append(allImages, target.ImageInNamespace{Namespace: info.PodNamespace, Image: c.Image})
if !containsImage(targetImages, target.ImageInNamespace{
Image: c.Image,
Namespace: info.PodNamespace,
}) && !p.K8s.HasAnnotation(info.Annotations, c) {
missingPods = append(missingPods, info)
logrus.Debugf("Pod %s/%s needs to be analyzed", info.PodNamespace, info.PodName)
break
}
}
}
}

if len(missingPods) > 0 {
p.executeSyftScans(missingPods, allImages)
}
if len(missingPods) > 0 {
p.executeSyftScans(missingPods, allImages)
}
}()
}
Loading

0 comments on commit a5c6e7c

Please sign in to comment.