Skip to content

Commit afff041

Browse files
author
Grant Griffiths
committed
WIP
Signed-off-by: Grant Griffiths <[email protected]>
1 parent 73f3def commit afff041

File tree

4 files changed

+138
-26
lines changed

4 files changed

+138
-26
lines changed

deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,16 @@ rules:
3434
verbs: ["get", "list", "watch"]
3535
- apiGroups: ["snapshot.storage.k8s.io"]
3636
resources: ["volumesnapshotcontents"]
37-
verbs: ["create", "get", "list", "watch", "update", "delete"]
37+
verbs: ["create", "get", "list", "watch", "update", "delete", "patch"]
38+
- apiGroups: ["snapshot.storage.k8s.io"]
39+
resources: ["volumesnapshotcontents/status"]
40+
verbs: ["patch"]
3841
- apiGroups: ["snapshot.storage.k8s.io"]
3942
resources: ["volumesnapshots"]
40-
verbs: ["get", "list", "watch", "update"]
43+
verbs: ["get", "list", "watch", "update", "patch"]
4144
- apiGroups: ["snapshot.storage.k8s.io"]
4245
resources: ["volumesnapshots/status"]
43-
verbs: ["update"]
46+
verbs: ["update", "patch"]
4447

4548
---
4649
kind: ClusterRoleBinding

