Skip to content

Commit 659ff9a

Browse files
committed
Move project to CloudStackCluster Spec
1 parent 64d390e commit 659ff9a

16 files changed

+105
-48
lines changed

api/v1beta1/conversion.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package v1beta1
1919
import (
2020
"context"
2121
"fmt"
22+
2223
corev1 "k8s.io/api/core/v1"
2324
conv "k8s.io/apimachinery/pkg/conversion"
2425
"sigs.k8s.io/cluster-api-provider-cloudstack/api/v1beta3"
@@ -156,7 +157,7 @@ func fetchZoneIDUsingK8s(namespace string, zoneName string) (string, error) {
156157
}
157158

158159
func fetchZoneIDUsingCloudStack(secret *corev1.Secret, zoneName string) (string, error) {
159-
client, err := cloud.NewClientFromK8sSecret(secret, nil)
160+
client, err := cloud.NewClientFromK8sSecret(secret, nil, "")
160161
if err != nil {
161162
return "", err
162163
}

api/v1beta3/cloudstackfailuredomain_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ type CloudStackFailureDomainSpec struct {
8585
// +optional
8686
Domain string `json:"domain,omitempty"`
8787

88+
// CloudStack project.
89+
// +optional
90+
Project string `json:"project,omitempty"`
91+
8892
// Apache CloudStack Endpoint secret reference.
8993
ACSEndpoint corev1.SecretReference `json:"acsEndpoint"`
9094
}

config/crd/bases/infrastructure.cluster.x-k8s.io_cloudstackclusters.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,9 @@ spec:
376376
name:
377377
description: The failure domain unique name.
378378
type: string
379+
project:
380+
description: CloudStack project.
381+
type: string
379382
zone:
380383
description: The ACS Zone for this failure domain.
381384
properties:

config/crd/bases/infrastructure.cluster.x-k8s.io_cloudstackfailuredomains.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ spec:
154154
name:
155155
description: The failure domain unique name.
156156
type: string
157+
project:
158+
description: CloudStack project.
159+
type: string
157160
zone:
158161
description: The ACS Zone for this failure domain.
159162
properties:

controllers/utils/failuredomains.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,12 +147,12 @@ func (c *CloudClientImplementation) AsFailureDomainUser(fdSpec *infrav1.CloudSta
147147
_ = c.K8sClient.Get(c.RequestCtx, key, clientConfig)
148148

149149
var err error
150-
if c.CSClient, err = cloud.NewClientFromK8sSecret(endpointCredentials, clientConfig); err != nil {
150+
if c.CSClient, err = cloud.NewClientFromK8sSecret(endpointCredentials, clientConfig, fdSpec.Project); err != nil {
151151
return ctrl.Result{}, errors.Wrapf(err, "parsing ACSEndpoint secret with ref: %v", fdSpec.ACSEndpoint)
152152
}
153153

154154
if fdSpec.Account != "" { // Set r.CSUser CloudStack Client per Account and Domain.
155-
client, err := c.CSClient.NewClientInDomainAndAccount(fdSpec.Domain, fdSpec.Account)
155+
client, err := c.CSClient.NewClientInDomainAndAccount(fdSpec.Domain, fdSpec.Account, fdSpec.Project)
156156
if err != nil {
157157
return ctrl.Result{}, err
158158
}

pkg/cloud/affinity_groups.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ type AffinityGroupIface interface {
4343

4444
func (c *client) FetchAffinityGroup(group *AffinityGroup) (reterr error) {
4545
if group.ID != "" {
46-
affinityGroup, count, err := c.cs.AffinityGroup.GetAffinityGroupByID(group.ID, cloudstack.WithProject(c.config.ProjectID))
46+
affinityGroup, count, err := c.cs.AffinityGroup.GetAffinityGroupByID(group.ID, cloudstack.WithProject(c.user.Project.ID))
4747
if err != nil {
4848
// handle via multierr
4949
c.customMetrics.EvaluateErrorAndIncrementAcsReconciliationErrorCounter(err)
@@ -58,7 +58,7 @@ func (c *client) FetchAffinityGroup(group *AffinityGroup) (reterr error) {
5858
}
5959
}
6060
if group.Name != "" {
61-
affinityGroup, count, err := c.cs.AffinityGroup.GetAffinityGroupByName(group.Name, cloudstack.WithProject(c.config.ProjectID))
61+
affinityGroup, count, err := c.cs.AffinityGroup.GetAffinityGroupByName(group.Name, cloudstack.WithProject(c.user.Project.ID))
6262
if err != nil {
6363
// handle via multierr
6464
c.customMetrics.EvaluateErrorAndIncrementAcsReconciliationErrorCounter(err)
@@ -79,7 +79,7 @@ func (c *client) GetOrCreateAffinityGroup(group *AffinityGroup) (retErr error) {
7979
if err := c.FetchAffinityGroup(group); err != nil { // Group not found?
8080
p := c.cs.AffinityGroup.NewCreateAffinityGroupParams(group.Name, group.Type)
8181
p.SetName(group.Name)
82-
setIfNotEmpty(c.config.ProjectID, p.SetProjectid)
82+
setIfNotEmpty(c.user.Project.ID, p.SetProjectid)
8383
resp, err := c.cs.AffinityGroup.CreateAffinityGroup(p)
8484
if err != nil {
8585
c.customMetrics.EvaluateErrorAndIncrementAcsReconciliationErrorCounter(err)
@@ -94,7 +94,7 @@ func (c *client) DeleteAffinityGroup(group *AffinityGroup) (retErr error) {
9494
p := c.cs.AffinityGroup.NewDeleteAffinityGroupParams()
9595
setIfNotEmpty(group.ID, p.SetId)
9696
setIfNotEmpty(group.Name, p.SetName)
97-
setIfNotEmpty(c.config.ProjectID, p.SetProjectid)
97+
setIfNotEmpty(c.user.Project.ID, p.SetProjectid)
9898
_, retErr = c.cs.AffinityGroup.DeleteAffinityGroup(p)
9999
c.customMetrics.EvaluateErrorAndIncrementAcsReconciliationErrorCounter(retErr)
100100
return retErr
@@ -104,7 +104,7 @@ type affinityGroups []AffinityGroup
104104

105105
func (c *client) getCurrentAffinityGroups(csMachine *infrav1.CloudStackMachine) (affinityGroups, error) {
106106
// Start by fetching VM details which includes an array of currently associated affinity groups.
107-
if virtM, count, err := c.cs.VirtualMachine.GetVirtualMachineByID(*csMachine.Spec.InstanceID, cloudstack.WithProject(c.config.ProjectID)); err != nil {
107+
if virtM, count, err := c.cs.VirtualMachine.GetVirtualMachineByID(*csMachine.Spec.InstanceID, cloudstack.WithProject(c.user.Project.ID)); err != nil {
108108
c.customMetrics.EvaluateErrorAndIncrementAcsReconciliationErrorCounter(err)
109109
return nil, err
110110
} else if count > 1 {

pkg/cloud/client.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ type Client interface {
4444
ZoneIFace
4545
IsoNetworkIface
4646
UserCredIFace
47-
NewClientInDomainAndAccount(string, string) (Client, error)
47+
NewClientInDomainAndAccount(string, string, string) (Client, error)
4848
}
4949

5050
// cloud-config ini structure.
@@ -53,7 +53,6 @@ type Config struct {
5353
APIKey string `yaml:"api-key"`
5454
SecretKey string `yaml:"secret-key"`
5555
VerifySSL string `yaml:"verify-ssl"`
56-
ProjectID string `yaml:"project-id"`
5756
}
5857

5958
type client struct {
@@ -102,7 +101,7 @@ func UnmarshalAllSecretConfigs(in []byte, out *[]SecretConfig) error {
102101
}
103102

104103
// NewClientFromK8sSecret returns a client from a k8s secret
105-
func NewClientFromK8sSecret(endpointSecret *corev1.Secret, clientConfig *corev1.ConfigMap) (Client, error) {
104+
func NewClientFromK8sSecret(endpointSecret *corev1.Secret, clientConfig *corev1.ConfigMap, project string) (Client, error) {
106105
endpointSecretStrings := map[string]string{}
107106
for k, v := range endpointSecret.Data {
108107
endpointSecretStrings[k] = string(v)
@@ -111,19 +110,19 @@ func NewClientFromK8sSecret(endpointSecret *corev1.Secret, clientConfig *corev1.
111110
if err != nil {
112111
return nil, err
113112
}
114-
return NewClientFromBytesConfig(bytes, clientConfig)
113+
return NewClientFromBytesConfig(bytes, clientConfig, project)
115114
}
116115

117116
// NewClientFromBytesConfig returns a client from a bytes array that unmarshals to a yaml config.
118-
func NewClientFromBytesConfig(conf []byte, clientConfig *corev1.ConfigMap) (Client, error) {
117+
func NewClientFromBytesConfig(conf []byte, clientConfig *corev1.ConfigMap, project string) (Client, error) {
119118
r := bytes.NewReader(conf)
120119
dec := yaml.NewDecoder(r)
121120
var config Config
122121
if err := dec.Decode(&config); err != nil {
123122
return nil, err
124123
}
125124

126-
return NewClientFromConf(config, clientConfig)
125+
return NewClientFromConf(config, clientConfig, project)
127126
}
128127

129128
// NewClientFromYamlPath returns a client from a yaml config at path.
@@ -147,11 +146,11 @@ func NewClientFromYamlPath(confPath string, secretName string) (Client, error) {
147146
return nil, errors.Errorf("config with secret name %s not found", secretName)
148147
}
149148

150-
return NewClientFromConf(conf, nil)
149+
return NewClientFromConf(conf, nil, "")
151150
}
152151

153152
// NewClientFromConf creates a new Cloud Client form a map of strings to strings.
154-
func NewClientFromConf(conf Config, clientConfig *corev1.ConfigMap) (Client, error) {
153+
func NewClientFromConf(conf Config, clientConfig *corev1.ConfigMap, project string) (Client, error) {
155154
cacheMutex.Lock()
156155
defer cacheMutex.Unlock()
157156

@@ -190,6 +189,9 @@ func NewClientFromConf(conf Config, clientConfig *corev1.ConfigMap) (Client, err
190189
ID: userResponse.Users[0].Domainid,
191190
},
192191
},
192+
Project: Project{
193+
Name: project,
194+
},
193195
}
194196
if found, err := c.GetUserWithKeys(user); err != nil {
195197
return nil, err
@@ -204,10 +206,11 @@ func NewClientFromConf(conf Config, clientConfig *corev1.ConfigMap) (Client, err
204206
}
205207

206208
// NewClientInDomainAndAccount returns a new client in the specified domain and account.
207-
func (c *client) NewClientInDomainAndAccount(domain string, account string) (Client, error) {
209+
func (c *client) NewClientInDomainAndAccount(domain string, account string, project string) (Client, error) {
208210
user := &User{}
209211
user.Account.Domain.Path = domain
210212
user.Account.Name = account
213+
user.Project.Name = project
211214
if found, err := c.GetUserWithKeys(user); err != nil {
212215
return nil, err
213216
} else if !found {
@@ -218,7 +221,7 @@ func (c *client) NewClientInDomainAndAccount(domain string, account string) (Cli
218221
c.config.SecretKey = user.SecretKey
219222
c.user = user
220223

221-
return NewClientFromConf(c.config, nil)
224+
return NewClientFromConf(c.config, nil, project)
222225
}
223226

224227
// NewClientFromCSAPIClient creates a client from a CloudStack-Go API client. Used only for testing.

pkg/cloud/client_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ var _ = Describe("Client", func() {
162162
config := cloud.Config{
163163
APIUrl: "http://1.1.1.1",
164164
}
165-
result, err := cloud.NewClientFromConf(config, clientConfig)
165+
result, err := cloud.NewClientFromConf(config, clientConfig, "")
166166
Ω(err).ShouldNot(HaveOccurred())
167167
Ω(result).ShouldNot(BeNil())
168168
})
@@ -174,8 +174,8 @@ var _ = Describe("Client", func() {
174174
config2 := cloud.Config{
175175
APIUrl: "http://3.3.3.3",
176176
}
177-
result1, _ := cloud.NewClientFromConf(config1, clientConfig)
178-
result2, _ := cloud.NewClientFromConf(config2, clientConfig)
177+
result1, _ := cloud.NewClientFromConf(config1, clientConfig, "")
178+
result2, _ := cloud.NewClientFromConf(config2, clientConfig, "")
179179
Ω(result1).ShouldNot(Equal(result2))
180180
})
181181

@@ -186,8 +186,8 @@ var _ = Describe("Client", func() {
186186
config2 := cloud.Config{
187187
APIUrl: "http://4.4.4.4",
188188
}
189-
result1, _ := cloud.NewClientFromConf(config1, clientConfig)
190-
result2, _ := cloud.NewClientFromConf(config2, clientConfig)
189+
result1, _ := cloud.NewClientFromConf(config1, clientConfig, "")
190+
result2, _ := cloud.NewClientFromConf(config2, clientConfig, "")
191191
Ω(result1).Should(Equal(result2))
192192
})
193193
})

pkg/cloud/cloud_suite_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func TestCloud(t *testing.T) {
7070

7171
// Switch to test account user.
7272
realCloudClient, connectionErr = realCloudClient.NewClientInDomainAndAccount(
73-
newAccount.Domain.Name, newAccount.Name)
73+
newAccount.Domain.Name, newAccount.Name, "")
7474
Ω(connectionErr).ShouldNot(HaveOccurred())
7575
}
7676
})

pkg/cloud/instance.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func setMachineDataFromVMMetrics(vmResponse *cloudstack.VirtualMachinesMetric, c
5858
func (c *client) ResolveVMInstanceDetails(csMachine *infrav1.CloudStackMachine) error {
5959
// Attempt to fetch by ID.
6060
if csMachine.Spec.InstanceID != nil {
61-
vmResp, count, err := c.cs.VirtualMachine.GetVirtualMachinesMetricByID(*csMachine.Spec.InstanceID, cloudstack.WithProject(c.config.ProjectID))
61+
vmResp, count, err := c.cs.VirtualMachine.GetVirtualMachinesMetricByID(*csMachine.Spec.InstanceID, cloudstack.WithProject(c.user.Project.ID))
6262
if err != nil && !strings.Contains(strings.ToLower(err.Error()), "no match found") {
6363
c.customMetrics.EvaluateErrorAndIncrementAcsReconciliationErrorCounter(err)
6464
return err
@@ -72,7 +72,7 @@ func (c *client) ResolveVMInstanceDetails(csMachine *infrav1.CloudStackMachine)
7272

7373
// Attempt fetch by name.
7474
if csMachine.Name != "" {
75-
vmResp, count, err := c.cs.VirtualMachine.GetVirtualMachinesMetricByName(csMachine.Name, cloudstack.WithProject(c.config.ProjectID))
75+
vmResp, count, err := c.cs.VirtualMachine.GetVirtualMachinesMetricByName(csMachine.Name, cloudstack.WithProject(c.user.Project.ID))
7676
if err != nil && !strings.Contains(strings.ToLower(err.Error()), "no match") {
7777
c.customMetrics.EvaluateErrorAndIncrementAcsReconciliationErrorCounter(err)
7878
return err
@@ -88,7 +88,7 @@ func (c *client) ResolveVMInstanceDetails(csMachine *infrav1.CloudStackMachine)
8888

8989
func (c *client) ResolveServiceOffering(csMachine *infrav1.CloudStackMachine, zoneID string) (offering cloudstack.ServiceOffering, retErr error) {
9090
if len(csMachine.Spec.Offering.ID) > 0 {
91-
csOffering, count, err := c.cs.ServiceOffering.GetServiceOfferingByID(csMachine.Spec.Offering.ID, cloudstack.WithProject(c.config.ProjectID))
91+
csOffering, count, err := c.cs.ServiceOffering.GetServiceOfferingByID(csMachine.Spec.Offering.ID, cloudstack.WithProject(c.user.Project.ID))
9292
if err != nil {
9393
c.customMetrics.EvaluateErrorAndIncrementAcsReconciliationErrorCounter(err)
9494
return cloudstack.ServiceOffering{}, multierror.Append(retErr, errors.Wrapf(
@@ -104,7 +104,7 @@ func (c *client) ResolveServiceOffering(csMachine *infrav1.CloudStackMachine, zo
104104
}
105105
return *csOffering, nil
106106
}
107-
csOffering, count, err := c.cs.ServiceOffering.GetServiceOfferingByName(csMachine.Spec.Offering.Name, cloudstack.WithZone(zoneID), cloudstack.WithProject(c.config.ProjectID))
107+
csOffering, count, err := c.cs.ServiceOffering.GetServiceOfferingByName(csMachine.Spec.Offering.Name, cloudstack.WithZone(zoneID), cloudstack.WithProject(c.user.Project.ID))
108108
if err != nil {
109109
c.customMetrics.EvaluateErrorAndIncrementAcsReconciliationErrorCounter(err)
110110
return cloudstack.ServiceOffering{}, multierror.Append(retErr, errors.Wrapf(
@@ -122,7 +122,7 @@ func (c *client) ResolveTemplate(
122122
zoneID string,
123123
) (templateID string, retErr error) {
124124
if len(csMachine.Spec.Template.ID) > 0 {
125-
csTemplate, count, err := c.cs.Template.GetTemplateByID(csMachine.Spec.Template.ID, "executable", cloudstack.WithProject(c.config.ProjectID))
125+
csTemplate, count, err := c.cs.Template.GetTemplateByID(csMachine.Spec.Template.ID, "executable", cloudstack.WithProject(c.user.Project.ID))
126126
if err != nil {
127127
c.customMetrics.EvaluateErrorAndIncrementAcsReconciliationErrorCounter(err)
128128
return "", multierror.Append(retErr, errors.Wrapf(
@@ -138,7 +138,7 @@ func (c *client) ResolveTemplate(
138138
}
139139
return csMachine.Spec.Template.ID, nil
140140
}
141-
templateID, count, err := c.cs.Template.GetTemplateID(csMachine.Spec.Template.Name, "executable", zoneID, cloudstack.WithProject(c.config.ProjectID))
141+
templateID, count, err := c.cs.Template.GetTemplateID(csMachine.Spec.Template.Name, "executable", zoneID, cloudstack.WithProject(c.user.Project.ID))
142142
if err != nil {
143143
c.customMetrics.EvaluateErrorAndIncrementAcsReconciliationErrorCounter(err)
144144
return "", multierror.Append(retErr, errors.Wrapf(
@@ -156,7 +156,7 @@ func (c *client) ResolveTemplate(
156156
func (c *client) ResolveDiskOffering(csMachine *infrav1.CloudStackMachine, zoneID string) (diskOfferingID string, retErr error) {
157157
diskOfferingID = csMachine.Spec.DiskOffering.ID
158158
if len(csMachine.Spec.DiskOffering.Name) > 0 {
159-
diskID, count, err := c.cs.DiskOffering.GetDiskOfferingID(csMachine.Spec.DiskOffering.Name, cloudstack.WithZone(zoneID), cloudstack.WithProject(c.config.ProjectID))
159+
diskID, count, err := c.cs.DiskOffering.GetDiskOfferingID(csMachine.Spec.DiskOffering.Name, cloudstack.WithZone(zoneID), cloudstack.WithProject(c.user.Project.ID))
160160
if err != nil {
161161
c.customMetrics.EvaluateErrorAndIncrementAcsReconciliationErrorCounter(err)
162162
return "", multierror.Append(retErr, errors.Wrapf(
@@ -183,7 +183,7 @@ func (c *client) ResolveDiskOffering(csMachine *infrav1.CloudStackMachine, zoneI
183183
}
184184

185185
func verifyDiskoffering(csMachine *infrav1.CloudStackMachine, c *client, diskOfferingID string, retErr error) (string, error) {
186-
csDiskOffering, count, err := c.cs.DiskOffering.GetDiskOfferingByID(diskOfferingID, cloudstack.WithProject(c.config.ProjectID))
186+
csDiskOffering, count, err := c.cs.DiskOffering.GetDiskOfferingByID(diskOfferingID, cloudstack.WithProject(c.user.Project.ID))
187187
if err != nil {
188188
c.customMetrics.EvaluateErrorAndIncrementAcsReconciliationErrorCounter(err)
189189
return "", multierror.Append(retErr, errors.Wrapf(
@@ -300,7 +300,7 @@ func (c *client) DeployVM(
300300
setIfNotEmpty(csMachine.Name, p.SetName)
301301
setIfNotEmpty(capiMachine.Name, p.SetDisplayname)
302302
setIfNotEmpty(diskOfferingID, p.SetDiskofferingid)
303-
setIfNotEmpty(c.config.ProjectID, p.SetProjectid)
303+
setIfNotEmpty(c.user.Project.ID, p.SetProjectid)
304304
setIntIfPositive(csMachine.Spec.DiskOffering.CustomSize, p.SetSize)
305305

306306
setIfNotEmpty(csMachine.Spec.SSHKey, p.SetKeypair)
@@ -331,7 +331,7 @@ func (c *client) DeployVM(
331331
// CloudStack may have created the VM even though it reported an error. We attempt to
332332
// retrieve the VM so we can populate the CloudStackMachine for the user to manually
333333
// clean up.
334-
vm, findErr := findVirtualMachine(c.cs.VirtualMachine, templateID, fd, csMachine, c.config.ProjectID)
334+
vm, findErr := findVirtualMachine(c.cs.VirtualMachine, templateID, fd, csMachine, c.user.Project.ID)
335335
if findErr != nil {
336336
c.customMetrics.EvaluateErrorAndIncrementAcsReconciliationErrorCounter(findErr)
337337
return fmt.Errorf("%v; find virtual machine: %v", err, findErr)
@@ -455,7 +455,7 @@ func (c *client) listVMInstanceDatadiskVolumeIDs(instanceID string) ([]string, e
455455
p.SetVirtualmachineid(instanceID)
456456
// VM root volumes are destroyed automatically, no need to explicitly include
457457
p.SetType("DATADISK")
458-
setIfNotEmpty(c.config.ProjectID, p.SetProjectid)
458+
setIfNotEmpty(c.user.Project.ID, p.SetProjectid)
459459

460460
listVOLResp, err := c.csAsync.Volume.ListVolumes(p)
461461
if err != nil {

0 commit comments

Comments
 (0)