forked from kubermatic/kubermatic
/
unstructured.go
69 lines (55 loc) · 2.7 KB
/
unstructured.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/*
Copyright 2020 The Kubermatic Kubernetes Platform contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package reconciling
import (
"context"
"fmt"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
ctrlruntimeclient "sigs.k8s.io/controller-runtime/pkg/client"
)
// UnstructuredCreator defines an interface to create/update Unstructureds
type UnstructuredCreator = func(existing *unstructured.Unstructured) (*unstructured.Unstructured, error)
// NamedUnstructuredCreatorGetter returns the name of the resource and the corresponding creator function
type NamedUnstructuredCreatorGetter = func() (name, kind, apiVersion string, create UnstructuredCreator)
// UnstructuredObjectWrapper adds a wrapper so the UnstructuredCreator matches ObjectCreator.
// This is needed as Go does not support function interface matching.
func UnstructuredObjectWrapper(create UnstructuredCreator, emptyObject *unstructured.Unstructured) ObjectCreator {
return func(existing runtime.Object) (runtime.Object, error) {
if existing != nil {
return create(existing.(*unstructured.Unstructured))
}
return create(emptyObject)
}
}
// ReconcileUnstructureds will create and update the Unstructureds coming from the passed UnstructuredCreator slice
func ReconcileUnstructureds(ctx context.Context, namedGetters []NamedUnstructuredCreatorGetter, namespace string, client ctrlruntimeclient.Client, objectModifiers ...ObjectModifier) error {
for _, get := range namedGetters {
name, kind, apiVersion, create := get()
if kind == "" || apiVersion == "" {
return fmt.Errorf("both Kind(%q) and apiVersion(%q) must be set", kind, apiVersion)
}
emptyObject := &unstructured.Unstructured{}
emptyObject.SetKind(kind)
emptyObject.SetAPIVersion(apiVersion)
createObject := UnstructuredObjectWrapper(create, emptyObject)
for _, objectModifier := range objectModifiers {
createObject = objectModifier(createObject)
}
if err := EnsureNamedObject(ctx, types.NamespacedName{Namespace: namespace, Name: name}, createObject, client, emptyObject, false); err != nil {
return fmt.Errorf("failed to ensure Unstructured %s.%s %s/%s: %v", kind, apiVersion, namespace, name, err)
}
}
return nil
}