Skip to content

Commit 340fefc

Browse files
author
Harsh Vardhan
authored
Add lvmlocalpv vg listing & zfspool listing (#53)
* Make zfslocalpv client testable Signed-off-by: Harsh Vardhan <[email protected]>
1 parent 7c26ad5 commit 340fefc

File tree

12 files changed

+327
-80
lines changed

12 files changed

+327
-80
lines changed

cmd/describe/storage.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ limitations under the License.
1717
package describe
1818

1919
import (
20+
"strings"
21+
2022
"github.com/openebs/openebsctl/pkg/storage"
2123
"github.com/openebs/openebsctl/pkg/util"
2224
"github.com/spf13/cobra"
@@ -50,7 +52,9 @@ func NewCmdDescribeStorage() *cobra.Command {
5052
Example: `kubectl openebs describe storage storage-1`,
5153
Run: func(cmd *cobra.Command, args []string) {
5254
openebsNs, _ := cmd.Flags().GetString("openebs-namespace")
53-
util.CheckErr(storage.Describe(args, openebsNs), util.Fatal)
55+
casType, _ := cmd.Flags().GetString("cas-type")
56+
casType = strings.ToLower(casType)
57+
util.CheckErr(storage.Describe(args, openebsNs, casType), util.Fatal)
5458
},
5559
}
5660
return cmd

go.sum

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,6 @@ github.com/openebs/api/v2 v2.3.0/go.mod h1:nLCaNvVjgjkjeD2a+n1fMbv5HjoEYP4XB8OAb
343343
github.com/openebs/jiva-operator v1.12.2-0.20210607114402-811a3af7c34a h1:HuCp3D9TOhJogGTcH5JePJuebceQhPRgB5SizB0bmTg=
344344
github.com/openebs/jiva-operator v1.12.2-0.20210607114402-811a3af7c34a/go.mod h1:5oMQaMQKa0swN1hJnAP7CEMI/MOLVz0S2Mcu0H/l0oc=
345345
github.com/openebs/lib-csi v0.3.0/go.mod h1:uruyzJiTwRoytQPQXOf4spaezn1cjkiAXjvFGw6aY/8=
346-
github.com/openebs/lib-csi v0.6.0 h1:nucurCo91lKNhtjbYNPJIrbJU0F4oinphZtkGWI/DEY=
347346
github.com/openebs/lib-csi v0.6.0/go.mod h1:KWANWF2zNB8RYyELegid8PxHFrP/cdttR320NA9gVUQ=
348347
github.com/openebs/lvm-localpv v0.6.0 h1:2LWSF/qy6jGKNAALtIN1O5y6tEKhwTGcVUcxy0Qgnpk=
349348
github.com/openebs/lvm-localpv v0.6.0/go.mod h1:DVDU+pjCFdb3rZd4MwVVEZ2eXqq+LT16CpQTm1j0MYo=

pkg/client/k8s.go

Lines changed: 5 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,12 @@ import (
2727
"github.com/openebs/api/v2/pkg/apis/openebs.io/v1alpha1"
2828
lvmclient "github.com/openebs/lvm-localpv/pkg/generated/clientset/internalclientset"
2929
"github.com/openebs/openebsctl/pkg/util"
30+
zfsclient "github.com/openebs/zfs-localpv/pkg/generated/clientset/internalclientset"
3031
"github.com/pkg/errors"
3132

3233
cstorv1 "github.com/openebs/api/v2/pkg/apis/cstor/v1"
3334
openebsclientset "github.com/openebs/api/v2/pkg/client/clientset/versioned"
3435
jiva "github.com/openebs/jiva-operator/pkg/apis/openebs/v1alpha1"
35-
zfs "github.com/openebs/zfs-localpv/pkg/apis/openebs.io/zfs/v1"
36-
zfsBuilder "github.com/openebs/zfs-localpv/pkg/builder/volbuilder"
3736

3837
appsv1 "k8s.io/api/apps/v1"
3938
corev1 "k8s.io/api/core/v1"
@@ -65,6 +64,8 @@ type K8sClient struct {
6564
OpenebsCS openebsclientset.Interface
6665
// LVMCS is the client for accessing OpenEBS LVM components
6766
LVMCS lvmclient.Interface
67+
// ZFCS is the client for accessing OpenEBS ZFS components
68+
ZFCS zfsclient.Interface
6869
}
6970

7071
/*
@@ -88,11 +89,13 @@ func NewK8sClient(ns string) (*K8sClient, error) {
8889
return nil, errors.Wrap(err, "failed to build OpenEBS clientset")
8990
}
9091
lv, _ := getLVMclient(config)
92+
zf, _ := getZFSclient(config)
9193
return &K8sClient{
9294
Ns: ns,
9395
K8sCS: k8sCS,
9496
OpenebsCS: openebsCS,
9597
LVMCS: lv,
98+
ZFCS: zf,
9699
}, nil
97100
}
98101

@@ -641,60 +644,6 @@ func (k K8sClient) GetJVTargetPod(volumeName string) (*corev1.PodList, error) {
641644
return pods, nil
642645
}
643646

644-
// GetZFSVols returns a list or a map of ZFSVolume depending upon rType & options
645-
func (k K8sClient) GetZFSVols(volNames []string, rType util.ReturnType, labelSelector string, options util.MapOptions) (*zfs.ZFSVolumeList, map[string]zfs.ZFSVolume, error) {
646-
config := os.Getenv("KUBECONFIG")
647-
zvols, err := zfsBuilder.NewKubeclient(zfsBuilder.WithKubeConfigPath(config)).
648-
WithNamespace("").
649-
List(metav1.ListOptions{
650-
LabelSelector: labelSelector,
651-
})
652-
if err != nil {
653-
return nil, nil, err
654-
}
655-
var list []zfs.ZFSVolume
656-
if len(volNames) == 0 {
657-
list = zvols.Items
658-
} else {
659-
zvsMap := make(map[string]zfs.ZFSVolume)
660-
for _, zv := range zvols.Items {
661-
zvsMap[zv.Name] = zv
662-
}
663-
for _, name := range volNames {
664-
if zv, ok := zvsMap[name]; ok {
665-
list = append(list, zv)
666-
} else {
667-
fmt.Printf("Error from server (NotFound): zfsVolume %s not found\n", name)
668-
}
669-
}
670-
}
671-
if rType == util.List {
672-
return &zfs.ZFSVolumeList{
673-
Items: list,
674-
}, nil, nil
675-
}
676-
if rType == util.Map {
677-
zvMap := make(map[string]zfs.ZFSVolume)
678-
switch options.Key {
679-
case util.Label:
680-
for _, zv := range list {
681-
if vol, ok := zv.Labels[options.LabelKey]; ok {
682-
zvMap[vol] = zv
683-
}
684-
}
685-
return nil, zvMap, nil
686-
case util.Name:
687-
for _, zv := range list {
688-
zvMap[zv.Name] = zv
689-
}
690-
return nil, zvMap, nil
691-
default:
692-
return nil, nil, errors.New("invalid map options")
693-
}
694-
}
695-
return nil, nil, errors.New("invalid return type")
696-
}
697-
698647
// GetCSIControllerSTS returns the CSI controller sts with a specific
699648
// openebs-component-name label key
700649
func (k K8sClient) GetCSIControllerSTS(name string) (*appsv1.StatefulSet, error) {

pkg/client/lvmlocalpv.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,8 @@ func (k K8sClient) GetLVMvol(lVols []string, rType util.ReturnType, labelSelecto
9191
}
9292
return nil, nil, errors.New("invalid return type")
9393
}
94+
95+
// GetLVMNodes return a list of LVMNodes
96+
func (k K8sClient) GetLVMNodes() (*lvm.LVMNodeList, error) {
97+
return k.LVMCS.LocalV1alpha1().LVMNodes("").List(context.TODO(), v1.ListOptions{})
98+
}

pkg/client/zfslocalpv.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
Copyright 2020-2021 The OpenEBS Authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package client
18+
19+
import (
20+
"context"
21+
"fmt"
22+
23+
"github.com/openebs/openebsctl/pkg/util"
24+
zfs "github.com/openebs/zfs-localpv/pkg/apis/openebs.io/zfs/v1"
25+
zvolclient "github.com/openebs/zfs-localpv/pkg/generated/clientset/internalclientset"
26+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27+
"k8s.io/client-go/tools/clientcmd"
28+
)
29+
30+
// getLVMClient returns OpenEBS clientset by taking kubeconfig as an
31+
// argument
32+
func getZFSclient(kubeconfig string) (*zvolclient.Clientset, error) {
33+
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
34+
if err != nil {
35+
return nil, fmt.Errorf("could not build config from flags: %v", err)
36+
}
37+
client, err := zvolclient.NewForConfig(config)
38+
if err != nil {
39+
return nil, fmt.Errorf("could not get new config: %v", err)
40+
}
41+
return client, nil
42+
}
43+
44+
// GetZFSVols returns a list or a map of ZFSVolume depending upon rType & options
45+
func (k K8sClient) GetZFSVols(volNames []string, rType util.ReturnType, labelSelector string, options util.MapOptions) (*zfs.ZFSVolumeList, map[string]zfs.ZFSVolume, error) {
46+
zvols, err := k.ZFCS.ZfsV1().ZFSVolumes("").List(context.TODO(), metav1.ListOptions{LabelSelector: labelSelector})
47+
if err != nil {
48+
return nil, nil, err
49+
}
50+
var list []zfs.ZFSVolume
51+
if len(volNames) == 0 {
52+
list = zvols.Items
53+
} else {
54+
zvsMap := make(map[string]zfs.ZFSVolume)
55+
for _, zv := range zvols.Items {
56+
zvsMap[zv.Name] = zv
57+
}
58+
for _, name := range volNames {
59+
if zv, ok := zvsMap[name]; ok {
60+
list = append(list, zv)
61+
} else {
62+
fmt.Printf("Error from server (NotFound): zfsVolume %s not found\n", name)
63+
}
64+
}
65+
}
66+
if rType == util.List {
67+
return &zfs.ZFSVolumeList{
68+
Items: list,
69+
}, nil, nil
70+
}
71+
if rType == util.Map {
72+
zvMap := make(map[string]zfs.ZFSVolume)
73+
switch options.Key {
74+
case util.Label:
75+
for _, zv := range list {
76+
if vol, ok := zv.Labels[options.LabelKey]; ok {
77+
zvMap[vol] = zv
78+
}
79+
}
80+
return nil, zvMap, nil
81+
case util.Name:
82+
for _, zv := range list {
83+
zvMap[zv.Name] = zv
84+
}
85+
return nil, zvMap, nil
86+
default:
87+
return nil, nil, fmt.Errorf("invalid map options")
88+
}
89+
}
90+
return nil, nil, fmt.Errorf("invalid return type")
91+
}
92+
93+
// GetZFSNodes return a list of ZFSNodes
94+
func (k K8sClient) GetZFSNodes() (*zfs.ZFSNodeList, error) {
95+
return k.ZFCS.ZfsV1().ZFSNodes("").List(context.TODO(), metav1.ListOptions{})
96+
}

pkg/storage/cstor.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,9 @@ func GetCstorPools(c *client.K8sClient, pools []string) error {
7676
util.Duration(time.Since(item.ObjectMeta.CreationTimestamp.Time))}})
7777
}
7878
if len(cpools.Items) == 0 {
79-
fmt.Println("No Pools are found")
80-
} else {
81-
util.TablePrinter(util.CstorPoolListColumnDefinations, rows, printers.PrintOptions{Wide: true})
79+
return fmt.Errorf("no cstor pools are found")
8280
}
81+
util.TablePrinter(util.CstorPoolListColumnDefinations, rows, printers.PrintOptions{Wide: true})
8382
return nil
8483
}
8584

pkg/storage/lvmlocalpv.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
Copyright 2020-2021 The OpenEBS Authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package storage
18+
19+
import (
20+
"fmt"
21+
22+
"github.com/openebs/openebsctl/pkg/client"
23+
"github.com/openebs/openebsctl/pkg/util"
24+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25+
"k8s.io/cli-runtime/pkg/printers"
26+
)
27+
28+
const (
29+
firstElemPrefix = `├─`
30+
lastElemPrefix = `└─`
31+
)
32+
33+
// GetVolumeGroups lists all volume groups by node
34+
func GetVolumeGroups(c *client.K8sClient, vgs []string) error {
35+
lvmNodes, err := c.GetLVMNodes()
36+
if err != nil {
37+
return err
38+
}
39+
var rows []metav1.TableRow
40+
for _, lv := range lvmNodes.Items {
41+
rows = append(rows, metav1.TableRow{Cells: []interface{}{lv.Name, "", "", ""}})
42+
for i, vg := range lv.VolumeGroups {
43+
var prefix string
44+
if i < len(lv.VolumeGroups)-1 {
45+
prefix = firstElemPrefix
46+
} else {
47+
prefix = lastElemPrefix
48+
}
49+
rows = append(rows, metav1.TableRow{Cells: []interface{}{prefix + vg.Name,
50+
util.ConvertToIBytes(vg.Free.String()), util.ConvertToIBytes(vg.Size.String())}})
51+
}
52+
rows = append(rows, metav1.TableRow{Cells: []interface{}{"", "", ""}})
53+
}
54+
// 3. Actually print the table or return an error
55+
if len(rows) == 0 {
56+
return fmt.Errorf("no lvm volumegroups found")
57+
}
58+
util.TablePrinter(util.LVMvolgroupListColumnDefinitions, rows, printers.PrintOptions{Wide: true})
59+
return nil
60+
}

pkg/storage/lvmlocalpv_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
Copyright 2020-2021 The OpenEBS Authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package storage
18+
19+
import (
20+
"testing"
21+
22+
fakelvmclient "github.com/openebs/lvm-localpv/pkg/generated/clientset/internalclientset/fake"
23+
"github.com/openebs/openebsctl/pkg/client"
24+
)
25+
26+
func TestGetVolumeGroup(t *testing.T) {
27+
type args struct {
28+
c *client.K8sClient
29+
vg []string
30+
}
31+
tests := []struct {
32+
name string
33+
args args
34+
wantErr bool
35+
}{
36+
{
37+
"no LVM volumegroups present",
38+
args{
39+
c: &client.K8sClient{
40+
Ns: "lvmlocalpv",
41+
K8sCS: nil,
42+
OpenebsCS: nil,
43+
LVMCS: fakelvmclient.NewSimpleClientset(),
44+
},
45+
vg: nil,
46+
},
47+
true,
48+
},
49+
}
50+
for _, tt := range tests {
51+
t.Run(tt.name, func(t *testing.T) {
52+
if err := GetVolumeGroups(tt.args.c, tt.args.vg); (err != nil) != tt.wantErr {
53+
t.Errorf("GetVolumeGroups() error = %v, wantErr %v", err, tt.wantErr)
54+
}
55+
})
56+
}
57+
}

0 commit comments

Comments
 (0)