diff --git a/pkg/app/pipedv1/plugin/kubernetes/provider/deployment.go b/pkg/app/pipedv1/plugin/kubernetes/provider/deployment.go index b60aaa6162..fc0efa30cc 100644 --- a/pkg/app/pipedv1/plugin/kubernetes/provider/deployment.go +++ b/pkg/app/pipedv1/plugin/kubernetes/provider/deployment.go @@ -22,8 +22,9 @@ import ( // // It looks for container images in the following fields: // - spec.template.spec.containers.image -// -// TODO: we should consider other fields like spec.template.spec.initContainers.image, spec.jobTempate.spec.template.spec.containers.image +// - spec.template.spec.initContainers.image +// - spec.jobTemplate.spec.template.spec.containers.image +// - spec.jobTemplate.spec.template.spec.initContainers.image func FindContainerImages(m Manifest) []string { var images []string @@ -31,6 +32,18 @@ func FindContainerImages(m Manifest) []string { images = append(images, n...) } + if n := nestedStringSlice(m.body.Object, "spec", "template", "spec", "initContainers", "image"); len(n) > 0 { + images = append(images, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "containers", "image"); len(n) > 0 { + images = append(images, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "initContainers", "image"); len(n) > 0 { + images = append(images, n...) + } + slices.Sort(images) return slices.Compact(images) } @@ -43,6 +56,11 @@ func FindContainerImages(m Manifest) []string { // - spec.template.spec.initContainers.envFrom.configMapRef.name // - spec.template.spec.containers.env.valueFrom.configMapKeyRef.name // - spec.template.spec.containers.envFrom.configMapRef.name +// - spec.jobTemplate.spec.template.spec.volumes.configMap.name +// - spec.jobTemplate.spec.template.spec.initContainers.env.valueFrom.configMapKeyRef.name +// - spec.jobTemplate.spec.template.spec.initContainers.envFrom.configMapRef.name +// - spec.jobTemplate.spec.template.spec.containers.env.valueFrom.configMapKeyRef.name +// - spec.jobTemplate.spec.template.spec.containers.envFrom.configMapRef.name func FindReferencingConfigMaps(m Manifest) []string { var configMaps []string @@ -66,6 +84,26 @@ func FindReferencingConfigMaps(m Manifest) []string { configMaps = append(configMaps, n...) } + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "volumes", "configMap", "name"); len(n) > 0 { + configMaps = append(configMaps, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "initContainers", "env", "valueFrom", "configMapKeyRef", "name"); len(n) > 0 { + configMaps = append(configMaps, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "initContainers", "envFrom", "configMapRef", "name"); len(n) > 0 { + configMaps = append(configMaps, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "containers", "env", "valueFrom", "configMapKeyRef", "name"); len(n) > 0 { + configMaps = append(configMaps, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "containers", "envFrom", "configMapRef", "name"); len(n) > 0 { + configMaps = append(configMaps, n...) + } + slices.Sort(configMaps) return slices.Compact(configMaps) } @@ -78,6 +116,11 @@ func FindReferencingConfigMaps(m Manifest) []string { // - spec.template.spec.initContainers.envFrom.secretRef.name // - spec.template.spec.containers.env.valueFrom.secretKeyRef.name // - spec.template.spec.containers.envFrom.secretRef.name +// - spec.jobTemplate.spec.template.spec.volumes.secret.secretName +// - spec.jobTemplate.spec.template.spec.initContainers.env.valueFrom.secretKeyRef.name +// - spec.jobTemplate.spec.template.spec.initContainers.envFrom.secretRef.name +// - spec.jobTemplate.spec.template.spec.containers.env.valueFrom.secretKeyRef.name +// - spec.jobTemplate.spec.template.spec.containers.envFrom.secretRef.name func FindReferencingSecrets(m Manifest) []string { var secrets []string @@ -101,6 +144,26 @@ func FindReferencingSecrets(m Manifest) []string { secrets = append(secrets, n...) } + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "volumes", "secret", "secretName"); len(n) > 0 { + secrets = append(secrets, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "initContainers", "env", "valueFrom", "secretKeyRef", "name"); len(n) > 0 { + secrets = append(secrets, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "initContainers", "envFrom", "secretRef", "name"); len(n) > 0 { + secrets = append(secrets, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "containers", "env", "valueFrom", "secretKeyRef", "name"); len(n) > 0 { + secrets = append(secrets, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "containers", "envFrom", "secretRef", "name"); len(n) > 0 { + secrets = append(secrets, n...) + } + slices.Sort(secrets) return slices.Compact(secrets) } diff --git a/pkg/app/pipedv1/plugin/kubernetes/provider/deployment_test.go b/pkg/app/pipedv1/plugin/kubernetes/provider/deployment_test.go index 52c9a99764..57a711cd15 100644 --- a/pkg/app/pipedv1/plugin/kubernetes/provider/deployment_test.go +++ b/pkg/app/pipedv1/plugin/kubernetes/provider/deployment_test.go @@ -239,6 +239,87 @@ spec: "init-configmap-1", }, }, + { + name: "cronjob with configmap in volume", + manifest: ` +apiVersion: batch/v1 +kind: CronJob +metadata: + name: cronjob-with-configmap +spec: + schedule: "0 * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - name: worker + image: gcr.io/pipecd/helloworld:v0.5.0 + volumeMounts: + - name: config + mountPath: /etc/config + volumes: + - name: config + configMap: + name: cronjob-configmap +`, + expected: []string{ + "cronjob-configmap", + }, + }, + { + name: "cronjob with multiple configmaps across containers and initContainers", + manifest: ` +apiVersion: batch/v1 +kind: CronJob +metadata: + name: cronjob-multi-configmap +spec: + schedule: "0 * * * *" + jobTemplate: + spec: + template: + spec: + initContainers: + - name: init + image: gcr.io/pipecd/helloworld:v0.5.0 + env: + - name: INIT_KEY + valueFrom: + configMapKeyRef: + name: cronjob-init-configmap + key: key1 + envFrom: + - configMapRef: + name: cronjob-init-envfrom-configmap + containers: + - name: worker + image: gcr.io/pipecd/helloworld:v0.5.0 + env: + - name: APP_KEY + valueFrom: + configMapKeyRef: + name: cronjob-configmap-1 + key: key1 + envFrom: + - configMapRef: + name: cronjob-envfrom-configmap + volumeMounts: + - name: config + mountPath: /etc/config + volumes: + - name: config + configMap: + name: cronjob-volume-configmap +`, + expected: []string{ + "cronjob-configmap-1", + "cronjob-envfrom-configmap", + "cronjob-init-configmap", + "cronjob-init-envfrom-configmap", + "cronjob-volume-configmap", + }, + }, } for _, tc := range testcases { @@ -404,6 +485,87 @@ spec: "secret-2", }, }, + { + name: "cronjob with secret in volume", + manifest: ` +apiVersion: batch/v1 +kind: CronJob +metadata: + name: cronjob-with-secret +spec: + schedule: "0 * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - name: worker + image: gcr.io/pipecd/helloworld:v0.5.0 + volumeMounts: + - name: secret-vol + mountPath: /etc/secret + volumes: + - name: secret-vol + secret: + secretName: cronjob-secret +`, + expected: []string{ + "cronjob-secret", + }, + }, + { + name: "cronjob with multiple secrets across containers and initContainers", + manifest: ` +apiVersion: batch/v1 +kind: CronJob +metadata: + name: cronjob-multi-secret +spec: + schedule: "0 * * * *" + jobTemplate: + spec: + template: + spec: + initContainers: + - name: init + image: gcr.io/pipecd/helloworld:v0.5.0 + env: + - name: INIT_SECRET + valueFrom: + secretKeyRef: + name: cronjob-init-secret + key: key1 + envFrom: + - secretRef: + name: cronjob-init-envfrom-secret + containers: + - name: worker + image: gcr.io/pipecd/helloworld:v0.5.0 + env: + - name: APP_SECRET + valueFrom: + secretKeyRef: + name: cronjob-secret-1 + key: key1 + envFrom: + - secretRef: + name: cronjob-envfrom-secret + volumeMounts: + - name: secret-vol + mountPath: /etc/secret + volumes: + - name: secret-vol + secret: + secretName: cronjob-volume-secret +`, + expected: []string{ + "cronjob-envfrom-secret", + "cronjob-init-envfrom-secret", + "cronjob-init-secret", + "cronjob-secret-1", + "cronjob-volume-secret", + }, + }, } for _, tc := range testcases { diff --git a/pkg/app/pipedv1/plugin/kubernetes_multicluster/provider/deployment.go b/pkg/app/pipedv1/plugin/kubernetes_multicluster/provider/deployment.go index b60aaa6162..fc0efa30cc 100644 --- a/pkg/app/pipedv1/plugin/kubernetes_multicluster/provider/deployment.go +++ b/pkg/app/pipedv1/plugin/kubernetes_multicluster/provider/deployment.go @@ -22,8 +22,9 @@ import ( // // It looks for container images in the following fields: // - spec.template.spec.containers.image -// -// TODO: we should consider other fields like spec.template.spec.initContainers.image, spec.jobTempate.spec.template.spec.containers.image +// - spec.template.spec.initContainers.image +// - spec.jobTemplate.spec.template.spec.containers.image +// - spec.jobTemplate.spec.template.spec.initContainers.image func FindContainerImages(m Manifest) []string { var images []string @@ -31,6 +32,18 @@ func FindContainerImages(m Manifest) []string { images = append(images, n...) } + if n := nestedStringSlice(m.body.Object, "spec", "template", "spec", "initContainers", "image"); len(n) > 0 { + images = append(images, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "containers", "image"); len(n) > 0 { + images = append(images, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "initContainers", "image"); len(n) > 0 { + images = append(images, n...) + } + slices.Sort(images) return slices.Compact(images) } @@ -43,6 +56,11 @@ func FindContainerImages(m Manifest) []string { // - spec.template.spec.initContainers.envFrom.configMapRef.name // - spec.template.spec.containers.env.valueFrom.configMapKeyRef.name // - spec.template.spec.containers.envFrom.configMapRef.name +// - spec.jobTemplate.spec.template.spec.volumes.configMap.name +// - spec.jobTemplate.spec.template.spec.initContainers.env.valueFrom.configMapKeyRef.name +// - spec.jobTemplate.spec.template.spec.initContainers.envFrom.configMapRef.name +// - spec.jobTemplate.spec.template.spec.containers.env.valueFrom.configMapKeyRef.name +// - spec.jobTemplate.spec.template.spec.containers.envFrom.configMapRef.name func FindReferencingConfigMaps(m Manifest) []string { var configMaps []string @@ -66,6 +84,26 @@ func FindReferencingConfigMaps(m Manifest) []string { configMaps = append(configMaps, n...) } + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "volumes", "configMap", "name"); len(n) > 0 { + configMaps = append(configMaps, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "initContainers", "env", "valueFrom", "configMapKeyRef", "name"); len(n) > 0 { + configMaps = append(configMaps, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "initContainers", "envFrom", "configMapRef", "name"); len(n) > 0 { + configMaps = append(configMaps, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "containers", "env", "valueFrom", "configMapKeyRef", "name"); len(n) > 0 { + configMaps = append(configMaps, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "containers", "envFrom", "configMapRef", "name"); len(n) > 0 { + configMaps = append(configMaps, n...) + } + slices.Sort(configMaps) return slices.Compact(configMaps) } @@ -78,6 +116,11 @@ func FindReferencingConfigMaps(m Manifest) []string { // - spec.template.spec.initContainers.envFrom.secretRef.name // - spec.template.spec.containers.env.valueFrom.secretKeyRef.name // - spec.template.spec.containers.envFrom.secretRef.name +// - spec.jobTemplate.spec.template.spec.volumes.secret.secretName +// - spec.jobTemplate.spec.template.spec.initContainers.env.valueFrom.secretKeyRef.name +// - spec.jobTemplate.spec.template.spec.initContainers.envFrom.secretRef.name +// - spec.jobTemplate.spec.template.spec.containers.env.valueFrom.secretKeyRef.name +// - spec.jobTemplate.spec.template.spec.containers.envFrom.secretRef.name func FindReferencingSecrets(m Manifest) []string { var secrets []string @@ -101,6 +144,26 @@ func FindReferencingSecrets(m Manifest) []string { secrets = append(secrets, n...) } + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "volumes", "secret", "secretName"); len(n) > 0 { + secrets = append(secrets, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "initContainers", "env", "valueFrom", "secretKeyRef", "name"); len(n) > 0 { + secrets = append(secrets, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "initContainers", "envFrom", "secretRef", "name"); len(n) > 0 { + secrets = append(secrets, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "containers", "env", "valueFrom", "secretKeyRef", "name"); len(n) > 0 { + secrets = append(secrets, n...) + } + + if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "containers", "envFrom", "secretRef", "name"); len(n) > 0 { + secrets = append(secrets, n...) + } + slices.Sort(secrets) return slices.Compact(secrets) } diff --git a/pkg/app/pipedv1/plugin/kubernetes_multicluster/provider/deployment_test.go b/pkg/app/pipedv1/plugin/kubernetes_multicluster/provider/deployment_test.go index 52c9a99764..57a711cd15 100644 --- a/pkg/app/pipedv1/plugin/kubernetes_multicluster/provider/deployment_test.go +++ b/pkg/app/pipedv1/plugin/kubernetes_multicluster/provider/deployment_test.go @@ -239,6 +239,87 @@ spec: "init-configmap-1", }, }, + { + name: "cronjob with configmap in volume", + manifest: ` +apiVersion: batch/v1 +kind: CronJob +metadata: + name: cronjob-with-configmap +spec: + schedule: "0 * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - name: worker + image: gcr.io/pipecd/helloworld:v0.5.0 + volumeMounts: + - name: config + mountPath: /etc/config + volumes: + - name: config + configMap: + name: cronjob-configmap +`, + expected: []string{ + "cronjob-configmap", + }, + }, + { + name: "cronjob with multiple configmaps across containers and initContainers", + manifest: ` +apiVersion: batch/v1 +kind: CronJob +metadata: + name: cronjob-multi-configmap +spec: + schedule: "0 * * * *" + jobTemplate: + spec: + template: + spec: + initContainers: + - name: init + image: gcr.io/pipecd/helloworld:v0.5.0 + env: + - name: INIT_KEY + valueFrom: + configMapKeyRef: + name: cronjob-init-configmap + key: key1 + envFrom: + - configMapRef: + name: cronjob-init-envfrom-configmap + containers: + - name: worker + image: gcr.io/pipecd/helloworld:v0.5.0 + env: + - name: APP_KEY + valueFrom: + configMapKeyRef: + name: cronjob-configmap-1 + key: key1 + envFrom: + - configMapRef: + name: cronjob-envfrom-configmap + volumeMounts: + - name: config + mountPath: /etc/config + volumes: + - name: config + configMap: + name: cronjob-volume-configmap +`, + expected: []string{ + "cronjob-configmap-1", + "cronjob-envfrom-configmap", + "cronjob-init-configmap", + "cronjob-init-envfrom-configmap", + "cronjob-volume-configmap", + }, + }, } for _, tc := range testcases { @@ -404,6 +485,87 @@ spec: "secret-2", }, }, + { + name: "cronjob with secret in volume", + manifest: ` +apiVersion: batch/v1 +kind: CronJob +metadata: + name: cronjob-with-secret +spec: + schedule: "0 * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - name: worker + image: gcr.io/pipecd/helloworld:v0.5.0 + volumeMounts: + - name: secret-vol + mountPath: /etc/secret + volumes: + - name: secret-vol + secret: + secretName: cronjob-secret +`, + expected: []string{ + "cronjob-secret", + }, + }, + { + name: "cronjob with multiple secrets across containers and initContainers", + manifest: ` +apiVersion: batch/v1 +kind: CronJob +metadata: + name: cronjob-multi-secret +spec: + schedule: "0 * * * *" + jobTemplate: + spec: + template: + spec: + initContainers: + - name: init + image: gcr.io/pipecd/helloworld:v0.5.0 + env: + - name: INIT_SECRET + valueFrom: + secretKeyRef: + name: cronjob-init-secret + key: key1 + envFrom: + - secretRef: + name: cronjob-init-envfrom-secret + containers: + - name: worker + image: gcr.io/pipecd/helloworld:v0.5.0 + env: + - name: APP_SECRET + valueFrom: + secretKeyRef: + name: cronjob-secret-1 + key: key1 + envFrom: + - secretRef: + name: cronjob-envfrom-secret + volumeMounts: + - name: secret-vol + mountPath: /etc/secret + volumes: + - name: secret-vol + secret: + secretName: cronjob-volume-secret +`, + expected: []string{ + "cronjob-envfrom-secret", + "cronjob-init-envfrom-secret", + "cronjob-init-secret", + "cronjob-secret-1", + "cronjob-volume-secret", + }, + }, } for _, tc := range testcases {