Skip to content

Commit

Permalink
Replace Ingress resource Update calls with Patch
Browse files Browse the repository at this point in the history
  • Loading branch information
skmatti committed Jun 2, 2020
1 parent 7f64b4a commit a874d56
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 29 deletions.
11 changes: 7 additions & 4 deletions pkg/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ func (lbc *LoadBalancerController) updateIngressStatus(l7 *loadbalancers.L7, ing
if err != nil {
return err
}
currIng.Status = v1beta1.IngressStatus{
updatedIngStatus := v1beta1.IngressStatus{
LoadBalancer: apiv1.LoadBalancerStatus{
Ingress: []apiv1.LoadBalancerIngress{
{IP: ip},
Expand All @@ -629,7 +629,8 @@ func (lbc *LoadBalancerController) updateIngressStatus(l7 *loadbalancers.L7, ing
// TODO: If this update fails it's probably resource version related,
// which means it's advantageous to retry right away vs requeuing.
klog.Infof("Updating loadbalancer %v/%v with IP %v", ing.Namespace, ing.Name, ip)
if _, err := ingClient.UpdateStatus(context2.TODO(), currIng, metav1.UpdateOptions{}); err != nil {
if _, err := common.PatchIngressStatus(ingClient, currIng, updatedIngStatus); err != nil {
klog.Errorf("PatchIngressStatus(%s/%s) failed: %v", currIng.Namespace, currIng.Name, err)
return err
}
lbc.ctx.Recorder(ing.Namespace).Eventf(currIng, apiv1.EventTypeNormal, "CREATE", "ip: %v", ip)
Expand Down Expand Up @@ -691,8 +692,10 @@ func updateAnnotations(client kubernetes.Interface, name, namespace string, anno
}
if !reflect.DeepEqual(currIng.Annotations, annotations) {
klog.V(3).Infof("Updating annotations of %v/%v", namespace, name)
currIng.Annotations = annotations
if _, err := ingClient.Update(context2.TODO(), currIng, metav1.UpdateOptions{}); err != nil {
updatedObjectMeta := currIng.ObjectMeta.DeepCopy()
updatedObjectMeta.Annotations = annotations
if _, err := common.PatchIngressObjectMetadata(ingClient, currIng, *updatedObjectMeta); err != nil {
klog.Errorf("PatchIngressObjectMetadata(%s/%s) failed: %v", currIng.Namespace, currIng.Name, err)
return err
}
}
Expand Down
47 changes: 47 additions & 0 deletions pkg/utils/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,17 @@ limitations under the License.
package common

import (
"context"
"crypto/sha256"
"encoding/json"
"fmt"
"strconv"

"k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/strategicpatch"
client "k8s.io/client-go/kubernetes/typed/networking/v1beta1"
"k8s.io/client-go/tools/cache"
"k8s.io/klog"
)
Expand Down Expand Up @@ -89,3 +95,44 @@ func ToIngressKeys(ings []*v1beta1.Ingress) []string {
}
return ingKeys
}

// PatchIngressObjectMetadata patches the given ingress's metadata based on new
// ingress metadata.
func PatchIngressObjectMetadata(ic client.IngressInterface, ing *v1beta1.Ingress, newObjectMetadata metav1.ObjectMeta) (*v1beta1.Ingress, error) {
newIng := ing.DeepCopy()
newIng.ObjectMeta = newObjectMetadata
return patchIngress(ic, ing, newIng)
}

// PatchIngressStatus patches the given ingress's Status based on new ingress
// status.
func PatchIngressStatus(ic client.IngressInterface, ing *v1beta1.Ingress, newStatus v1beta1.IngressStatus) (*v1beta1.Ingress, error) {
newIng := ing.DeepCopy()
newIng.Status = newStatus
return patchIngress(ic, ing, newIng)
}

// patchIngress patches the given ingress's Status or ObjectMetadata based on
// the old and new ingresses.
// Note that both Status and ObjectMetadata (annotations and finalizers)
// can be patched via `status` subresource API endpoint.
func patchIngress(ic client.IngressInterface, oldIngress, newIngress *v1beta1.Ingress) (*v1beta1.Ingress, error) {
ingKey := fmt.Sprintf("%s/%s", oldIngress.Namespace, oldIngress.Name)
oldData, err := json.Marshal(oldIngress)
if err != nil {
return nil, fmt.Errorf("failed to Marshal oldData for ingress %s: %v", ingKey, err)
}

newData, err := json.Marshal(newIngress)
if err != nil {
return nil, fmt.Errorf("failed to Marshal newData for ingress %s: %v", ingKey, err)
}

patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, v1beta1.Ingress{})
if err != nil {
return nil, fmt.Errorf("failed to create TwoWayMergePatch for ingress %s: %v", ingKey, err)
}

klog.V(4).Infof("Patch bytes for ingress %s: %s", ingKey, patchBytes)
return ic.Patch(context.TODO(), oldIngress.Name, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}, "status")
}
29 changes: 4 additions & 25 deletions pkg/utils/common/finalizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func EnsureFinalizer(ing *v1beta1.Ingress, ingClient client.IngressInterface, fi
updated := ing.DeepCopy()
if needToAddFinalizer(ing.ObjectMeta, finalizerKey) {
updated.ObjectMeta.Finalizers = append(updated.ObjectMeta.Finalizers, finalizerKey)
if _, err := patchIngressFinalizer(ingClient, ing, updated); err != nil {
if _, err := PatchIngressObjectMetadata(ingClient, ing, updated.ObjectMeta); err != nil {
return nil, fmt.Errorf("error patching Ingress %s/%s: %v", ing.Namespace, ing.Name, err)
}
klog.V(2).Infof("Added finalizer %q for Ingress %s/%s", finalizerKey, ing.Namespace, ing.Name)
Expand All @@ -84,37 +84,16 @@ func needToAddFinalizer(m meta_v1.ObjectMeta, key string) bool {
// EnsureDeleteFinalizer ensures that the specified finalizer is deleted from given Ingress.
func EnsureDeleteFinalizer(ing *v1beta1.Ingress, ingClient client.IngressInterface, finalizerKey string) error {
if HasGivenFinalizer(ing.ObjectMeta, finalizerKey) {
updated := ing.DeepCopy()
updated.ObjectMeta.Finalizers = slice.RemoveString(updated.ObjectMeta.Finalizers, finalizerKey, nil)
if _, err := patchIngressFinalizer(ingClient, ing, updated); err != nil {
updatedObjectMeta := ing.ObjectMeta.DeepCopy()
updatedObjectMeta.Finalizers = slice.RemoveString(updatedObjectMeta.Finalizers, finalizerKey, nil)
if _, err := PatchIngressObjectMetadata(ingClient, ing, *updatedObjectMeta); err != nil {
return fmt.Errorf("error patching Ingress %s/%s: %v", ing.Namespace, ing.Name, err)
}
klog.V(2).Infof("Removed finalizer %q for Ingress %s/%s", finalizerKey, ing.Namespace, ing.Name)
}
return nil
}

func patchIngressFinalizer(ic client.IngressInterface, oldIngress, newIngress *v1beta1.Ingress) (*v1beta1.Ingress, error) {
ingKey := fmt.Sprintf("%s/%s", oldIngress.Namespace, oldIngress.Name)
oldData, err := json.Marshal(oldIngress)
if err != nil {
return nil, fmt.Errorf("failed to Marshal oldData for ingress %s: %v", ingKey, err)
}

newData, err := json.Marshal(newIngress)
if err != nil {
return nil, fmt.Errorf("failed to Marshal newData for ingress %s: %v", ingKey, err)
}

patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, v1beta1.Ingress{})
if err != nil {
return nil, fmt.Errorf("failed to create TwoWayMergePatch for ingress %s: %v", ingKey, err)
}

klog.V(3).Infof("Patch bytes for ingress %s: %s", ingKey, patchBytes)
return ic.Patch(context.TODO(), oldIngress.Name, types.StrategicMergePatchType, patchBytes, meta_v1.PatchOptions{}, "status")
}

// EnsureServiceFinalizer patches the service to add finalizer.
func EnsureServiceFinalizer(service *corev1.Service, key string, kubeClient kubernetes.Interface) error {
if HasGivenFinalizer(service.ObjectMeta, key) {
Expand Down

0 comments on commit a874d56

Please sign in to comment.