mirror of
https://github.com/stakater/Reloader.git
synced 2026-08-27 14:37:17 +00:00
feat: add v2 foundation packages for config and workload abstraction
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
package workload
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
// CronJobWorkload wraps a Kubernetes CronJob.
|
||||
// Note: CronJobs have a special update mechanism - instead of updating the CronJob itself,
|
||||
// Reloader creates a new Job from the CronJob's template.
|
||||
type CronJobWorkload struct {
|
||||
cronjob *batchv1.CronJob
|
||||
}
|
||||
|
||||
// NewCronJobWorkload creates a new CronJobWorkload.
|
||||
func NewCronJobWorkload(c *batchv1.CronJob) *CronJobWorkload {
|
||||
return &CronJobWorkload{cronjob: c}
|
||||
}
|
||||
|
||||
// Ensure CronJobWorkload implements WorkloadAccessor.
|
||||
var _ WorkloadAccessor = (*CronJobWorkload)(nil)
|
||||
|
||||
func (w *CronJobWorkload) Kind() Kind {
|
||||
return KindCronJob
|
||||
}
|
||||
|
||||
func (w *CronJobWorkload) GetObject() client.Object {
|
||||
return w.cronjob
|
||||
}
|
||||
|
||||
func (w *CronJobWorkload) GetName() string {
|
||||
return w.cronjob.Name
|
||||
}
|
||||
|
||||
func (w *CronJobWorkload) GetNamespace() string {
|
||||
return w.cronjob.Namespace
|
||||
}
|
||||
|
||||
func (w *CronJobWorkload) GetAnnotations() map[string]string {
|
||||
return w.cronjob.Annotations
|
||||
}
|
||||
|
||||
// GetPodTemplateAnnotations returns annotations from the JobTemplate's pod template.
|
||||
func (w *CronJobWorkload) GetPodTemplateAnnotations() map[string]string {
|
||||
if w.cronjob.Spec.JobTemplate.Spec.Template.Annotations == nil {
|
||||
w.cronjob.Spec.JobTemplate.Spec.Template.Annotations = make(map[string]string)
|
||||
}
|
||||
return w.cronjob.Spec.JobTemplate.Spec.Template.Annotations
|
||||
}
|
||||
|
||||
func (w *CronJobWorkload) SetPodTemplateAnnotation(key, value string) {
|
||||
if w.cronjob.Spec.JobTemplate.Spec.Template.Annotations == nil {
|
||||
w.cronjob.Spec.JobTemplate.Spec.Template.Annotations = make(map[string]string)
|
||||
}
|
||||
w.cronjob.Spec.JobTemplate.Spec.Template.Annotations[key] = value
|
||||
}
|
||||
|
||||
func (w *CronJobWorkload) GetContainers() []corev1.Container {
|
||||
return w.cronjob.Spec.JobTemplate.Spec.Template.Spec.Containers
|
||||
}
|
||||
|
||||
func (w *CronJobWorkload) SetContainers(containers []corev1.Container) {
|
||||
w.cronjob.Spec.JobTemplate.Spec.Template.Spec.Containers = containers
|
||||
}
|
||||
|
||||
func (w *CronJobWorkload) GetInitContainers() []corev1.Container {
|
||||
return w.cronjob.Spec.JobTemplate.Spec.Template.Spec.InitContainers
|
||||
}
|
||||
|
||||
func (w *CronJobWorkload) SetInitContainers(containers []corev1.Container) {
|
||||
w.cronjob.Spec.JobTemplate.Spec.Template.Spec.InitContainers = containers
|
||||
}
|
||||
|
||||
func (w *CronJobWorkload) GetVolumes() []corev1.Volume {
|
||||
return w.cronjob.Spec.JobTemplate.Spec.Template.Spec.Volumes
|
||||
}
|
||||
|
||||
// Update for CronJob is a no-op - use CreateJobFromCronJob instead.
|
||||
// CronJobs trigger reloads by creating a new Job from their template.
|
||||
func (w *CronJobWorkload) Update(ctx context.Context, c client.Client) error {
|
||||
// CronJobs don't get updated directly - a new Job is created instead
|
||||
// This is handled by the reload package's special CronJob logic
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *CronJobWorkload) DeepCopy() Workload {
|
||||
return &CronJobWorkload{cronjob: w.cronjob.DeepCopy()}
|
||||
}
|
||||
|
||||
func (w *CronJobWorkload) GetEnvFromSources() []corev1.EnvFromSource {
|
||||
var sources []corev1.EnvFromSource
|
||||
for _, container := range w.cronjob.Spec.JobTemplate.Spec.Template.Spec.Containers {
|
||||
sources = append(sources, container.EnvFrom...)
|
||||
}
|
||||
for _, container := range w.cronjob.Spec.JobTemplate.Spec.Template.Spec.InitContainers {
|
||||
sources = append(sources, container.EnvFrom...)
|
||||
}
|
||||
return sources
|
||||
}
|
||||
|
||||
func (w *CronJobWorkload) UsesConfigMap(name string) bool {
|
||||
spec := &w.cronjob.Spec.JobTemplate.Spec.Template.Spec
|
||||
|
||||
// Check volumes
|
||||
for _, vol := range spec.Volumes {
|
||||
if vol.ConfigMap != nil && vol.ConfigMap.Name == name {
|
||||
return true
|
||||
}
|
||||
if vol.Projected != nil {
|
||||
for _, source := range vol.Projected.Sources {
|
||||
if source.ConfigMap != nil && source.ConfigMap.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check containers
|
||||
for _, container := range spec.Containers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.ConfigMapRef != nil && envFrom.ConfigMapRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.ConfigMapKeyRef != nil && env.ValueFrom.ConfigMapKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check init containers
|
||||
for _, container := range spec.InitContainers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.ConfigMapRef != nil && envFrom.ConfigMapRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.ConfigMapKeyRef != nil && env.ValueFrom.ConfigMapKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *CronJobWorkload) UsesSecret(name string) bool {
|
||||
spec := &w.cronjob.Spec.JobTemplate.Spec.Template.Spec
|
||||
|
||||
// Check volumes
|
||||
for _, vol := range spec.Volumes {
|
||||
if vol.Secret != nil && vol.Secret.SecretName == name {
|
||||
return true
|
||||
}
|
||||
if vol.Projected != nil {
|
||||
for _, source := range vol.Projected.Sources {
|
||||
if source.Secret != nil && source.Secret.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check containers
|
||||
for _, container := range spec.Containers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.SecretRef != nil && envFrom.SecretRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil && env.ValueFrom.SecretKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check init containers
|
||||
for _, container := range spec.InitContainers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.SecretRef != nil && envFrom.SecretRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil && env.ValueFrom.SecretKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *CronJobWorkload) GetOwnerReferences() []metav1.OwnerReference {
|
||||
return w.cronjob.OwnerReferences
|
||||
}
|
||||
|
||||
// GetCronJob returns the underlying CronJob for special handling.
|
||||
func (w *CronJobWorkload) GetCronJob() *batchv1.CronJob {
|
||||
return w.cronjob
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
package workload
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
// DaemonSetWorkload wraps a Kubernetes DaemonSet.
|
||||
type DaemonSetWorkload struct {
|
||||
daemonset *appsv1.DaemonSet
|
||||
}
|
||||
|
||||
// NewDaemonSetWorkload creates a new DaemonSetWorkload.
|
||||
func NewDaemonSetWorkload(d *appsv1.DaemonSet) *DaemonSetWorkload {
|
||||
return &DaemonSetWorkload{daemonset: d}
|
||||
}
|
||||
|
||||
// Ensure DaemonSetWorkload implements WorkloadAccessor.
|
||||
var _ WorkloadAccessor = (*DaemonSetWorkload)(nil)
|
||||
|
||||
func (w *DaemonSetWorkload) Kind() Kind {
|
||||
return KindDaemonSet
|
||||
}
|
||||
|
||||
func (w *DaemonSetWorkload) GetObject() client.Object {
|
||||
return w.daemonset
|
||||
}
|
||||
|
||||
func (w *DaemonSetWorkload) GetName() string {
|
||||
return w.daemonset.Name
|
||||
}
|
||||
|
||||
func (w *DaemonSetWorkload) GetNamespace() string {
|
||||
return w.daemonset.Namespace
|
||||
}
|
||||
|
||||
func (w *DaemonSetWorkload) GetAnnotations() map[string]string {
|
||||
return w.daemonset.Annotations
|
||||
}
|
||||
|
||||
func (w *DaemonSetWorkload) GetPodTemplateAnnotations() map[string]string {
|
||||
if w.daemonset.Spec.Template.Annotations == nil {
|
||||
w.daemonset.Spec.Template.Annotations = make(map[string]string)
|
||||
}
|
||||
return w.daemonset.Spec.Template.Annotations
|
||||
}
|
||||
|
||||
func (w *DaemonSetWorkload) SetPodTemplateAnnotation(key, value string) {
|
||||
if w.daemonset.Spec.Template.Annotations == nil {
|
||||
w.daemonset.Spec.Template.Annotations = make(map[string]string)
|
||||
}
|
||||
w.daemonset.Spec.Template.Annotations[key] = value
|
||||
}
|
||||
|
||||
func (w *DaemonSetWorkload) GetContainers() []corev1.Container {
|
||||
return w.daemonset.Spec.Template.Spec.Containers
|
||||
}
|
||||
|
||||
func (w *DaemonSetWorkload) SetContainers(containers []corev1.Container) {
|
||||
w.daemonset.Spec.Template.Spec.Containers = containers
|
||||
}
|
||||
|
||||
func (w *DaemonSetWorkload) GetInitContainers() []corev1.Container {
|
||||
return w.daemonset.Spec.Template.Spec.InitContainers
|
||||
}
|
||||
|
||||
func (w *DaemonSetWorkload) SetInitContainers(containers []corev1.Container) {
|
||||
w.daemonset.Spec.Template.Spec.InitContainers = containers
|
||||
}
|
||||
|
||||
func (w *DaemonSetWorkload) GetVolumes() []corev1.Volume {
|
||||
return w.daemonset.Spec.Template.Spec.Volumes
|
||||
}
|
||||
|
||||
func (w *DaemonSetWorkload) Update(ctx context.Context, c client.Client) error {
|
||||
return c.Update(ctx, w.daemonset)
|
||||
}
|
||||
|
||||
func (w *DaemonSetWorkload) DeepCopy() Workload {
|
||||
return &DaemonSetWorkload{daemonset: w.daemonset.DeepCopy()}
|
||||
}
|
||||
|
||||
func (w *DaemonSetWorkload) GetEnvFromSources() []corev1.EnvFromSource {
|
||||
var sources []corev1.EnvFromSource
|
||||
for _, container := range w.daemonset.Spec.Template.Spec.Containers {
|
||||
sources = append(sources, container.EnvFrom...)
|
||||
}
|
||||
for _, container := range w.daemonset.Spec.Template.Spec.InitContainers {
|
||||
sources = append(sources, container.EnvFrom...)
|
||||
}
|
||||
return sources
|
||||
}
|
||||
|
||||
func (w *DaemonSetWorkload) UsesConfigMap(name string) bool {
|
||||
// Check volumes
|
||||
for _, vol := range w.daemonset.Spec.Template.Spec.Volumes {
|
||||
if vol.ConfigMap != nil && vol.ConfigMap.Name == name {
|
||||
return true
|
||||
}
|
||||
if vol.Projected != nil {
|
||||
for _, source := range vol.Projected.Sources {
|
||||
if source.ConfigMap != nil && source.ConfigMap.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check envFrom
|
||||
for _, container := range w.daemonset.Spec.Template.Spec.Containers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.ConfigMapRef != nil && envFrom.ConfigMapRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.ConfigMapKeyRef != nil && env.ValueFrom.ConfigMapKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check init containers
|
||||
for _, container := range w.daemonset.Spec.Template.Spec.InitContainers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.ConfigMapRef != nil && envFrom.ConfigMapRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.ConfigMapKeyRef != nil && env.ValueFrom.ConfigMapKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *DaemonSetWorkload) UsesSecret(name string) bool {
|
||||
// Check volumes
|
||||
for _, vol := range w.daemonset.Spec.Template.Spec.Volumes {
|
||||
if vol.Secret != nil && vol.Secret.SecretName == name {
|
||||
return true
|
||||
}
|
||||
if vol.Projected != nil {
|
||||
for _, source := range vol.Projected.Sources {
|
||||
if source.Secret != nil && source.Secret.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check envFrom
|
||||
for _, container := range w.daemonset.Spec.Template.Spec.Containers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.SecretRef != nil && envFrom.SecretRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil && env.ValueFrom.SecretKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check init containers
|
||||
for _, container := range w.daemonset.Spec.Template.Spec.InitContainers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.SecretRef != nil && envFrom.SecretRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil && env.ValueFrom.SecretKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *DaemonSetWorkload) GetOwnerReferences() []metav1.OwnerReference {
|
||||
return w.daemonset.OwnerReferences
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
package workload
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
// DeploymentWorkload wraps a Kubernetes Deployment.
|
||||
type DeploymentWorkload struct {
|
||||
deployment *appsv1.Deployment
|
||||
}
|
||||
|
||||
// NewDeploymentWorkload creates a new DeploymentWorkload.
|
||||
func NewDeploymentWorkload(d *appsv1.Deployment) *DeploymentWorkload {
|
||||
return &DeploymentWorkload{deployment: d}
|
||||
}
|
||||
|
||||
// Ensure DeploymentWorkload implements WorkloadAccessor.
|
||||
var _ WorkloadAccessor = (*DeploymentWorkload)(nil)
|
||||
|
||||
func (w *DeploymentWorkload) Kind() Kind {
|
||||
return KindDeployment
|
||||
}
|
||||
|
||||
func (w *DeploymentWorkload) GetObject() client.Object {
|
||||
return w.deployment
|
||||
}
|
||||
|
||||
func (w *DeploymentWorkload) GetName() string {
|
||||
return w.deployment.Name
|
||||
}
|
||||
|
||||
func (w *DeploymentWorkload) GetNamespace() string {
|
||||
return w.deployment.Namespace
|
||||
}
|
||||
|
||||
func (w *DeploymentWorkload) GetAnnotations() map[string]string {
|
||||
return w.deployment.Annotations
|
||||
}
|
||||
|
||||
func (w *DeploymentWorkload) GetPodTemplateAnnotations() map[string]string {
|
||||
if w.deployment.Spec.Template.Annotations == nil {
|
||||
w.deployment.Spec.Template.Annotations = make(map[string]string)
|
||||
}
|
||||
return w.deployment.Spec.Template.Annotations
|
||||
}
|
||||
|
||||
func (w *DeploymentWorkload) SetPodTemplateAnnotation(key, value string) {
|
||||
if w.deployment.Spec.Template.Annotations == nil {
|
||||
w.deployment.Spec.Template.Annotations = make(map[string]string)
|
||||
}
|
||||
w.deployment.Spec.Template.Annotations[key] = value
|
||||
}
|
||||
|
||||
func (w *DeploymentWorkload) GetContainers() []corev1.Container {
|
||||
return w.deployment.Spec.Template.Spec.Containers
|
||||
}
|
||||
|
||||
func (w *DeploymentWorkload) SetContainers(containers []corev1.Container) {
|
||||
w.deployment.Spec.Template.Spec.Containers = containers
|
||||
}
|
||||
|
||||
func (w *DeploymentWorkload) GetInitContainers() []corev1.Container {
|
||||
return w.deployment.Spec.Template.Spec.InitContainers
|
||||
}
|
||||
|
||||
func (w *DeploymentWorkload) SetInitContainers(containers []corev1.Container) {
|
||||
w.deployment.Spec.Template.Spec.InitContainers = containers
|
||||
}
|
||||
|
||||
func (w *DeploymentWorkload) GetVolumes() []corev1.Volume {
|
||||
return w.deployment.Spec.Template.Spec.Volumes
|
||||
}
|
||||
|
||||
func (w *DeploymentWorkload) Update(ctx context.Context, c client.Client) error {
|
||||
return c.Update(ctx, w.deployment)
|
||||
}
|
||||
|
||||
func (w *DeploymentWorkload) DeepCopy() Workload {
|
||||
return &DeploymentWorkload{deployment: w.deployment.DeepCopy()}
|
||||
}
|
||||
|
||||
func (w *DeploymentWorkload) GetEnvFromSources() []corev1.EnvFromSource {
|
||||
var sources []corev1.EnvFromSource
|
||||
for _, container := range w.deployment.Spec.Template.Spec.Containers {
|
||||
sources = append(sources, container.EnvFrom...)
|
||||
}
|
||||
for _, container := range w.deployment.Spec.Template.Spec.InitContainers {
|
||||
sources = append(sources, container.EnvFrom...)
|
||||
}
|
||||
return sources
|
||||
}
|
||||
|
||||
func (w *DeploymentWorkload) UsesConfigMap(name string) bool {
|
||||
// Check volumes
|
||||
for _, vol := range w.deployment.Spec.Template.Spec.Volumes {
|
||||
if vol.ConfigMap != nil && vol.ConfigMap.Name == name {
|
||||
return true
|
||||
}
|
||||
if vol.Projected != nil {
|
||||
for _, source := range vol.Projected.Sources {
|
||||
if source.ConfigMap != nil && source.ConfigMap.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check envFrom
|
||||
for _, container := range w.deployment.Spec.Template.Spec.Containers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.ConfigMapRef != nil && envFrom.ConfigMapRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// Check individual env vars
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.ConfigMapKeyRef != nil && env.ValueFrom.ConfigMapKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check init containers
|
||||
for _, container := range w.deployment.Spec.Template.Spec.InitContainers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.ConfigMapRef != nil && envFrom.ConfigMapRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.ConfigMapKeyRef != nil && env.ValueFrom.ConfigMapKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *DeploymentWorkload) UsesSecret(name string) bool {
|
||||
// Check volumes
|
||||
for _, vol := range w.deployment.Spec.Template.Spec.Volumes {
|
||||
if vol.Secret != nil && vol.Secret.SecretName == name {
|
||||
return true
|
||||
}
|
||||
if vol.Projected != nil {
|
||||
for _, source := range vol.Projected.Sources {
|
||||
if source.Secret != nil && source.Secret.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check envFrom
|
||||
for _, container := range w.deployment.Spec.Template.Spec.Containers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.SecretRef != nil && envFrom.SecretRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// Check individual env vars
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil && env.ValueFrom.SecretKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check init containers
|
||||
for _, container := range w.deployment.Spec.Template.Spec.InitContainers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.SecretRef != nil && envFrom.SecretRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil && env.ValueFrom.SecretKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *DeploymentWorkload) GetOwnerReferences() []metav1.OwnerReference {
|
||||
return w.deployment.OwnerReferences
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
// Package workload provides an abstraction layer for Kubernetes workload types.
|
||||
// It allows uniform handling of Deployments, DaemonSets, StatefulSets, Jobs, CronJobs, and Argo Rollouts.
|
||||
//
|
||||
// Note: Jobs and CronJobs have special update mechanisms:
|
||||
// - Job: deleted and recreated with the same spec
|
||||
// - CronJob: a new Job is created from the CronJob's template
|
||||
package workload
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
// Kind represents the type of workload.
|
||||
type Kind string
|
||||
|
||||
const (
|
||||
KindDeployment Kind = "Deployment"
|
||||
KindDaemonSet Kind = "DaemonSet"
|
||||
KindStatefulSet Kind = "StatefulSet"
|
||||
KindArgoRollout Kind = "Rollout"
|
||||
KindJob Kind = "Job"
|
||||
KindCronJob Kind = "CronJob"
|
||||
)
|
||||
|
||||
// Workload provides a uniform interface for managing Kubernetes workloads.
|
||||
// All implementations must be safe for concurrent use.
|
||||
type Workload interface {
|
||||
// Kind returns the workload type.
|
||||
Kind() Kind
|
||||
|
||||
// GetObject returns the underlying Kubernetes object.
|
||||
GetObject() client.Object
|
||||
|
||||
// GetName returns the workload name.
|
||||
GetName() string
|
||||
|
||||
// GetNamespace returns the workload namespace.
|
||||
GetNamespace() string
|
||||
|
||||
// GetAnnotations returns the workload's annotations.
|
||||
GetAnnotations() map[string]string
|
||||
|
||||
// GetPodTemplateAnnotations returns annotations from the pod template spec.
|
||||
GetPodTemplateAnnotations() map[string]string
|
||||
|
||||
// SetPodTemplateAnnotation sets an annotation on the pod template.
|
||||
SetPodTemplateAnnotation(key, value string)
|
||||
|
||||
// GetContainers returns all containers (including init containers).
|
||||
GetContainers() []corev1.Container
|
||||
|
||||
// SetContainers updates the containers.
|
||||
SetContainers(containers []corev1.Container)
|
||||
|
||||
// GetInitContainers returns all init containers.
|
||||
GetInitContainers() []corev1.Container
|
||||
|
||||
// SetInitContainers updates the init containers.
|
||||
SetInitContainers(containers []corev1.Container)
|
||||
|
||||
// GetVolumes returns the pod template volumes.
|
||||
GetVolumes() []corev1.Volume
|
||||
|
||||
// Update persists changes to the workload.
|
||||
Update(ctx context.Context, c client.Client) error
|
||||
|
||||
// DeepCopy returns a deep copy of the workload.
|
||||
DeepCopy() Workload
|
||||
}
|
||||
|
||||
// Accessor provides read-only access to workload configuration.
|
||||
// Use this interface when you only need to inspect workload state.
|
||||
type Accessor interface {
|
||||
// Kind returns the workload type.
|
||||
Kind() Kind
|
||||
|
||||
// GetName returns the workload name.
|
||||
GetName() string
|
||||
|
||||
// GetNamespace returns the workload namespace.
|
||||
GetNamespace() string
|
||||
|
||||
// GetAnnotations returns the workload's annotations.
|
||||
GetAnnotations() map[string]string
|
||||
|
||||
// GetPodTemplateAnnotations returns annotations from the pod template spec.
|
||||
GetPodTemplateAnnotations() map[string]string
|
||||
|
||||
// GetContainers returns all containers (including init containers).
|
||||
GetContainers() []corev1.Container
|
||||
|
||||
// GetInitContainers returns all init containers.
|
||||
GetInitContainers() []corev1.Container
|
||||
|
||||
// GetVolumes returns the pod template volumes.
|
||||
GetVolumes() []corev1.Volume
|
||||
|
||||
// GetEnvFromSources returns all envFrom sources from all containers.
|
||||
GetEnvFromSources() []corev1.EnvFromSource
|
||||
|
||||
// UsesConfigMap checks if the workload uses a specific ConfigMap.
|
||||
UsesConfigMap(name string) bool
|
||||
|
||||
// UsesSecret checks if the workload uses a specific Secret.
|
||||
UsesSecret(name string) bool
|
||||
|
||||
// GetOwnerReferences returns the owner references of the workload.
|
||||
GetOwnerReferences() []metav1.OwnerReference
|
||||
}
|
||||
|
||||
// WorkloadAccessor provides both Workload and Accessor interfaces.
|
||||
// This is the primary type returned by the registry.
|
||||
type WorkloadAccessor interface {
|
||||
Workload
|
||||
Accessor
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
package workload
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
// JobWorkload wraps a Kubernetes Job.
|
||||
// Note: Jobs have a special update mechanism - instead of updating the Job,
|
||||
// Reloader deletes and recreates it with the same spec.
|
||||
type JobWorkload struct {
|
||||
job *batchv1.Job
|
||||
}
|
||||
|
||||
// NewJobWorkload creates a new JobWorkload.
|
||||
func NewJobWorkload(j *batchv1.Job) *JobWorkload {
|
||||
return &JobWorkload{job: j}
|
||||
}
|
||||
|
||||
// Ensure JobWorkload implements WorkloadAccessor.
|
||||
var _ WorkloadAccessor = (*JobWorkload)(nil)
|
||||
|
||||
func (w *JobWorkload) Kind() Kind {
|
||||
return KindJob
|
||||
}
|
||||
|
||||
func (w *JobWorkload) GetObject() client.Object {
|
||||
return w.job
|
||||
}
|
||||
|
||||
func (w *JobWorkload) GetName() string {
|
||||
return w.job.Name
|
||||
}
|
||||
|
||||
func (w *JobWorkload) GetNamespace() string {
|
||||
return w.job.Namespace
|
||||
}
|
||||
|
||||
func (w *JobWorkload) GetAnnotations() map[string]string {
|
||||
return w.job.Annotations
|
||||
}
|
||||
|
||||
func (w *JobWorkload) GetPodTemplateAnnotations() map[string]string {
|
||||
if w.job.Spec.Template.Annotations == nil {
|
||||
w.job.Spec.Template.Annotations = make(map[string]string)
|
||||
}
|
||||
return w.job.Spec.Template.Annotations
|
||||
}
|
||||
|
||||
func (w *JobWorkload) SetPodTemplateAnnotation(key, value string) {
|
||||
if w.job.Spec.Template.Annotations == nil {
|
||||
w.job.Spec.Template.Annotations = make(map[string]string)
|
||||
}
|
||||
w.job.Spec.Template.Annotations[key] = value
|
||||
}
|
||||
|
||||
func (w *JobWorkload) GetContainers() []corev1.Container {
|
||||
return w.job.Spec.Template.Spec.Containers
|
||||
}
|
||||
|
||||
func (w *JobWorkload) SetContainers(containers []corev1.Container) {
|
||||
w.job.Spec.Template.Spec.Containers = containers
|
||||
}
|
||||
|
||||
func (w *JobWorkload) GetInitContainers() []corev1.Container {
|
||||
return w.job.Spec.Template.Spec.InitContainers
|
||||
}
|
||||
|
||||
func (w *JobWorkload) SetInitContainers(containers []corev1.Container) {
|
||||
w.job.Spec.Template.Spec.InitContainers = containers
|
||||
}
|
||||
|
||||
func (w *JobWorkload) GetVolumes() []corev1.Volume {
|
||||
return w.job.Spec.Template.Spec.Volumes
|
||||
}
|
||||
|
||||
// Update for Job is a no-op - use RecreateJob instead.
|
||||
// Jobs trigger reloads by being deleted and recreated.
|
||||
func (w *JobWorkload) Update(ctx context.Context, c client.Client) error {
|
||||
// Jobs don't get updated directly - they are deleted and recreated
|
||||
// This is handled by the reload package's special Job logic
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *JobWorkload) DeepCopy() Workload {
|
||||
return &JobWorkload{job: w.job.DeepCopy()}
|
||||
}
|
||||
|
||||
func (w *JobWorkload) GetEnvFromSources() []corev1.EnvFromSource {
|
||||
var sources []corev1.EnvFromSource
|
||||
for _, container := range w.job.Spec.Template.Spec.Containers {
|
||||
sources = append(sources, container.EnvFrom...)
|
||||
}
|
||||
for _, container := range w.job.Spec.Template.Spec.InitContainers {
|
||||
sources = append(sources, container.EnvFrom...)
|
||||
}
|
||||
return sources
|
||||
}
|
||||
|
||||
func (w *JobWorkload) UsesConfigMap(name string) bool {
|
||||
// Check volumes
|
||||
for _, vol := range w.job.Spec.Template.Spec.Volumes {
|
||||
if vol.ConfigMap != nil && vol.ConfigMap.Name == name {
|
||||
return true
|
||||
}
|
||||
if vol.Projected != nil {
|
||||
for _, source := range vol.Projected.Sources {
|
||||
if source.ConfigMap != nil && source.ConfigMap.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check containers
|
||||
for _, container := range w.job.Spec.Template.Spec.Containers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.ConfigMapRef != nil && envFrom.ConfigMapRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.ConfigMapKeyRef != nil && env.ValueFrom.ConfigMapKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check init containers
|
||||
for _, container := range w.job.Spec.Template.Spec.InitContainers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.ConfigMapRef != nil && envFrom.ConfigMapRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.ConfigMapKeyRef != nil && env.ValueFrom.ConfigMapKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *JobWorkload) UsesSecret(name string) bool {
|
||||
// Check volumes
|
||||
for _, vol := range w.job.Spec.Template.Spec.Volumes {
|
||||
if vol.Secret != nil && vol.Secret.SecretName == name {
|
||||
return true
|
||||
}
|
||||
if vol.Projected != nil {
|
||||
for _, source := range vol.Projected.Sources {
|
||||
if source.Secret != nil && source.Secret.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check containers
|
||||
for _, container := range w.job.Spec.Template.Spec.Containers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.SecretRef != nil && envFrom.SecretRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil && env.ValueFrom.SecretKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check init containers
|
||||
for _, container := range w.job.Spec.Template.Spec.InitContainers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.SecretRef != nil && envFrom.SecretRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil && env.ValueFrom.SecretKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *JobWorkload) GetOwnerReferences() []metav1.OwnerReference {
|
||||
return w.job.OwnerReferences
|
||||
}
|
||||
|
||||
// GetJob returns the underlying Job for special handling.
|
||||
func (w *JobWorkload) GetJob() *batchv1.Job {
|
||||
return w.job
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package workload
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
// Registry provides factory methods for creating Workload instances.
|
||||
type Registry struct {
|
||||
argoRolloutsEnabled bool
|
||||
}
|
||||
|
||||
// NewRegistry creates a new workload registry.
|
||||
func NewRegistry(argoRolloutsEnabled bool) *Registry {
|
||||
return &Registry{
|
||||
argoRolloutsEnabled: argoRolloutsEnabled,
|
||||
}
|
||||
}
|
||||
|
||||
// SupportedKinds returns all supported workload kinds.
|
||||
func (r *Registry) SupportedKinds() []Kind {
|
||||
kinds := []Kind{
|
||||
KindDeployment,
|
||||
KindDaemonSet,
|
||||
KindStatefulSet,
|
||||
KindJob,
|
||||
KindCronJob,
|
||||
}
|
||||
if r.argoRolloutsEnabled {
|
||||
kinds = append(kinds, KindArgoRollout)
|
||||
}
|
||||
return kinds
|
||||
}
|
||||
|
||||
// FromObject creates a WorkloadAccessor from a Kubernetes object.
|
||||
func (r *Registry) FromObject(obj client.Object) (WorkloadAccessor, error) {
|
||||
switch o := obj.(type) {
|
||||
case *appsv1.Deployment:
|
||||
return NewDeploymentWorkload(o), nil
|
||||
case *appsv1.DaemonSet:
|
||||
return NewDaemonSetWorkload(o), nil
|
||||
case *appsv1.StatefulSet:
|
||||
return NewStatefulSetWorkload(o), nil
|
||||
case *batchv1.Job:
|
||||
return NewJobWorkload(o), nil
|
||||
case *batchv1.CronJob:
|
||||
return NewCronJobWorkload(o), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported object type: %T", obj)
|
||||
}
|
||||
}
|
||||
|
||||
// KindFromString converts a string to a Kind.
|
||||
func KindFromString(s string) (Kind, error) {
|
||||
switch s {
|
||||
case "Deployment", "deployment", "deployments":
|
||||
return KindDeployment, nil
|
||||
case "DaemonSet", "daemonset", "daemonsets":
|
||||
return KindDaemonSet, nil
|
||||
case "StatefulSet", "statefulset", "statefulsets":
|
||||
return KindStatefulSet, nil
|
||||
case "Rollout", "rollout", "rollouts":
|
||||
return KindArgoRollout, nil
|
||||
case "Job", "job", "jobs":
|
||||
return KindJob, nil
|
||||
case "CronJob", "cronjob", "cronjobs":
|
||||
return KindCronJob, nil
|
||||
default:
|
||||
return "", fmt.Errorf("unknown workload kind: %s", s)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
package workload
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
// StatefulSetWorkload wraps a Kubernetes StatefulSet.
|
||||
type StatefulSetWorkload struct {
|
||||
statefulset *appsv1.StatefulSet
|
||||
}
|
||||
|
||||
// NewStatefulSetWorkload creates a new StatefulSetWorkload.
|
||||
func NewStatefulSetWorkload(s *appsv1.StatefulSet) *StatefulSetWorkload {
|
||||
return &StatefulSetWorkload{statefulset: s}
|
||||
}
|
||||
|
||||
// Ensure StatefulSetWorkload implements WorkloadAccessor.
|
||||
var _ WorkloadAccessor = (*StatefulSetWorkload)(nil)
|
||||
|
||||
func (w *StatefulSetWorkload) Kind() Kind {
|
||||
return KindStatefulSet
|
||||
}
|
||||
|
||||
func (w *StatefulSetWorkload) GetObject() client.Object {
|
||||
return w.statefulset
|
||||
}
|
||||
|
||||
func (w *StatefulSetWorkload) GetName() string {
|
||||
return w.statefulset.Name
|
||||
}
|
||||
|
||||
func (w *StatefulSetWorkload) GetNamespace() string {
|
||||
return w.statefulset.Namespace
|
||||
}
|
||||
|
||||
func (w *StatefulSetWorkload) GetAnnotations() map[string]string {
|
||||
return w.statefulset.Annotations
|
||||
}
|
||||
|
||||
func (w *StatefulSetWorkload) GetPodTemplateAnnotations() map[string]string {
|
||||
if w.statefulset.Spec.Template.Annotations == nil {
|
||||
w.statefulset.Spec.Template.Annotations = make(map[string]string)
|
||||
}
|
||||
return w.statefulset.Spec.Template.Annotations
|
||||
}
|
||||
|
||||
func (w *StatefulSetWorkload) SetPodTemplateAnnotation(key, value string) {
|
||||
if w.statefulset.Spec.Template.Annotations == nil {
|
||||
w.statefulset.Spec.Template.Annotations = make(map[string]string)
|
||||
}
|
||||
w.statefulset.Spec.Template.Annotations[key] = value
|
||||
}
|
||||
|
||||
func (w *StatefulSetWorkload) GetContainers() []corev1.Container {
|
||||
return w.statefulset.Spec.Template.Spec.Containers
|
||||
}
|
||||
|
||||
func (w *StatefulSetWorkload) SetContainers(containers []corev1.Container) {
|
||||
w.statefulset.Spec.Template.Spec.Containers = containers
|
||||
}
|
||||
|
||||
func (w *StatefulSetWorkload) GetInitContainers() []corev1.Container {
|
||||
return w.statefulset.Spec.Template.Spec.InitContainers
|
||||
}
|
||||
|
||||
func (w *StatefulSetWorkload) SetInitContainers(containers []corev1.Container) {
|
||||
w.statefulset.Spec.Template.Spec.InitContainers = containers
|
||||
}
|
||||
|
||||
func (w *StatefulSetWorkload) GetVolumes() []corev1.Volume {
|
||||
return w.statefulset.Spec.Template.Spec.Volumes
|
||||
}
|
||||
|
||||
func (w *StatefulSetWorkload) Update(ctx context.Context, c client.Client) error {
|
||||
return c.Update(ctx, w.statefulset)
|
||||
}
|
||||
|
||||
func (w *StatefulSetWorkload) DeepCopy() Workload {
|
||||
return &StatefulSetWorkload{statefulset: w.statefulset.DeepCopy()}
|
||||
}
|
||||
|
||||
func (w *StatefulSetWorkload) GetEnvFromSources() []corev1.EnvFromSource {
|
||||
var sources []corev1.EnvFromSource
|
||||
for _, container := range w.statefulset.Spec.Template.Spec.Containers {
|
||||
sources = append(sources, container.EnvFrom...)
|
||||
}
|
||||
for _, container := range w.statefulset.Spec.Template.Spec.InitContainers {
|
||||
sources = append(sources, container.EnvFrom...)
|
||||
}
|
||||
return sources
|
||||
}
|
||||
|
||||
func (w *StatefulSetWorkload) UsesConfigMap(name string) bool {
|
||||
// Check volumes
|
||||
for _, vol := range w.statefulset.Spec.Template.Spec.Volumes {
|
||||
if vol.ConfigMap != nil && vol.ConfigMap.Name == name {
|
||||
return true
|
||||
}
|
||||
if vol.Projected != nil {
|
||||
for _, source := range vol.Projected.Sources {
|
||||
if source.ConfigMap != nil && source.ConfigMap.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check envFrom
|
||||
for _, container := range w.statefulset.Spec.Template.Spec.Containers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.ConfigMapRef != nil && envFrom.ConfigMapRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.ConfigMapKeyRef != nil && env.ValueFrom.ConfigMapKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check init containers
|
||||
for _, container := range w.statefulset.Spec.Template.Spec.InitContainers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.ConfigMapRef != nil && envFrom.ConfigMapRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.ConfigMapKeyRef != nil && env.ValueFrom.ConfigMapKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *StatefulSetWorkload) UsesSecret(name string) bool {
|
||||
// Check volumes
|
||||
for _, vol := range w.statefulset.Spec.Template.Spec.Volumes {
|
||||
if vol.Secret != nil && vol.Secret.SecretName == name {
|
||||
return true
|
||||
}
|
||||
if vol.Projected != nil {
|
||||
for _, source := range vol.Projected.Sources {
|
||||
if source.Secret != nil && source.Secret.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check envFrom
|
||||
for _, container := range w.statefulset.Spec.Template.Spec.Containers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.SecretRef != nil && envFrom.SecretRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil && env.ValueFrom.SecretKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check init containers
|
||||
for _, container := range w.statefulset.Spec.Template.Spec.InitContainers {
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
if envFrom.SecretRef != nil && envFrom.SecretRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, env := range container.Env {
|
||||
if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil && env.ValueFrom.SecretKeyRef.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *StatefulSetWorkload) GetOwnerReferences() []metav1.OwnerReference {
|
||||
return w.statefulset.OwnerReferences
|
||||
}
|
||||
Reference in New Issue
Block a user