Skip to content

Commit 7b394b3

Browse files
committed
Add Support for Restoring OCS Operator CRs in ODF CLI
Signed-off-by: Oded Viner <[email protected]>
1 parent 3d5598e commit 7b394b3

File tree

2 files changed

+129
-2
lines changed

2 files changed

+129
-2
lines changed

cmd/odf/restore/crds.go

+54-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,54 @@
11
package restore
22

33
import (
4+
"fmt"
5+
"strings"
6+
47
"github.com/red-hat-storage/odf-cli/cmd/odf/root"
58
"github.com/rook/kubectl-rook-ceph/pkg/k8sutil"
9+
"github.com/rook/kubectl-rook-ceph/pkg/logging"
610
pkgrestore "github.com/rook/kubectl-rook-ceph/pkg/restore"
711
"github.com/spf13/cobra"
812
)
913

14+
// groupVersions defines the supported CRD groups and their corresponding API versions.
15+
var groupVersions = map[string]string{
16+
"ocs.openshift.io": "v1",
17+
"ceph.rook.io": "v1",
18+
"csi.ceph.io": "v1beta1",
19+
"odf.openshift.io": "v1alpha1",
20+
"noobaa.io": "v1alpha1",
21+
"csiaddons.openshift.io": "v1alpha1",
22+
}
23+
24+
// keys returns the keys of a string map. It is used to print out supported group names.
25+
func keys(m map[string]string) []string {
26+
out := make([]string, 0, len(m))
27+
for k := range m {
28+
out = append(out, k)
29+
}
30+
return out
31+
}
32+
33+
// parseFullyQualifiedCRD takes a fully qualified CRD type of the form "resource.group"
34+
// (for example, "cephclusters.ceph.rook.io") and returns the resource name, group name, and
35+
// the API version associated with that group. It returns an error if the format is invalid
36+
// or the group is not recognized.
37+
func parseFullyQualifiedCRD(fqcrd string) (resourceName, groupName, version string, err error) {
38+
parts := strings.SplitN(fqcrd, ".", 2)
39+
if len(parts) != 2 {
40+
return "", "", "", fmt.Errorf("invalid CRD format %q; expected format <resource>.<group>", fqcrd)
41+
}
42+
resourceName = parts[0]
43+
groupName = parts[1]
44+
45+
ver, ok := groupVersions[groupName]
46+
if !ok {
47+
return "", "", "", fmt.Errorf("unsupported group %q; supported groups are: %v", groupName, keys(groupVersions))
48+
}
49+
return resourceName, groupName, ver, nil
50+
}
51+
1052
// deletedCmd represents the deleted command
1153
var deletedCmd = &cobra.Command{
1254
Use: "deleted",
@@ -20,8 +62,18 @@ var deletedCmd = &cobra.Command{
2062
},
2163
Run: func(cmd *cobra.Command, args []string) {
2264
k8sutil.SetDeploymentScale(cmd.Context(), root.ClientSets.Kube, root.OperatorNamespace, "ocs-operator", 0)
23-
pkgrestore.RestoreCrd(cmd.Context(), root.ClientSets, root.OperatorNamespace, root.StorageClusterNamespace, args)
65+
// Parse the fully qualified CRD (e.g. "cephclusters.ceph.rook.io").
66+
resourceName, groupName, version, err := parseFullyQualifiedCRD(args[0])
67+
if err != nil {
68+
logging.Fatal(fmt.Errorf("Error parsing CRD type: %v\n", err))
69+
}
70+
// Construct a new args slice with the resource name as the first argument.
71+
newArgs := make([]string, len(args))
72+
newArgs[0] = resourceName
73+
if len(args) > 1 {
74+
newArgs[1] = args[1]
75+
}
76+
pkgrestore.RestoreCrd(cmd.Context(), root.ClientSets, root.OperatorNamespace, root.StorageClusterNamespace, groupName, version, newArgs)
2477
k8sutil.SetDeploymentScale(cmd.Context(), root.ClientSets.Kube, root.OperatorNamespace, "ocs-operator", 1)
25-
2678
},
2779
}

cmd/odf/restore/restore_test.go

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package restore
2+
3+
import (
4+
"github.com/stretchr/testify/assert"
5+
"testing"
6+
)
7+
8+
func Test_parseFullyQualifiedCRD(t *testing.T) {
9+
tests := []struct {
10+
name string
11+
input string
12+
expectResource string
13+
expectGroup string
14+
expectVersion string
15+
expectErr bool
16+
expectedErrMsg string
17+
}{
18+
{
19+
name: "valid CRD: cephclusters.ceph.rook.io",
20+
input: "cephclusters.ceph.rook.io",
21+
expectResource: "cephclusters",
22+
expectGroup: "ceph.rook.io",
23+
expectVersion: "v1",
24+
},
25+
{
26+
name: "valid CRD: storageclusters.ocs.openshift.io",
27+
input: "storageclusters.ocs.openshift.io",
28+
expectResource: "storageclusters",
29+
expectGroup: "ocs.openshift.io",
30+
expectVersion: "v1",
31+
},
32+
{
33+
name: "valid CRD: cephconnections.csi.ceph.io",
34+
input: "cephconnections.csi.ceph.io",
35+
expectResource: "cephconnections",
36+
expectGroup: "csi.ceph.io",
37+
expectVersion: "v1beta1",
38+
},
39+
{
40+
name: "valid CRD: storagesystems.odf.openshift.io",
41+
input: "storagesystems.odf.openshift.io",
42+
expectResource: "storagesystems",
43+
expectGroup: "odf.openshift.io",
44+
expectVersion: "v1alpha1",
45+
},
46+
{
47+
name: "invalid format: missing dot",
48+
input: "invalidformat",
49+
expectErr: true,
50+
expectedErrMsg: "invalid CRD format",
51+
},
52+
{
53+
name: "unsupported group",
54+
input: "foo.unsupported.group",
55+
expectErr: true,
56+
expectedErrMsg: "unsupported group",
57+
},
58+
}
59+
60+
for _, tt := range tests {
61+
tt := tt // capture range variable
62+
t.Run(tt.name, func(t *testing.T) {
63+
resource, group, version, err := parseFullyQualifiedCRD(tt.input)
64+
if tt.expectErr {
65+
assert.Error(t, err)
66+
assert.Contains(t, err.Error(), tt.expectedErrMsg)
67+
} else {
68+
assert.NoError(t, err)
69+
assert.Equal(t, tt.expectResource, resource)
70+
assert.Equal(t, tt.expectGroup, group)
71+
assert.Equal(t, tt.expectVersion, version)
72+
}
73+
})
74+
}
75+
}

0 commit comments

Comments
 (0)