diff --git a/charts/dioscuri-0.1.5.tgz b/charts/dioscuri-0.1.5.tgz new file mode 100644 index 0000000..94d6d65 Binary files /dev/null and b/charts/dioscuri-0.1.5.tgz differ diff --git a/charts/dioscuri/Chart.yaml b/charts/dioscuri/Chart.yaml index c960ecf..bfab034 100644 --- a/charts/dioscuri/Chart.yaml +++ b/charts/dioscuri/Chart.yaml @@ -14,8 +14,8 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. -version: 0.1.4 +version: 0.1.5 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. -appVersion: 0.1.6 +appVersion: 0.1.7 diff --git a/charts/dioscuri/values.yaml b/charts/dioscuri/values.yaml index bfa4ea4..e6af17c 100644 --- a/charts/dioscuri/values.yaml +++ b/charts/dioscuri/values.yaml @@ -6,7 +6,7 @@ replicaCount: 1 image: repository: amazeeio/dioscuri - tag: v0.1.6 + tag: v0.1.7 pullPolicy: IfNotPresent kubeRbacProxy: diff --git a/charts/index.yaml b/charts/index.yaml index 86f0bd9..7775202 100644 --- a/charts/index.yaml +++ b/charts/index.yaml @@ -1,9 +1,19 @@ apiVersion: v1 entries: dioscuri: + - apiVersion: v2 + appVersion: 0.1.7 + created: "2020-12-02T12:28:09.451492+11:00" + description: A Helm chart for dioscuri + digest: 282b5b1255ab4a70e7fd8b0e592711db50b14c35fdfca931a3c587aaa1b1cf2d + name: dioscuri + type: application + urls: + - dioscuri-0.1.5.tgz + version: 0.1.5 - apiVersion: v2 appVersion: 0.1.6 - created: "2020-11-02T09:18:35.139741+11:00" + created: "2020-12-02T12:28:09.450482+11:00" description: A Helm chart for dioscuri digest: ad08ced993bb6926a6c26cf78262c09d1926a6c3b8444e1b0af46e5fbe5e33ae name: dioscuri @@ -13,7 +23,7 @@ entries: version: 0.1.4 - apiVersion: v2 appVersion: 0.1.6rc2 - created: "2020-11-02T09:18:35.139337+11:00" + created: "2020-12-02T12:28:09.449815+11:00" description: A Helm chart for dioscuri digest: a135357d009a3e4070bedaf72d7b5c96cc71d8d21f54f54094efc237371bfac0 name: dioscuri @@ -23,7 +33,7 @@ entries: version: 0.1.3 - apiVersion: v2 appVersion: 0.1.6rc2 - created: "2020-11-02T09:18:35.138651+11:00" + created: "2020-12-02T12:28:09.449151+11:00" description: A Helm chart for dioscuri digest: 057df5c8fcc93af6f11a6ff897380993afa7d19ecc4a22de693903759dab44b5 name: dioscuri @@ -33,7 +43,7 @@ entries: version: 0.1.2 - apiVersion: v2 appVersion: 0.1.6rc2 - created: "2020-11-02T09:18:35.137789+11:00" + created: "2020-12-02T12:28:09.448129+11:00" description: A Helm chart for dioscuri digest: 26dabd76ba6be80d2d2bb96be56a9072c9898171bea55db946b6f55156a83ea2 name: dioscuri @@ -43,7 +53,7 @@ entries: version: 0.1.1 - apiVersion: v2 appVersion: 0.1.6rc1 - created: "2020-11-02T09:18:35.136305+11:00" + created: "2020-12-02T12:28:09.447401+11:00" description: A Helm chart for dioscuri digest: 061da4faee494f78731af48db46d3af8c1e388c0c292b91f5ebb00e3c4c16e84 name: dioscuri @@ -51,4 +61,4 @@ entries: urls: - dioscuri-0.1.0.tgz version: 0.1.0 -generated: "2020-11-02T09:18:35.135326+11:00" +generated: "2020-12-02T12:28:09.444566+11:00" diff --git a/controllers/hostmigration_controller.go b/controllers/hostmigration_controller.go index bebdba1..e644cd9 100644 --- a/controllers/hostmigration_controller.go +++ b/controllers/hostmigration_controller.go @@ -17,9 +17,11 @@ package controllers import ( "context" + "encoding/json" "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -87,7 +89,12 @@ func (r *HostMigrationReconciler) Reconcile(req ctrl.Request) (ctrl.Result, erro // registering our finalizer. if !ContainsString(dioscuri.ObjectMeta.Finalizers, finalizerName) { dioscuri.ObjectMeta.Finalizers = append(dioscuri.ObjectMeta.Finalizers, finalizerName) - if err := r.Update(ctx, &dioscuri); err != nil { + mergePatch, _ := json.Marshal(map[string]interface{}{ + "metadata": map[string]interface{}{ + "finalizers": dioscuri.ObjectMeta.Finalizers, + }, + }) + if err := r.Patch(ctx, &dioscuri, client.ConstantPatch(types.MergePatchType, mergePatch)); err != nil { return ctrl.Result{}, err } } @@ -102,7 +109,12 @@ func (r *HostMigrationReconciler) Reconcile(req ctrl.Request) (ctrl.Result, erro } // remove our finalizer from the list and update it. dioscuri.ObjectMeta.Finalizers = RemoveString(dioscuri.ObjectMeta.Finalizers, finalizerName) - if err := r.Update(ctx, &dioscuri); err != nil { + mergePatch, _ := json.Marshal(map[string]interface{}{ + "metadata": map[string]interface{}{ + "finalizers": dioscuri.ObjectMeta.Finalizers, + }, + }) + if err := r.Patch(ctx, &dioscuri, client.ConstantPatch(types.MergePatchType, mergePatch)); err != nil { return ctrl.Result{}, err } } diff --git a/controllers/ingress_handler.go b/controllers/ingress_handler.go index 3b9ff4d..c55cf48 100644 --- a/controllers/ingress_handler.go +++ b/controllers/ingress_handler.go @@ -319,7 +319,12 @@ func (r *HostMigrationReconciler) KubernetesHandler(ctx context.Context, opLog l return ctrl.Result{}, nil } -func (r *HostMigrationReconciler) checkKubernetesServices(ctx context.Context, dioscuri *dioscuriv1.HostMigration, ingressList *networkv1beta1.IngressList, ingressToMigrate *networkv1beta1.IngressList, destinationNamespace string) error { +func (r *HostMigrationReconciler) checkKubernetesServices(ctx context.Context, + dioscuri *dioscuriv1.HostMigration, + ingressList *networkv1beta1.IngressList, + ingressToMigrate *networkv1beta1.IngressList, + destinationNamespace string, +) error { // check service for ingress exists in destination namespace for _, ingress := range ingressList.Items { for _, host := range ingress.Spec.Rules { @@ -334,7 +339,8 @@ func (r *HostMigrationReconciler) checkKubernetesServices(ctx context.Context, d ) if err != nil { if apierrors.IsNotFound(err) { - return fmt.Errorf("Service %s for ingress %s doesn't exist in namespace %s, skipping ingress", path.Backend.ServiceName, host.Host, destinationNamespace) + return fmt.Errorf("Service %s for ingress %s doesn't exist in namespace %s, skipping ingress", + path.Backend.ServiceName, host.Host, destinationNamespace) } return fmt.Errorf("Error getting service, error was: %v", err) } @@ -345,7 +351,11 @@ func (r *HostMigrationReconciler) checkKubernetesServices(ctx context.Context, d return nil } -func (r *HostMigrationReconciler) checkSecrets(ctx context.Context, dioscuri *dioscuriv1.HostMigration, ingressList *networkv1beta1.IngressList, destinationNamespace string) error { +func (r *HostMigrationReconciler) checkSecrets(ctx context.Context, + dioscuri *dioscuriv1.HostMigration, + ingressList *networkv1beta1.IngressList, + destinationNamespace string, +) error { // check service for ingress exists in destination namespace opLog := r.Log.WithValues("ingressmigrate", dioscuri.ObjectMeta.Namespace) for _, ingress := range ingressList.Items { @@ -371,7 +381,11 @@ func (r *HostMigrationReconciler) checkSecrets(ctx context.Context, dioscuri *di return nil } -func (r *HostMigrationReconciler) getIngressWithLabel(dioscuri *dioscuriv1.HostMigration, ingress *networkv1beta1.IngressList, namespace string, labels map[string]string) error { +func (r *HostMigrationReconciler) getIngressWithLabel(dioscuri *dioscuriv1.HostMigration, + ingress *networkv1beta1.IngressList, + namespace string, + labels map[string]string, +) error { // collect any ingress with specific labels listOption := (&client.ListOptions{}).ApplyOptions([]client.ListOption{ client.InNamespace(namespace), @@ -399,7 +413,12 @@ func (r *HostMigrationReconciler) getIngressWithLabel(dioscuri *dioscuriv1.HostM // return nil // } -func (r *HostMigrationReconciler) individualIngressMigration(ctx context.Context, dioscuri *dioscuriv1.HostMigration, ingress *networkv1beta1.Ingress, sourceNamespace string, destinationNamespace string) (*networkv1beta1.Ingress, error) { +func (r *HostMigrationReconciler) individualIngressMigration(ctx context.Context, + dioscuri *dioscuriv1.HostMigration, + ingress *networkv1beta1.Ingress, + sourceNamespace string, + destinationNamespace string, +) (*networkv1beta1.Ingress, error) { opLog := r.Log.WithValues("ingressmigrate", dioscuri.ObjectMeta.Namespace) oldIngress := &networkv1beta1.Ingress{} newIngress := &networkv1beta1.Ingress{} @@ -435,17 +454,21 @@ func (r *HostMigrationReconciler) individualIngressMigration(ctx context.Context } // add ingress, and then remove the old one only if we successfully create the new one -func (r *HostMigrationReconciler) migrateIngress(ctx context.Context, dioscuri *dioscuriv1.HostMigration, newIngress *networkv1beta1.Ingress, oldIngress *networkv1beta1.Ingress) error { - // add ingress +func (r *HostMigrationReconciler) migrateIngress(ctx context.Context, + dioscuri *dioscuriv1.HostMigration, + newIngress *networkv1beta1.Ingress, + oldIngress *networkv1beta1.Ingress, +) error { opLog := r.Log.WithValues("ingressmigrate", dioscuri.ObjectMeta.Namespace) - if err := r.addIngressIfNotExist(ctx, dioscuri, newIngress); err != nil { - return fmt.Errorf("Unable to create ingress %s in %s: %v", newIngress.ObjectMeta.Name, newIngress.ObjectMeta.Namespace, err) - } // delete old ingress from the old namespace opLog.Info(fmt.Sprintf("Removing old ingress %s in namespace %s", oldIngress.ObjectMeta.Name, oldIngress.ObjectMeta.Namespace)) if err := r.removeIngress(ctx, oldIngress); err != nil { return fmt.Errorf("Unable to remove old ingress %s in %s: %v", oldIngress.ObjectMeta.Name, oldIngress.ObjectMeta.Namespace, err) } + // add ingress + if err := r.addIngressIfNotExist(ctx, dioscuri, newIngress); err != nil { + return fmt.Errorf("Unable to create ingress %s in %s: %v", newIngress.ObjectMeta.Name, newIngress.ObjectMeta.Namespace, err) + } return nil } @@ -527,14 +550,27 @@ func (r *HostMigrationReconciler) removeIngress(ctx context.Context, ingress *ne } // update status -func (r *HostMigrationReconciler) updateKubernetesStatusCondition(ctx context.Context, dioscuri *dioscuriv1.HostMigration, condition dioscuriv1.HostMigrationConditions, activeIngress []string, standbyIngress []string) error { - dioscuri.Spec.Hosts.ActiveHosts = strings.Join(activeIngress, ",") - dioscuri.Spec.Hosts.StandbyHosts = strings.Join(standbyIngress, ",") +func (r *HostMigrationReconciler) updateKubernetesStatusCondition(ctx context.Context, + dioscuri *dioscuriv1.HostMigration, + condition dioscuriv1.HostMigrationConditions, + activeIngress []string, + standbyIngress []string) error { // set the transition time - condition.LastTransitionTime = time.Now().Format(time.RFC3339) + condition.LastTransitionTime = time.Now().UTC().Format(time.RFC3339) if !HostMigrationContainsStatus(dioscuri.Status.Conditions, condition) { dioscuri.Status.Conditions = append(dioscuri.Status.Conditions, condition) - if err := r.Update(ctx, dioscuri); err != nil { + mergePatch, _ := json.Marshal(map[string]interface{}{ + "status": map[string]interface{}{ + "conditions": dioscuri.Status.Conditions, + }, + "spec": map[string]interface{}{ + "hosts": map[string]string{ + "activeHosts": strings.Join(activeIngress, ","), + "standbyHosts": strings.Join(standbyIngress, ","), + }, + }, + }) + if err := r.Patch(ctx, dioscuri, client.ConstantPatch(types.MergePatchType, mergePatch)); err != nil { return fmt.Errorf("Unable to update status condition: %v", err) } } diff --git a/controllers/ingressmigrate_controller.go b/controllers/ingressmigrate_controller.go index ca8a961..deeefde 100644 --- a/controllers/ingressmigrate_controller.go +++ b/controllers/ingressmigrate_controller.go @@ -383,7 +383,12 @@ func (r *IngressMigrateReconciler) Reconcile(req ctrl.Request) (ctrl.Result, err // registering our finalizer. if !ContainsString(dioscuri.ObjectMeta.Finalizers, finalizerName) { dioscuri.ObjectMeta.Finalizers = append(dioscuri.ObjectMeta.Finalizers, finalizerName) - if err := r.Update(ctx, &dioscuri); err != nil { + mergePatch, _ := json.Marshal(map[string]interface{}{ + "metadata": map[string]interface{}{ + "finalizers": dioscuri.ObjectMeta.Finalizers, + }, + }) + if err := r.Patch(ctx, &dioscuri, client.ConstantPatch(types.MergePatchType, mergePatch)); err != nil { return ctrl.Result{}, err } } @@ -398,7 +403,12 @@ func (r *IngressMigrateReconciler) Reconcile(req ctrl.Request) (ctrl.Result, err } // remove our finalizer from the list and update it. dioscuri.ObjectMeta.Finalizers = RemoveString(dioscuri.ObjectMeta.Finalizers, finalizerName) - if err := r.Update(ctx, &dioscuri); err != nil { + mergePatch, _ := json.Marshal(map[string]interface{}{ + "metadata": map[string]interface{}{ + "finalizers": dioscuri.ObjectMeta.Finalizers, + }, + }) + if err := r.Patch(ctx, &dioscuri, client.ConstantPatch(types.MergePatchType, mergePatch)); err != nil { return ctrl.Result{}, err } } @@ -418,7 +428,12 @@ func (r *IngressMigrateReconciler) deleteExternalResources(dioscuri *dioscuriv1. return nil } -func (r *IngressMigrateReconciler) checkServices(ctx context.Context, dioscuri *dioscuriv1.IngressMigrate, ingressList *networkv1beta1.IngressList, ingressToMigrate *networkv1beta1.IngressList, destinationNamespace string) error { +func (r *IngressMigrateReconciler) checkServices(ctx context.Context, + dioscuri *dioscuriv1.IngressMigrate, + ingressList *networkv1beta1.IngressList, + ingressToMigrate *networkv1beta1.IngressList, + destinationNamespace string, +) error { // check service for ingress exists in destination namespace for _, ingress := range ingressList.Items { for _, host := range ingress.Spec.Rules { @@ -444,7 +459,11 @@ func (r *IngressMigrateReconciler) checkServices(ctx context.Context, dioscuri * return nil } -func (r *IngressMigrateReconciler) checkSecrets(ctx context.Context, dioscuri *dioscuriv1.IngressMigrate, ingressList *networkv1beta1.IngressList, destinationNamespace string) error { +func (r *IngressMigrateReconciler) checkSecrets(ctx context.Context, + dioscuri *dioscuriv1.IngressMigrate, + ingressList *networkv1beta1.IngressList, + destinationNamespace string, +) error { // check service for ingress exists in destination namespace opLog := r.Log.WithValues("ingressmigrate", dioscuri.ObjectMeta.Namespace) for _, ingress := range ingressList.Items { @@ -470,7 +489,11 @@ func (r *IngressMigrateReconciler) checkSecrets(ctx context.Context, dioscuri *d return nil } -func (r *IngressMigrateReconciler) getIngressWithLabel(dioscuri *dioscuriv1.IngressMigrate, ingress *networkv1beta1.IngressList, namespace string, labels map[string]string) error { +func (r *IngressMigrateReconciler) getIngressWithLabel(dioscuri *dioscuriv1.IngressMigrate, + ingress *networkv1beta1.IngressList, + namespace string, + labels map[string]string, +) error { // collect any ingress with specific labels listOption := (&client.ListOptions{}).ApplyOptions([]client.ListOption{ client.InNamespace(namespace), @@ -498,7 +521,12 @@ func (r *IngressMigrateReconciler) cleanUpAcmeChallenges(dioscuri *dioscuriv1.In return nil } -func (r *IngressMigrateReconciler) individualIngressMigration(ctx context.Context, dioscuri *dioscuriv1.IngressMigrate, ingress *networkv1beta1.Ingress, sourceNamespace string, destinationNamespace string) (*networkv1beta1.Ingress, error) { +func (r *IngressMigrateReconciler) individualIngressMigration(ctx context.Context, + dioscuri *dioscuriv1.IngressMigrate, + ingress *networkv1beta1.Ingress, + sourceNamespace string, + destinationNamespace string, +) (*networkv1beta1.Ingress, error) { opLog := r.Log.WithValues("ingressmigrate", dioscuri.ObjectMeta.Namespace) oldIngress := &networkv1beta1.Ingress{} newIngress := &networkv1beta1.Ingress{} @@ -534,17 +562,21 @@ func (r *IngressMigrateReconciler) individualIngressMigration(ctx context.Contex } // add ingress, and then remove the old one only if we successfully create the new one -func (r *IngressMigrateReconciler) migrateIngress(ctx context.Context, dioscuri *dioscuriv1.IngressMigrate, newIngress *networkv1beta1.Ingress, oldIngress *networkv1beta1.Ingress) error { - // add ingress +func (r *IngressMigrateReconciler) migrateIngress(ctx context.Context, + dioscuri *dioscuriv1.IngressMigrate, + newIngress *networkv1beta1.Ingress, + oldIngress *networkv1beta1.Ingress, +) error { opLog := r.Log.WithValues("ingressmigrate", dioscuri.ObjectMeta.Namespace) - if err := r.addIngressIfNotExist(ctx, dioscuri, newIngress); err != nil { - return fmt.Errorf("Unable to create ingress %s in %s: %v", newIngress.ObjectMeta.Name, newIngress.ObjectMeta.Namespace, err) - } // delete old ingress from the old namespace opLog.Info(fmt.Sprintf("Removing old ingress %s in namespace %s", oldIngress.ObjectMeta.Name, oldIngress.ObjectMeta.Namespace)) if err := r.removeIngress(ctx, oldIngress); err != nil { return fmt.Errorf("Unable to remove old ingress %s in %s: %v", oldIngress.ObjectMeta.Name, oldIngress.ObjectMeta.Namespace, err) } + // add ingress + if err := r.addIngressIfNotExist(ctx, dioscuri, newIngress); err != nil { + return fmt.Errorf("Unable to create ingress %s in %s: %v", newIngress.ObjectMeta.Name, newIngress.ObjectMeta.Namespace, err) + } return nil } @@ -626,14 +658,28 @@ func (r *IngressMigrateReconciler) removeIngress(ctx context.Context, ingress *n } // update status -func (r *IngressMigrateReconciler) updateStatusCondition(ctx context.Context, dioscuri *dioscuriv1.IngressMigrate, condition dioscuriv1.IngressMigrateConditions, activeIngress []string, standbyIngress []string) error { - dioscuri.Spec.Ingress.ActiveIngress = strings.Join(activeIngress, ",") - dioscuri.Spec.Ingress.StandbyIngress = strings.Join(standbyIngress, ",") +func (r *IngressMigrateReconciler) updateStatusCondition(ctx context.Context, + dioscuri *dioscuriv1.IngressMigrate, + condition dioscuriv1.IngressMigrateConditions, + activeIngress []string, + standbyIngress []string, +) error { // set the transition time - condition.LastTransitionTime = time.Now().Format(time.RFC3339) + condition.LastTransitionTime = time.Now().UTC().Format(time.RFC3339) if !IngressContainsStatus(dioscuri.Status.Conditions, condition) { dioscuri.Status.Conditions = append(dioscuri.Status.Conditions, condition) - if err := r.Update(ctx, dioscuri); err != nil { + mergePatch, _ := json.Marshal(map[string]interface{}{ + "status": map[string]interface{}{ + "conditions": dioscuri.Status.Conditions, + }, + "spec": map[string]interface{}{ + "ingress": map[string]string{ + "activeIngress": strings.Join(activeIngress, ","), + "standbyIngress": strings.Join(standbyIngress, ","), + }, + }, + }) + if err := r.Patch(ctx, dioscuri, client.ConstantPatch(types.MergePatchType, mergePatch)); err != nil { return fmt.Errorf("Unable to update status condition: %v", err) } } diff --git a/controllers/route_handler.go b/controllers/route_handler.go index c4702ee..cd000e2 100644 --- a/controllers/route_handler.go +++ b/controllers/route_handler.go @@ -35,7 +35,7 @@ func (r *HostMigrationReconciler) OpenshiftHandler(ctx context.Context, opLog lo if err := r.Patch(ctx, &dioscuri, client.ConstantPatch(types.MergePatchType, mergePatch)); err != nil { return ctrl.Result{}, fmt.Errorf("Unable to patch routemigrate %s, error was: %v", dioscuri.ObjectMeta.Name, err) } - r.updateStatusCondition(&dioscuri, dioscuriv1.HostMigrationConditions{ + r.updateStatusCondition(ctx, &dioscuri, dioscuriv1.HostMigrationConditions{ Status: "True", Type: "started", Condition: "Started route migration", @@ -60,7 +60,7 @@ func (r *HostMigrationReconciler) OpenshiftHandler(ctx context.Context, opLog lo opLog.Info(fmt.Sprintf("%v", err)) } if err := r.cleanUpAcmeChallenges(&dioscuri, acmeSourceToDestination); err != nil { - r.updateStatusCondition(&dioscuri, dioscuriv1.HostMigrationConditions{ + r.updateStatusCondition(ctx, &dioscuri, dioscuriv1.HostMigrationConditions{ Status: "True", Type: "failed", Condition: fmt.Sprintf("%v", err), @@ -72,7 +72,7 @@ func (r *HostMigrationReconciler) OpenshiftHandler(ctx context.Context, opLog lo opLog.Info(fmt.Sprintf("%v", err)) } if err := r.cleanUpAcmeChallenges(&dioscuri, acmeDestinationToSource); err != nil { - r.updateStatusCondition(&dioscuri, dioscuriv1.HostMigrationConditions{ + r.updateStatusCondition(ctx, &dioscuri, dioscuriv1.HostMigrationConditions{ Status: "True", Type: "failed", Condition: fmt.Sprintf("%v", err), @@ -105,7 +105,7 @@ func (r *HostMigrationReconciler) OpenshiftHandler(ctx context.Context, opLog lo // migrate these routes newRoute, err := r.individualRouteMigration(&dioscuri, &route, sourceNamespace, destinationNamespace) if err != nil { - r.updateStatusCondition(&dioscuri, dioscuriv1.HostMigrationConditions{ + r.updateStatusCondition(ctx, &dioscuri, dioscuriv1.HostMigrationConditions{ Status: "True", Type: "failed", Condition: fmt.Sprintf("%v", err), @@ -125,7 +125,7 @@ func (r *HostMigrationReconciler) OpenshiftHandler(ctx context.Context, opLog lo // migrate these routes newRoute, err := r.individualRouteMigration(&dioscuri, &route, destinationNamespace, sourceNamespace) if err != nil { - r.updateStatusCondition(&dioscuri, dioscuriv1.HostMigrationConditions{ + r.updateStatusCondition(ctx, &dioscuri, dioscuriv1.HostMigrationConditions{ Status: "True", Type: "failed", Condition: fmt.Sprintf("%v", err), @@ -149,7 +149,7 @@ func (r *HostMigrationReconciler) OpenshiftHandler(ctx context.Context, opLog lo for _, migratedRoute := range migratedRoutes { err := r.updateRoute(&dioscuri, migratedRoute.NewRoute, migratedRoute.OldRouteNamespace) if err != nil { - r.updateStatusCondition(&dioscuri, dioscuriv1.HostMigrationConditions{ + r.updateStatusCondition(ctx, &dioscuri, dioscuriv1.HostMigrationConditions{ Status: "True", Type: "failed", Condition: fmt.Sprintf("%v", err), @@ -157,7 +157,7 @@ func (r *HostMigrationReconciler) OpenshiftHandler(ctx context.Context, opLog lo return ctrl.Result{}, err } } - r.updateStatusCondition(&dioscuri, dioscuriv1.HostMigrationConditions{ + r.updateStatusCondition(ctx, &dioscuri, dioscuriv1.HostMigrationConditions{ Status: "True", Type: "completed", Condition: "Completed route migration", @@ -170,7 +170,11 @@ func (r *HostMigrationReconciler) deleteExternalResources(dioscuri *dioscuriv1.H return nil } -func (r *HostMigrationReconciler) checkServices(dioscuri *dioscuriv1.HostMigration, routeList *routev1.RouteList, routesToMigrate *routev1.RouteList, destinationNamespace string) { +func (r *HostMigrationReconciler) checkServices(dioscuri *dioscuriv1.HostMigration, + routeList *routev1.RouteList, + routesToMigrate *routev1.RouteList, + destinationNamespace string, +) { // check service for route exists in destination namespace opLog := r.Log.WithValues("routemigrate", dioscuri.ObjectMeta.Namespace) for _, route := range routeList.Items { @@ -185,7 +189,11 @@ func (r *HostMigrationReconciler) checkServices(dioscuri *dioscuriv1.HostMigrati // return nil } -func (r *HostMigrationReconciler) getRoutesWithLabel(dioscuri *dioscuriv1.HostMigration, routes *routev1.RouteList, namespace string, labels map[string]string) error { +func (r *HostMigrationReconciler) getRoutesWithLabel(dioscuri *dioscuriv1.HostMigration, + routes *routev1.RouteList, + namespace string, + labels map[string]string, +) error { // collect any routes with specific labels listOption := (&client.ListOptions{}).ApplyOptions([]client.ListOption{ client.InNamespace(namespace), @@ -213,7 +221,11 @@ func (r *HostMigrationReconciler) cleanUpAcmeChallenges(dioscuri *dioscuriv1.Hos return nil } -func (r *HostMigrationReconciler) individualRouteMigration(dioscuri *dioscuriv1.HostMigration, route *routev1.Route, sourceNamespace string, destinationNamespace string) (*routev1.Route, error) { +func (r *HostMigrationReconciler) individualRouteMigration(dioscuri *dioscuriv1.HostMigration, + route *routev1.Route, + sourceNamespace string, + destinationNamespace string, +) (*routev1.Route, error) { opLog := r.Log.WithValues("routemigrate", dioscuri.ObjectMeta.Namespace) oldRoute := &routev1.Route{} newRoute := &routev1.Route{} @@ -325,14 +337,28 @@ func (r *HostMigrationReconciler) removeRoute(route *routev1.Route) error { } // update status -func (r *HostMigrationReconciler) updateStatusCondition(dioscuri *dioscuriv1.HostMigration, condition dioscuriv1.HostMigrationConditions, activeRoutes []string, standbyRotues []string) error { - dioscuri.Spec.Hosts.ActiveHosts = strings.Join(activeRoutes, ",") - dioscuri.Spec.Hosts.StandbyHosts = strings.Join(standbyRotues, ",") +func (r *HostMigrationReconciler) updateStatusCondition(ctx context.Context, + dioscuri *dioscuriv1.HostMigration, + condition dioscuriv1.HostMigrationConditions, + activeRoutes []string, + standbyRotues []string, +) error { // set the transition time - condition.LastTransitionTime = time.Now().Format(time.RFC3339) + condition.LastTransitionTime = time.Now().UTC().Format(time.RFC3339) if !HostMigrationContainsStatus(dioscuri.Status.Conditions, condition) { dioscuri.Status.Conditions = append(dioscuri.Status.Conditions, condition) - if err := r.Update(context.Background(), dioscuri); err != nil { + mergePatch, _ := json.Marshal(map[string]interface{}{ + "status": map[string]interface{}{ + "conditions": dioscuri.Status.Conditions, + }, + "spec": map[string]interface{}{ + "hosts": map[string]string{ + "activeHosts": strings.Join(activeRoutes, ","), + "standbyHosts": strings.Join(standbyRotues, ","), + }, + }, + }) + if err := r.Patch(ctx, dioscuri, client.ConstantPatch(types.MergePatchType, mergePatch)); err != nil { return fmt.Errorf("Unable to update status condition: %v", err) } } diff --git a/controllers/routemigrate_controller.go b/controllers/routemigrate_controller.go index cb6ebaa..6972ca2 100644 --- a/controllers/routemigrate_controller.go +++ b/controllers/routemigrate_controller.go @@ -93,7 +93,7 @@ func (r *RouteMigrateReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error if err := r.Patch(ctx, &dioscuri, client.ConstantPatch(types.MergePatchType, mergePatch)); err != nil { return ctrl.Result{}, fmt.Errorf("Unable to patch routemigrate %s, error was: %v", dioscuri.ObjectMeta.Name, err) } - r.updateStatusCondition(&dioscuri, dioscuriv1.RouteMigrateConditions{ + r.updateStatusCondition(ctx, &dioscuri, dioscuriv1.RouteMigrateConditions{ Status: "True", Type: "started", Condition: "Started route migration", @@ -118,7 +118,7 @@ func (r *RouteMigrateReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error opLog.Info(fmt.Sprintf("%v", err)) } if err := r.cleanUpAcmeChallenges(&dioscuri, acmeSourceToDestination); err != nil { - r.updateStatusCondition(&dioscuri, dioscuriv1.RouteMigrateConditions{ + r.updateStatusCondition(ctx, &dioscuri, dioscuriv1.RouteMigrateConditions{ Status: "True", Type: "failed", Condition: fmt.Sprintf("%v", err), @@ -130,7 +130,7 @@ func (r *RouteMigrateReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error opLog.Info(fmt.Sprintf("%v", err)) } if err := r.cleanUpAcmeChallenges(&dioscuri, acmeDestinationToSource); err != nil { - r.updateStatusCondition(&dioscuri, dioscuriv1.RouteMigrateConditions{ + r.updateStatusCondition(ctx, &dioscuri, dioscuriv1.RouteMigrateConditions{ Status: "True", Type: "failed", Condition: fmt.Sprintf("%v", err), @@ -163,7 +163,7 @@ func (r *RouteMigrateReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error // migrate these routes newRoute, err := r.individualRouteMigration(&dioscuri, &route, sourceNamespace, destinationNamespace) if err != nil { - r.updateStatusCondition(&dioscuri, dioscuriv1.RouteMigrateConditions{ + r.updateStatusCondition(ctx, &dioscuri, dioscuriv1.RouteMigrateConditions{ Status: "True", Type: "failed", Condition: fmt.Sprintf("%v", err), @@ -183,7 +183,7 @@ func (r *RouteMigrateReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error // migrate these routes newRoute, err := r.individualRouteMigration(&dioscuri, &route, destinationNamespace, sourceNamespace) if err != nil { - r.updateStatusCondition(&dioscuri, dioscuriv1.RouteMigrateConditions{ + r.updateStatusCondition(ctx, &dioscuri, dioscuriv1.RouteMigrateConditions{ Status: "True", Type: "failed", Condition: fmt.Sprintf("%v", err), @@ -207,7 +207,7 @@ func (r *RouteMigrateReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error for _, migratedRoute := range migratedRoutes { err := r.updateRoute(&dioscuri, migratedRoute.NewRoute, migratedRoute.OldRouteNamespace) if err != nil { - r.updateStatusCondition(&dioscuri, dioscuriv1.RouteMigrateConditions{ + r.updateStatusCondition(ctx, &dioscuri, dioscuriv1.RouteMigrateConditions{ Status: "True", Type: "failed", Condition: fmt.Sprintf("%v", err), @@ -215,7 +215,7 @@ func (r *RouteMigrateReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error return ctrl.Result{}, err } } - r.updateStatusCondition(&dioscuri, dioscuriv1.RouteMigrateConditions{ + r.updateStatusCondition(ctx, &dioscuri, dioscuriv1.RouteMigrateConditions{ Status: "True", Type: "completed", Condition: "Completed route migration", @@ -226,7 +226,12 @@ func (r *RouteMigrateReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error // registering our finalizer. if !ContainsString(dioscuri.ObjectMeta.Finalizers, finalizerName) { dioscuri.ObjectMeta.Finalizers = append(dioscuri.ObjectMeta.Finalizers, finalizerName) - if err := r.Update(ctx, &dioscuri); err != nil { + mergePatch, _ := json.Marshal(map[string]interface{}{ + "metadata": map[string]interface{}{ + "finalizers": dioscuri.ObjectMeta.Finalizers, + }, + }) + if err := r.Patch(ctx, &dioscuri, client.ConstantPatch(types.MergePatchType, mergePatch)); err != nil { return ctrl.Result{}, err } } @@ -241,7 +246,12 @@ func (r *RouteMigrateReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error } // remove our finalizer from the list and update it. dioscuri.ObjectMeta.Finalizers = RemoveString(dioscuri.ObjectMeta.Finalizers, finalizerName) - if err := r.Update(ctx, &dioscuri); err != nil { + mergePatch, _ := json.Marshal(map[string]interface{}{ + "metadata": map[string]interface{}{ + "finalizers": dioscuri.ObjectMeta.Finalizers, + }, + }) + if err := r.Patch(ctx, &dioscuri, client.ConstantPatch(types.MergePatchType, mergePatch)); err != nil { return ctrl.Result{}, err } } @@ -261,7 +271,11 @@ func (r *RouteMigrateReconciler) deleteExternalResources(dioscuri *dioscuriv1.Ro return nil } -func (r *RouteMigrateReconciler) checkServices(dioscuri *dioscuriv1.RouteMigrate, routeList *routev1.RouteList, routesToMigrate *routev1.RouteList, destinationNamespace string) { +func (r *RouteMigrateReconciler) checkServices(dioscuri *dioscuriv1.RouteMigrate, + routeList *routev1.RouteList, + routesToMigrate *routev1.RouteList, + destinationNamespace string, +) { // check service for route exists in destination namespace opLog := r.Log.WithValues("routemigrate", dioscuri.ObjectMeta.Namespace) for _, route := range routeList.Items { @@ -276,7 +290,11 @@ func (r *RouteMigrateReconciler) checkServices(dioscuri *dioscuriv1.RouteMigrate // return nil } -func (r *RouteMigrateReconciler) getRoutesWithLabel(dioscuri *dioscuriv1.RouteMigrate, routes *routev1.RouteList, namespace string, labels map[string]string) error { +func (r *RouteMigrateReconciler) getRoutesWithLabel(dioscuri *dioscuriv1.RouteMigrate, + routes *routev1.RouteList, + namespace string, + labels map[string]string, +) error { // collect any routes with specific labels listOption := (&client.ListOptions{}).ApplyOptions([]client.ListOption{ client.InNamespace(namespace), @@ -304,7 +322,11 @@ func (r *RouteMigrateReconciler) cleanUpAcmeChallenges(dioscuri *dioscuriv1.Rout return nil } -func (r *RouteMigrateReconciler) individualRouteMigration(dioscuri *dioscuriv1.RouteMigrate, route *routev1.Route, sourceNamespace string, destinationNamespace string) (*routev1.Route, error) { +func (r *RouteMigrateReconciler) individualRouteMigration(dioscuri *dioscuriv1.RouteMigrate, + route *routev1.Route, + sourceNamespace string, + destinationNamespace string, +) (*routev1.Route, error) { opLog := r.Log.WithValues("routemigrate", dioscuri.ObjectMeta.Namespace) oldRoute := &routev1.Route{} newRoute := &routev1.Route{} @@ -416,14 +438,28 @@ func (r *RouteMigrateReconciler) removeRoute(route *routev1.Route) error { } // update status -func (r *RouteMigrateReconciler) updateStatusCondition(dioscuri *dioscuriv1.RouteMigrate, condition dioscuriv1.RouteMigrateConditions, activeRoutes []string, standbyRotues []string) error { - dioscuri.Spec.Routes.ActiveRoutes = strings.Join(activeRoutes, ",") - dioscuri.Spec.Routes.StandbyRoutes = strings.Join(standbyRotues, ",") +func (r *RouteMigrateReconciler) updateStatusCondition(ctx context.Context, + dioscuri *dioscuriv1.RouteMigrate, + condition dioscuriv1.RouteMigrateConditions, + activeRoutes []string, + standbyRotues []string, +) error { // set the transition time - condition.LastTransitionTime = time.Now().Format(time.RFC3339) + condition.LastTransitionTime = time.Now().UTC().Format(time.RFC3339) if !RouteContainsStatus(dioscuri.Status.Conditions, condition) { dioscuri.Status.Conditions = append(dioscuri.Status.Conditions, condition) - if err := r.Update(context.Background(), dioscuri); err != nil { + mergePatch, _ := json.Marshal(map[string]interface{}{ + "status": map[string]interface{}{ + "conditions": dioscuri.Status.Conditions, + }, + "spec": map[string]interface{}{ + "routes": map[string]string{ + "activeRoutes": strings.Join(activeRoutes, ","), + "standbyRoutes": strings.Join(standbyRotues, ","), + }, + }, + }) + if err := r.Patch(ctx, dioscuri, client.ConstantPatch(types.MergePatchType, mergePatch)); err != nil { return fmt.Errorf("Unable to update status condition: %v", err) } }