From f5a0fe4a0b6cde65aded3e7ed087b4e1f0d3e2a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20Fl=C3=B6tzinger?= Date: Wed, 25 Feb 2026 14:13:39 +0100 Subject: [PATCH 1/5] Fix bug in client to also use project id when getting VM by name --- pkg/cloud/vms.go | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/pkg/cloud/vms.go b/pkg/cloud/vms.go index 2df3c7f..e52f15a 100644 --- a/pkg/cloud/vms.go +++ b/pkg/cloud/vms.go @@ -22,46 +22,44 @@ package cloud import ( "context" + "github.com/apache/cloudstack-go/v2/cloudstack" "k8s.io/klog/v2" ) func (c *client) GetVMByID(ctx context.Context, vmID string) (*VM, error) { logger := klog.FromContext(ctx) - p := c.VirtualMachine.NewListVirtualMachinesParams() - p.SetId(vmID) - if c.projectID != "" { - p.SetProjectid(c.projectID) - } logger.V(2).Info("CloudStack API call", "command", "ListVirtualMachines", "params", map[string]string{ "id": vmID, "projectID": c.projectID, }) - l, err := c.VirtualMachine.ListVirtualMachines(p) - if err != nil { - return nil, err - } - if l.Count == 0 { - return nil, ErrNotFound - } - if l.Count > 1 { - return nil, ErrTooManyResults - } - vm := l.VirtualMachines[0] - logger.V(2).Info("Returning VM", "vmID", vm.Id, "zoneID", vm.Zoneid) - return &VM{ - ID: vm.Id, - ZoneID: vm.Zoneid, - }, nil + return c.getVMByParam(ctx, func(p *cloudstack.ListVirtualMachinesParams) { + p.SetId(vmID) + }) } func (c *client) getVMByName(ctx context.Context, name string) (*VM, error) { logger := klog.FromContext(ctx) - p := c.VirtualMachine.NewListVirtualMachinesParams() - p.SetName(name) logger.V(2).Info("CloudStack API call", "command", "ListVirtualMachines", "params", map[string]string{ - "name": name, + "name": name, + "projectID": c.projectID, + }) + + return c.getVMByParam(ctx, func(p *cloudstack.ListVirtualMachinesParams) { + p.SetName(name) }) +} + +func (c *client) getVMByParam(ctx context.Context, setParams func(p *cloudstack.ListVirtualMachinesParams)) (*VM, error) { + p := c.VirtualMachine.NewListVirtualMachinesParams() + + if c.projectID != "" { + p.SetProjectid(c.projectID) + } + + // set params for virtual machine list + setParams(p) + l, err := c.VirtualMachine.ListVirtualMachines(p) if err != nil { return nil, err @@ -73,6 +71,7 @@ func (c *client) getVMByName(ctx context.Context, name string) (*VM, error) { return nil, ErrTooManyResults } vm := l.VirtualMachines[0] + klog.FromContext(ctx).V(2).Info("Returning VM", "vmID", vm.Id, "zoneID", vm.Zoneid) return &VM{ ID: vm.Id, From 6622409c7f9a40886b06312d177abf6f3f631fb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20Fl=C3=B6tzinger?= Date: Wed, 25 Feb 2026 15:18:36 +0100 Subject: [PATCH 2/5] Remove all occurrence of global projectID in cloudstack client because we can set it as default option --- pkg/cloud/cloud.go | 12 ++++++++++-- pkg/cloud/snapshots.go | 20 ++++---------------- pkg/cloud/vms.go | 10 ++-------- pkg/cloud/volumes.go | 11 +---------- 4 files changed, 17 insertions(+), 36 deletions(-) diff --git a/pkg/cloud/cloud.go b/pkg/cloud/cloud.go index 19109a3..a36b1b9 100644 --- a/pkg/cloud/cloud.go +++ b/pkg/cloud/cloud.go @@ -26,6 +26,7 @@ import ( "errors" "github.com/apache/cloudstack-go/v2/cloudstack" + "k8s.io/klog/v2" ) // Interface is the CloudStack client interface. @@ -70,6 +71,7 @@ type Volume struct { DeviceID string } +// Volume represents a CloudStack snapshot. type Snapshot struct { ID string Name string @@ -99,12 +101,18 @@ var ( // client is the implementation of Interface. type client struct { *cloudstack.CloudStackClient - projectID string } // New creates a new cloud connector, given its configuration. func New(config *Config) Interface { csClient := cloudstack.NewAsyncClient(config.APIURL, config.APIKey, config.SecretKey, config.VerifySSL) - return &client{csClient, config.ProjectID} + // Set the project id to every request. + // This is possible because we just could work in one project with the previous implementation. + if config.ProjectID != "" { + csClient.DefaultOptions(cloudstack.WithProject(config.ProjectID)) + klog.Background().V(2).Info("Set projectID to cloud connector", "projectID", config.ProjectID) + } + + return &client{csClient} } diff --git a/pkg/cloud/snapshots.go b/pkg/cloud/snapshots.go index fe2451f..2e001b4 100644 --- a/pkg/cloud/snapshots.go +++ b/pkg/cloud/snapshots.go @@ -34,12 +34,8 @@ func (c *client) GetSnapshotByID(ctx context.Context, snapshotID string) (*Snaps if snapshotID != "" { p.SetId(snapshotID) } - if c.projectID != "" { - p.SetProjectid(c.projectID) - } logger.V(2).Info("CloudStack API call", "command", "ListSnapshots", "params", map[string]string{ - "id": snapshotID, - "projectid": c.projectID, + "id": snapshotID, }) l, err := c.Snapshot.ListSnapshots(p) if err != nil { @@ -112,12 +108,8 @@ func (c *client) GetSnapshotByName(ctx context.Context, name string) (*Snapshot, } p := c.Snapshot.NewListSnapshotsParams() p.SetName(name) - if c.projectID != "" { - p.SetProjectid(c.projectID) - } logger.V(2).Info("CloudStack API call", "command", "ListSnapshots", "params", map[string]string{ - "name": name, - "projectid": c.projectID, + "name": name, }) l, err := c.Snapshot.ListSnapshots(p) if err != nil { @@ -152,13 +144,9 @@ func (c *client) ListSnapshots(ctx context.Context, volumeID, snapshotID string) if volumeID != "" { p.SetVolumeid(volumeID) } - if c.projectID != "" { - p.SetProjectid(c.projectID) - } logger.V(2).Info("CloudStack API call", "command", "ListSnapshots", "params", map[string]string{ - "id": snapshotID, - "volumeid": volumeID, - "projectid": c.projectID, + "id": snapshotID, + "volumeid": volumeID, }) l, err := c.Snapshot.ListSnapshots(p) if err != nil { diff --git a/pkg/cloud/vms.go b/pkg/cloud/vms.go index e52f15a..05596f7 100644 --- a/pkg/cloud/vms.go +++ b/pkg/cloud/vms.go @@ -29,8 +29,7 @@ import ( func (c *client) GetVMByID(ctx context.Context, vmID string) (*VM, error) { logger := klog.FromContext(ctx) logger.V(2).Info("CloudStack API call", "command", "ListVirtualMachines", "params", map[string]string{ - "id": vmID, - "projectID": c.projectID, + "id": vmID, }) return c.getVMByParam(ctx, func(p *cloudstack.ListVirtualMachinesParams) { @@ -41,8 +40,7 @@ func (c *client) GetVMByID(ctx context.Context, vmID string) (*VM, error) { func (c *client) getVMByName(ctx context.Context, name string) (*VM, error) { logger := klog.FromContext(ctx) logger.V(2).Info("CloudStack API call", "command", "ListVirtualMachines", "params", map[string]string{ - "name": name, - "projectID": c.projectID, + "name": name, }) return c.getVMByParam(ctx, func(p *cloudstack.ListVirtualMachinesParams) { @@ -53,10 +51,6 @@ func (c *client) getVMByName(ctx context.Context, name string) (*VM, error) { func (c *client) getVMByParam(ctx context.Context, setParams func(p *cloudstack.ListVirtualMachinesParams)) (*VM, error) { p := c.VirtualMachine.NewListVirtualMachinesParams() - if c.projectID != "" { - p.SetProjectid(c.projectID) - } - // set params for virtual machine list setParams(p) diff --git a/pkg/cloud/volumes.go b/pkg/cloud/volumes.go index caaa7a3..1d69a0b 100644 --- a/pkg/cloud/volumes.go +++ b/pkg/cloud/volumes.go @@ -62,12 +62,8 @@ func (c *client) GetVolumeByID(ctx context.Context, volumeID string) (*Volume, e logger := klog.FromContext(ctx) p := c.Volume.NewListVolumesParams() p.SetId(volumeID) - if c.projectID != "" { - p.SetProjectid(c.projectID) - } logger.V(2).Info("CloudStack API call", "command", "ListVolumes", "params", map[string]string{ - "id": volumeID, - "projectid": c.projectID, + "id": volumeID, }) return c.listVolumes(p) @@ -91,15 +87,11 @@ func (c *client) CreateVolume(ctx context.Context, diskOfferingID, zoneID, name p.SetZoneid(zoneID) p.SetName(name) p.SetSize(sizeInGB) - if c.projectID != "" { - p.SetProjectid(c.projectID) - } logger.V(2).Info("CloudStack API call", "command", "CreateVolume", "params", map[string]string{ "diskofferingid": diskOfferingID, "zoneid": zoneID, "name": name, "size": strconv.FormatInt(sizeInGB, 10), - "projectid": c.projectID, }) vol, err := c.Volume.CreateVolume(p) if err != nil { @@ -199,7 +191,6 @@ func (c *client) CreateVolumeFromSnapshot(ctx context.Context, zoneID, name, pro "name": name, "size": strconv.FormatInt(sizeInGB, 10), "snapshotid": snapshotID, - "projectid": projectID, "zoneid": zoneID, }) // Execute the API call to create volume from snapshot From 424e93d2247d4fe0883d24fdab3df39a19f92ea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20Fl=C3=B6tzinger?= Date: Wed, 25 Feb 2026 15:40:50 +0100 Subject: [PATCH 3/5] Sanitize snapshot functions to require required arguments --- pkg/cloud/snapshots.go | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/pkg/cloud/snapshots.go b/pkg/cloud/snapshots.go index 2e001b4..7615274 100644 --- a/pkg/cloud/snapshots.go +++ b/pkg/cloud/snapshots.go @@ -31,9 +31,7 @@ import ( func (c *client) GetSnapshotByID(ctx context.Context, snapshotID string) (*Snapshot, error) { logger := klog.FromContext(ctx) p := c.Snapshot.NewListSnapshotsParams() - if snapshotID != "" { - p.SetId(snapshotID) - } + p.SetId(snapshotID) logger.V(2).Info("CloudStack API call", "command", "ListSnapshots", "params", map[string]string{ "id": snapshotID, }) @@ -63,9 +61,7 @@ func (c *client) GetSnapshotByID(ctx context.Context, snapshotID string) (*Snaps func (c *client) CreateSnapshot(ctx context.Context, volumeID, name string) (*Snapshot, error) { logger := klog.FromContext(ctx) p := c.Snapshot.NewCreateSnapshotParams(volumeID) - if name != "" { - p.SetName(name) - } + p.SetName(name) logger.V(2).Info("CloudStack API call", "command", "CreateSnapshot", "params", map[string]string{ "volumeid": volumeID, "name": name, @@ -103,9 +99,6 @@ func (c *client) DeleteSnapshot(_ context.Context, snapshotID string) error { func (c *client) GetSnapshotByName(ctx context.Context, name string) (*Snapshot, error) { logger := klog.FromContext(ctx) - if name == "" { - return nil, ErrNotFound - } p := c.Snapshot.NewListSnapshotsParams() p.SetName(name) logger.V(2).Info("CloudStack API call", "command", "ListSnapshots", "params", map[string]string{ @@ -138,12 +131,16 @@ func (c *client) GetSnapshotByName(ctx context.Context, name string) (*Snapshot, func (c *client) ListSnapshots(ctx context.Context, volumeID, snapshotID string) ([]*Snapshot, error) { logger := klog.FromContext(ctx) p := c.Snapshot.NewListSnapshotsParams() + + // snapshotID is optional: csi.ListSnapshotsRequest if snapshotID != "" { p.SetId(snapshotID) } + // volumeID is optional: csi.ListSnapshotsRequest if volumeID != "" { p.SetVolumeid(volumeID) } + logger.V(2).Info("CloudStack API call", "command", "ListSnapshots", "params", map[string]string{ "id": snapshotID, "volumeid": volumeID, From 10330ad5708921f2f5bc2b0ec83f84a2642b7845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20Fl=C3=B6tzinger?= Date: Thu, 26 Feb 2026 11:51:20 +0100 Subject: [PATCH 4/5] Refactor cloud client to use project id default with other cloudstack methods --- pkg/cloud/cloud.go | 3 ++- pkg/cloud/snapshots.go | 53 ++++++++++++++---------------------------- pkg/cloud/vms.go | 38 ++++++++++-------------------- pkg/cloud/volumes.go | 47 ++++++++++++++++++------------------- 4 files changed, 54 insertions(+), 87 deletions(-) diff --git a/pkg/cloud/cloud.go b/pkg/cloud/cloud.go index a36b1b9..ad42d4e 100644 --- a/pkg/cloud/cloud.go +++ b/pkg/cloud/cloud.go @@ -101,6 +101,7 @@ var ( // client is the implementation of Interface. type client struct { *cloudstack.CloudStackClient + projectID string // Used by some specific cloudstack api calls } // New creates a new cloud connector, given its configuration. @@ -114,5 +115,5 @@ func New(config *Config) Interface { klog.Background().V(2).Info("Set projectID to cloud connector", "projectID", config.ProjectID) } - return &client{csClient} + return &client{csClient, config.ProjectID} } diff --git a/pkg/cloud/snapshots.go b/pkg/cloud/snapshots.go index 7615274..ea1b1b7 100644 --- a/pkg/cloud/snapshots.go +++ b/pkg/cloud/snapshots.go @@ -30,32 +30,23 @@ import ( func (c *client) GetSnapshotByID(ctx context.Context, snapshotID string) (*Snapshot, error) { logger := klog.FromContext(ctx) - p := c.Snapshot.NewListSnapshotsParams() - p.SetId(snapshotID) - logger.V(2).Info("CloudStack API call", "command", "ListSnapshots", "params", map[string]string{ + logger.V(2).Info("CloudStack API call", "command", "GetSnapshotByID", "params", map[string]string{ "id": snapshotID, }) - l, err := c.Snapshot.ListSnapshots(p) + + snapshot, _, err := c.Snapshot.GetSnapshotByID(snapshotID) if err != nil { return nil, err } - if l.Count == 0 { - return nil, ErrNotFound - } - if l.Count > 1 { - return nil, ErrTooManyResults - } - snapshot := l.Snapshots[0] - s := Snapshot{ + + return &Snapshot{ ID: snapshot.Id, Name: snapshot.Name, DomainID: snapshot.Domainid, ProjectID: snapshot.Projectid, ZoneID: snapshot.Zoneid, VolumeID: snapshot.Volumeid, - } - - return &s, nil + }, nil } func (c *client) CreateSnapshot(ctx context.Context, volumeID, name string) (*Snapshot, error) { @@ -72,7 +63,7 @@ func (c *client) CreateSnapshot(ctx context.Context, volumeID, name string) (*Sn return nil, status.Errorf(codes.Internal, "Error %v", err) } - snap := Snapshot{ + return &Snapshot{ ID: snapshot.Id, Name: snapshot.Name, Size: snapshot.Virtualsize, @@ -81,9 +72,7 @@ func (c *client) CreateSnapshot(ctx context.Context, volumeID, name string) (*Sn ZoneID: snapshot.Zoneid, VolumeID: snapshot.Volumeid, CreatedAt: snapshot.Created, - } - - return &snap, nil + }, nil } func (c *client) DeleteSnapshot(_ context.Context, snapshotID string) error { @@ -99,23 +88,15 @@ func (c *client) DeleteSnapshot(_ context.Context, snapshotID string) error { func (c *client) GetSnapshotByName(ctx context.Context, name string) (*Snapshot, error) { logger := klog.FromContext(ctx) - p := c.Snapshot.NewListSnapshotsParams() - p.SetName(name) - logger.V(2).Info("CloudStack API call", "command", "ListSnapshots", "params", map[string]string{ + logger.V(2).Info("CloudStack API call", "command", "GetSnapshotByName", "params", map[string]string{ "name": name, }) - l, err := c.Snapshot.ListSnapshots(p) + snapshot, _, err := c.Snapshot.GetSnapshotByName(name) if err != nil { return nil, err } - if l.Count == 0 { - return nil, ErrNotFound - } - if l.Count > 1 { - return nil, ErrTooManyResults - } - snapshot := l.Snapshots[0] - s := Snapshot{ + + return &Snapshot{ ID: snapshot.Id, Name: snapshot.Name, DomainID: snapshot.Domainid, @@ -123,15 +104,12 @@ func (c *client) GetSnapshotByName(ctx context.Context, name string) (*Snapshot, ZoneID: snapshot.Zoneid, VolumeID: snapshot.Volumeid, CreatedAt: snapshot.Created, - } - - return &s, nil + }, nil } func (c *client) ListSnapshots(ctx context.Context, volumeID, snapshotID string) ([]*Snapshot, error) { logger := klog.FromContext(ctx) p := c.Snapshot.NewListSnapshotsParams() - // snapshotID is optional: csi.ListSnapshotsRequest if snapshotID != "" { p.SetId(snapshotID) @@ -141,6 +119,11 @@ func (c *client) ListSnapshots(ctx context.Context, volumeID, snapshotID string) p.SetVolumeid(volumeID) } + // There is no list function that uses the client default project id + if c.projectID != "" { + p.SetProjectid(c.projectID) + } + logger.V(2).Info("CloudStack API call", "command", "ListSnapshots", "params", map[string]string{ "id": snapshotID, "volumeid": volumeID, diff --git a/pkg/cloud/vms.go b/pkg/cloud/vms.go index 05596f7..52ac6be 100644 --- a/pkg/cloud/vms.go +++ b/pkg/cloud/vms.go @@ -22,50 +22,36 @@ package cloud import ( "context" - "github.com/apache/cloudstack-go/v2/cloudstack" "k8s.io/klog/v2" ) func (c *client) GetVMByID(ctx context.Context, vmID string) (*VM, error) { logger := klog.FromContext(ctx) - logger.V(2).Info("CloudStack API call", "command", "ListVirtualMachines", "params", map[string]string{ + logger.V(2).Info("CloudStack API call", "command", "GetVirtualMachineByID", "params", map[string]string{ "id": vmID, }) - return c.getVMByParam(ctx, func(p *cloudstack.ListVirtualMachinesParams) { - p.SetId(vmID) - }) + vm, _, err := c.VirtualMachine.GetVirtualMachineByID(vmID) + if err != nil { + return nil, err + } + + return &VM{ + ID: vm.Id, + ZoneID: vm.Zoneid, + }, nil } func (c *client) getVMByName(ctx context.Context, name string) (*VM, error) { logger := klog.FromContext(ctx) - logger.V(2).Info("CloudStack API call", "command", "ListVirtualMachines", "params", map[string]string{ + logger.V(2).Info("CloudStack API call", "command", "GetVirtualMachineByName", "params", map[string]string{ "name": name, }) - return c.getVMByParam(ctx, func(p *cloudstack.ListVirtualMachinesParams) { - p.SetName(name) - }) -} - -func (c *client) getVMByParam(ctx context.Context, setParams func(p *cloudstack.ListVirtualMachinesParams)) (*VM, error) { - p := c.VirtualMachine.NewListVirtualMachinesParams() - - // set params for virtual machine list - setParams(p) - - l, err := c.VirtualMachine.ListVirtualMachines(p) + vm, _, err := c.VirtualMachine.GetVirtualMachineByName(name) if err != nil { return nil, err } - if l.Count == 0 { - return nil, ErrNotFound - } - if l.Count > 1 { - return nil, ErrTooManyResults - } - vm := l.VirtualMachines[0] - klog.FromContext(ctx).V(2).Info("Returning VM", "vmID", vm.Id, "zoneID", vm.Zoneid) return &VM{ ID: vm.Id, diff --git a/pkg/cloud/volumes.go b/pkg/cloud/volumes.go index 1d69a0b..de7901e 100644 --- a/pkg/cloud/volumes.go +++ b/pkg/cloud/volumes.go @@ -31,19 +31,8 @@ import ( "github.com/cloudstack/cloudstack-csi-driver/pkg/util" ) -func (c *client) listVolumes(p *cloudstack.ListVolumesParams) (*Volume, error) { - l, err := c.Volume.ListVolumes(p) - if err != nil { - return nil, err - } - if l.Count == 0 { - return nil, ErrNotFound - } - if l.Count > 1 { - return nil, ErrTooManyResults - } - vol := l.Volumes[0] - v := Volume{ +func mapVolume(vol *cloudstack.Volume) *Volume { + return &Volume{ ID: vol.Id, Name: vol.Name, Size: vol.Size, @@ -54,30 +43,36 @@ func (c *client) listVolumes(p *cloudstack.ListVolumesParams) (*Volume, error) { VirtualMachineID: vol.Virtualmachineid, DeviceID: strconv.FormatInt(vol.Deviceid, 10), } - - return &v, nil } func (c *client) GetVolumeByID(ctx context.Context, volumeID string) (*Volume, error) { logger := klog.FromContext(ctx) - p := c.Volume.NewListVolumesParams() - p.SetId(volumeID) - logger.V(2).Info("CloudStack API call", "command", "ListVolumes", "params", map[string]string{ + logger.V(2).Info("CloudStack API call", "command", "GetVolumeByID", "params", map[string]string{ "id": volumeID, }) - return c.listVolumes(p) + volume, _, err := c.Volume.GetVolumeByID(volumeID) + if err != nil { + return nil, err + } + + return mapVolume(volume), nil } func (c *client) GetVolumeByName(ctx context.Context, name string) (*Volume, error) { logger := klog.FromContext(ctx) p := c.Volume.NewListVolumesParams() p.SetName(name) - logger.V(2).Info("CloudStack API call", "command", "ListVolumes", "params", map[string]string{ + logger.V(2).Info("CloudStack API call", "command", "GetVolumeByName", "params", map[string]string{ "name": name, }) - return c.listVolumes(p) + volume, _, err := c.Volume.GetVolumeByName(name) + if err != nil { + return nil, err + } + + return mapVolume(volume), nil } func (c *client) CreateVolume(ctx context.Context, diskOfferingID, zoneID, name string, sizeInGB int64) (string, error) { @@ -87,6 +82,10 @@ func (c *client) CreateVolume(ctx context.Context, diskOfferingID, zoneID, name p.SetZoneid(zoneID) p.SetName(name) p.SetSize(sizeInGB) + // There is no create function that uses the client default project id + if c.projectID != "" { + p.SetProjectid(c.projectID) + } logger.V(2).Info("CloudStack API call", "command", "CreateVolume", "params", map[string]string{ "diskofferingid": diskOfferingID, "zoneid": zoneID, @@ -200,7 +199,7 @@ func (c *client) CreateVolumeFromSnapshot(ctx context.Context, zoneID, name, pro return nil, fmt.Errorf("failed to create volume from snapshot '%s': %w", snapshotID, err) } - v := Volume{ + return &Volume{ ID: vol.Id, Name: vol.Name, Size: vol.Size, @@ -210,7 +209,5 @@ func (c *client) CreateVolumeFromSnapshot(ctx context.Context, zoneID, name, pro ZoneID: vol.Zoneid, VirtualMachineID: vol.Virtualmachineid, DeviceID: strconv.FormatInt(vol.Deviceid, 10), - } - - return &v, nil + }, nil } From 7dce33ccd9ab7c10968b66c0f8a12326d1190d91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20Fl=C3=B6tzinger?= Date: Thu, 26 Feb 2026 13:16:07 +0100 Subject: [PATCH 5/5] Change description for default project id options --- pkg/cloud/cloud.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/cloud/cloud.go b/pkg/cloud/cloud.go index ad42d4e..cc90d63 100644 --- a/pkg/cloud/cloud.go +++ b/pkg/cloud/cloud.go @@ -108,8 +108,8 @@ type client struct { func New(config *Config) Interface { csClient := cloudstack.NewAsyncClient(config.APIURL, config.APIKey, config.SecretKey, config.VerifySSL) - // Set the project id to every request. - // This is possible because we just could work in one project with the previous implementation. + // Set the project id to every request that support options. + // This is possible because we also could work in one project only with the previous implementation. if config.ProjectID != "" { csClient.DefaultOptions(cloudstack.WithProject(config.ProjectID)) klog.Background().V(2).Info("Set projectID to cloud connector", "projectID", config.ProjectID)