/
persistentvolumeclaim.go
103 lines (88 loc) · 3.3 KB
/
persistentvolumeclaim.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package persistentvolume
import (
"context"
"github.com/ViaQ/logerr/v2/kverrors"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/equality"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/client-go/util/retry"
"sigs.k8s.io/controller-runtime/pkg/client"
)
// EqualityPVCFunc is the type for functions that compare two persistentvolumeclaims.
// Return true if two persistentvolumeclaim are equal.
type EqualityPVCFunc func(current, desired *corev1.PersistentVolumeClaim) bool
// MutatePVCFunc is the type for functions that mutate the current persistentvolumeclaim
// by applying the values from the desired persistentvolumeclaim.
type MutatePVCFunc func(current, desired *corev1.PersistentVolumeClaim)
// CreateOrUpdatePVC attempts first to get the given persistentvolumeclaim. If the
// persistentvolumeclaim does not exist, the persistentvolumeclaim will be created. Otherwise,
// if the persistentvolumeclaim exists and the provided comparison func detects any changes
// an update is attempted. Updates are retried with backoff (See retry.DefaultRetry).
// Returns on failure an non-nil error.
func CreateOrUpdatePVC(ctx context.Context, c client.Client, pvc *corev1.PersistentVolumeClaim, equal EqualityPVCFunc, mutate MutatePVCFunc) error {
current := &corev1.PersistentVolumeClaim{}
key := client.ObjectKey{Name: pvc.Name, Namespace: pvc.Namespace}
err := c.Get(ctx, key, current)
if err != nil {
if apierrors.IsNotFound(err) {
err = c.Create(ctx, pvc)
if err == nil {
return nil
}
return kverrors.Wrap(err, "failed to create persistentvolumeclaim",
"name", pvc.Name,
"namespace", pvc.Namespace,
)
}
return kverrors.Wrap(err, "failed to get persistentvolumeclaim",
"name", pvc.Name,
"namespace", pvc.Namespace,
)
}
if !equal(current, pvc) {
err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
if err := c.Get(ctx, key, current); err != nil {
return kverrors.Wrap(err, "failed to get persistentvolumeclaim",
"name", pvc.Name,
"namespace", pvc.Namespace,
)
}
mutate(current, pvc)
if err := c.Update(ctx, current); err != nil {
return err
}
return nil
})
if err != nil {
return kverrors.Wrap(err, "failed to update persistentvolumeclaim",
"name", pvc.Name,
"namespace", pvc.Namespace,
)
}
return nil
}
return nil
}
// LabelsEqual return only true if the pvcs are equal in labels only.
func LabelsEqual(current, desired *corev1.PersistentVolumeClaim) bool {
return equality.Semantic.DeepEqual(current.Labels, desired.Labels)
}
// MutateLabelsOnly is a default mutate function implementation
// that copies only the labels from desired to current persistentvolumeclaim.
func MutateLabelsOnly(current, desired *corev1.PersistentVolumeClaim) {
current.Labels = desired.Labels
}
// List returns a list of pods that match the given selector.
func ListPVC(ctx context.Context, c client.Client, namespace string, selector map[string]string) ([]corev1.PersistentVolumeClaim, error) {
list := &corev1.PersistentVolumeClaimList{}
opts := []client.ListOption{
client.InNamespace(namespace),
client.MatchingLabels(selector),
}
if err := c.List(ctx, list, opts...); err != nil {
return nil, kverrors.Wrap(err, "failed to list persistentvolumeclaim",
"namespace", namespace,
)
}
return list.Items, nil
}