diff --git a/pkg/api/pod/util.go b/pkg/api/pod/util.go index ec91c03276b..45e935b90aa 100644 --- a/pkg/api/pod/util.go +++ b/pkg/api/pod/util.go @@ -21,11 +21,14 @@ import ( "k8s.io/kubernetes/pkg/api" ) +// Visitor is called with each object name, and returns true if visiting should continue +type Visitor func(name string) (shouldContinue bool) + // VisitPodSecretNames invokes the visitor function with the name of every secret // referenced by the pod spec. If visitor returns false, visiting is short-circuited. // Transitive references (e.g. pod -> pvc -> pv -> secret) are not visited. // Returns true if visiting completed, false if visiting was short-circuited. -func VisitPodSecretNames(pod *api.Pod, visitor func(string) bool) bool { +func VisitPodSecretNames(pod *api.Pod, visitor Visitor) bool { for _, reference := range pod.Spec.ImagePullSecrets { if !visitor(reference.Name) { return false @@ -86,7 +89,7 @@ func VisitPodSecretNames(pod *api.Pod, visitor func(string) bool) bool { return true } -func visitContainerSecretNames(container *api.Container, visitor func(string) bool) bool { +func visitContainerSecretNames(container *api.Container, visitor Visitor) bool { for _, env := range container.EnvFrom { if env.SecretRef != nil { if !visitor(env.SecretRef.Name) { @@ -104,6 +107,60 @@ func visitContainerSecretNames(container *api.Container, visitor func(string) bo return true } +// VisitPodConfigmapNames invokes the visitor function with the name of every configmap +// referenced by the pod spec. If visitor returns false, visiting is short-circuited. +// Transitive references (e.g. pod -> pvc -> pv -> secret) are not visited. +// Returns true if visiting completed, false if visiting was short-circuited. +func VisitPodConfigmapNames(pod *api.Pod, visitor Visitor) bool { + for i := range pod.Spec.InitContainers { + if !visitContainerConfigmapNames(&pod.Spec.InitContainers[i], visitor) { + return false + } + } + for i := range pod.Spec.Containers { + if !visitContainerConfigmapNames(&pod.Spec.Containers[i], visitor) { + return false + } + } + var source *api.VolumeSource + for i := range pod.Spec.Volumes { + source = &pod.Spec.Volumes[i].VolumeSource + switch { + case source.Projected != nil: + for j := range source.Projected.Sources { + if source.Projected.Sources[j].ConfigMap != nil { + if !visitor(source.Projected.Sources[j].ConfigMap.Name) { + return false + } + } + } + case source.ConfigMap != nil: + if !visitor(source.ConfigMap.Name) { + return false + } + } + } + return true +} + +func visitContainerConfigmapNames(container *api.Container, visitor Visitor) bool { + for _, env := range container.EnvFrom { + if env.ConfigMapRef != nil { + if !visitor(env.ConfigMapRef.Name) { + return false + } + } + } + for _, envVar := range container.Env { + if envVar.ValueFrom != nil && envVar.ValueFrom.ConfigMapKeyRef != nil { + if !visitor(envVar.ValueFrom.ConfigMapKeyRef.Name) { + return false + } + } + } + return true +} + // IsPodReady returns true if a pod is ready; false otherwise. func IsPodReady(pod *api.Pod) bool { return IsPodReadyConditionTrue(pod.Status) diff --git a/pkg/api/v1/pod/util.go b/pkg/api/v1/pod/util.go index bb24a3c7626..85eb5338337 100644 --- a/pkg/api/v1/pod/util.go +++ b/pkg/api/v1/pod/util.go @@ -107,11 +107,14 @@ func SetInitContainersStatusesAnnotations(pod *v1.Pod) error { return nil } +// Visitor is called with each object name, and returns true if visiting should continue +type Visitor func(name string) (shouldContinue bool) + // VisitPodSecretNames invokes the visitor function with the name of every secret // referenced by the pod spec. If visitor returns false, visiting is short-circuited. // Transitive references (e.g. pod -> pvc -> pv -> secret) are not visited. // Returns true if visiting completed, false if visiting was short-circuited. -func VisitPodSecretNames(pod *v1.Pod, visitor func(string) bool) bool { +func VisitPodSecretNames(pod *v1.Pod, visitor Visitor) bool { for _, reference := range pod.Spec.ImagePullSecrets { if !visitor(reference.Name) { return false @@ -173,7 +176,7 @@ func VisitPodSecretNames(pod *v1.Pod, visitor func(string) bool) bool { return true } -func visitContainerSecretNames(container *v1.Container, visitor func(string) bool) bool { +func visitContainerSecretNames(container *v1.Container, visitor Visitor) bool { for _, env := range container.EnvFrom { if env.SecretRef != nil { if !visitor(env.SecretRef.Name) {