Skip to content

Commit 7ae5d0e

Browse files
committed
Add CreateOrUpdate utility method
1 parent 471f9cd commit 7ae5d0e

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

pkg/controller/controllerutil/controllerutil.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@ limitations under the License.
1717
package controllerutil
1818

1919
import (
20+
"context"
2021
"fmt"
22+
"reflect"
2123

24+
"k8s.io/apimachinery/pkg/api/errors"
2225
"k8s.io/apimachinery/pkg/apis/meta/v1"
2326
"k8s.io/apimachinery/pkg/runtime"
2427
"k8s.io/apimachinery/pkg/runtime/schema"
28+
"sigs.k8s.io/controller-runtime/pkg/client"
2529
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
2630
)
2731

@@ -97,3 +101,55 @@ func referSameObject(a, b v1.OwnerReference) bool {
97101

98102
return aGV == bGV && a.Kind == b.Kind && a.Name == b.Name
99103
}
104+
105+
// OperationType is the action result of a CreateOrUpdate call
106+
type OperationType string
107+
108+
const ( // They should complete the sentence "v1.Deployment has been ..."
109+
OperationNoop = "unchanged"
110+
OperationCreated = "created"
111+
OperationUpdated = "updated"
112+
)
113+
114+
// CreateOrUpdate creates or updates a kuberenes resource. It takes in a key and
115+
// a placeholder for the existing object and returns the modified object
116+
func CreateOrUpdate(c client.Client, ctx context.Context, key client.ObjectKey, existing runtime.Object, t TransformFn) (runtime.Object, OperationType, error) {
117+
err := c.Get(ctx, key, existing)
118+
var obj runtime.Object
119+
120+
if errors.IsNotFound(err) {
121+
obj, err = t(existing)
122+
if err != nil {
123+
return nil, OperationNoop, err
124+
}
125+
126+
err = c.Create(ctx, obj)
127+
if err != nil {
128+
return nil, OperationNoop, err
129+
} else {
130+
return obj, OperationCreated, err
131+
}
132+
} else if err != nil {
133+
return nil, OperationNoop, err
134+
} else {
135+
obj, err = t(existing.DeepCopyObject())
136+
if err != nil {
137+
return nil, OperationNoop, err
138+
}
139+
140+
if !reflect.DeepEqual(existing, obj) {
141+
err = c.Update(ctx, obj)
142+
if err != nil {
143+
return nil, OperationNoop, err
144+
} else {
145+
return obj, OperationUpdated, err
146+
}
147+
} else {
148+
return obj, OperationNoop, nil
149+
}
150+
}
151+
}
152+
153+
// TransformFn is a function which take in a kubernetes object and returns the
154+
// desired state of that object
155+
type TransformFn func(in runtime.Object) (runtime.Object, error)

0 commit comments

Comments
 (0)