Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add logic for openebs namespace determination from cli code #21

Merged
merged 4 commits into from
Jun 2, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions client/k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"

cstorv1 "github.com/openebs/api/v2/pkg/apis/cstor/v1"
"github.com/openebs/api/v2/pkg/apis/openebs.io/v1alpha1"
Expand All @@ -47,9 +48,9 @@ type K8sAPIVersion string
// K8sClient provides the necessary utility to operate over
// various K8s Kind objects
type K8sClient struct {
// ns refers to K8s namespace where the operation
// Ns refers to K8s namespace where the operation
// will be performed
ns string
Ns string
// K8sCS refers to the Clientset capable of communicating
// with the K8s cluster
K8sCS kubernetes.Interface
Expand All @@ -59,7 +60,7 @@ type K8sClient struct {
}

// NewK8sClient creates a new K8sClient
// TODO: improve K8sClientset instantiation. for example remove the ns from
// TODO: improve K8sClientset instantiation. for example remove the Ns from
// K8sClient struct
func NewK8sClient(ns string) (*K8sClient, error) {
// get the appropriate clientsets & set the kubeconfig accordingly
Expand All @@ -75,7 +76,7 @@ func NewK8sClient(ns string) (*K8sClient, error) {
return nil, errors.Wrap(err, "failed to build OpenEBS clientset")
}
return &K8sClient{
ns: ns,
Ns: ns,
K8sCS: k8sCS,
OpenebsCS: openebsCS,
}, nil
Expand Down Expand Up @@ -130,6 +131,14 @@ func homeDir() string {
}
return os.Getenv("KUBECONFIG")
}
// GetOpenEBSNamespace from the specific engine component based on cas-type
func (k K8sClient) GetOpenEBSNamespace(casType string) (string, error) {
pods, err := k.K8sCS.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{LabelSelector: fmt.Sprintf("openebs.io/component-name=%s", util.CasTypeAndComponentNameMap[strings.ToLower(casType)])})
if err != nil || len(pods.Items) == 0 {
return "", errors.New("unable to determine openebs namespace")
}
return pods.Items[0].Namespace, nil
}

