From 890b3619db79a2217a603bbe77ae1c7b055aa7c7 Mon Sep 17 00:00:00 2001 From: Rakshith R Date: Thu, 16 Sep 2021 15:15:22 +0530 Subject: [PATCH] rbd admin: add type ImageSpec to work with rbd task api ImageSpec type has been added to work with rbd task api. It consists of optional pool & namespace and image name/id. [pool/][namespace/]image[Name/id]. Added unit tests. Signed-off-by: Rakshith R --- rbd/admin/imagespec.go | 43 +++++++++++++++++ rbd/admin/imagespec_test.go | 96 +++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 rbd/admin/imagespec.go create mode 100644 rbd/admin/imagespec_test.go diff --git a/rbd/admin/imagespec.go b/rbd/admin/imagespec.go new file mode 100644 index 0000000..c95d99b --- /dev/null +++ b/rbd/admin/imagespec.go @@ -0,0 +1,43 @@ +// +build !nautilus,ceph_preview + +package admin + +import ( + "fmt" +) + +// ImageSpec values are used to identify an RBD image wherever Ceph APIs +// require an image_spec/image_id_spec using image name/id and optional +// pool and namespace. +// PREVIEW +type ImageSpec struct { + spec string +} + +// NewImageSpec is used to construct an ImageSpec given an image name/id +// and optional namespace and pool names. +// NewImageSpec constructs an ImageSpec to identify an RBD image and thus +// requires image name/id, whereas NewLevelSpec constructs LevelSpec to +// identify entire pool, pool namespace or single RBD image, all of which +// requires pool name. +// PREVIEW +func NewImageSpec(pool, namespace, image string) ImageSpec { + var s string + if pool != "" && namespace != "" { + s = fmt.Sprintf("%s/%s/%s", pool, namespace, image) + } else if pool != "" { + s = fmt.Sprintf("%s/%s", pool, image) + } else { + s = image + } + return ImageSpec{s} +} + +// NewRawImageSpec returns a ImageSpec directly based on the spec string +// argument without constructing it from component values. This should only be +// used if NewImageSpec can not create the imagespec value you want to pass to +// ceph. +// PREVIEW +func NewRawImageSpec(spec string) ImageSpec { + return ImageSpec{spec} +} diff --git a/rbd/admin/imagespec_test.go b/rbd/admin/imagespec_test.go new file mode 100644 index 0000000..6fdb392 --- /dev/null +++ b/rbd/admin/imagespec_test.go @@ -0,0 +1,96 @@ +// +build !nautilus,ceph_preview + +package admin + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNewImageSpec(t *testing.T) { + type args struct { + pool string + namespace string + image string + } + tests := []struct { + name string + args args + want ImageSpec + }{ + { + name: "onlyImageName", + args: args{ + pool: "", + namespace: "", + image: "img", + }, + want: ImageSpec{ + spec: "img", + }, + }, + { + name: "Image&PoolName", + args: args{ + pool: "pool", + namespace: "", + image: "img", + }, + want: ImageSpec{ + spec: "pool/img", + }, + }, + { + name: "all args", + args: args{ + pool: "pool", + namespace: "ns", + image: "img", + }, + want: ImageSpec{ + spec: "pool/ns/img", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, NewImageSpec(tt.args.pool, tt.args.namespace, tt.args.image)) + }) + } +} + +func TestNewRawImageSpec(t *testing.T) { + type args struct { + spec string + } + tests := []struct { + name string + args args + want ImageSpec + }{ + { + name: "valid", + args: args{ + spec: "pool/img", + }, + want: ImageSpec{ + spec: "pool/img", + }, + }, + { + name: "invalid but still accepts", + args: args{ + spec: "invalid format ...", + }, + want: ImageSpec{ + spec: "invalid format ...", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, NewRawImageSpec(tt.args.spec)) + }) + } +}