200
vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil.go
generated
vendored
200
vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil.go
generated
vendored
@@ -19,11 +19,12 @@ package controllerutil
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/equality"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/utils/pointer"
|
||||
@@ -33,7 +34,7 @@ import (
|
||||
|
||||
// AlreadyOwnedError is an error returned if the object you are trying to assign
|
||||
// a controller reference is already owned by another controller Object is the
|
||||
// subject and Owner is the reference for the current owner
|
||||
// subject and Owner is the reference for the current owner.
|
||||
type AlreadyOwnedError struct {
|
||||
Object metav1.Object
|
||||
Owner metav1.OwnerReference
|
||||
@@ -43,10 +44,10 @@ func (e *AlreadyOwnedError) Error() string {
|
||||
return fmt.Sprintf("Object %s/%s is already owned by another %s controller %s", e.Object.GetNamespace(), e.Object.GetName(), e.Owner.Kind, e.Owner.Name)
|
||||
}
|
||||
|
||||
func newAlreadyOwnedError(Object metav1.Object, Owner metav1.OwnerReference) *AlreadyOwnedError {
|
||||
func newAlreadyOwnedError(obj metav1.Object, owner metav1.OwnerReference) *AlreadyOwnedError {
|
||||
return &AlreadyOwnedError{
|
||||
Object: Object,
|
||||
Owner: Owner,
|
||||
Object: obj,
|
||||
Owner: owner,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,13 +118,11 @@ func SetOwnerReference(owner, object metav1.Object, scheme *runtime.Scheme) erro
|
||||
// Update owner references and return.
|
||||
upsertOwnerRef(ref, object)
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func upsertOwnerRef(ref metav1.OwnerReference, object metav1.Object) {
|
||||
owners := object.GetOwnerReferences()
|
||||
idx := indexOwnerRef(owners, ref)
|
||||
if idx == -1 {
|
||||
if idx := indexOwnerRef(owners, ref); idx == -1 {
|
||||
owners = append(owners, ref)
|
||||
} else {
|
||||
owners[idx] = ref
|
||||
@@ -155,7 +154,7 @@ func validateOwner(owner, object metav1.Object) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Returns true if a and b point to the same object
|
||||
// Returns true if a and b point to the same object.
|
||||
func referSameObject(a, b metav1.OwnerReference) bool {
|
||||
aGV, err := schema.ParseGroupVersion(a.APIVersion)
|
||||
if err != nil {
|
||||
@@ -170,16 +169,20 @@ func referSameObject(a, b metav1.OwnerReference) bool {
|
||||
return aGV.Group == bGV.Group && a.Kind == b.Kind && a.Name == b.Name
|
||||
}
|
||||
|
||||
// OperationResult is the action result of a CreateOrUpdate call
|
||||
// OperationResult is the action result of a CreateOrUpdate call.
|
||||
type OperationResult string
|
||||
|
||||
const ( // They should complete the sentence "Deployment default/foo has been ..."
|
||||
// OperationResultNone means that the resource has not been changed
|
||||
// OperationResultNone means that the resource has not been changed.
|
||||
OperationResultNone OperationResult = "unchanged"
|
||||
// OperationResultCreated means that a new resource is created
|
||||
// OperationResultCreated means that a new resource is created.
|
||||
OperationResultCreated OperationResult = "created"
|
||||
// OperationResultUpdated means that an existing resource is updated
|
||||
// OperationResultUpdated means that an existing resource is updated.
|
||||
OperationResultUpdated OperationResult = "updated"
|
||||
// OperationResultUpdatedStatus means that an existing resource and its status is updated.
|
||||
OperationResultUpdatedStatus OperationResult = "updatedStatus"
|
||||
// OperationResultUpdatedStatusOnly means that only an existing status is updated.
|
||||
OperationResultUpdatedStatusOnly OperationResult = "updatedStatusOnly"
|
||||
)
|
||||
|
||||
// CreateOrUpdate creates or updates the given object in the Kubernetes
|
||||
@@ -189,14 +192,10 @@ const ( // They should complete the sentence "Deployment default/foo has been ..
|
||||
// The MutateFn is called regardless of creating or updating an object.
|
||||
//
|
||||
// It returns the executed operation and an error.
|
||||
func CreateOrUpdate(ctx context.Context, c client.Client, obj runtime.Object, f MutateFn) (OperationResult, error) {
|
||||
key, err := client.ObjectKeyFromObject(obj)
|
||||
if err != nil {
|
||||
return OperationResultNone, err
|
||||
}
|
||||
|
||||
func CreateOrUpdate(ctx context.Context, c client.Client, obj client.Object, f MutateFn) (OperationResult, error) {
|
||||
key := client.ObjectKeyFromObject(obj)
|
||||
if err := c.Get(ctx, key, obj); err != nil {
|
||||
if !errors.IsNotFound(err) {
|
||||
if !apierrors.IsNotFound(err) {
|
||||
return OperationResultNone, err
|
||||
}
|
||||
if err := mutate(f, key, obj); err != nil {
|
||||
@@ -208,7 +207,7 @@ func CreateOrUpdate(ctx context.Context, c client.Client, obj runtime.Object, f
|
||||
return OperationResultCreated, nil
|
||||
}
|
||||
|
||||
existing := obj.DeepCopyObject()
|
||||
existing := obj.DeepCopyObject() //nolint:ifshort
|
||||
if err := mutate(f, key, obj); err != nil {
|
||||
return OperationResultNone, err
|
||||
}
|
||||
@@ -223,12 +222,124 @@ func CreateOrUpdate(ctx context.Context, c client.Client, obj runtime.Object, f
|
||||
return OperationResultUpdated, nil
|
||||
}
|
||||
|
||||
// mutate wraps a MutateFn and applies validation to its result
|
||||
func mutate(f MutateFn, key client.ObjectKey, obj runtime.Object) error {
|
||||
// CreateOrPatch creates or patches the given object in the Kubernetes
|
||||
// cluster. The object's desired state must be reconciled with the before
|
||||
// state inside the passed in callback MutateFn.
|
||||
//
|
||||
// The MutateFn is called regardless of creating or updating an object.
|
||||
//
|
||||
// It returns the executed operation and an error.
|
||||
func CreateOrPatch(ctx context.Context, c client.Client, obj client.Object, f MutateFn) (OperationResult, error) {
|
||||
key := client.ObjectKeyFromObject(obj)
|
||||
if err := c.Get(ctx, key, obj); err != nil {
|
||||
if !apierrors.IsNotFound(err) {
|
||||
return OperationResultNone, err
|
||||
}
|
||||
if f != nil {
|
||||
if err := mutate(f, key, obj); err != nil {
|
||||
return OperationResultNone, err
|
||||
}
|
||||
}
|
||||
if err := c.Create(ctx, obj); err != nil {
|
||||
return OperationResultNone, err
|
||||
}
|
||||
return OperationResultCreated, nil
|
||||
}
|
||||
|
||||
// Create patches for the object and its possible status.
|
||||
objPatch := client.MergeFrom(obj.DeepCopyObject().(client.Object))
|
||||
statusPatch := client.MergeFrom(obj.DeepCopyObject().(client.Object))
|
||||
|
||||
// Create a copy of the original object as well as converting that copy to
|
||||
// unstructured data.
|
||||
before, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj.DeepCopyObject())
|
||||
if err != nil {
|
||||
return OperationResultNone, err
|
||||
}
|
||||
|
||||
// Attempt to extract the status from the resource for easier comparison later
|
||||
beforeStatus, hasBeforeStatus, err := unstructured.NestedFieldCopy(before, "status")
|
||||
if err != nil {
|
||||
return OperationResultNone, err
|
||||
}
|
||||
|
||||
// If the resource contains a status then remove it from the unstructured
|
||||
// copy to avoid unnecessary patching later.
|
||||
if hasBeforeStatus {
|
||||
unstructured.RemoveNestedField(before, "status")
|
||||
}
|
||||
|
||||
// Mutate the original object.
|
||||
if f != nil {
|
||||
if err := mutate(f, key, obj); err != nil {
|
||||
return OperationResultNone, err
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the resource to unstructured to compare against our before copy.
|
||||
after, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
|
||||
if err != nil {
|
||||
return OperationResultNone, err
|
||||
}
|
||||
|
||||
// Attempt to extract the status from the resource for easier comparison later
|
||||
afterStatus, hasAfterStatus, err := unstructured.NestedFieldCopy(after, "status")
|
||||
if err != nil {
|
||||
return OperationResultNone, err
|
||||
}
|
||||
|
||||
// If the resource contains a status then remove it from the unstructured
|
||||
// copy to avoid unnecessary patching later.
|
||||
if hasAfterStatus {
|
||||
unstructured.RemoveNestedField(after, "status")
|
||||
}
|
||||
|
||||
result := OperationResultNone
|
||||
|
||||
if !reflect.DeepEqual(before, after) {
|
||||
// Only issue a Patch if the before and after resources (minus status) differ
|
||||
if err := c.Patch(ctx, obj, objPatch); err != nil {
|
||||
return result, err
|
||||
}
|
||||
result = OperationResultUpdated
|
||||
}
|
||||
|
||||
if (hasBeforeStatus || hasAfterStatus) && !reflect.DeepEqual(beforeStatus, afterStatus) {
|
||||
// Only issue a Status Patch if the resource has a status and the beforeStatus
|
||||
// and afterStatus copies differ
|
||||
if result == OperationResultUpdated {
|
||||
// If Status was replaced by Patch before, set it to afterStatus
|
||||
objectAfterPatch, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
if err = unstructured.SetNestedField(objectAfterPatch, afterStatus, "status"); err != nil {
|
||||
return result, err
|
||||
}
|
||||
// If Status was replaced by Patch before, restore patched structure to the obj
|
||||
if err = runtime.DefaultUnstructuredConverter.FromUnstructured(objectAfterPatch, obj); err != nil {
|
||||
return result, err
|
||||
}
|
||||
}
|
||||
if err := c.Status().Patch(ctx, obj, statusPatch); err != nil {
|
||||
return result, err
|
||||
}
|
||||
if result == OperationResultUpdated {
|
||||
result = OperationResultUpdatedStatus
|
||||
} else {
|
||||
result = OperationResultUpdatedStatusOnly
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// mutate wraps a MutateFn and applies validation to its result.
|
||||
func mutate(f MutateFn, key client.ObjectKey, obj client.Object) error {
|
||||
if err := f(); err != nil {
|
||||
return err
|
||||
}
|
||||
if newKey, err := client.ObjectKeyFromObject(obj); err != nil || key != newKey {
|
||||
if newKey := client.ObjectKeyFromObject(obj); key != newKey {
|
||||
return fmt.Errorf("MutateFn cannot mutate object name and/or object namespace")
|
||||
}
|
||||
return nil
|
||||
@@ -238,7 +349,7 @@ func mutate(f MutateFn, key client.ObjectKey, obj runtime.Object) error {
|
||||
type MutateFn func() error
|
||||
|
||||
// AddFinalizer accepts an Object and adds the provided finalizer if not present.
|
||||
func AddFinalizer(o Object, finalizer string) {
|
||||
func AddFinalizer(o client.Object, finalizer string) {
|
||||
f := o.GetFinalizers()
|
||||
for _, e := range f {
|
||||
if e == finalizer {
|
||||
@@ -248,21 +359,8 @@ func AddFinalizer(o Object, finalizer string) {
|
||||
o.SetFinalizers(append(f, finalizer))
|
||||
}
|
||||
|
||||
// AddFinalizerWithError tries to convert a runtime object to a metav1 object and add the provided finalizer.
|
||||
// It returns an error if the provided object cannot provide an accessor.
|
||||
//
|
||||
// Deprecated: Use AddFinalizer instead. Check is performing on compile time.
|
||||
func AddFinalizerWithError(o runtime.Object, finalizer string) error {
|
||||
m, err := meta.Accessor(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
AddFinalizer(m.(Object), finalizer)
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveFinalizer accepts an Object and removes the provided finalizer if present.
|
||||
func RemoveFinalizer(o Object, finalizer string) {
|
||||
func RemoveFinalizer(o client.Object, finalizer string) {
|
||||
f := o.GetFinalizers()
|
||||
for i := 0; i < len(f); i++ {
|
||||
if f[i] == finalizer {
|
||||
@@ -273,21 +371,8 @@ func RemoveFinalizer(o Object, finalizer string) {
|
||||
o.SetFinalizers(f)
|
||||
}
|
||||
|
||||
// RemoveFinalizerWithError tries to convert a runtime object to a metav1 object and remove the provided finalizer.
|
||||
// It returns an error if the provided object cannot provide an accessor.
|
||||
//
|
||||
// Deprecated: Use RemoveFinalizer instead. Check is performing on compile time.
|
||||
func RemoveFinalizerWithError(o runtime.Object, finalizer string) error {
|
||||
m, err := meta.Accessor(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
RemoveFinalizer(m.(Object), finalizer)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContainsFinalizer checks an Object that the provided finalizer is present.
|
||||
func ContainsFinalizer(o Object, finalizer string) bool {
|
||||
func ContainsFinalizer(o client.Object, finalizer string) bool {
|
||||
f := o.GetFinalizers()
|
||||
for _, e := range f {
|
||||
if e == finalizer {
|
||||
@@ -299,7 +384,6 @@ func ContainsFinalizer(o Object, finalizer string) bool {
|
||||
|
||||
// Object allows functions to work indistinctly with any resource that
|
||||
// implements both Object interfaces.
|
||||
type Object interface {
|
||||
metav1.Object
|
||||
runtime.Object
|
||||
}
|
||||
//
|
||||
// Deprecated: Use client.Object instead.
|
||||
type Object = client.Object
|
||||
|
||||
Reference in New Issue
Block a user