Skip to content

Commit

Permalink
Added changes related to Volume_limits
Browse files Browse the repository at this point in the history
  • Loading branch information
tssushma committed Jul 25, 2023
1 parent 4a1ade1 commit f79d0c1
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
6 changes: 6 additions & 0 deletions service/envvars.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,15 @@ const (
// EnvManagedArrays is an env variable with a list of space separated arrays.
EnvManagedArrays = "X_CSI_MANAGED_ARRAYS"

// EnvKubeConfigPath indicates kubernetes configuration that has to be used by CSI Driver
EnvKubeConfigPath = "KUBECONFIG"

// EnvConfigFilePath is an env variable which contains the full path for the config file
EnvConfigFilePath = "X_CSI_POWERMAX_CONFIG_PATH"

// EnvMaxVolumesPerNode specifies maximum number of volumes that controller can publish to the node.
EnvMaxVolumesPerNode = "X_CSI_MAX_VOLUMES_PER_NODE"

// EnvHealthMonitorEnabled is an env variable which indicated if volume health monitor is enabled
EnvHealthMonitorEnabled = "X_CSI_HEALTH_MONITOR_ENABLED"

Expand Down
41 changes: 41 additions & 0 deletions service/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -1050,11 +1050,52 @@ func (s *service) NodeGetInfo(
return nil, status.Error(codes.FailedPrecondition, "no topology keys could be generate")
}

var maxPowerMaxVolumesPerNode int64
labels, err := s.GetNodeLabels()
if err != nil {
log.Error("failed to get Node Labels with error", err.Error())
return nil, err
}
if val, ok := labels["max-powermax-volumes-per-node"]; ok {
maxPowerMaxVolumesPerNode, err = strconv.ParseInt(val, 10, 64)
if err != nil {
return nil, fmt.Errorf("invalid value '%s' specified for 'max-powermax-volumes-per-node' node label", val)
}
if s.opts.IsVsphereEnabled {
if maxPowerMaxVolumesPerNode <= 0 || maxPowerMaxVolumesPerNode > 60 {
log.Errorf("Node label max-powermax-volumes-per-node should not be greater than 60 or set to any negative value for RDM volumes, Setting to default value 60")
}
maxPowerMaxVolumesPerNode = 60
} else {
if maxPowerMaxVolumesPerNode < 0 {
log.Errorf("Node label max-powermax-volumes-per-node should not be set to negative value, Using default value 0")
maxPowerMaxVolumesPerNode = 0
}
}
log.Infof("node label 'max-powermax-volumes-per-node' is available and is set to value '%v'", maxPowerMaxVolumesPerNode)
} else {
// As per the csi spec the plugin MUST NOT set negative values to
// 'MaxVolumesPerNode' in the NodeGetInfoResponse response
log.Infof("Node label 'max-powermax-volumes-per-node' is not available. Retrieving the value from yaml file")
if s.opts.IsVsphereEnabled {
if s.opts.MaxVolumesPerNode <= 0 || s.opts.MaxVolumesPerNode > 60 {
log.Errorf("maxPowerMaxVolumesPerNode MUST NOT be greater than 60 or set to any negative value for RDM volumes. Setting to default value 60")
}
s.opts.MaxVolumesPerNode = 60
} else {
if s.opts.MaxVolumesPerNode < 0 {
log.Errorf("maxPowerMaxVolumesPerNode MUST NOT be set to negative value, setting to default value 0")
s.opts.MaxVolumesPerNode = 0
}
}
maxPowerMaxVolumesPerNode = s.opts.MaxVolumesPerNode
}
return &csi.NodeGetInfoResponse{
NodeId: s.opts.NodeName,
AccessibleTopology: &csi.Topology{
Segments: topology,
},
MaxVolumesPerNode: maxPowerMaxVolumesPerNode,
}, nil
}

Expand Down
36 changes: 36 additions & 0 deletions service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"time"

"github.com/container-storage-interface/spec/lib/go/csi"
"github.com/dell/csi-powermax/v2/k8sutils"
"github.com/dell/gocsi"
csictx "github.com/dell/gocsi/context"
"github.com/dell/goiscsi"
Expand All @@ -46,6 +47,7 @@ import (
migrext "github.com/dell/dell-csi-extensions/migration"
csiext "github.com/dell/dell-csi-extensions/replication"
pmax "github.com/dell/gopowermax/v2"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// Constants for the service
Expand Down Expand Up @@ -95,6 +97,7 @@ type Opts struct {
Password string
SystemName string
NodeName string
NodeFullName string
TransportProtocol string
DriverName string
CHAPUserName string
Expand Down Expand Up @@ -125,6 +128,8 @@ type Opts struct {
VCenterHostURL string // vCenter host url
VCenterHostUserName string // vCenter host username
VCenterHostPassword string // vCenter password
MaxVolumesPerNode int64 // to specify volume limits
KubeConfigPath string // to specify k8s configuration to be used CSI driver
}

// NodeConfig defines rules for given node
Expand Down Expand Up @@ -362,6 +367,7 @@ func (s *service) BeforeServe(
if name, ok := csictx.LookupEnv(ctx, EnvNodeName); ok {
shortHostName := strings.Split(name, ".")[0]
opts.NodeName = shortHostName
opts.NodeFullName = name
}
if portgroups, ok := csictx.LookupEnv(ctx, EnvPortGroups); ok {
tempList, err := s.parseCommaSeperatedList(portgroups)
Expand All @@ -378,13 +384,27 @@ func (s *service) BeforeServe(
os.Exit(1)
}

if kubeConfigPath, ok := csictx.LookupEnv(ctx, EnvKubeConfigPath); ok {
opts.KubeConfigPath = kubeConfigPath
}

if replicationContextPrefix, ok := csictx.LookupEnv(ctx, EnvReplicationContextPrefix); ok {
opts.ReplicationContextPrefix = replicationContextPrefix
}
if replicationPrefix, ok := csictx.LookupEnv(ctx, EnvReplicationPrefix); ok {
opts.ReplicationPrefix = replicationPrefix
}

if MaxVolumesPerNode, ok := csictx.LookupEnv(ctx, EnvMaxVolumesPerNode); ok {
val, err := strconv.ParseInt(MaxVolumesPerNode, 10, 64)
if err != nil {
log.Warningf("error while parsing env variable '%s', %s, defaulting to 0", EnvMaxVolumesPerNode, err)
opts.MaxVolumesPerNode = 0
} else {
opts.MaxVolumesPerNode = val
}
}

opts.TransportProtocol = s.getTransportProtocolFromEnv()
opts.ProxyServiceHost, opts.ProxyServicePort, opts.UseProxy = s.getProxySettingsFromEnv()
if !opts.UseProxy && !inducedMockReverseProxy {
Expand Down Expand Up @@ -792,3 +812,19 @@ func getLogFields(ctx context.Context) log.Fields {
fields["RequestID"] = csiReqID
return fields
}

func (s *service) GetNodeLabels() (map[string]string, error) {
k8sclientset, err := k8sutils.CreateKubeClientSet(s.opts.KubeConfigPath)
if err != nil {
log.Errorf("init client failed: '%s'", err.Error())
return nil, err
}
// access the API to fetch node object
node, err := k8sclientset.CoreV1().Nodes().Get(context.TODO(), s.opts.NodeFullName, v1.GetOptions{})
if err != nil {
return nil, err
}
log.Debugf("Node %s details\n", node)

return node.Labels, nil
}

0 comments on commit f79d0c1

Please sign in to comment.