github.com/openebs/node-disk-manager@v1.9.1-0.20230225014141-4531f06ffa1e/db/kubernetes/client.go (about)

     1  /*
     2  Copyright 2019 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 kubernetes
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  
    23  	apis "github.com/openebs/node-disk-manager/api/v1alpha1"
    24  	"github.com/openebs/node-disk-manager/blockdevice"
    25  
    26  	"os"
    27  
    28  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    29  	"k8s.io/client-go/rest"
    30  	"k8s.io/klog/v2"
    31  	"sigs.k8s.io/controller-runtime/pkg/client"
    32  	"sigs.k8s.io/controller-runtime/pkg/client/config"
    33  	"sigs.k8s.io/controller-runtime/pkg/manager"
    34  )
    35  
    36  const (
    37  	// NamespaceENV is the name of environment variable to get the namespace
    38  	NamespaceENV = "NAMESPACE"
    39  )
    40  
    41  const (
    42  	// kubernetesLabelPrefix is the label prefix for kubernetes
    43  	kubernetesLabelPrefix = "kubernetes.io/"
    44  
    45  	// openebsLabelPrefix is the label prefix for openebs labels
    46  	openebsLabelPrefix = "openebs.io/"
    47  
    48  	// blockDeviceTag is the label suffix used to tag a blockdevice
    49  	blockDeviceTag = "block-device-tag"
    50  
    51  	// KubernetesHostNameLabel is the kubernetes hostname label
    52  	KubernetesHostNameLabel = kubernetesLabelPrefix + blockdevice.HostName
    53  
    54  	// BlockDeviceTagLabel is the label used to tag a blockdevice for
    55  	// a particular use case.
    56  	// BlockDevices having this label can only be claimed by BDCs which
    57  	// have a matching label selector.
    58  	BlockDeviceTagLabel = openebsLabelPrefix + blockDeviceTag
    59  )
    60  
    61  // Client is the wrapper over the k8s client that will be used by
    62  // NDM to interface with etcd
    63  type Client struct {
    64  	// cfg is configuration used to generate the client
    65  	cfg *rest.Config
    66  
    67  	// client is the controller-runtime client used to interface with etcd
    68  	client client.Client
    69  
    70  	// namespace in which this client is operating
    71  	namespace string
    72  }
    73  
    74  // New creates a new client object using the default config
    75  func New() (Client, error) {
    76  
    77  	c := Client{}
    78  
    79  	// get the kube cfg
    80  	cfg, err := config.GetConfig()
    81  	if err != nil {
    82  		klog.Errorf("error getting cfg. %v", err)
    83  		return c, err
    84  	}
    85  
    86  	c.cfg = cfg
    87  
    88  	klog.V(2).Info("Client config created.")
    89  
    90  	err = c.setNamespace()
    91  	if err != nil {
    92  		klog.Errorf("error setting namespace for client. %v", err)
    93  		return c, err
    94  	}
    95  
    96  	klog.V(2).Infof("Namespace \"%s\" set for the client", c.namespace)
    97  
    98  	err = c.InitClient()
    99  	return c, err
   100  }
   101  
   102  // InitClient sets the client using the config
   103  func (cl *Client) InitClient() error {
   104  	c, err := client.New(cl.cfg, client.Options{})
   105  	if err != nil {
   106  		return err
   107  	}
   108  	cl.client = c
   109  	return nil
   110  }
   111  
   112  // SetClient sets the given client
   113  func (cl *Client) SetClient(client2 client.Client) {
   114  	cl.client = client2
   115  }
   116  
   117  // RegisterAPI registers the API scheme in the client using the manager.
   118  // This function needs to be called only once a client object
   119  func (cl *Client) RegisterAPI() error {
   120  	mgr, err := manager.New(cl.cfg, manager.Options{Namespace: cl.namespace})
   121  	if err != nil {
   122  		return err
   123  	}
   124  
   125  	// Setup Scheme for all resources
   126  	if err := apis.AddToScheme(mgr.GetScheme()); err != nil {
   127  		return err
   128  	}
   129  	return nil
   130  }
   131  
   132  // setNamespace sets the namespace in which NDM is running
   133  func (cl *Client) setNamespace() error {
   134  	ns, ok := os.LookupEnv(NamespaceENV)
   135  	if !ok {
   136  		return fmt.Errorf("error getting namespace from ENV variable")
   137  	}
   138  
   139  	cl.namespace = ns
   140  
   141  	return nil
   142  }
   143  
   144  // ListBlockDevice lists the block device from etcd based on
   145  // the filters used
   146  func (cl *Client) ListBlockDevice(filters ...interface{}) ([]blockdevice.BlockDevice, error) {
   147  	bdList := &apis.BlockDeviceList{
   148  		TypeMeta: metav1.TypeMeta{
   149  			Kind:       "BlockDevice",
   150  			APIVersion: "openebs.io/v1alpha1",
   151  		},
   152  	}
   153  
   154  	// list only from this namespace
   155  	listOpts := []client.ListOption{
   156  		client.InNamespace(cl.namespace),
   157  	}
   158  
   159  	for _, filter := range filters {
   160  		// convert the filter interface to relevant list option
   161  		opts := filter.(client.ListOption)
   162  		listOpts = append(listOpts, opts)
   163  	}
   164  
   165  	err := cl.client.List(context.TODO(), bdList, listOpts...)
   166  	if err != nil {
   167  		klog.Error("error in listing BDs. ", err)
   168  		return nil, err
   169  	}
   170  
   171  	blockDeviceList := make([]blockdevice.BlockDevice, 0)
   172  	err = convertBlockDeviceAPIListToBlockDeviceList(bdList, &blockDeviceList)
   173  	if err != nil {
   174  		return blockDeviceList, err
   175  	}
   176  
   177  	klog.V(4).Infof("no of blockdevices listed : %d", len(blockDeviceList))
   178  
   179  	return blockDeviceList, nil
   180  }