Skip to content

Commit

Permalink
[cinder-csi]: allow node service to run without openstack client (#2655)
Browse files Browse the repository at this point in the history
  • Loading branch information
kayrus authored Sep 18, 2024
1 parent 84a4732 commit 4aeaf2e
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 17 deletions.
31 changes: 22 additions & 9 deletions cmd/cinder-csi-plugin/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ var (
httpEndpoint string
provideControllerService bool
provideNodeService bool
noClient bool
)

func main() {
Expand Down Expand Up @@ -75,6 +76,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)

Expand All @@ -87,21 +89,32 @@ func handle() {
d := cinder.NewDriver(&cinder.DriverOpts{Endpoint: endpoint, ClusterID: cluster})

openstack.InitOpenStackProvider(cloudConfig, httpEndpoint)
var err error
clouds := make(map[string]openstack.IOpenStack)
for _, cloudName := range cloudNames {
clouds[cloudName], err = openstack.GetOpenStackProvider(cloudName)
if err != nil {
klog.Warningf("Failed to GetOpenStackProvider %s: %v", cloudName, err)
return
}
}

if provideControllerService {
var err error
clouds := make(map[string]openstack.IOpenStack)
for _, cloudName := range cloudNames {
clouds[cloudName], err = openstack.GetOpenStackProvider(cloudName, false)
if err != nil {
klog.Warningf("Failed to GetOpenStackProvider %s: %v", cloudName, err)
return
}
}

d.SetupControllerService(clouds)
}

if provideNodeService {
var err error
clouds := make(map[string]openstack.IOpenStack)
for _, cloudName := range cloudNames {
clouds[cloudName], err = openstack.GetOpenStackProvider(cloudName, noClient)
if err != nil {
klog.Warningf("Failed to GetOpenStackProvider %s: %v", cloudName, err)
return
}
}

//Initialize mount
mount := mount.GetMountProvider()

Expand Down
7 changes: 7 additions & 0 deletions docs/cinder-csi-plugin/using-cinder-csi-plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
</dd>

<dt>--node-service-no-os-client &lt;disabled&gt;</dt>
<dd>
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.
</dd>
</dl>

## Driver Config
Expand Down
144 changes: 144 additions & 0 deletions pkg/csi/cinder/openstack/noop_openstack.go
Original file line number Diff line number Diff line change
@@ -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/v2/openstack/blockstorage/v3/backups"
"github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/snapshots"
"github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/volumes"
"github.com/gophercloud/gophercloud/v2/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, sourceBackupID 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) (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
}
41 changes: 33 additions & 8 deletions pkg/csi/cinder/openstack/openstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,12 @@ func GetConfigFromFiles(configFilePaths []string) (Config, error) {
const defaultMaxVolAttachLimit int64 = 256

var OsInstances map[string]IOpenStack
var NoopInstances map[string]IOpenStack
var configFiles = []string{"/etc/cloud.conf"}

func InitOpenStackProvider(cfgFiles []string, httpEndpoint string) {
OsInstances = make(map[string]IOpenStack)
NoopInstances = make(map[string]IOpenStack)
metrics.RegisterMetrics("cinder-csi")
if httpEndpoint != "" {
mux := http.NewServeMux()
Expand All @@ -166,7 +168,7 @@ func InitOpenStackProvider(cfgFiles []string, httpEndpoint string) {
}

// CreateOpenStackProvider creates Openstack Instance with custom Global config param
func CreateOpenStackProvider(cloudName string) (IOpenStack, error) {
func CreateOpenStackProvider(cloudName string, noClient bool) (IOpenStack, error) {
// Get config from file
cfg, err := GetConfigFromFiles(configFiles)
if err != nil {
Expand All @@ -179,6 +181,21 @@ func CreateOpenStackProvider(cloudName string) (IOpenStack, error) {
return nil, fmt.Errorf("GetConfigFromFiles cloud name \"%s\" not found in configuration files: %s", cloudName, configFiles)
}

// 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
NoopInstances[cloudName] = &NoopOpenStack{
bsOpts: cfg.BlockStorage,
metadataOpts: cfg.Metadata,
}

return NoopInstances[cloudName], nil
}

provider, err := client.NewOpenStackClient(cfg.Global[cloudName], "cinder-csi-plugin", userAgentData...)
if err != nil {
return nil, err
Expand All @@ -201,11 +218,6 @@ func CreateOpenStackProvider(cloudName string) (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
OsInstances[cloudName] = &OpenStack{
compute: computeclient,
Expand All @@ -219,12 +231,25 @@ func CreateOpenStackProvider(cloudName string) (IOpenStack, error) {
}

// GetOpenStackProvider returns Openstack Instance
func GetOpenStackProvider(cloudName string) (IOpenStack, error) {
func GetOpenStackProvider(cloudName string, noClient bool) (IOpenStack, error) {
if noClient {
NoopInstance, NoopInstanceDefined := NoopInstances[cloudName]
if NoopInstanceDefined {
return NoopInstance, nil
}
NoopInstance, err := CreateOpenStackProvider(cloudName, noClient)
if err != nil {
return nil, err
}

return NoopInstance, nil
}

OsInstance, OsInstanceDefined := OsInstances[cloudName]
if OsInstanceDefined {
return OsInstance, nil
}
OsInstance, err := CreateOpenStackProvider(cloudName)
OsInstance, err := CreateOpenStackProvider(cloudName, noClient)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 4aeaf2e

Please sign in to comment.