|
23 | 23 | package k8sutil |
24 | 24 |
|
25 | 25 | import ( |
26 | | - "fmt" |
27 | 26 | "strconv" |
| 27 | + "time" |
28 | 28 |
|
| 29 | + "github.com/arangodb/arangosync/pkg/retry" |
29 | 30 | "k8s.io/api/storage/v1" |
30 | | - "k8s.io/apimachinery/pkg/types" |
| 31 | + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
31 | 32 | storagev1 "k8s.io/client-go/kubernetes/typed/storage/v1" |
32 | 33 | ) |
33 | 34 |
|
34 | | -const ( |
35 | | - annStorageClassIsDefault = "storageclass.kubernetes.io/is-default-class" |
| 35 | +var ( |
| 36 | + annStorageClassIsDefault = []string{ |
| 37 | + // Make sure first entry is the one we'll put in |
| 38 | + "storageclass.kubernetes.io/is-default-class", |
| 39 | + "storageclass.beta.kubernetes.io/is-default-class", |
| 40 | + } |
36 | 41 | ) |
37 | 42 |
|
38 | 43 | // StorageClassIsDefault returns true if the given storage class is marked default, |
39 | 44 | // false otherwise. |
40 | 45 | func StorageClassIsDefault(sc *v1.StorageClass) bool { |
41 | | - value, found := sc.GetObjectMeta().GetAnnotations()[annStorageClassIsDefault] |
42 | | - if !found { |
43 | | - return false |
44 | | - } |
45 | | - boolValue, err := strconv.ParseBool(value) |
46 | | - if err != nil { |
47 | | - return false |
| 46 | + for _, key := range annStorageClassIsDefault { |
| 47 | + if value, found := sc.GetObjectMeta().GetAnnotations()[key]; found { |
| 48 | + if boolValue, err := strconv.ParseBool(value); err == nil && boolValue { |
| 49 | + return true |
| 50 | + } |
| 51 | + } |
48 | 52 | } |
49 | | - return boolValue |
| 53 | + return false |
50 | 54 | } |
51 | 55 |
|
52 | 56 | // PatchStorageClassIsDefault changes the default flag of the given storage class. |
53 | 57 | func PatchStorageClassIsDefault(cli storagev1.StorageV1Interface, name string, isDefault bool) error { |
54 | | - jsonPatch := fmt.Sprintf(`{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"%v"}}}`, isDefault) |
55 | | - if _, err := cli.StorageClasses().Patch(name, types.StrategicMergePatchType, []byte(jsonPatch)); err != nil { |
| 58 | + stcs := cli.StorageClasses() |
| 59 | + op := func() error { |
| 60 | + // Fetch current version of StorageClass |
| 61 | + current, err := stcs.Get(name, metav1.GetOptions{}) |
| 62 | + if IsNotFound(err) { |
| 63 | + return retry.Permanent(maskAny(err)) |
| 64 | + } else if err != nil { |
| 65 | + return maskAny(err) |
| 66 | + } |
| 67 | + // Tweak annotations |
| 68 | + ann := current.GetAnnotations() |
| 69 | + if ann == nil { |
| 70 | + ann = make(map[string]string) |
| 71 | + } |
| 72 | + for _, key := range annStorageClassIsDefault { |
| 73 | + delete(ann, key) |
| 74 | + } |
| 75 | + ann[annStorageClassIsDefault[0]] = strconv.FormatBool(isDefault) |
| 76 | + current.SetAnnotations(ann) |
| 77 | + // Save StorageClass |
| 78 | + if _, err := stcs.Update(current); IsConflict(err) { |
| 79 | + // StorageClass has been modified since we read it |
| 80 | + return maskAny(err) |
| 81 | + } else if err != nil { |
| 82 | + return retry.Permanent(maskAny(err)) |
| 83 | + } |
| 84 | + return nil |
| 85 | + } |
| 86 | + if err := retry.Retry(op, time.Second*15); err != nil { |
56 | 87 | return maskAny(err) |
57 | 88 | } |
58 | 89 | return nil |
|
0 commit comments