pkg/common-controller/snapshot_controller.go

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,19 @@ func (ctrl *csiSnapshotCommonController) updateSnapshotErrorStatusWithEvent(snap
809809

810810
// addContentFinalizer adds a Finalizer for VolumeSnapshotContent.
811811
func (ctrl *csiSnapshotCommonController) addContentFinalizer(content *crdv1.VolumeSnapshotContent) error {
812+
// patches := []utils.PatchOp{
813+
// {
814+
// Op: "add",
815+
// Path: "/metadata/finalizers/-",
816+
// Value: utils.VolumeSnapshotContentFinalizer,
817+
// },
818+
// }
819+
820+
// newContent, err := utils.PatchVolumeSnapshotContent(content, patches, ctrl.clientset)
821+
// if err != nil {
822+
// return newControllerUpdateError(content.Name, err.Error())
823+
// }
824+
812825
contentClone := content.DeepCopy()
813826
contentClone.ObjectMeta.Finalizers = append(contentClone.ObjectMeta.Finalizers, utils.VolumeSnapshotContentFinalizer)
814827

@@ -1392,24 +1405,55 @@ func isControllerUpdateFailError(err *crdv1.VolumeSnapshotError) bool {
13921405

13931406
// addSnapshotFinalizer adds a Finalizer for VolumeSnapshot.
13941407
func (ctrl *csiSnapshotCommonController) addSnapshotFinalizer(snapshot *crdv1.VolumeSnapshot, addSourceFinalizer bool, addBoundFinalizer bool) error {
1395-
snapshotClone := snapshot.DeepCopy()
1396-
if addSourceFinalizer {
1397-
snapshotClone.ObjectMeta.Finalizers = append(snapshotClone.ObjectMeta.Finalizers, utils.VolumeSnapshotAsSourceFinalizer)
1398-
}
1399-
if addBoundFinalizer {
1400-
snapshotClone.ObjectMeta.Finalizers = append(snapshotClone.ObjectMeta.Finalizers, utils.VolumeSnapshotBoundFinalizer)
1401-
}
1402-
newSnapshot, err := ctrl.clientset.SnapshotV1().VolumeSnapshots(snapshotClone.Namespace).Update(context.TODO(), snapshotClone, metav1.UpdateOptions{})
1403-
if err != nil {
1404-
return newControllerUpdateError(utils.SnapshotKey(snapshot), err.Error())
1408+
var updatedSnapshot *crdv1.VolumeSnapshot
1409+
var err error
1410+
1411+
// Must perform an update if no finalizers exist
1412+
if len(snapshot.ObjectMeta.Finalizers) == 0 {
1413+
snapshotClone := snapshot.DeepCopy()
1414+
if addSourceFinalizer {
1415+
snapshotClone.ObjectMeta.Finalizers = append(snapshotClone.ObjectMeta.Finalizers, utils.VolumeSnapshotAsSourceFinalizer)
1416+
}
1417+
if addBoundFinalizer {
1418+
snapshotClone.ObjectMeta.Finalizers = append(snapshotClone.ObjectMeta.Finalizers, utils.VolumeSnapshotBoundFinalizer)
1419+
}
1420+
updatedSnapshot, err = ctrl.clientset.SnapshotV1().VolumeSnapshots(snapshotClone.Namespace).Update(context.TODO(), snapshotClone, metav1.UpdateOptions{})
1421+
if err != nil {
1422+
return newControllerUpdateError(utils.SnapshotKey(snapshot), err.Error())
1423+
}
1424+
} else {
1425+
// Otherwise, perform a patch
1426+
var patches []utils.PatchOp
1427+
1428+
if addSourceFinalizer {
1429+
patches = append(patches, utils.PatchOp{
1430+
Op: "add",
1431+
Path: "/metadata/finalizers/-",
1432+
Value: utils.VolumeSnapshotAsSourceFinalizer,
1433+
})
1434+
}
1435+
if addBoundFinalizer {
1436+
patches = append(patches, utils.PatchOp{
1437+
Op: "add",
1438+
Path: "/metadata/finalizers/-",
1439+
Value: utils.VolumeSnapshotBoundFinalizer,
1440+
})
1441+
}
1442+
1443+
klog.Infof("GGCSI - ADD SNAPSHOT FINALIZER - snapshot: %v", snapshot)
1444+
klog.Infof("GGCSI - ADD SNAPSHOT FINALIZER - patches: %v", patches)
1445+
updatedSnapshot, err = utils.PatchVolumeSnapshot(snapshot, patches, ctrl.clientset)
1446+
if err != nil {
1447+
return newControllerUpdateError(utils.SnapshotKey(snapshot), err.Error())
1448+
}
14051449
}
14061450

1407-
_, err = ctrl.storeSnapshotUpdate(newSnapshot)
1451+
_, err = ctrl.storeSnapshotUpdate(updatedSnapshot)
14081452
if err != nil {
14091453
klog.Errorf("failed to update snapshot store %v", err)
14101454
}
14111455

1412-
klog.V(5).Infof("Added protection finalizer to volume snapshot %s", utils.SnapshotKey(newSnapshot))
1456+
klog.V(5).Infof("Added protection finalizer to volume snapshot %s", utils.SnapshotKey(updatedSnapshot))
14131457
return nil
14141458
}
14151459

pkg/sidecar-controller/snapshot_controller.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -146,19 +146,26 @@ func (ctrl *csiSnapshotSideCarController) updateContentErrorStatusWithEvent(cont
146146
klog.V(4).Infof("updateContentStatusWithEvent[%s]: the same error %v is already set", content.Name, content.Status.Error)
147147
return nil
148148
}
149-
contentClone := content.DeepCopy()
150-
if contentClone.Status == nil {
151-
contentClone.Status = &crdv1.VolumeSnapshotContentStatus{}
152-
}
153-
contentClone.Status.Error = &crdv1.VolumeSnapshotError{
154-
Time: &metav1.Time{
155-
Time: time.Now(),
149+
150+
ready := false
151+
patch := []utils.PatchOp{
152+
{
153+
Op: "replace",
154+
Path: "/status/error",
155+
Value: &crdv1.VolumeSnapshotError{
156+
Time: &metav1.Time{
157+
Time: time.Now(),
158+
},
159+
Message: &message,
160+
},
161+
},
162+
{
163+
Op: "replace",
164+
Path: "/status/readyToUse",
165+
Value: &ready,
156166
},
157-
Message: &message,
158167
}
159-
ready := false
160-
contentClone.Status.ReadyToUse = &ready
161-
newContent, err := ctrl.clientset.SnapshotV1().VolumeSnapshotContents().UpdateStatus(context.TODO(), contentClone, metav1.UpdateOptions{})
168+
newContent, err := utils.PatchVolumeSnapshotContent(content, patch, ctrl.clientset, "status")
162169

163170
// Emit the event even if the status update fails so that user can see the error
164171
ctrl.eventRecorder.Event(newContent, eventtype, reason, message)

pkg/utils/patch.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package utils
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
7+
crdv1 "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1"
8+
clientset "github.com/kubernetes-csi/external-snapshotter/client/v4/clientset/versioned"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/apimachinery/pkg/types"
11+
)
12+
13+
// PatchOp represents a json patch operation
14+
type PatchOp struct {
15+
Op string `json:"op"`
16+
Path string `json:"path"`
17+
Value interface{} `json:"value,omitempty"`
18+
}
19+
20+
// PatchVolumeSnapshotContent patches a volume snapshot content object
21+
func PatchVolumeSnapshotContent(
22+
existingSnapshotContent *crdv1.VolumeSnapshotContent,
23+
patch []PatchOp,
24+
client clientset.Interface,
25+
subresources ...string,
26+
) (*crdv1.VolumeSnapshotContent, error) {
27+
data, err := json.Marshal(patch)
28+
if nil != err {
29+
return existingSnapshotContent, err
30+
}
31+
32+
newSnapshotContent, err := client.SnapshotV1().VolumeSnapshotContents().Patch(context.TODO(), existingSnapshotContent.Name, types.JSONPatchType, data, metav1.PatchOptions{}, subresources...)
33+
if err != nil {
34+
return existingSnapshotContent, err
35+
}
36+
37+
return newSnapshotContent, nil
38+
}
39+
40+
// PatchVolumeSnapshot patches a volume snapshot object
41+
func PatchVolumeSnapshot(
42+
existingSnapshot *crdv1.VolumeSnapshot,
43+
patch []PatchOp,
44+
client clientset.Interface,
45+
subresources ...string,
46+
) (*crdv1.VolumeSnapshot, error) {
47+
data, err := json.Marshal(patch)
48+
if nil != err {
49+
return existingSnapshot, err
50+
}
51+
52+
newSnapshot, err := client.SnapshotV1().VolumeSnapshots(existingSnapshot.Namespace).Patch(context.TODO(), existingSnapshot.Name, types.JSONPatchType, data, metav1.PatchOptions{}, subresources...)
53+
if err != nil {
54+
return existingSnapshot, err
55+
}
56+
57+
return newSnapshot, nil
58+
}

0 commit comments

Comments
 (0)