Skip to content

Commit

Permalink
Add new flags to toggle deletion of orphan images, setting parent pro…
Browse files Browse the repository at this point in the history
…ject and dtrack project name by k8s pod annotation (#563)

* feat: add new flags to toggle deletion of orphan projects, setting parent project and dtrack project name by k8s annotation

feat: add two new flags to toggle deletion of orphan projects and setting parent project by k8s annotation

feat: add new flags to toggle deletion of orphan projects, setting parent project and dtrack project name by k8s annotation

readme

readme

readme

readme

readme

readme

readme

release test

release test

chore: release 2.0.0

release test

chore: release 2.0.1

release test

chore: release 2.0.2

release test

release test

chore: release 2.0.4

release test

chore: release 2.0.5

release test

chore: release 2.0.6

cleanup test stuff

* for loop bug fixed

* Renamed config Key "DeleteOrphanProjects" to "DeleteOrphanImages"

---------

Co-authored-by: mondeg <[email protected]>
  • Loading branch information
romwol-witt and monadegelingwitt authored Apr 5, 2024
1 parent 9d6a469 commit a715b4f
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 62 deletions.
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ All parameters are cli-flags. The flags can be configured as args or as environm
| `namespace-label-selector` | `false` | `""` | Kubernetes Label-Selector for namespaces. |
| `fallback-image-pull-secret` | `false` | `""` | Kubernetes Pull-Secret Name to load as a fallback when all others fail (must be in the same namespace as the sbom-operator) |
| `registry-proxy` | `false` | `[]` | Proxy-Registry-Hosts to use. Flag can be used multiple times. Value-Mapping e.g. `docker.io=ghcr.io` |
| `delete-orphan-images` | `false` | `true` | Delete orphan images automatically |


### Example Helm-Config
Expand Down Expand Up @@ -122,12 +123,63 @@ not present in the cluster anymore are removed from the configured targets (exce
| `dtrack-ca-cert-file` | `false` | `""` | CA-Certificate filepath when using mTLS to connect to dtrack |
| `dtrack-client-cert-file` | `true` when `dtrack-ca-cert-file` is provided | `""` | Client-Certificate filepath when using mTLS to connect to dtrack |
| `dtrack-client-key-file` | `true` when `dtrack-ca-cert-file` is provided | `""` | Client-Key filepath when using mTLS to connect to dtrack |
| `dtrack-parent-project-annotation-key` | `false` | `""` | Kubernetes pod annotation key to set parent project automatically, e.g. "my.pod.annotation" |
| `dtrack-project-name-annotation-key` | `false` | `""` | Kubernetes pod annotation key to set custom dtrack project name automatically, e.g. "my.pod.annotation" |
| `kubernetes-cluster-id` | `false` | `"default"` | Kubernetes Cluster ID (to be used in Dependency-Track or Job-Images) |

Each image in the cluster is created as project with the full-image name (registry and image-path without tag) and the image-tag as project-version.
When there's no image-tag, but a digest, the digest is used as project-version.
The `autoCreate` option of DT is used. You have to set the `--format` flag to `cyclonedx` with this target.

---
#### Custom dtrack project name:

The key at kubernetes has to be suffixed with the container name the project is for. e.g. `my.project.name/my-nginx`.
> [!IMPORTANT]
> The suffix regarding container name must not be added to the config value and must not include `/`. e.g. `my.project.name`

The value for a custom project name in dtrack by annotation at the specific Pod is written in the format of `project:version` or just `project` where version defaults to `latest`. E.g. `MyParentProject` or `MyParentProject:1.0`

---

#### Setting parent project at Dependency Track automatically:

The key at kubernetes has to be suffixed with the container name the parent project is for. e.g. `my.parent.project/my-nginx`.
The value for the parent project annotation at the specific Pod is written in the format of `project:version` or just `project` where version defaults to `latest`. E.g. `MyParentProject` or `MyParentProject:1.0`

> [!IMPORTANT]
> The suffix regarding container name must not be added to the config value and must not include `/`. e.g. `my.parent.project`

---

#### Example Pod Annotation:
```yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
my.parent.project/my-nginx: MyParentProject
my.project.name/my-nginx: MyNginxProject:1.0
my.parent.project/my-sidecar: MyOtherParentProject
my.project.name/my-sidecar: MySidecarProject:1.0.1
spec:
containers:
- image: nginx:latest
name: my-nginx
...
- image: some-other-image:latest
name: my-sidecar
...
...
```
---

#### sbom-operator config:
```bash
--dtrack-parent-project-annotation-key=my.parent.project
--dtrack-project-name-annotation-key=my.project.name
```
---

### Git

Expand Down
88 changes: 47 additions & 41 deletions internal/config.go
Original file line number Diff line number Diff line change
@@ -1,40 +1,43 @@
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"`
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"`
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"`
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"`
}

var (
Expand All @@ -55,15 +58,18 @@ var (
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"
ConfigKeyKubernetesClusterId = "kubernetes-cluster-id"
ConfigKeyJobImage = "job-image"
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"
Expand Down
10 changes: 7 additions & 3 deletions internal/processor/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,13 @@ func initTargets(k8s *kubernetes.KubeClient) []target.Target {
baseUrl := internal.OperatorConfig.DtrackBaseUrl
apiKey := internal.OperatorConfig.DtrackApiKey
podLabelTagMatcher := internal.OperatorConfig.DtrackLabelTagMatcher
parentProjectAnnotationKey := internal.OperatorConfig.DtrackParentProjectAnnotationKey
projectNameAnnotationKey := internal.OperatorConfig.DtrackProjectNameAnnotationKey
caCertFile := internal.OperatorConfig.DtrackCaCertFile
clientCertFile := internal.OperatorConfig.DtrackClientCertFile
clientKeyFile := internal.OperatorConfig.DtrackClientKeyFile
k8sClusterId := internal.OperatorConfig.KubernetesClusterId
t := dtrack.NewDependencyTrackTarget(baseUrl, apiKey, podLabelTagMatcher, caCertFile, clientCertFile, clientKeyFile, k8sClusterId)
t := dtrack.NewDependencyTrackTarget(baseUrl, apiKey, podLabelTagMatcher, caCertFile, clientCertFile, clientKeyFile, k8sClusterId, parentProjectAnnotationKey, projectNameAnnotationKey)
err = t.ValidateConfig()
targets = append(targets, t)
} else if ta == "oci" {
Expand Down Expand Up @@ -195,7 +197,7 @@ func (p *Processor) executeSyftScans(pods []libk8s.PodInfo, allImages []*liboci.
}
}

if len(removableImages) > 0 {
if len(removableImages) > 0 && internal.OperatorConfig.DeleteOrphanImages {
t.Remove(removableImages)
}
}
Expand Down Expand Up @@ -302,7 +304,9 @@ func (p *Processor) cleanupImagesIfNeeded(removedContainers []*libk8s.ContainerI

if len(images) > 0 {
for _, t := range p.Targets {
t.Remove(images)
if internal.OperatorConfig.DeleteOrphanImages {
t.Remove(images)
}
}
}
}
Expand Down
Loading

0 comments on commit a715b4f

Please sign in to comment.