mirror of
https://github.com/stakater/Reloader.git
synced 2026-08-20 12:36:26 +00:00
187 lines
5.3 KiB
Go
187 lines
5.3 KiB
Go
package workload
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
argorolloutv1alpha1 "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1"
|
|
corev1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
)
|
|
|
|
// RolloutStrategy defines how Argo Rollouts are updated.
|
|
type RolloutStrategy string
|
|
|
|
const (
|
|
// RolloutStrategyRollout performs a standard rollout update.
|
|
RolloutStrategyRollout RolloutStrategy = "rollout"
|
|
|
|
// RolloutStrategyRestart sets the restartAt field to trigger a restart.
|
|
RolloutStrategyRestart RolloutStrategy = "restart"
|
|
)
|
|
|
|
// RolloutStrategyAnnotation is the annotation key for specifying the rollout strategy.
|
|
const RolloutStrategyAnnotation = "reloader.stakater.com/rollout-strategy"
|
|
|
|
// RolloutWorkload wraps an Argo Rollout.
|
|
type RolloutWorkload struct {
|
|
rollout *argorolloutv1alpha1.Rollout
|
|
}
|
|
|
|
// NewRolloutWorkload creates a new RolloutWorkload.
|
|
func NewRolloutWorkload(r *argorolloutv1alpha1.Rollout) *RolloutWorkload {
|
|
return &RolloutWorkload{rollout: r}
|
|
}
|
|
|
|
// Ensure RolloutWorkload implements WorkloadAccessor.
|
|
var _ WorkloadAccessor = (*RolloutWorkload)(nil)
|
|
|
|
func (w *RolloutWorkload) Kind() Kind {
|
|
return KindArgoRollout
|
|
}
|
|
|
|
func (w *RolloutWorkload) GetObject() client.Object {
|
|
return w.rollout
|
|
}
|
|
|
|
func (w *RolloutWorkload) GetName() string {
|
|
return w.rollout.Name
|
|
}
|
|
|
|
func (w *RolloutWorkload) GetNamespace() string {
|
|
return w.rollout.Namespace
|
|
}
|
|
|
|
func (w *RolloutWorkload) GetAnnotations() map[string]string {
|
|
return w.rollout.Annotations
|
|
}
|
|
|
|
func (w *RolloutWorkload) GetPodTemplateAnnotations() map[string]string {
|
|
if w.rollout.Spec.Template.Annotations == nil {
|
|
w.rollout.Spec.Template.Annotations = make(map[string]string)
|
|
}
|
|
return w.rollout.Spec.Template.Annotations
|
|
}
|
|
|
|
func (w *RolloutWorkload) SetPodTemplateAnnotation(key, value string) {
|
|
if w.rollout.Spec.Template.Annotations == nil {
|
|
w.rollout.Spec.Template.Annotations = make(map[string]string)
|
|
}
|
|
w.rollout.Spec.Template.Annotations[key] = value
|
|
}
|
|
|
|
func (w *RolloutWorkload) GetContainers() []corev1.Container {
|
|
return w.rollout.Spec.Template.Spec.Containers
|
|
}
|
|
|
|
func (w *RolloutWorkload) SetContainers(containers []corev1.Container) {
|
|
w.rollout.Spec.Template.Spec.Containers = containers
|
|
}
|
|
|
|
func (w *RolloutWorkload) GetInitContainers() []corev1.Container {
|
|
return w.rollout.Spec.Template.Spec.InitContainers
|
|
}
|
|
|
|
func (w *RolloutWorkload) SetInitContainers(containers []corev1.Container) {
|
|
w.rollout.Spec.Template.Spec.InitContainers = containers
|
|
}
|
|
|
|
func (w *RolloutWorkload) GetVolumes() []corev1.Volume {
|
|
return w.rollout.Spec.Template.Spec.Volumes
|
|
}
|
|
|
|
// Update updates the Rollout. It uses the rollout strategy annotation to determine
|
|
// whether to do a standard rollout or set the restartAt field.
|
|
func (w *RolloutWorkload) Update(ctx context.Context, c client.Client) error {
|
|
strategy := w.getStrategy()
|
|
switch strategy {
|
|
case RolloutStrategyRestart:
|
|
// Use merge patch to set restartAt field
|
|
restartAt := metav1.NewTime(time.Now())
|
|
w.rollout.Spec.RestartAt = &restartAt
|
|
}
|
|
// For both strategies, we update the rollout (annotations have already been set)
|
|
return c.Update(ctx, w.rollout)
|
|
}
|
|
|
|
// getStrategy returns the rollout strategy from the annotation.
|
|
func (w *RolloutWorkload) getStrategy() RolloutStrategy {
|
|
annotations := w.rollout.GetAnnotations()
|
|
if annotations == nil {
|
|
return RolloutStrategyRollout
|
|
}
|
|
strategy := annotations[RolloutStrategyAnnotation]
|
|
switch RolloutStrategy(strategy) {
|
|
case RolloutStrategyRestart:
|
|
return RolloutStrategyRestart
|
|
default:
|
|
return RolloutStrategyRollout
|
|
}
|
|
}
|
|
|
|
func (w *RolloutWorkload) DeepCopy() Workload {
|
|
return &RolloutWorkload{rollout: w.rollout.DeepCopy()}
|
|
}
|
|
|
|
func (w *RolloutWorkload) GetEnvFromSources() []corev1.EnvFromSource {
|
|
var sources []corev1.EnvFromSource
|
|
for _, container := range w.rollout.Spec.Template.Spec.Containers {
|
|
sources = append(sources, container.EnvFrom...)
|
|
}
|
|
for _, container := range w.rollout.Spec.Template.Spec.InitContainers {
|
|
sources = append(sources, container.EnvFrom...)
|
|
}
|
|
return sources
|
|
}
|
|
|
|
func (w *RolloutWorkload) UsesConfigMap(name string) bool {
|
|
return SpecUsesConfigMap(&w.rollout.Spec.Template.Spec, name)
|
|
}
|
|
|
|
func (w *RolloutWorkload) UsesSecret(name string) bool {
|
|
return SpecUsesSecret(&w.rollout.Spec.Template.Spec, name)
|
|
}
|
|
|
|
func (w *RolloutWorkload) GetOwnerReferences() []metav1.OwnerReference {
|
|
return w.rollout.OwnerReferences
|
|
}
|
|
|
|
// GetRollout returns the underlying Rollout for special handling.
|
|
func (w *RolloutWorkload) GetRollout() *argorolloutv1alpha1.Rollout {
|
|
return w.rollout
|
|
}
|
|
|
|
// GetStrategy returns the configured rollout strategy.
|
|
func (w *RolloutWorkload) GetStrategy() RolloutStrategy {
|
|
return w.getStrategy()
|
|
}
|
|
|
|
// String returns a string representation of the strategy.
|
|
func (s RolloutStrategy) String() string {
|
|
return string(s)
|
|
}
|
|
|
|
// ToRolloutStrategy converts a string to RolloutStrategy.
|
|
func ToRolloutStrategy(s string) RolloutStrategy {
|
|
switch RolloutStrategy(s) {
|
|
case RolloutStrategyRestart:
|
|
return RolloutStrategyRestart
|
|
case RolloutStrategyRollout:
|
|
return RolloutStrategyRollout
|
|
default:
|
|
return RolloutStrategyRollout
|
|
}
|
|
}
|
|
|
|
// Validate checks if the rollout strategy is valid.
|
|
func (s RolloutStrategy) Validate() error {
|
|
switch s {
|
|
case RolloutStrategyRollout, RolloutStrategyRestart:
|
|
return nil
|
|
default:
|
|
return fmt.Errorf("invalid rollout strategy: %s", s)
|
|
}
|
|
}
|