Skip to content

Commit 01b9efd

Browse files
authored
Merge branch 'main' into bug/disk_offering_ptr
2 parents d9813b6 + 514e4c3 commit 01b9efd

29 files changed

+588
-128
lines changed

api/v1beta1/conversion.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ func fetchZoneIDUsingK8s(namespace string, zoneName string) (string, error) {
157157
}
158158

159159
func fetchZoneIDUsingCloudStack(secret *corev1.Secret, zoneName string) (string, error) {
160-
client, err := cloud.NewClientFromK8sSecret(secret, nil)
160+
client, err := cloud.NewClientFromK8sSecret(secret, nil, "")
161161
if err != nil {
162162
return "", err
163163
}

api/v1beta3/cloudstackfailuredomain_types.go

+4
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

+3
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

+3
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/cloudstackaffinitygroup_controller_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ var _ = Describe("CloudStackAffinityGroupReconciler", func() {
8181
mockCloudClient.EXPECT().FetchAffinityGroup(gomock.Any()).Do(func(arg1 interface{}) {
8282
arg1.(*cloud.AffinityGroup).ID = ""
8383
}).AnyTimes().Return(nil)
84+
Ω(k8sClient.Delete(ctx, dummies.CSAffinityGroup))
8485

8586
Ω(k8sClient.Delete(ctx, dummies.CSAffinityGroup))
8687

controllers/utils/failuredomains.go

+2-2
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

+6-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package cloud
1818

1919
import (
20+
"github.com/apache/cloudstack-go/v2/cloudstack"
2021
"github.com/pkg/errors"
2122
infrav1 "sigs.k8s.io/cluster-api-provider-cloudstack/api/v1beta3"
2223
)
@@ -42,7 +43,7 @@ type AffinityGroupIface interface {
4243

4344
func (c *client) FetchAffinityGroup(group *AffinityGroup) (reterr error) {
4445
if group.ID != "" {
45-
affinityGroup, count, err := c.cs.AffinityGroup.GetAffinityGroupByID(group.ID)
46+
affinityGroup, count, err := c.cs.AffinityGroup.GetAffinityGroupByID(group.ID, cloudstack.WithProject(c.user.Project.ID))
4647
if err != nil {
4748
// handle via multierr
4849
c.customMetrics.EvaluateErrorAndIncrementAcsReconciliationErrorCounter(err)
@@ -57,7 +58,7 @@ func (c *client) FetchAffinityGroup(group *AffinityGroup) (reterr error) {
5758
}
5859
}
5960
if group.Name != "" {
60-
affinityGroup, count, err := c.cs.AffinityGroup.GetAffinityGroupByName(group.Name)
61+
affinityGroup, count, err := c.cs.AffinityGroup.GetAffinityGroupByName(group.Name, cloudstack.WithProject(c.user.Project.ID))
6162
if err != nil {
6263
// handle via multierr
6364
c.customMetrics.EvaluateErrorAndIncrementAcsReconciliationErrorCounter(err)
@@ -78,6 +79,7 @@ func (c *client) GetOrCreateAffinityGroup(group *AffinityGroup) (retErr error) {
7879
if err := c.FetchAffinityGroup(group); err != nil { // Group not found?
7980
p := c.cs.AffinityGroup.NewCreateAffinityGroupParams(group.Name, group.Type)
8081
p.SetName(group.Name)
82+
setIfNotEmpty(c.user.Project.ID, p.SetProjectid)
8183
resp, err := c.cs.AffinityGroup.CreateAffinityGroup(p)
8284
if err != nil {
8385
c.customMetrics.EvaluateErrorAndIncrementAcsReconciliationErrorCounter(err)
@@ -92,6 +94,7 @@ func (c *client) DeleteAffinityGroup(group *AffinityGroup) (retErr error) {
9294
p := c.cs.AffinityGroup.NewDeleteAffinityGroupParams()
9395
setIfNotEmpty(group.ID, p.SetId)
9496
setIfNotEmpty(group.Name, p.SetName)
97+
setIfNotEmpty(c.user.Project.ID, p.SetProjectid)
9598
_, retErr = c.cs.AffinityGroup.DeleteAffinityGroup(p)
9699
c.customMetrics.EvaluateErrorAndIncrementAcsReconciliationErrorCounter(retErr)
97100
return retErr
@@ -101,7 +104,7 @@ type affinityGroups []AffinityGroup
101104

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

pkg/cloud/affinity_groups_test.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -58,21 +58,21 @@ var _ = Describe("AffinityGroup Unit Tests", func() {
5858
Context("Fetch or Create Affinity group", func() {
5959
It("fetches an affinity group by Name", func() {
6060
dummies.AffinityGroup.ID = "" // Force name fetching.
61-
ags.EXPECT().GetAffinityGroupByName(dummies.AffinityGroup.Name).Return(&cloudstack.AffinityGroup{}, 1, nil)
61+
ags.EXPECT().GetAffinityGroupByName(dummies.AffinityGroup.Name, gomock.Any()).Return(&cloudstack.AffinityGroup{}, 1, nil)
6262

6363
Ω(client.GetOrCreateAffinityGroup(dummies.AffinityGroup)).Should(Succeed())
6464
})
6565

6666
It("fetches an affinity group by ID", func() {
67-
ags.EXPECT().GetAffinityGroupByID(dummies.AffinityGroup.ID).Return(&cloudstack.AffinityGroup{}, 1, nil)
67+
ags.EXPECT().GetAffinityGroupByID(dummies.AffinityGroup.ID, gomock.Any()).Return(&cloudstack.AffinityGroup{}, 1, nil)
6868

6969
Ω(client.GetOrCreateAffinityGroup(dummies.AffinityGroup)).Should(Succeed())
7070
})
7171

7272
It("creates an affinity group", func() {
7373
// dummies.SetDummyDomainAndAccount()
7474
// dummies.SetDummyDomainID()
75-
ags.EXPECT().GetAffinityGroupByID(dummies.AffinityGroup.ID).Return(nil, -1, fakeError)
75+
ags.EXPECT().GetAffinityGroupByID(dummies.AffinityGroup.ID, gomock.Any()).Return(nil, -1, fakeError)
7676
ags.EXPECT().NewCreateAffinityGroupParams(dummies.AffinityGroup.Name, dummies.AffinityGroup.Type).
7777
Return(&cloudstack.CreateAffinityGroupParams{})
7878
ags.EXPECT().CreateAffinityGroup(ParamMatch(And(NameEquals(dummies.AffinityGroup.Name)))).
@@ -84,7 +84,7 @@ var _ = Describe("AffinityGroup Unit Tests", func() {
8484
It("creates an affinity group if Name provided returns more than one affinity group", func() {
8585
dummies.AffinityGroup.ID = "" // Force name fetching.
8686
agp := &cloudstack.CreateAffinityGroupParams{}
87-
ags.EXPECT().GetAffinityGroupByName(dummies.AffinityGroup.Name).Return(&cloudstack.AffinityGroup{}, 2, nil)
87+
ags.EXPECT().GetAffinityGroupByName(dummies.AffinityGroup.Name, gomock.Any()).Return(&cloudstack.AffinityGroup{}, 2, nil)
8888
ags.EXPECT().NewCreateAffinityGroupParams(gomock.Any(), gomock.Any()).Return(agp)
8989
ags.EXPECT().CreateAffinityGroup(agp).Return(&cloudstack.CreateAffinityGroupResponse{}, nil)
9090

@@ -94,7 +94,7 @@ var _ = Describe("AffinityGroup Unit Tests", func() {
9494
It("creates an affinity group if getting affinity group by name fails", func() {
9595
dummies.AffinityGroup.ID = "" // Force name fetching.
9696
agp := &cloudstack.CreateAffinityGroupParams{}
97-
ags.EXPECT().GetAffinityGroupByName(dummies.AffinityGroup.Name).Return(nil, -1, fakeError)
97+
ags.EXPECT().GetAffinityGroupByName(dummies.AffinityGroup.Name, gomock.Any()).Return(nil, -1, fakeError)
9898
ags.EXPECT().NewCreateAffinityGroupParams(gomock.Any(), gomock.Any()).Return(agp)
9999
ags.EXPECT().CreateAffinityGroup(agp).Return(&cloudstack.CreateAffinityGroupResponse{}, nil)
100100

@@ -103,7 +103,7 @@ var _ = Describe("AffinityGroup Unit Tests", func() {
103103

104104
It("creates an affinity group if ID provided returns more than one affinity group", func() {
105105
agp := &cloudstack.CreateAffinityGroupParams{}
106-
ags.EXPECT().GetAffinityGroupByID(dummies.AffinityGroup.ID).Return(&cloudstack.AffinityGroup{}, 2, nil)
106+
ags.EXPECT().GetAffinityGroupByID(dummies.AffinityGroup.ID, gomock.Any()).Return(&cloudstack.AffinityGroup{}, 2, nil)
107107
ags.EXPECT().NewCreateAffinityGroupParams(gomock.Any(), gomock.Any()).Return(agp)
108108
ags.EXPECT().CreateAffinityGroup(agp).Return(&cloudstack.CreateAffinityGroupResponse{}, nil)
109109

@@ -112,7 +112,7 @@ var _ = Describe("AffinityGroup Unit Tests", func() {
112112

113113
It("creates an affinity group if getting affinity group by ID fails", func() {
114114
agp := &cloudstack.CreateAffinityGroupParams{}
115-
ags.EXPECT().GetAffinityGroupByID(dummies.AffinityGroup.ID).Return(nil, -1, fakeError)
115+
ags.EXPECT().GetAffinityGroupByID(dummies.AffinityGroup.ID, gomock.Any()).Return(nil, -1, fakeError)
116116
ags.EXPECT().NewCreateAffinityGroupParams(gomock.Any(), gomock.Any()).Return(agp)
117117
ags.EXPECT().CreateAffinityGroup(agp).Return(&cloudstack.CreateAffinityGroupResponse{}, nil)
118118

@@ -164,7 +164,7 @@ var _ = Describe("AffinityGroup Unit Tests", func() {
164164
It("Associate affinity group", func() {
165165
uagp := &cloudstack.UpdateVMAffinityGroupParams{}
166166
vmp := &cloudstack.StartVirtualMachineParams{}
167-
vms.EXPECT().GetVirtualMachineByID(*dummies.CSMachine1.Spec.InstanceID).Return(&cloudstack.VirtualMachine{}, 1, nil)
167+
vms.EXPECT().GetVirtualMachineByID(*dummies.CSMachine1.Spec.InstanceID, gomock.Any()).Return(&cloudstack.VirtualMachine{}, 1, nil)
168168
ags.EXPECT().NewUpdateVMAffinityGroupParams(*dummies.CSMachine1.Spec.InstanceID).Return(uagp)
169169
vms.EXPECT().NewStopVirtualMachineParams(*dummies.CSMachine1.Spec.InstanceID).Return(&cloudstack.StopVirtualMachineParams{})
170170
vms.EXPECT().StopVirtualMachine(&cloudstack.StopVirtualMachineParams{}).Return(&cloudstack.StopVirtualMachineResponse{State: "Stopping"}, nil)
@@ -177,7 +177,7 @@ var _ = Describe("AffinityGroup Unit Tests", func() {
177177
It("Disassociate affinity group", func() {
178178
uagp := &cloudstack.UpdateVMAffinityGroupParams{}
179179
vmp := &cloudstack.StartVirtualMachineParams{}
180-
vms.EXPECT().GetVirtualMachineByID(*dummies.CSMachine1.Spec.InstanceID).Return(&cloudstack.VirtualMachine{}, 1, nil)
180+
vms.EXPECT().GetVirtualMachineByID(*dummies.CSMachine1.Spec.InstanceID, gomock.Any()).Return(&cloudstack.VirtualMachine{}, 1, nil)
181181
ags.EXPECT().NewUpdateVMAffinityGroupParams(*dummies.CSMachine1.Spec.InstanceID).Return(uagp)
182182
vms.EXPECT().NewStopVirtualMachineParams(*dummies.CSMachine1.Spec.InstanceID).Return(&cloudstack.StopVirtualMachineParams{})
183183
vms.EXPECT().StopVirtualMachine(&cloudstack.StopVirtualMachineParams{}).Return(&cloudstack.StopVirtualMachineResponse{State: "Stopping"}, nil)

pkg/cloud/client.go

+13-9
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.
@@ -101,7 +101,7 @@ func UnmarshalAllSecretConfigs(in []byte, out *[]SecretConfig) error {
101101
}
102102

103103
// NewClientFromK8sSecret returns a client from a k8s secret
104-
func NewClientFromK8sSecret(endpointSecret *corev1.Secret, clientConfig *corev1.ConfigMap) (Client, error) {
104+
func NewClientFromK8sSecret(endpointSecret *corev1.Secret, clientConfig *corev1.ConfigMap, project string) (Client, error) {
105105
endpointSecretStrings := map[string]string{}
106106
for k, v := range endpointSecret.Data {
107107
endpointSecretStrings[k] = string(v)
@@ -110,19 +110,19 @@ func NewClientFromK8sSecret(endpointSecret *corev1.Secret, clientConfig *corev1.
110110
if err != nil {
111111
return nil, err
112112
}
113-
return NewClientFromBytesConfig(bytes, clientConfig)
113+
return NewClientFromBytesConfig(bytes, clientConfig, project)
114114
}
115115

116116
// NewClientFromBytesConfig returns a client from a bytes array that unmarshals to a yaml config.
117-
func NewClientFromBytesConfig(conf []byte, clientConfig *corev1.ConfigMap) (Client, error) {
117+
func NewClientFromBytesConfig(conf []byte, clientConfig *corev1.ConfigMap, project string) (Client, error) {
118118
r := bytes.NewReader(conf)
119119
dec := yaml.NewDecoder(r)
120120
var config Config
121121
if err := dec.Decode(&config); err != nil {
122122
return nil, err
123123
}
124124

125-
return NewClientFromConf(config, clientConfig)
125+
return NewClientFromConf(config, clientConfig, project)
126126
}
127127

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

149-
return NewClientFromConf(conf, nil)
149+
return NewClientFromConf(conf, nil, "")
150150
}
151151

152152
// NewClientFromConf creates a new Cloud Client form a map of strings to strings.
153-
func NewClientFromConf(conf Config, clientConfig *corev1.ConfigMap) (Client, error) {
153+
func NewClientFromConf(conf Config, clientConfig *corev1.ConfigMap, project string) (Client, error) {
154154
cacheMutex.Lock()
155155
defer cacheMutex.Unlock()
156156

@@ -189,6 +189,9 @@ func NewClientFromConf(conf Config, clientConfig *corev1.ConfigMap) (Client, err
189189
ID: userResponse.Users[0].Domainid,
190190
},
191191
},
192+
Project: Project{
193+
Name: project,
194+
},
192195
}
193196
if found, err := c.GetUserWithKeys(user); err != nil {
194197
return nil, err
@@ -203,10 +206,11 @@ func NewClientFromConf(conf Config, clientConfig *corev1.ConfigMap) (Client, err
203206
}
204207

205208
// NewClientInDomainAndAccount returns a new client in the specified domain and account.
206-
func (c *client) NewClientInDomainAndAccount(domain string, account string) (Client, error) {
209+
func (c *client) NewClientInDomainAndAccount(domain string, account string, project string) (Client, error) {
207210
user := &User{}
208211
user.Account.Domain.Path = domain
209212
user.Account.Name = account
213+
user.Project.Name = project
210214
if found, err := c.GetUserWithKeys(user); err != nil {
211215
return nil, err
212216
} else if !found {
@@ -217,7 +221,7 @@ func (c *client) NewClientInDomainAndAccount(domain string, account string) (Cli
217221
c.config.SecretKey = user.SecretKey
218222
c.user = user
219223

220-
return NewClientFromConf(c.config, nil)
224+
return NewClientFromConf(c.config, nil, project)
221225
}
222226

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

pkg/cloud/client_test.go

+5-5
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

+1-1
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
})

0 commit comments

Comments
 (0)