diff --git a/cmd/vngcloud-blockstorage-csi-driver/main.go b/cmd/vngcloud-blockstorage-csi-driver/main.go index 0b2cd71..5738c16 100644 --- a/cmd/vngcloud-blockstorage-csi-driver/main.go +++ b/cmd/vngcloud-blockstorage-csi-driver/main.go @@ -58,6 +58,7 @@ func main() { lsdriver.WithClusterID(options.ServerOptions.ClusterID), lsdriver.WithTagKeyLength(options.ServerOptions.TagKeyLength), lsdriver.WithTagValueLength(options.ServerOptions.TagValueLength), + lsdriver.WithMaxVolumesPerNode(options.NodeOptions.MaxVolumesPerNode), ) if err != nil { @@ -122,9 +123,12 @@ func (s *ControllerOptions) AddFlags(fs *lflag.FlagSet) { } -type NodeOptions struct{} +type NodeOptions struct { + MaxVolumesPerNode int +} func (s *NodeOptions) AddFlags(fs *lflag.FlagSet) { + fs.IntVar(&s.MaxVolumesPerNode, "max-volumes-per-node", 0, "The maximum number of volumes that can be attached to each node. Default is 0.") } func (s *NodeOptions) Validate() error { diff --git a/pkg/driver/driver.go b/pkg/driver/driver.go index 7d3ac1b..53d6786 100644 --- a/pkg/driver/driver.go +++ b/pkg/driver/driver.go @@ -51,6 +51,7 @@ type DriverOptions struct { // nolint: maligned alertChannelSize int tagKeyLength int tagValueLength int + maxVolumesPerNode int // The maximum number of volumes CAN be attached to each node } func NewDriver(options ...func(*DriverOptions)) (*Driver, error) { @@ -170,6 +171,12 @@ func WithTagValueLength(ptvl int) func(*DriverOptions) { } } +func WithMaxVolumesPerNode(pmvpn int) func(*DriverOptions) { + return func(o *DriverOptions) { + o.maxVolumesPerNode = pmvpn + } +} + func WithUserAgentExtra(userAgentExtra string) func(*DriverOptions) { return func(o *DriverOptions) { o.userAgentExtra = userAgentExtra diff --git a/pkg/driver/node.go b/pkg/driver/node.go index 02a03a0..2299423 100644 --- a/pkg/driver/node.go +++ b/pkg/driver/node.go @@ -507,46 +507,56 @@ func (s *nodeService) NodeGetInfo(_ lctx.Context, _ *lcsi.NodeGetInfoRequest) (* klog.V(5).InfoS("[DEBUG] - NodeGetInfo: START to get the node info") nodeUUID := s.metadata.GetInstanceID() zone := s.metadata.GetAvailabilityZone() - projectID := s.metadata.GetProjectID() + mvpn := 0 - klog.InfoS("[INFO] - NodeGetInfo: the necessary information is retrieved successfully", "nodeId", nodeUUID, "zone", zone, "projectId", projectID) - if len(projectID) < 1 { - klog.ErrorS(nil, "[ERROR] - NodeGetInfo; projectID is empty") - return nil, fmt.Errorf("projectID is empty") - } + if s.driverOptions.maxVolumesPerNode < 1 { + projectID := s.metadata.GetProjectID() + + klog.InfoS("[INFO] - NodeGetInfo: the necessary information is retrieved successfully", "nodeId", nodeUUID, "zone", zone, "projectId", projectID) + if len(projectID) < 1 { + klog.ErrorS(nil, "[ERROR] - NodeGetInfo; projectID is empty") + return nil, fmt.Errorf("projectID is empty") + } - clientCfg := lsdkClientV2.NewSdkConfigure(). - WithClientId(s.driverOptions.clientID). - WithClientSecret(s.driverOptions.clientSecret). - WithIamEndpoint(s.driverOptions.identityURL). - WithVServerEndpoint(s.driverOptions.vServerURL) + clientCfg := lsdkClientV2.NewSdkConfigure(). + WithClientId(s.driverOptions.clientID). + WithClientSecret(s.driverOptions.clientSecret). + WithIamEndpoint(s.driverOptions.identityURL). + WithVServerEndpoint(s.driverOptions.vServerURL) - cloudClient := lsdkClientV2.NewClient(lctx.TODO()).Configure(clientCfg) + cloudClient := lsdkClientV2.NewClient(lctx.TODO()).Configure(clientCfg) - klog.V(5).InfoS("[DEBUG] - NodeGetInfo: Get the portal info and quota") - portal, sdkErr := cloudClient.VServerGateway().V1().PortalService(). - GetPortalInfo(lsdkPortalSvcV1.NewGetPortalInfoRequest(projectID)) - if sdkErr != nil { - klog.ErrorS(sdkErr.GetError(), "[ERROR] - NodeGetInfo; failed to get portal info") - return nil, sdkErr.GetError() - } + klog.V(5).InfoS("[DEBUG] - NodeGetInfo: Get the portal info and quota") + portal, sdkErr := cloudClient.VServerGateway().V1().PortalService(). + GetPortalInfo(lsdkPortalSvcV1.NewGetPortalInfoRequest(projectID)) + if sdkErr != nil { + klog.ErrorS(sdkErr.GetError(), "[ERROR] - NodeGetInfo; failed to get portal info") + return nil, sdkErr.GetError() + } + + klog.InfoS("[INFO] - NodeGetInfo: Received the portal info successfully", "portal", portal) + cloudClient = cloudClient.WithProjectId(portal.ProjectID) - klog.InfoS("[INFO] - NodeGetInfo: Received the portal info successfully", "portal", portal) - cloudClient = cloudClient.WithProjectId(portal.ProjectID) + quota, sdkErr := cloudClient.VServerGateway().V2().PortalService(). + GetQuotaByName(lsdkPortalSvcV2.NewGetQuotaByNameRequest(lsdkPortalSvcV2.QtVolumeAttachLimit)) - quota, sdkErr := cloudClient.VServerGateway().V2().PortalService(). - GetQuotaByName(lsdkPortalSvcV2.NewGetQuotaByNameRequest(lsdkPortalSvcV2.QtVolumeAttachLimit)) + if sdkErr != nil { + klog.ErrorS(sdkErr.GetError(), "[ERROR] - NodeGetInfo; failed to get quota") + return nil, sdkErr.GetError() + } + klog.InfoS("[INFO] - NodeGetInfo: Setup the VngCloud Manage CSI driver for this node successfully", + "quota", quota, "nodeId", nodeUUID, "zone", zone, "projectId", projectID) - if sdkErr != nil { - klog.ErrorS(sdkErr.GetError(), "[ERROR] - NodeGetInfo; failed to get quota") - return nil, sdkErr.GetError() + mvpn = quota.Limit + } else { + mvpn = s.driverOptions.maxVolumesPerNode + klog.InfoS("[INFO] - NodeGetInfo: Setup the VngCloud Manage CSI driver for this node successfully", + "maxVolumesPerNode", mvpn, "nodeId", nodeUUID, "zone", zone) } - klog.InfoS("[INFO] - NodeGetInfo: Setup the VngCloud Manage CSI driver for this node successfully", - "quota", quota, "nodeId", nodeUUID, "zone", zone, "projectId", projectID) return &lcsi.NodeGetInfoResponse{ NodeId: nodeUUID, - MaxVolumesPerNode: int64(quota.Limit), + MaxVolumesPerNode: int64(mvpn), AccessibleTopology: &lcsi.Topology{ Segments: map[string]string{ ZoneTopologyKey: zone,