diff --git a/cmd/cinder-csi-plugin/main.go b/cmd/cinder-csi-plugin/main.go
index 1673bda4e1..b07b7433fe 100644
--- a/cmd/cinder-csi-plugin/main.go
+++ b/cmd/cinder-csi-plugin/main.go
@@ -38,6 +38,7 @@ var (
httpEndpoint string
provideControllerService bool
provideNodeService bool
+ noClient bool
)
func main() {
@@ -70,6 +71,7 @@ func main() {
cmd.PersistentFlags().BoolVar(&provideControllerService, "provide-controller-service", true, "If set to true then the CSI driver does provide the controller service (default: true)")
cmd.PersistentFlags().BoolVar(&provideNodeService, "provide-node-service", true, "If set to true then the CSI driver does provide the node service (default: true)")
+ cmd.PersistentFlags().BoolVar(&noClient, "node-service-no-os-client", false, "If set to true then the CSI driver node service will not use the OpenStack client (default: false)")
openstack.AddExtraFlags(pflag.CommandLine)
@@ -82,17 +84,24 @@ func handle() {
d := cinder.NewDriver(&cinder.DriverOpts{Endpoint: endpoint, ClusterID: cluster})
openstack.InitOpenStackProvider(cloudConfig, httpEndpoint)
- cloud, err := openstack.GetOpenStackProvider()
- if err != nil {
- klog.Warningf("Failed to GetOpenStackProvider: %v", err)
- return
- }
if provideControllerService {
+ cloud, err := openstack.GetOpenStackProvider(false)
+ if err != nil {
+ klog.Warningf("Failed to GetOpenStackProvider: %v", err)
+ return
+ }
+
d.SetupControllerService(cloud)
}
if provideNodeService {
+ cloud, err := openstack.GetOpenStackProvider(noClient)
+ if err != nil {
+ klog.Warningf("Failed to GetOpenStackProvider: %v", err)
+ return
+ }
+
//Initialize mount
mount := mount.GetMountProvider()
diff --git a/docs/cinder-csi-plugin/using-cinder-csi-plugin.md b/docs/cinder-csi-plugin/using-cinder-csi-plugin.md
index c3a3656ffd..b2aac7ca46 100644
--- a/docs/cinder-csi-plugin/using-cinder-csi-plugin.md
+++ b/docs/cinder-csi-plugin/using-cinder-csi-plugin.md
@@ -111,6 +111,13 @@ In addition to the standard set of klog flags, `cinder-csi-plugin` accepts the f
The default is to provide the node service.
+
+
--node-service-no-os-client <disabled>
+
+ If set to true then the CSI driver does not provide the OpenStack client in the node service.
+
+ The default is to provide the OpenStack client in the node service.
+
## Driver Config
diff --git a/pkg/csi/cinder/openstack/noop_openstack.go b/pkg/csi/cinder/openstack/noop_openstack.go
new file mode 100644
index 0000000000..4cd5c231d6
--- /dev/null
+++ b/pkg/csi/cinder/openstack/noop_openstack.go
@@ -0,0 +1,144 @@
+/*
+Copyright 2024 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package openstack
+
+import (
+ "fmt"
+
+ "github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/backups"
+ "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/snapshots"
+ "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes"
+ "github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
+ "k8s.io/cloud-provider-openstack/pkg/util/metadata"
+)
+
+type NoopOpenStack struct {
+ bsOpts BlockStorageOpts
+ metadataOpts metadata.Opts
+}
+
+func (os *NoopOpenStack) CreateVolume(name string, size int, vtype, availability string, snapshotID string, sourcevolID string, tags *map[string]string) (*volumes.Volume, error) {
+ return nil, fmt.Errorf("CreateVolume is not implemented for ephemeral storage in this configuration")
+}
+
+func (os *NoopOpenStack) ListVolumes(limit int, startingToken string) ([]volumes.Volume, string, error) {
+ return nil, "", nil
+}
+
+func (os *NoopOpenStack) GetVolumesByName(n string) ([]volumes.Volume, error) {
+ return nil, nil
+}
+
+func (os *NoopOpenStack) DeleteVolume(volumeID string) error {
+ return nil
+}
+
+func (os *NoopOpenStack) GetVolume(volumeID string) (*volumes.Volume, error) {
+ return &volumes.Volume{ID: volumeID}, nil
+}
+
+func (os *NoopOpenStack) AttachVolume(instanceID, volumeID string) (string, error) {
+ return volumeID, nil
+}
+
+func (os *NoopOpenStack) WaitDiskAttached(instanceID string, volumeID string) error {
+ return nil
+}
+
+func (os *NoopOpenStack) WaitVolumeTargetStatus(volumeID string, tStatus []string) error {
+ return nil
+}
+
+func (os *NoopOpenStack) DetachVolume(instanceID, volumeID string) error {
+ return nil
+}
+
+func (os *NoopOpenStack) WaitDiskDetached(instanceID string, volumeID string) error {
+ return nil
+}
+
+func (os *NoopOpenStack) GetAttachmentDiskPath(instanceID, volumeID string) (string, error) {
+ return "", nil
+}
+
+func (os *NoopOpenStack) ExpandVolume(volumeID string, status string, newSize int) error {
+ return nil
+}
+
+func (os *NoopOpenStack) GetMaxVolLimit() int64 {
+ if os.bsOpts.NodeVolumeAttachLimit > 0 && os.bsOpts.NodeVolumeAttachLimit <= 256 {
+ return os.bsOpts.NodeVolumeAttachLimit
+ }
+
+ return defaultMaxVolAttachLimit
+}
+
+func (os *NoopOpenStack) GetBlockStorageOpts() BlockStorageOpts {
+ return os.bsOpts
+}
+
+func (os *NoopOpenStack) GetMetadataOpts() metadata.Opts {
+ return os.metadataOpts
+}
+
+func (os *NoopOpenStack) CreateBackup(name, volID, snapshotID, availabilityZone string, tags map[string]string) (*backups.Backup, error) {
+ return &backups.Backup{}, nil
+}
+
+func (os *NoopOpenStack) BackupsAreEnabled() (bool, error) {
+ return false, nil
+}
+
+func (os *NoopOpenStack) DeleteBackup(backupID string) error {
+ return nil
+}
+
+func (os *NoopOpenStack) CreateSnapshot(name, volID string, tags *map[string]string) (*snapshots.Snapshot, error) {
+ return &snapshots.Snapshot{}, nil
+}
+
+func (os *NoopOpenStack) DeleteSnapshot(snapID string) error {
+ return nil
+}
+
+func (os *NoopOpenStack) GetSnapshotByID(snapshotID string) (*snapshots.Snapshot, error) {
+ return &snapshots.Snapshot{ID: snapshotID}, nil
+}
+
+func (os *NoopOpenStack) ListSnapshots(filters map[string]string) ([]snapshots.Snapshot, string, error) {
+ return nil, "", nil
+}
+
+func (os *NoopOpenStack) WaitSnapshotReady(snapshotID string) error {
+ return nil
+}
+
+func (os *NoopOpenStack) GetBackupByID(backupID string) (*backups.Backup, error) {
+ return &backups.Backup{ID: backupID}, nil
+}
+
+func (os *NoopOpenStack) ListBackups(filters map[string]string) ([]backups.Backup, error) {
+ return nil, nil
+}
+
+func (os *NoopOpenStack) WaitBackupReady(backupID string, snapshotSize int, backupMaxDurationSecondsPerGB int) (string, error) {
+ return "", nil
+}
+
+func (os *NoopOpenStack) GetInstanceByID(instanceID string) (*servers.Server, error) {
+ return &servers.Server{ID: instanceID}, nil
+}
diff --git a/pkg/csi/cinder/openstack/openstack.go b/pkg/csi/cinder/openstack/openstack.go
index e3a76a167f..fd8f3f8914 100644
--- a/pkg/csi/cinder/openstack/openstack.go
+++ b/pkg/csi/cinder/openstack/openstack.go
@@ -132,6 +132,7 @@ func GetConfigFromFiles(configFilePaths []string) (Config, error) {
const defaultMaxVolAttachLimit int64 = 256
var OsInstance IOpenStack
+var NoopInstance IOpenStack
var configFiles = []string{"/etc/cloud.conf"}
func InitOpenStackProvider(cfgFiles []string, httpEndpoint string) {
@@ -153,7 +154,7 @@ func InitOpenStackProvider(cfgFiles []string, httpEndpoint string) {
}
// CreateOpenStackProvider creates Openstack Instance
-func CreateOpenStackProvider() (IOpenStack, error) {
+func CreateOpenStackProvider(noClient bool) (IOpenStack, error) {
// Get config from file
cfg, err := GetConfigFromFiles(configFiles)
if err != nil {
@@ -162,6 +163,21 @@ func CreateOpenStackProvider() (IOpenStack, error) {
}
logcfg(cfg)
+ // if no search order given, use default
+ if len(cfg.Metadata.SearchOrder) == 0 {
+ cfg.Metadata.SearchOrder = fmt.Sprintf("%s,%s", metadata.ConfigDriveID, metadata.MetadataID)
+ }
+
+ if noClient {
+ // Init OpenStack
+ NoopInstance = &NoopOpenStack{
+ bsOpts: cfg.BlockStorage,
+ metadataOpts: cfg.Metadata,
+ }
+
+ return NoopInstance, nil
+ }
+
provider, err := client.NewOpenStackClient(&cfg.Global, "cinder-csi-plugin", userAgentData...)
if err != nil {
return nil, err
@@ -184,11 +200,6 @@ func CreateOpenStackProvider() (IOpenStack, error) {
return nil, err
}
- // if no search order given, use default
- if len(cfg.Metadata.SearchOrder) == 0 {
- cfg.Metadata.SearchOrder = fmt.Sprintf("%s,%s", metadata.ConfigDriveID, metadata.MetadataID)
- }
-
// Init OpenStack
OsInstance = &OpenStack{
compute: computeclient,
@@ -202,12 +213,25 @@ func CreateOpenStackProvider() (IOpenStack, error) {
}
// GetOpenStackProvider returns Openstack Instance
-func GetOpenStackProvider() (IOpenStack, error) {
+func GetOpenStackProvider(noClient bool) (IOpenStack, error) {
+ if noClient {
+ if NoopInstance != nil {
+ return NoopInstance, nil
+ }
+ var err error
+ NoopInstance, err = CreateOpenStackProvider(noClient)
+ if err != nil {
+ return nil, err
+ }
+
+ return NoopInstance, nil
+ }
+
if OsInstance != nil {
return OsInstance, nil
}
var err error
- OsInstance, err = CreateOpenStackProvider()
+ OsInstance, err = CreateOpenStackProvider(noClient)
if err != nil {
return nil, err
}