Files
Reloader/internal/pkg/callbacks/rolling_upgrade_test.go
faizanahmad055 0f1d02e975 Readme update and code refactor
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2026-01-04 02:40:42 +01:00

774 lines
26 KiB
Go

package callbacks_test
import (
"context"
"fmt"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
appsv1 "k8s.io/api/apps/v1"
batchv1 "k8s.io/api/batch/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
watch "k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/kubernetes/fake"
argorolloutv1alpha1 "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1"
fakeargoclientset "github.com/argoproj/argo-rollouts/pkg/client/clientset/versioned/fake"
patchtypes "k8s.io/apimachinery/pkg/types"
"github.com/stakater/Reloader/internal/pkg/callbacks"
"github.com/stakater/Reloader/internal/pkg/options"
"github.com/stakater/Reloader/internal/pkg/testutil"
"github.com/stakater/Reloader/pkg/kube"
)
var (
clients = setupTestClients()
)
type testFixtures struct {
defaultContainers []v1.Container
defaultInitContainers []v1.Container
defaultVolumes []v1.Volume
namespace string
}
func newTestFixtures() testFixtures {
return testFixtures{
defaultContainers: []v1.Container{{Name: "container1"}, {Name: "container2"}},
defaultInitContainers: []v1.Container{{Name: "init-container1"}, {Name: "init-container2"}},
defaultVolumes: []v1.Volume{{Name: "volume1"}, {Name: "volume2"}},
namespace: "default",
}
}
func setupTestClients() kube.Clients {
return kube.Clients{
KubernetesClient: fake.NewClientset(),
ArgoRolloutClient: fakeargoclientset.NewSimpleClientset(),
}
}
// TestUpdateRollout test update rollout strategy annotation
func TestUpdateRollout(t *testing.T) {
namespace := "test-ns"
cases := map[string]struct {
name string
strategy string
isRestart bool
}{
"test-without-strategy": {
name: "defaults to rollout strategy",
strategy: "",
isRestart: false,
},
"test-with-restart-strategy": {
name: "triggers a restart strategy",
strategy: "restart",
isRestart: true,
},
"test-with-rollout-strategy": {
name: "triggers a rollout strategy",
strategy: "rollout",
isRestart: false,
},
}
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
rollout, err := testutil.CreateRollout(
clients.ArgoRolloutClient, name, namespace,
map[string]string{options.RolloutStrategyAnnotation: tc.strategy},
)
if err != nil {
t.Errorf("creating rollout: %v", err)
}
modifiedChan := watchRollout(rollout.Name, namespace)
err = callbacks.UpdateRollout(clients, namespace, rollout)
if err != nil {
t.Errorf("updating rollout: %v", err)
}
rollout, err = clients.ArgoRolloutClient.ArgoprojV1alpha1().Rollouts(
namespace).Get(context.TODO(), rollout.Name, metav1.GetOptions{})
if err != nil {
t.Errorf("getting rollout: %v", err)
}
if isRestartStrategy(rollout) == tc.isRestart {
t.Errorf("Should not be a restart strategy")
}
select {
case <-modifiedChan:
// object has been modified
case <-time.After(1 * time.Second):
t.Errorf("Rollout has not been updated")
}
})
}
}
func TestPatchRollout(t *testing.T) {
namespace := "test-ns"
rollout := testutil.GetRollout(namespace, "test", map[string]string{options.RolloutStrategyAnnotation: ""})
err := callbacks.PatchRollout(clients, namespace, rollout, patchtypes.StrategicMergePatchType, []byte(`{"spec": {}}`))
assert.EqualError(t, err, "not supported patching: Rollout")
}
func TestResourceItem(t *testing.T) {
fixtures := newTestFixtures()
tests := []struct {
name string
createFunc func(kube.Clients, string, string) (runtime.Object, error)
getItemFunc func(kube.Clients, string, string) (runtime.Object, error)
deleteFunc func(kube.Clients, string, string) error
}{
{
name: "Deployment",
createFunc: createTestDeploymentWithAnnotations,
getItemFunc: callbacks.GetDeploymentItem,
deleteFunc: deleteTestDeployment,
},
{
name: "CronJob",
createFunc: createTestCronJobWithAnnotations,
getItemFunc: callbacks.GetCronJobItem,
deleteFunc: deleteTestCronJob,
},
{
name: "Job",
createFunc: createTestJobWithAnnotations,
getItemFunc: callbacks.GetJobItem,
deleteFunc: deleteTestJob,
},
{
name: "DaemonSet",
createFunc: createTestDaemonSetWithAnnotations,
getItemFunc: callbacks.GetDaemonSetItem,
deleteFunc: deleteTestDaemonSet,
},
{
name: "StatefulSet",
createFunc: createTestStatefulSetWithAnnotations,
getItemFunc: callbacks.GetStatefulSetItem,
deleteFunc: deleteTestStatefulSet,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
resource, err := tt.createFunc(clients, fixtures.namespace, "1")
assert.NoError(t, err)
accessor, err := meta.Accessor(resource)
assert.NoError(t, err)
_, err = tt.getItemFunc(clients, accessor.GetName(), fixtures.namespace)
assert.NoError(t, err)
err = tt.deleteFunc(clients, fixtures.namespace, accessor.GetName())
assert.NoError(t, err)
})
}
}
func TestResourceItems(t *testing.T) {
fixtures := newTestFixtures()
tests := []struct {
name string
createFunc func(kube.Clients, string) error
getItemsFunc func(kube.Clients, string) []runtime.Object
deleteFunc func(kube.Clients, string) error
expectedCount int
}{
{
name: "Deployments",
createFunc: createTestDeployments,
getItemsFunc: callbacks.GetDeploymentItems,
deleteFunc: deleteTestDeployments,
expectedCount: 2,
},
{
name: "CronJobs",
createFunc: createTestCronJobs,
getItemsFunc: callbacks.GetCronJobItems,
deleteFunc: deleteTestCronJobs,
expectedCount: 2,
},
{
name: "Jobs",
createFunc: createTestJobs,
getItemsFunc: callbacks.GetJobItems,
deleteFunc: deleteTestJobs,
expectedCount: 2,
},
{
name: "DaemonSets",
createFunc: createTestDaemonSets,
getItemsFunc: callbacks.GetDaemonSetItems,
deleteFunc: deleteTestDaemonSets,
expectedCount: 2,
},
{
name: "StatefulSets",
createFunc: createTestStatefulSets,
getItemsFunc: callbacks.GetStatefulSetItems,
deleteFunc: deleteTestStatefulSets,
expectedCount: 2,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.createFunc(clients, fixtures.namespace)
assert.NoError(t, err)
items := tt.getItemsFunc(clients, fixtures.namespace)
assert.Equal(t, tt.expectedCount, len(items))
})
}
}
func TestGetAnnotations(t *testing.T) {
testAnnotations := map[string]string{"version": "1"}
tests := []struct {
name string
resource runtime.Object
getFunc func(runtime.Object) map[string]string
}{
{"Deployment", &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Annotations: testAnnotations}}, callbacks.GetDeploymentAnnotations},
{"CronJob", &batchv1.CronJob{ObjectMeta: metav1.ObjectMeta{Annotations: testAnnotations}}, callbacks.GetCronJobAnnotations},
{"Job", &batchv1.Job{ObjectMeta: metav1.ObjectMeta{Annotations: testAnnotations}}, callbacks.GetJobAnnotations},
{"DaemonSet", &appsv1.DaemonSet{ObjectMeta: metav1.ObjectMeta{Annotations: testAnnotations}}, callbacks.GetDaemonSetAnnotations},
{"StatefulSet", &appsv1.StatefulSet{ObjectMeta: metav1.ObjectMeta{Annotations: testAnnotations}}, callbacks.GetStatefulSetAnnotations},
{"Rollout", &argorolloutv1alpha1.Rollout{ObjectMeta: metav1.ObjectMeta{Annotations: testAnnotations}}, callbacks.GetRolloutAnnotations},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, testAnnotations, tt.getFunc(tt.resource))
})
}
}
func TestGetPodAnnotations(t *testing.T) {
testAnnotations := map[string]string{"version": "1"}
tests := []struct {
name string
resource runtime.Object
getFunc func(runtime.Object) map[string]string
}{
{"Deployment", createResourceWithPodAnnotations(&appsv1.Deployment{}, testAnnotations), callbacks.GetDeploymentPodAnnotations},
{"CronJob", createResourceWithPodAnnotations(&batchv1.CronJob{}, testAnnotations), callbacks.GetCronJobPodAnnotations},
{"Job", createResourceWithPodAnnotations(&batchv1.Job{}, testAnnotations), callbacks.GetJobPodAnnotations},
{"DaemonSet", createResourceWithPodAnnotations(&appsv1.DaemonSet{}, testAnnotations), callbacks.GetDaemonSetPodAnnotations},
{"StatefulSet", createResourceWithPodAnnotations(&appsv1.StatefulSet{}, testAnnotations), callbacks.GetStatefulSetPodAnnotations},
{"Rollout", createResourceWithPodAnnotations(&argorolloutv1alpha1.Rollout{}, testAnnotations), callbacks.GetRolloutPodAnnotations},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, testAnnotations, tt.getFunc(tt.resource))
})
}
}
func TestGetContainers(t *testing.T) {
fixtures := newTestFixtures()
tests := []struct {
name string
resource runtime.Object
getFunc func(runtime.Object) []v1.Container
}{
{"Deployment", createResourceWithContainers(&appsv1.Deployment{}, fixtures.defaultContainers), callbacks.GetDeploymentContainers},
{"DaemonSet", createResourceWithContainers(&appsv1.DaemonSet{}, fixtures.defaultContainers), callbacks.GetDaemonSetContainers},
{"StatefulSet", createResourceWithContainers(&appsv1.StatefulSet{}, fixtures.defaultContainers), callbacks.GetStatefulSetContainers},
{"CronJob", createResourceWithContainers(&batchv1.CronJob{}, fixtures.defaultContainers), callbacks.GetCronJobContainers},
{"Job", createResourceWithContainers(&batchv1.Job{}, fixtures.defaultContainers), callbacks.GetJobContainers},
{"Rollout", createResourceWithContainers(&argorolloutv1alpha1.Rollout{}, fixtures.defaultContainers), callbacks.GetRolloutContainers},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, fixtures.defaultContainers, tt.getFunc(tt.resource))
})
}
}
func TestGetInitContainers(t *testing.T) {
fixtures := newTestFixtures()
tests := []struct {
name string
resource runtime.Object
getFunc func(runtime.Object) []v1.Container
}{
{"Deployment", createResourceWithInitContainers(&appsv1.Deployment{}, fixtures.defaultInitContainers), callbacks.GetDeploymentInitContainers},
{"DaemonSet", createResourceWithInitContainers(&appsv1.DaemonSet{}, fixtures.defaultInitContainers), callbacks.GetDaemonSetInitContainers},
{"StatefulSet", createResourceWithInitContainers(&appsv1.StatefulSet{}, fixtures.defaultInitContainers), callbacks.GetStatefulSetInitContainers},
{"CronJob", createResourceWithInitContainers(&batchv1.CronJob{}, fixtures.defaultInitContainers), callbacks.GetCronJobInitContainers},
{"Job", createResourceWithInitContainers(&batchv1.Job{}, fixtures.defaultInitContainers), callbacks.GetJobInitContainers},
{"Rollout", createResourceWithInitContainers(&argorolloutv1alpha1.Rollout{}, fixtures.defaultInitContainers), callbacks.GetRolloutInitContainers},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, fixtures.defaultInitContainers, tt.getFunc(tt.resource))
})
}
}
func TestUpdateResources(t *testing.T) {
fixtures := newTestFixtures()
tests := []struct {
name string
createFunc func(kube.Clients, string, string) (runtime.Object, error)
updateFunc func(kube.Clients, string, runtime.Object) error
deleteFunc func(kube.Clients, string, string) error
}{
{"Deployment", createTestDeploymentWithAnnotations, callbacks.UpdateDeployment, deleteTestDeployment},
{"DaemonSet", createTestDaemonSetWithAnnotations, callbacks.UpdateDaemonSet, deleteTestDaemonSet},
{"StatefulSet", createTestStatefulSetWithAnnotations, callbacks.UpdateStatefulSet, deleteTestStatefulSet},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
resource, err := tt.createFunc(clients, fixtures.namespace, "1")
assert.NoError(t, err)
err = tt.updateFunc(clients, fixtures.namespace, resource)
assert.NoError(t, err)
accessor, err := meta.Accessor(resource)
assert.NoError(t, err)
err = tt.deleteFunc(clients, fixtures.namespace, accessor.GetName())
assert.NoError(t, err)
})
}
}
func TestPatchResources(t *testing.T) {
fixtures := newTestFixtures()
tests := []struct {
name string
createFunc func(kube.Clients, string, string) (runtime.Object, error)
patchFunc func(kube.Clients, string, runtime.Object, patchtypes.PatchType, []byte) error
deleteFunc func(kube.Clients, string, string) error
assertFunc func(err error)
}{
{"Deployment", createTestDeploymentWithAnnotations, callbacks.PatchDeployment, deleteTestDeployment, func(err error) {
assert.NoError(t, err)
patchedResource, err := callbacks.GetDeploymentItem(clients, "test-deployment", fixtures.namespace)
assert.NoError(t, err)
assert.Equal(t, "test", patchedResource.(*appsv1.Deployment).Annotations["test"])
}},
{"DaemonSet", createTestDaemonSetWithAnnotations, callbacks.PatchDaemonSet, deleteTestDaemonSet, func(err error) {
assert.NoError(t, err)
patchedResource, err := callbacks.GetDaemonSetItem(clients, "test-daemonset", fixtures.namespace)
assert.NoError(t, err)
assert.Equal(t, "test", patchedResource.(*appsv1.DaemonSet).Annotations["test"])
}},
{"StatefulSet", createTestStatefulSetWithAnnotations, callbacks.PatchStatefulSet, deleteTestStatefulSet, func(err error) {
assert.NoError(t, err)
patchedResource, err := callbacks.GetStatefulSetItem(clients, "test-statefulset", fixtures.namespace)
assert.NoError(t, err)
assert.Equal(t, "test", patchedResource.(*appsv1.StatefulSet).Annotations["test"])
}},
{"CronJob", createTestCronJobWithAnnotations, callbacks.PatchCronJob, deleteTestCronJob, func(err error) {
assert.EqualError(t, err, "not supported patching: CronJob")
}},
{"Job", createTestJobWithAnnotations, callbacks.PatchJob, deleteTestJob, func(err error) {
assert.EqualError(t, err, "not supported patching: Job")
}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
resource, err := tt.createFunc(clients, fixtures.namespace, "1")
assert.NoError(t, err)
err = tt.patchFunc(clients, fixtures.namespace, resource, patchtypes.StrategicMergePatchType, []byte(`{"metadata":{"annotations":{"test":"test"}}}`))
tt.assertFunc(err)
accessor, err := meta.Accessor(resource)
assert.NoError(t, err)
err = tt.deleteFunc(clients, fixtures.namespace, accessor.GetName())
assert.NoError(t, err)
})
}
}
func TestCreateJobFromCronjob(t *testing.T) {
fixtures := newTestFixtures()
runtimeObj, err := createTestCronJobWithAnnotations(clients, fixtures.namespace, "1")
assert.NoError(t, err)
cronJob := runtimeObj.(*batchv1.CronJob)
err = callbacks.CreateJobFromCronjob(clients, fixtures.namespace, cronJob)
assert.NoError(t, err)
jobList, err := clients.KubernetesClient.BatchV1().Jobs(fixtures.namespace).List(context.TODO(), metav1.ListOptions{})
assert.NoError(t, err)
ownerFound := false
for _, job := range jobList.Items {
if isControllerOwner("CronJob", cronJob.Name, job.OwnerReferences) {
ownerFound = true
break
}
}
assert.Truef(t, ownerFound, "Missing CronJob owner reference")
err = deleteTestCronJob(clients, fixtures.namespace, cronJob.Name)
assert.NoError(t, err)
}
func TestReCreateJobFromJob(t *testing.T) {
fixtures := newTestFixtures()
job, err := createTestJobWithAnnotations(clients, fixtures.namespace, "1")
assert.NoError(t, err)
err = callbacks.ReCreateJobFromjob(clients, fixtures.namespace, job.(*batchv1.Job))
assert.NoError(t, err)
err = deleteTestJob(clients, fixtures.namespace, "test-job")
assert.NoError(t, err)
}
func TestGetVolumes(t *testing.T) {
fixtures := newTestFixtures()
tests := []struct {
name string
resource runtime.Object
getFunc func(runtime.Object) []v1.Volume
}{
{"Deployment", createResourceWithVolumes(&appsv1.Deployment{}, fixtures.defaultVolumes), callbacks.GetDeploymentVolumes},
{"CronJob", createResourceWithVolumes(&batchv1.CronJob{}, fixtures.defaultVolumes), callbacks.GetCronJobVolumes},
{"Job", createResourceWithVolumes(&batchv1.Job{}, fixtures.defaultVolumes), callbacks.GetJobVolumes},
{"DaemonSet", createResourceWithVolumes(&appsv1.DaemonSet{}, fixtures.defaultVolumes), callbacks.GetDaemonSetVolumes},
{"StatefulSet", createResourceWithVolumes(&appsv1.StatefulSet{}, fixtures.defaultVolumes), callbacks.GetStatefulSetVolumes},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, fixtures.defaultVolumes, tt.getFunc(tt.resource))
})
}
}
func TesGetPatchTemplateAnnotation(t *testing.T) {
templates := callbacks.GetPatchTemplates()
assert.NotEmpty(t, templates.AnnotationTemplate)
assert.Equal(t, 2, strings.Count(templates.AnnotationTemplate, "%s"))
}
func TestGetPatchTemplateEnvVar(t *testing.T) {
templates := callbacks.GetPatchTemplates()
assert.NotEmpty(t, templates.EnvVarTemplate)
assert.Equal(t, 3, strings.Count(templates.EnvVarTemplate, "%s"))
}
func TestGetPatchDeleteTemplateEnvVar(t *testing.T) {
templates := callbacks.GetPatchTemplates()
assert.NotEmpty(t, templates.DeleteEnvVarTemplate)
assert.Equal(t, 2, strings.Count(templates.DeleteEnvVarTemplate, "%d"))
}
// Helper functions
func isRestartStrategy(rollout *argorolloutv1alpha1.Rollout) bool {
return rollout.Spec.RestartAt == nil
}
func watchRollout(name, namespace string) chan interface{} {
timeOut := int64(1)
modifiedChan := make(chan interface{})
watcher, _ := clients.ArgoRolloutClient.ArgoprojV1alpha1().Rollouts(namespace).Watch(context.Background(), metav1.ListOptions{TimeoutSeconds: &timeOut})
go watchModified(watcher, name, modifiedChan)
return modifiedChan
}
func watchModified(watcher watch.Interface, name string, modifiedChan chan interface{}) {
for event := range watcher.ResultChan() {
item := event.Object.(*argorolloutv1alpha1.Rollout)
if item.Name == name {
switch event.Type {
case watch.Modified:
modifiedChan <- nil
}
return
}
}
}
func createTestDeployments(clients kube.Clients, namespace string) error {
for i := 1; i <= 2; i++ {
_, err := testutil.CreateDeployment(clients.KubernetesClient, fmt.Sprintf("test-deployment-%d", i), namespace, false)
if err != nil {
return err
}
}
return nil
}
func deleteTestDeployments(clients kube.Clients, namespace string) error {
for i := 1; i <= 2; i++ {
err := testutil.DeleteDeployment(clients.KubernetesClient, namespace, fmt.Sprintf("test-deployment-%d", i))
if err != nil {
return err
}
}
return nil
}
func createTestCronJobs(clients kube.Clients, namespace string) error {
for i := 1; i <= 2; i++ {
_, err := testutil.CreateCronJob(clients.KubernetesClient, fmt.Sprintf("test-cron-%d", i), namespace, false)
if err != nil {
return err
}
}
return nil
}
func deleteTestCronJobs(clients kube.Clients, namespace string) error {
for i := 1; i <= 2; i++ {
err := testutil.DeleteCronJob(clients.KubernetesClient, namespace, fmt.Sprintf("test-cron-%d", i))
if err != nil {
return err
}
}
return nil
}
func createTestJobs(clients kube.Clients, namespace string) error {
for i := 1; i <= 2; i++ {
_, err := testutil.CreateJob(clients.KubernetesClient, fmt.Sprintf("test-job-%d", i), namespace, false)
if err != nil {
return err
}
}
return nil
}
func deleteTestJobs(clients kube.Clients, namespace string) error {
for i := 1; i <= 2; i++ {
err := testutil.DeleteJob(clients.KubernetesClient, namespace, fmt.Sprintf("test-job-%d", i))
if err != nil {
return err
}
}
return nil
}
func createTestDaemonSets(clients kube.Clients, namespace string) error {
for i := 1; i <= 2; i++ {
_, err := testutil.CreateDaemonSet(clients.KubernetesClient, fmt.Sprintf("test-daemonset-%d", i), namespace, false)
if err != nil {
return err
}
}
return nil
}
func deleteTestDaemonSets(clients kube.Clients, namespace string) error {
for i := 1; i <= 2; i++ {
err := testutil.DeleteDaemonSet(clients.KubernetesClient, namespace, fmt.Sprintf("test-daemonset-%d", i))
if err != nil {
return err
}
}
return nil
}
func createTestStatefulSets(clients kube.Clients, namespace string) error {
for i := 1; i <= 2; i++ {
_, err := testutil.CreateStatefulSet(clients.KubernetesClient, fmt.Sprintf("test-statefulset-%d", i), namespace, false)
if err != nil {
return err
}
}
return nil
}
func deleteTestStatefulSets(clients kube.Clients, namespace string) error {
for i := 1; i <= 2; i++ {
err := testutil.DeleteStatefulSet(clients.KubernetesClient, namespace, fmt.Sprintf("test-statefulset-%d", i))
if err != nil {
return err
}
}
return nil
}
func createResourceWithPodAnnotations(obj runtime.Object, annotations map[string]string) runtime.Object {
switch v := obj.(type) {
case *appsv1.Deployment:
v.Spec.Template.Annotations = annotations
case *appsv1.DaemonSet:
v.Spec.Template.Annotations = annotations
case *appsv1.StatefulSet:
v.Spec.Template.Annotations = annotations
case *batchv1.CronJob:
v.Spec.JobTemplate.Spec.Template.Annotations = annotations
case *batchv1.Job:
v.Spec.Template.Annotations = annotations
case *argorolloutv1alpha1.Rollout:
v.Spec.Template.Annotations = annotations
}
return obj
}
func createResourceWithContainers(obj runtime.Object, containers []v1.Container) runtime.Object {
switch v := obj.(type) {
case *appsv1.Deployment:
v.Spec.Template.Spec.Containers = containers
case *appsv1.DaemonSet:
v.Spec.Template.Spec.Containers = containers
case *appsv1.StatefulSet:
v.Spec.Template.Spec.Containers = containers
case *batchv1.CronJob:
v.Spec.JobTemplate.Spec.Template.Spec.Containers = containers
case *batchv1.Job:
v.Spec.Template.Spec.Containers = containers
case *argorolloutv1alpha1.Rollout:
v.Spec.Template.Spec.Containers = containers
}
return obj
}
func createResourceWithInitContainers(obj runtime.Object, initContainers []v1.Container) runtime.Object {
switch v := obj.(type) {
case *appsv1.Deployment:
v.Spec.Template.Spec.InitContainers = initContainers
case *appsv1.DaemonSet:
v.Spec.Template.Spec.InitContainers = initContainers
case *appsv1.StatefulSet:
v.Spec.Template.Spec.InitContainers = initContainers
case *batchv1.CronJob:
v.Spec.JobTemplate.Spec.Template.Spec.InitContainers = initContainers
case *batchv1.Job:
v.Spec.Template.Spec.InitContainers = initContainers
case *argorolloutv1alpha1.Rollout:
v.Spec.Template.Spec.InitContainers = initContainers
}
return obj
}
func createResourceWithVolumes(obj runtime.Object, volumes []v1.Volume) runtime.Object {
switch v := obj.(type) {
case *appsv1.Deployment:
v.Spec.Template.Spec.Volumes = volumes
case *batchv1.CronJob:
v.Spec.JobTemplate.Spec.Template.Spec.Volumes = volumes
case *batchv1.Job:
v.Spec.Template.Spec.Volumes = volumes
case *appsv1.DaemonSet:
v.Spec.Template.Spec.Volumes = volumes
case *appsv1.StatefulSet:
v.Spec.Template.Spec.Volumes = volumes
}
return obj
}
func createTestDeploymentWithAnnotations(clients kube.Clients, namespace, version string) (runtime.Object, error) {
deployment := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "test-deployment",
Namespace: namespace,
Annotations: map[string]string{"version": version},
},
}
return clients.KubernetesClient.AppsV1().Deployments(namespace).Create(context.TODO(), deployment, metav1.CreateOptions{})
}
func deleteTestDeployment(clients kube.Clients, namespace, name string) error {
return clients.KubernetesClient.AppsV1().Deployments(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
}
func createTestDaemonSetWithAnnotations(clients kube.Clients, namespace, version string) (runtime.Object, error) {
daemonSet := &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{
Name: "test-daemonset",
Namespace: namespace,
Annotations: map[string]string{"version": version},
},
}
return clients.KubernetesClient.AppsV1().DaemonSets(namespace).Create(context.TODO(), daemonSet, metav1.CreateOptions{})
}
func deleteTestDaemonSet(clients kube.Clients, namespace, name string) error {
return clients.KubernetesClient.AppsV1().DaemonSets(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
}
func createTestStatefulSetWithAnnotations(clients kube.Clients, namespace, version string) (runtime.Object, error) {
statefulSet := &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
Name: "test-statefulset",
Namespace: namespace,
Annotations: map[string]string{"version": version},
},
}
return clients.KubernetesClient.AppsV1().StatefulSets(namespace).Create(context.TODO(), statefulSet, metav1.CreateOptions{})
}
func deleteTestStatefulSet(clients kube.Clients, namespace, name string) error {
return clients.KubernetesClient.AppsV1().StatefulSets(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
}
func createTestCronJobWithAnnotations(clients kube.Clients, namespace, version string) (runtime.Object, error) {
cronJob := &batchv1.CronJob{
ObjectMeta: metav1.ObjectMeta{
Name: "test-cronjob",
Namespace: namespace,
Annotations: map[string]string{"version": version},
},
}
return clients.KubernetesClient.BatchV1().CronJobs(namespace).Create(context.TODO(), cronJob, metav1.CreateOptions{})
}
func deleteTestCronJob(clients kube.Clients, namespace, name string) error {
return clients.KubernetesClient.BatchV1().CronJobs(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
}
func createTestJobWithAnnotations(clients kube.Clients, namespace, version string) (runtime.Object, error) {
job := &batchv1.Job{
ObjectMeta: metav1.ObjectMeta{
Name: "test-job",
Namespace: namespace,
Annotations: map[string]string{"version": version},
},
}
return clients.KubernetesClient.BatchV1().Jobs(namespace).Create(context.TODO(), job, metav1.CreateOptions{})
}
func deleteTestJob(clients kube.Clients, namespace, name string) error {
return clients.KubernetesClient.BatchV1().Jobs(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
}
func isControllerOwner(kind, name string, ownerRefs []metav1.OwnerReference) bool {
for _, ownerRef := range ownerRefs {
if *ownerRef.Controller && ownerRef.Kind == kind && ownerRef.Name == name {
return true
}
}
return false
}