-
Notifications
You must be signed in to change notification settings - Fork 152
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding a Kanister function to delete CSI VolumeSnapshot (#1172)
* Added new function RestoreCSISnapshot * reviewer comments * Fixed failed to render outputartifact template 'snapshotInfo' issue * Updated const comments * Updated the return obj for the function * Added documentation for RestoreCSISnapshot function * Added test suite for RestoreCSISnapshot func * gofmt update * Reviewer comments * Updated the testcase for RestoreCSISnapshot function * Updated the createPVC method in testcase * Fixed RBAC YAML * Added the DeleteCSISnapshot function * Added RBAC updates * Added testcase for DeleteCSISnapshot function * gofmt fix * Added documentation for DeleteCSISnapshot function * Updated the namespace in testcase * Added validations for volumeMode and accessMode * Updated the logic to validate volume mode * context update * context update * Fixed the validateVolumeModeArg method * Added testcase for arg validation * gofmt updates * Added Note in the docs * Added table driven testcases for validate methods * Removed multiple context.Background() calls and removed the validate method calls in main test case * style: Add whitespace in error messages * refactor: Update const names in test files * refactor: Update length of random alphanumeric suffix to 5 characters * refactor: Update const in test file * refactor: Update argument validation methods * style: Fix typo in a comment * refactor: Update call to validate methods in restore unit test * refactor: Update restore test case as per reviewer comment * refactor: Update CreateCSiSnapshot function and the test case * refactor: Revert random alphanumeric string length * fix: gofmt error * refactor: Update CreateCSiSnapshot function and the test case * refactor: Update CreateCSiSnapshot function and the test case * refactor: Update CreateCSiSnapshot function and the test case * refactor: Moved code out of Exec method * chore: Update signature of the restoreCSISnapshot method * refactor: Revert CreateCSISnapshot Func changes in this PR * refactor: Update create snapshot unit test * fix: CI failure * chore: Comment update * fix: golangci-lint fix * Comment update in delete snapshot unit test * Update comment in delete snapshot unit test * Update for CI re-run * Fix CI issue MySQL GPG failed Please refer the bug logged at https://bugs.mysql.com/bug.php\?id\=106188 for more details Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
- Loading branch information
1 parent
b10d298
commit cdc321c
Showing
3 changed files
with
258 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// Copyright 2022 The Kanister Authors. | ||
// | ||
// 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 function | ||
|
||
import ( | ||
"context" | ||
|
||
v1 "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1" | ||
|
||
kanister "github.com/kanisterio/kanister/pkg" | ||
"github.com/kanisterio/kanister/pkg/kube" | ||
"github.com/kanisterio/kanister/pkg/kube/snapshot" | ||
"github.com/kanisterio/kanister/pkg/param" | ||
) | ||
|
||
func init() { | ||
_ = kanister.Register(&deleteCSISnapshotFunc{}) | ||
} | ||
|
||
var ( | ||
_ kanister.Func = (*deleteCSISnapshotFunc)(nil) | ||
) | ||
|
||
const ( | ||
// DeleteCSIVolumeSnapshotFuncName gives the name of the function | ||
DeleteCSISnapshotFuncName = "DeleteCSISnapshot" | ||
// DeleteCSISnapshotNameArg provides name of the VolumeSnapshot that needs to be deleted | ||
DeleteCSISnapshotNameArg = "name" | ||
// DeleteCSISnapshotNamespaceArg mentions the namespace where the VolumeSnapshot resides | ||
DeleteCSISnapshotNamespaceArg = "namespace" | ||
) | ||
|
||
type deleteCSISnapshotFunc struct{} | ||
|
||
func (*deleteCSISnapshotFunc) Name() string { | ||
return DeleteCSISnapshotFuncName | ||
} | ||
|
||
func (*deleteCSISnapshotFunc) Exec(ctx context.Context, tp param.TemplateParams, args map[string]interface{}) (map[string]interface{}, error) { | ||
var name, namespace string | ||
if err := Arg(args, DeleteCSISnapshotNameArg, &name); err != nil { | ||
return nil, err | ||
} | ||
if err := Arg(args, DeleteCSISnapshotNamespaceArg, &namespace); err != nil { | ||
return nil, err | ||
} | ||
kubeCli, err := kube.NewClient() | ||
if err != nil { | ||
return nil, err | ||
} | ||
dynCli, err := kube.NewDynamicClient() | ||
if err != nil { | ||
return nil, err | ||
} | ||
snapshotter, err := snapshot.NewSnapshotter(kubeCli, dynCli) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if _, err := deleteCSISnapshot(ctx, snapshotter, name, namespace); err != nil { | ||
return nil, err | ||
} | ||
return nil, nil | ||
} | ||
|
||
func (*deleteCSISnapshotFunc) RequiredArgs() []string { | ||
return []string{ | ||
DeleteCSISnapshotNameArg, | ||
DeleteCSISnapshotNamespaceArg, | ||
} | ||
} | ||
|
||
func deleteCSISnapshot(ctx context.Context, snapshotter snapshot.Snapshotter, name, namespace string) (*v1.VolumeSnapshot, error) { | ||
return snapshotter.Delete(ctx, name, namespace) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
// Copyright 2022 The Kanister Authors. | ||
// | ||
// 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 function | ||
|
||
import ( | ||
"context" | ||
|
||
. "gopkg.in/check.v1" | ||
v1 "k8s.io/api/core/v1" | ||
"k8s.io/apimachinery/pkg/api/resource" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/runtime" | ||
dynfake "k8s.io/client-go/dynamic/fake" | ||
"k8s.io/client-go/kubernetes/fake" | ||
|
||
"github.com/kanisterio/kanister/pkg/kube/snapshot" | ||
) | ||
|
||
const ( | ||
// testDeleteNamespace specifies the namespace where testing is done | ||
testDeleteNamespace = "test-delete-csi-snapshot" | ||
) | ||
|
||
type DeleteCSISnapshotTestSuite struct { | ||
snapName string | ||
pvcName string | ||
newPVCName string | ||
namespace string | ||
volumeSnapshotClass string | ||
storageClass string | ||
} | ||
|
||
var _ = Suite(&DeleteCSISnapshotTestSuite{}) | ||
|
||
func (testSuite *DeleteCSISnapshotTestSuite) SetUpSuite(c *C) { | ||
testSuite.volumeSnapshotClass = snapshotClass | ||
testSuite.storageClass = storageClass | ||
testSuite.pvcName = originalPVCName | ||
testSuite.newPVCName = newPVCName | ||
testSuite.snapName = snapshotName | ||
testSuite.namespace = testDeleteNamespace | ||
} | ||
|
||
func (testSuite *DeleteCSISnapshotTestSuite) TestDeleteCSISnapshot(c *C) { | ||
for _, apiResourceList := range []*metav1.APIResourceList{ | ||
{ | ||
TypeMeta: metav1.TypeMeta{ | ||
Kind: "VolumeSnapshot", | ||
APIVersion: "v1alpha1", | ||
}, | ||
GroupVersion: "snapshot.storage.k8s.io/v1alpha1", | ||
}, | ||
{ | ||
TypeMeta: metav1.TypeMeta{ | ||
Kind: "VolumeSnapshot", | ||
APIVersion: "v1beta1", | ||
}, | ||
GroupVersion: "snapshot.storage.k8s.io/v1beta1", | ||
}, | ||
{ | ||
TypeMeta: metav1.TypeMeta{ | ||
Kind: "VolumeSnapshot", | ||
APIVersion: "v1", | ||
}, | ||
GroupVersion: "snapshot.storage.k8s.io/v1", | ||
}, | ||
} { | ||
ctx := context.Background() | ||
fakeCli := fake.NewSimpleClientset() | ||
fakeCli.Resources = []*metav1.APIResourceList{apiResourceList} | ||
|
||
_, err := fakeCli.CoreV1().Namespaces().Create(ctx, &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: testSuite.namespace}}, metav1.CreateOptions{}) | ||
c.Assert(err, IsNil) | ||
|
||
scheme := runtime.NewScheme() | ||
fakeSnapshotter, err := snapshot.NewSnapshotter(fakeCli, dynfake.NewSimpleDynamicClient(scheme)) | ||
c.Assert(err, IsNil) | ||
|
||
originalPVC := &v1.PersistentVolumeClaim{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: testSuite.pvcName, | ||
}, | ||
Spec: v1.PersistentVolumeClaimSpec{ | ||
StorageClassName: &testSuite.storageClass, | ||
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce}, | ||
Resources: v1.ResourceRequirements{ | ||
Requests: v1.ResourceList{ | ||
v1.ResourceStorage: resource.MustParse("1Gi"), | ||
}, | ||
}, | ||
}, | ||
} | ||
_, err = fakeCli.CoreV1().PersistentVolumeClaims(testSuite.namespace).Create(ctx, originalPVC, metav1.CreateOptions{}) | ||
c.Assert(err, IsNil) | ||
|
||
err = fakeSnapshotter.Create(ctx, testSuite.snapName, testSuite.namespace, testSuite.pvcName, &testSuite.volumeSnapshotClass, false, nil) | ||
c.Assert(err, IsNil) | ||
|
||
vs, err := fakeSnapshotter.Get(ctx, testSuite.snapName, testSuite.namespace) | ||
c.Assert(err, IsNil) | ||
c.Assert(vs.Name, Equals, testSuite.snapName) | ||
|
||
restoreArgs := restoreCSISnapshotArgs{ | ||
Name: testSuite.snapName, | ||
PVC: testSuite.newPVCName, | ||
Namespace: testSuite.namespace, | ||
StorageClass: testSuite.storageClass, | ||
RestoreSize: originalPVC.Spec.Resources.Requests.Storage(), | ||
AccessModes: originalPVC.Spec.AccessModes, | ||
Labels: nil, | ||
} | ||
newPVC := newPVCManifest(restoreArgs) | ||
_, err = fakeCli.CoreV1().PersistentVolumeClaims(restoreArgs.Namespace).Create(ctx, newPVC, metav1.CreateOptions{}) | ||
c.Assert(err, IsNil) | ||
c.Assert(newPVC.Name, Equals, testSuite.newPVCName) | ||
|
||
_, err = deleteCSISnapshot(ctx, fakeSnapshotter, testSuite.snapName, testSuite.namespace) | ||
c.Assert(err, IsNil) | ||
_, err = fakeSnapshotter.Get(ctx, testSuite.snapName, testSuite.namespace) | ||
c.Assert(err, NotNil) | ||
|
||
err = fakeCli.CoreV1().Namespaces().Delete(ctx, testSuite.namespace, metav1.DeleteOptions{}) | ||
c.Assert(err, IsNil) | ||
} | ||
} |