/
crds.go
61 lines (53 loc) · 1.83 KB
/
crds.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
package velero
import (
"context"
"reflect"
veleroInstall "github.com/vmware-tanzu/velero/pkg/install"
"github.com/go-logr/logr"
apiv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
)
// InstallVeleroCRDs ensures that operator dependencies are installed at runtime.
func InstallVeleroCRDs(log logr.Logger, client client.Client) error {
var err error
// Install CRDs
for _, unstructuredCrd := range veleroInstall.AllCRDs().Items {
// Get upstream crds
crd := &apiv1.CustomResourceDefinition{}
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructuredCrd.Object, crd); err != nil {
return err
}
// Add Conversion to the spec, as this will be returned in the founcCrd
crd.Spec.Conversion = &apiv1.CustomResourceConversion{
Strategy: apiv1.NoneConverter,
}
// Lookup for installed/pre-existing crds
foundCrd := &apiv1.CustomResourceDefinition{}
if err = client.Get(context.TODO(), types.NamespacedName{Name: crd.ObjectMeta.Name}, foundCrd); err != nil {
if errors.IsNotFound(err) {
// Didn't find CRD, we should create it.
log.Info("Creating CRD", "CRD.Name", crd.ObjectMeta.Name)
if err = client.Create(context.TODO(), crd); err != nil {
return err
}
} else {
// Return other errors
return err
}
} else {
// CRD exists, check if it's updated.
if !reflect.DeepEqual(foundCrd.Spec, crd.Spec) {
// Specs aren't equal, update and fix.
log.Info("Updating CRD", "CRD.Name", crd.ObjectMeta.Name, "foundCrd.Spec", foundCrd.Spec, "crd.Spec", crd.Spec)
foundCrd.Spec = *crd.Spec.DeepCopy()
if err = client.Update(context.TODO(), foundCrd); err != nil {
return err
}
}
}
}
return nil
}