// GetStorageClass using the K8sClient's storage class client
func (k K8sClient) GetStorageClass(driver string) (*v1.StorageClass, error) {
Expand Down Expand Up @@ -160,7 +169,7 @@ func (k K8sClient) GetcStorVolumes() (*cstorv1.CStorVolumeList, error) {

// GetcStorVolume fetches the volume object of the given name in the given namespace
func (k K8sClient) GetcStorVolume(volName string) (*cstorv1.CStorVolume, error) {
volInfo, err := k.OpenebsCS.CstorV1().CStorVolumes(k.ns).Get(context.TODO(), volName, metav1.GetOptions{})
volInfo, err := k.OpenebsCS.CstorV1().CStorVolumes(k.Ns).Get(context.TODO(), volName, metav1.GetOptions{})
if err != nil {
return nil, errors.Wrapf(err, "error while while getting volume %s", volName)
}
Expand Down Expand Up @@ -210,9 +219,9 @@ func (k K8sClient) GetPV(name string) (*corev1.PersistentVolume, error) {

// GetCVC used to get cStor Volume Config information for cStor a given volume using a cStorClient
func (k K8sClient) GetCVC(name string) (*cstorv1.CStorVolumeConfig, error) {
cStorVolumeConfig, err := k.OpenebsCS.CstorV1().CStorVolumeConfigs(k.ns).Get(context.TODO(), name, metav1.GetOptions{})
cStorVolumeConfig, err := k.OpenebsCS.CstorV1().CStorVolumeConfigs(k.Ns).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
return nil, errors.Wrapf(err, "error while getting cStor Volume Config for %s in %s", name, k.ns)
return nil, errors.Wrapf(err, "error while getting cStor Volume Config for %s in %s", name, k.Ns)
}
return cStorVolumeConfig, nil
}
Expand Down Expand Up @@ -283,7 +292,7 @@ func (k K8sClient) GetCVA(volumeName string) (*cstorv1.CStorVolumeAttachment, er

// GetCstorVolumeTargetPod for the passed volume to show details
func (k K8sClient) GetCstorVolumeTargetPod(volumeClaim string, volumeName string) (*corev1.Pod, error) {
pods, err := k.K8sCS.CoreV1().Pods(k.ns).List(context.TODO(), metav1.ListOptions{LabelSelector: fmt.Sprintf("openebs.io/persistent-volume-claim=%s,openebs.io/persistent-volume=%s,openebs.io/target=cstor-target", volumeClaim, volumeName)})
pods, err := k.K8sCS.CoreV1().Pods(k.Ns).List(context.TODO(), metav1.ListOptions{LabelSelector: fmt.Sprintf("openebs.io/persistent-volume-claim=%s,openebs.io/persistent-volume=%s,openebs.io/target=cstor-target", volumeClaim, volumeName)})
if err != nil || len(pods.Items) == 0 {
return nil, errors.New("The target pod for the volume was not found")
}
Expand All @@ -292,7 +301,7 @@ func (k K8sClient) GetCstorVolumeTargetPod(volumeClaim string, volumeName string

// GetcStorPool using the OpenEBS's Client
func (k K8sClient) GetcStorPool(poolName string) (*cstorv1.CStorPoolInstance, error) {
cStorPool, err := k.OpenebsCS.CstorV1().CStorPoolInstances(k.ns).Get(context.TODO(), poolName, metav1.GetOptions{})
cStorPool, err := k.OpenebsCS.CstorV1().CStorPoolInstances(k.Ns).Get(context.TODO(), poolName, metav1.GetOptions{})
if err != nil {
return nil, errors.Wrapf(err, "Error while while getting cspi")
}
Expand All @@ -301,7 +310,7 @@ func (k K8sClient) GetcStorPool(poolName string) (*cstorv1.CStorPoolInstance, er

// GetBlockDevice using the OpenEBS's Client
func (k K8sClient) GetBlockDevice(bd string) (*v1alpha1.BlockDevice, error) {
blockDevice, err := k.OpenebsCS.OpenebsV1alpha1().BlockDevices(k.ns).Get(context.TODO(), bd, metav1.GetOptions{})
blockDevice, err := k.OpenebsCS.OpenebsV1alpha1().BlockDevices(k.Ns).Get(context.TODO(), bd, metav1.GetOptions{})
if err != nil {
return nil, errors.Wrapf(err, "Error while while getting block device")
}
Expand All @@ -311,7 +320,7 @@ func (k K8sClient) GetBlockDevice(bd string) (*v1alpha1.BlockDevice, error) {
// GetCVRByPoolName using the OpenEBS's Client
func (k K8sClient) GetCVRByPoolName(poolName string) (*cstorv1.CStorVolumeReplicaList, error) {
label := "cstorpoolinstance.openebs.io/name" + "=" + poolName
CVRs, err := k.OpenebsCS.CstorV1().CStorVolumeReplicas(k.ns).List(context.TODO(), metav1.ListOptions{LabelSelector: label})
CVRs, err := k.OpenebsCS.CstorV1().CStorVolumeReplicas(k.Ns).List(context.TODO(), metav1.ListOptions{LabelSelector: label})
if err != nil {
return nil, errors.Wrapf(err, "error while getting cStor Volume Replica for pool %s", poolName)
}
Expand Down
19 changes: 14 additions & 5 deletions kubectl-openebs/cli/command/describe/pvc_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,33 +80,36 @@ PV Status : {{.PVStatus}}

// NewCmdDescribePVC Displays the pvc describe details
func NewCmdDescribePVC() *cobra.Command {
var openebsNs string
cmd := &cobra.Command{
Use: "pvc",
Aliases: []string{"pvcs", "persistentvolumeclaims", "persistentvolumeclaim"},
Short: "Displays PersistentVolumeClaim information",
Long: pvcInfoCommandHelpText,
Example: `kubectl openebs describe pvc cstor-vol-1 cstor-vol-2 -n storage`,
Run: func(cmd *cobra.Command, args []string) {
var pvNs string // This namespace belongs to the PVC entered
var pvNs, openebsNamespace string // This namespace belongs to the PVC entered
vharsh marked this conversation as resolved.
Show resolved Hide resolved
if pvNs, _ = cmd.Flags().GetString("namespace"); pvNs == "" {
pvNs = "default"
}
util.CheckErr(RunPVCInfo(cmd, args, pvNs), util.Fatal)
openebsNamespace, _ = cmd.Flags().GetString("openebs-namespace")
util.CheckErr(RunPVCInfo(cmd, args, pvNs, openebsNamespace), util.Fatal)
},
}
cmd.Flags().StringVarP(&openebsNs, "openebs-namespace", "", "", "to read the openebs namespace from user.\nIf not provided it is determined from components.")
return cmd
}

// RunPVCInfo runs info command and make call to display the results
func RunPVCInfo(cmd *cobra.Command, pvcs []string, ns string) error {
func RunPVCInfo(cmd *cobra.Command, pvcs []string, ns string, openebsNs string) error {
if len(pvcs) == 0 {
return errors.New("Please give at least one pvc name to describe")
}
// TODO: Make K8sClient to be able to determine openebs namespace by itself.
// Below is currently hardcoded to support only if resources are in openebs ns
// because the -n flag is used to take the pvc namespace and same cannot be used to
// take the openebs namespace
clientset, err := client.NewK8sClient("openebs")
clientset, err := client.NewK8sClient(openebsNs)
if err != nil {
return errors.Wrap(err, "Failed to execute describe pvc command")
}
Expand All @@ -130,7 +133,13 @@ func RunPVCInfo(cmd *cobra.Command, pvcs []string, ns string) error {
// Get the casType from the storage class and branch on basic of CSTOR and NON-CSTOR PVCs.
casType := util.GetCasTypeFromSC(sc)
if casType == util.CstorCasType {

if openebsNs == "" {
nsFromCli, err := clientset.GetOpenEBSNamespace(util.CstorCasType)
if err != nil {
return errors.Wrap(err, "Error determining the openebs namespace, please specify using \"--openebs-namespace\" flag")
}
clientset.Ns = nsFromCli
}
// Create Empty template objects and fill gradually when underlying sub CRs are identified.
pvcInfo := util.CstorPVCInfo{}
cvcInfo := util.CVCInfo{}
Expand Down
15 changes: 15 additions & 0 deletions kubectl-openebs/cli/util/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,18 @@ const (
// StorageKey key present in pvc status.capacity
StorageKey = "storage"
)

var (
// CasTypeAndComponentNameMap stores the component name of the corresponding cas type
CasTypeAndComponentNameMap = map[string]string{
"cstor": "openebs-cstor-csi-controller",
}
// ProvsionerAndCasTypeMap stores the cas type name of the corresponding provisioner
ProvsionerAndCasTypeMap = map[string]string{
"cstor.csi.openebs.io": "cstor",
"openebs.io/provisioner-iscsi": "jiva",
"openebs.io/local": "local",
"local.csi.openebs.io ": "localpv-lvm",
"zfs.csi.openebs.io": "localpv-zfs",
}
)
6 changes: 5 additions & 1 deletion kubectl-openebs/cli/util/k8s_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ limitations under the License.
package util

import (
"strconv"

cstorv1 "github.com/openebs/api/v2/pkg/apis/cstor/v1"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/api/storage/v1"
"strconv"
)

// GetUsedCapacityFromCVR as the healthy replicas would have the correct used capacity details
Expand Down Expand Up @@ -70,6 +71,9 @@ func GetCasTypeFromSC(v1SC *v1.StorageClass) string {
return v1SC.Parameters[OpenEBSCasTypeKeySc]
}
}
if _, ok := ProvsionerAndCasTypeMap[v1SC.Provisioner]; ok {
return ProvsionerAndCasTypeMap[v1SC.Provisioner]
}
Abhinandan-Purkait marked this conversation as resolved.
Show resolved Hide resolved
return Unknown
}

Expand Down