Skip to content

Commit a3675cf

Browse files
author
Joshua Reed
committed
Built structure to run configurable ACS setup.
1 parent 91a8ecf commit a3675cf

20 files changed

+410
-93
lines changed

acs.yaml

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
apiVersion: cluster.x-k8s.io/v1beta1
2+
kind: Cluster
3+
metadata:
4+
name: cluster1
5+
spec:
6+
clusterNetwork:
7+
pods:
8+
cidrBlocks:
9+
- 192.168.0.0/16
10+
serviceDomain: cluster.local
11+
infrastructureRef:
12+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
13+
kind: CloudStackCluster
14+
name: cluster1
15+
controlPlaneRef:
16+
kind: KubeadmControlPlane
17+
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
18+
name: cluster1-control-plane
19+
---
20+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
21+
kind: CloudStackCluster
22+
metadata:
23+
name: cluster1
24+
spec:
25+
controlPlaneEndpoint:
26+
# host: ""
27+
host: ""
28+
port: 6443
29+
# domain: ROOT/blah/blah/subsub
30+
# account: SuperNested
31+
zones:
32+
- name : Zone1
33+
network:
34+
name: SomeGuestNet2
35+
# - name : Zone2
36+
# network:
37+
# name: SharedGuestNet2
38+
# - name : Zone1
39+
# network:
40+
# name: SharedGuestNet1
41+
---
42+
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
43+
kind: KubeadmControlPlane
44+
metadata:
45+
name: cluster1-control-plane
46+
spec:
47+
kubeadmConfigSpec:
48+
clusterConfiguration:
49+
imageRepository: k8s.gcr.io
50+
# etcd:
51+
# external:
52+
# endpoints: []
53+
# caFile: "/etc/kubernetes/pki/etcd/ca.crt"
54+
# certFile: "/etc/kubernetes/pki/apiserver-etcd-client.crt"
55+
# keyFile: "/etc/kubernetes/pki/apiserver-etcd-client.key"
56+
initConfiguration:
57+
nodeRegistration:
58+
kubeletExtraArgs:
59+
provider-id: "cloudstack:///'{{ ds.meta_data.instance_id }}'"
60+
name: '{{ local_hostname }}'
61+
joinConfiguration:
62+
nodeRegistration:
63+
kubeletExtraArgs:
64+
provider-id: "cloudstack:///'{{ ds.meta_data.instance_id }}'"
65+
name: '{{ local_hostname }}'
66+
preKubeadmCommands:
67+
- swapoff -a
68+
- echo '' >> /etc/hosts
69+
- echo '192.168.1.31 kend' >> /etc/hosts
70+
machineTemplate:
71+
infrastructureRef:
72+
kind: CloudStackMachineTemplate
73+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
74+
name: "cluster1-control-plane"
75+
replicas: 1
76+
version: v1.20.10
77+
---
78+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
79+
kind: CloudStackMachineTemplate
80+
metadata:
81+
name: cluster1-control-plane
82+
spec:
83+
template:
84+
spec:
85+
offering:
86+
name: Large Instance
87+
template:
88+
name: ubuntu20
89+
---
90+
apiVersion: cluster.x-k8s.io/v1beta1
91+
kind: MachineDeployment
92+
metadata:
93+
name: "cluster1-md-0"
94+
spec:
95+
clusterName: "cluster1"
96+
replicas: 1
97+
selector:
98+
matchLabels: null
99+
template:
100+
spec:
101+
bootstrap:
102+
configRef:
103+
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
104+
kind: KubeadmConfigTemplate
105+
name: "cluster1-md-0"
106+
clusterName: "cluster1"
107+
infrastructureRef:
108+
name: "cluster1-md-0"
109+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
110+
kind: CloudStackMachineTemplate
111+
version: v1.20.10
112+
---
113+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
114+
kind: CloudStackMachineTemplate
115+
metadata:
116+
name: cluster1-md-0
117+
spec:
118+
template:
119+
spec:
120+
affinity: pro
121+
offering:
122+
# name: Large Instance
123+
name: Insane Instance
124+
template:
125+
name: ubuntu20
126+
---
127+
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
128+
kind: KubeadmConfigTemplate
129+
metadata:
130+
name: cluster1-md-0
131+
spec:
132+
template:
133+
spec:
134+
joinConfiguration:
135+
nodeRegistration:
136+
kubeletExtraArgs:
137+
provider-id: "cloudstack:///'{{ ds.meta_data.instance_id }}'"
138+
name: '{{ local_hostname }}'
139+
preKubeadmCommands:
140+
- swapoff -a
141+
# ---
142+
# managedExternalEtcdRef:
143+
# kind: EtcdadmCluster
144+
# apiVersion: etcdcluster.cluster.x-k8s.io/v1beta1
145+
# name: cluster1-etcd
146+
# ---
147+
# kind: EtcdadmCluster
148+
# apiVersion: etcdcluster.cluster.x-k8s.io/v1beta1
149+
# metadata:
150+
# name: cluster1-etcd
151+
# namespace: default
152+
# spec:
153+
# replicas: 3
154+
# etcdadmConfigSpec:
155+
# etcdadmBuiltin: true
156+
# format: {{.format}}
157+
# cloudInitConfig:
158+
# version: {{.externalEtcdVersion}}
159+
# installDir: "/usr/bin"
160+
# preEtcdadmCommands:
161+
# - swapoff -a
162+
# - hostname "{{`{{ ds.meta_data.local_hostname }}`}}"
163+
# - echo "::1 ipv6-localhost ipv6-loopback" >/etc/hosts
164+
# - echo "127.0.0.1 localhost" >>/etc/hosts
165+
# - echo "127.0.0.1 {{`{{ ds.meta_data.local_hostname }}`}}" >>/etc/hosts
166+
# - echo "{{`{{ ds.meta_data.local_hostname }}`}}" >/etc/hostname
167+
# {{- if .etcdCipherSuites }}
168+
# cipherSuites: {{.etcdCipherSuites}}
169+
# {{- end }}
170+
# users:
171+
# - name: {{.etcdSshUsername}}
172+
# sshAuthorizedKeys:
173+
# - '{{.cloudstackEtcdSshAuthorizedKey}}'
174+
# sudo: ALL=(ALL) NOPASSWD:ALL
175+
# {{- if .proxyConfig }}
176+
# proxy:
177+
# httpProxy: {{ .httpProxy }}
178+
# httpsProxy: {{ .httpsProxy }}
179+
# noProxy: {{ range .noProxy }}
180+
# - {{ . }}
181+
# {{- end }}
182+
# {{- end }}
183+
# {{- if .registryMirrorConfiguration }}
184+
# registryMirror:
185+
# endpoint: {{.registryMirrorConfiguration}}
186+
# {{- if .registryCACert }}
187+
# caCert: |
188+
# {{ .registryCACert | indent 8 }}
189+
# {{- end }}
190+
# {{- end }}
191+
# infrastructureTemplate:
192+
# apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
193+
# kind: CloudStackMachineTemplate
194+
# name: cluster1-etcd
195+
# ---
196+
# apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
197+
# kind: CloudStackMachineTemplate
198+
# metadata:
199+
# name: cluster1-etcd
200+
# spec:
201+
# template:
202+
# spec:
203+
# affinity: pro
204+
# offering:
205+
# name: Large Instance
206+
# template:
207+
# name: ubuntu20
208+
# ---
209+
# kind: EtcdadmCluster
210+
# apiVersion: etcdcluster.cluster.x-k8s.io/v1beta1
211+
# metadata:
212+
# name: eksa-test-b77a195-etcd
213+
# namespace: eksa-system
214+
# spec:
215+
# replicas: 1
216+
# etcdadmConfigSpec:
217+
# etcdadmBuiltin: true
218+
# format: cloud-config
219+
# cloudInitConfig:
220+
# version: 3.4.18
221+
# installDir: "/usr/bin"
222+
# preEtcdadmCommands:
223+
# - swapoff -a
224+
# - hostname "{{ ds.meta_data.local_hostname }}"
225+
# - echo "::1 ipv6-localhost ipv6-loopback" >/etc/hosts
226+
# - echo "127.0.0.1 localhost" >>/etc/hosts
227+
# - echo "127.0.0.1 {{ ds.meta_data.local_hostname }}" >>/etc/hosts
228+
# - echo "{{ ds.meta_data.local_hostname }}" >/etc/hostname
229+
# cipherSuites: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
230+
# users:
231+
# - name: capc
232+
# sshAuthorizedKeys:
233+
# - 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDsnzypEZ7l9agzljZrZ2GWpEXdHHXRZYQsn4a5WcLcLvKDkkvZKV9WDpBpQtxdn6LOkxlhLsujSAVn8oRezdWaqBS2snKHU6jqf6QhQrDm268zwL421s6CDyfJj5+LN1GuHQpieY3RTH9iyxhzc/hnv803LNCuYMJK0HzKpuKkw3YelFvQeyzUUQbsflfP/0eSmEmw16MoPUML8OqPsQyt0JH7cbUWyAYQmYkOKLHVeOvY93Uq3h9H74neFH19DKvR+2PgKiMwxo+Ab6VzgC5TMwb1/ohj18ClENhcbKYR9zWeD2bkORniB8eETf2aOCBNVaLCsF6S7U93DY9v7TZ1Q+wVdZ5hLiHVAkeiXJwfYec+KqL7IdRmxpiBB4uZ8py6DijdX/jqRLS7bAwRhC6aioxmRrCWQxjgBSm+rdkMMrOev23KWDXDBOI4PfHp/C0jE2S8dDbeCbJmmwn2I1vNP9ZIBNtjjJglcrqJveZZFreGj1NMeiiSZPrqT4D0tr8='
234+
# sudo: ALL=(ALL) NOPASSWD:ALL
235+
# infrastructureTemplate:
236+
# apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
237+
# kind: CloudStackMachineTemplate
238+
# name: eksa-test-b77a195-etcd-template-1650656267111
239+
# ---
240+
# apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
241+
# kind: CloudStackMachineTemplate
242+
# metadata:
243+
# name: eksa-test-b77a195-etcd-template-1650656267111
244+
# namespace: 'eksa-system'
245+
# spec:
246+
# template:
247+
# spec:
248+
# offering:
249+
# name: Fruitstand Instance
250+
# template:
251+
# name: rhel-8-kube-v1.20.7-v0.6.3-beta-fruitstand

test/helpers/user.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ import (
1212
func GetDomainByPath(csClient *cloudstack.CloudStackClient, path string) (string, error, bool) {
1313
// Split path and get name.
1414
path = strings.Trim(path, "/")
15-
tokens := []string{}
16-
tokens = strings.Split(path, "/")
15+
tokens := strings.Split(path, "/")
1716

1817
// Ensure the path begins with ROOT.
1918
if !strings.EqualFold(tokens[0], "ROOT") {

test/unit/cloud/affinity_groups_test.go

Lines changed: 42 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -20,78 +20,71 @@ import (
2020
"errors"
2121

2222
"github.com/apache/cloudstack-go/v2/cloudstack"
23+
"github.com/aws/cluster-api-provider-cloudstack-staging/test/unit/dummies"
2324
"github.com/aws/cluster-api-provider-cloudstack/pkg/cloud"
24-
"github.com/aws/cluster-api-provider-cloudstack/test/dummies"
2525
"github.com/golang/mock/gomock"
2626
. "github.com/onsi/ginkgo/v2"
2727
. "github.com/onsi/gomega"
2828
)
2929

30-
var _ = Describe("AffinityGroup Unit Tests", func() {
31-
var ( // Declare shared vars.
32-
mockCtrl *gomock.Controller
33-
mockClient *cloudstack.CloudStackClient
34-
ags *cloudstack.MockAffinityGroupServiceIface
35-
client cloud.Client
36-
)
37-
30+
var _ = Describe("The AffinityGroup interface", func() {
31+
var client cloud.Client
3832
BeforeEach(func() {
39-
// Setup new mock services.
40-
mockCtrl = gomock.NewController(GinkgoT())
41-
mockClient = cloudstack.NewMockClient(mockCtrl)
42-
ags = mockClient.AffinityGroup.(*cloudstack.MockAffinityGroupServiceIface)
43-
client = cloud.NewClientFromCSAPIClient(mockClient)
4433
dummies.SetDummyVars()
4534
})
35+
When("using a mock CloudStack Client", func() {
36+
var (
37+
mockCtrl *gomock.Controller
38+
mockClient *cloudstack.CloudStackClient
39+
ags *cloudstack.MockAffinityGroupServiceIface
40+
)
41+
BeforeEach(func() {
42+
// Setup mock CloudstackClient.
43+
mockCtrl = gomock.NewController(GinkgoT())
44+
mockClient = cloudstack.NewMockClient(mockCtrl)
45+
ags = mockClient.AffinityGroup.(*cloudstack.MockAffinityGroupServiceIface)
46+
client = cloud.NewClientFromCSAPIClient(mockClient)
47+
})
48+
AfterEach(func() {
49+
// Check mocked calls match.
50+
mockCtrl.Finish()
51+
})
4652

47-
AfterEach(func() {
48-
mockCtrl.Finish()
49-
})
50-
51-
It("fetches an affinity group", func() {
52-
dummies.AffinityGroup.ID = "" // Force name fetching.
53-
ags.EXPECT().GetAffinityGroupByName(dummies.AffinityGroup.Name).Return(&cloudstack.AffinityGroup{}, 1, nil)
53+
It("fetches an affinity group", func() {
54+
dummies.AffinityGroup.ID = "" // Force name fetching.
55+
ags.EXPECT().GetAffinityGroupByName(dummies.AffinityGroup.Name).Return(&cloudstack.AffinityGroup{}, 1, nil)
5456

55-
Ω(client.GetOrCreateAffinityGroup(dummies.AffinityGroup)).Should(Succeed())
56-
})
57-
It("creates an affinity group", func() {
58-
dummies.SetDummyDomainAndAccount()
59-
dummies.SetDummyDomainID()
60-
ags.EXPECT().GetAffinityGroupByID(dummies.AffinityGroup.ID).Return(nil, -1, errors.New("FakeError"))
61-
ags.EXPECT().NewCreateAffinityGroupParams(dummies.AffinityGroup.Name, dummies.AffinityGroup.Type).
62-
Return(&cloudstack.CreateAffinityGroupParams{})
63-
ags.EXPECT().CreateAffinityGroup(ParamMatch(And(NameEquals(dummies.AffinityGroup.Name)))).
64-
Return(&cloudstack.CreateAffinityGroupResponse{}, nil)
57+
Ω(client.GetOrCreateAffinityGroup(dummies.AffinityGroup)).Should(Succeed())
58+
})
59+
It("creates an affinity group", func() {
60+
dummies.SetDummyDomainAndAccount()
61+
dummies.SetDummyDomainID()
62+
ags.EXPECT().GetAffinityGroupByID(dummies.AffinityGroup.ID).Return(nil, -1, errors.New("FakeError"))
63+
ags.EXPECT().NewCreateAffinityGroupParams(dummies.AffinityGroup.Name, dummies.AffinityGroup.Type).
64+
Return(&cloudstack.CreateAffinityGroupParams{})
65+
ags.EXPECT().CreateAffinityGroup(ParamMatch(And(NameEquals(dummies.AffinityGroup.Name)))).
66+
Return(&cloudstack.CreateAffinityGroupResponse{}, nil)
6567

66-
Ω(client.GetOrCreateAffinityGroup(dummies.AffinityGroup)).Should(Succeed())
68+
Ω(client.GetOrCreateAffinityGroup(dummies.AffinityGroup)).Should(Succeed())
69+
})
6770
})
6871

69-
Context("AffinityGroup Integ Tests", func() {
70-
client, connectionErr := cloud.NewClient("../../cloud-config")
71-
72+
When("using a real CloudStack client", func() {
7273
BeforeEach(func() {
73-
if connectionErr != nil { // Only do these tests if an actual ACS instance is available via cloud-config.
74-
Skip("Could not connect to ACS instance.")
75-
}
74+
client = realCloudClient
7675
dummies.AffinityGroup.ID = "" // Force name fetching.
7776
})
78-
AfterEach(func() {
79-
mockCtrl.Finish()
80-
})
81-
82-
It("Creates an affinity group.", func() {
77+
It("creates an affinity group.", func() {
8378
Ω(client.GetOrCreateAffinityGroup(dummies.AffinityGroup)).Should(Succeed())
8479
})
85-
It("Associates an affinity group.", func() {
86-
if err := client.GetOrCreateVMInstance(
80+
It("associates an affinity group.", func() {
81+
Ω(client.GetOrCreateVMInstance(
8782
dummies.CSMachine1, dummies.CAPIMachine, dummies.CSCluster, dummies.CSZone1, dummies.CSAffinityGroup, "",
88-
); err != nil {
89-
Skip("Could not create VM." + err.Error())
90-
}
83+
)).Should(Succeed())
9184
Ω(client.GetOrCreateAffinityGroup(dummies.AffinityGroup)).Should(Succeed())
9285
Ω(client.AssociateAffinityGroup(dummies.CSMachine1, *dummies.AffinityGroup)).Should(Succeed())
9386
})
94-
It("Deletes an affinity group.", func() {
87+
It("deletes an affinity group.", func() {
9588
Ω(client.DeleteAffinityGroup(dummies.AffinityGroup)).Should(Succeed())
9689
Ω(client.FetchAffinityGroup(dummies.AffinityGroup)).ShouldNot(Succeed())
9790
})

0 commit comments

Comments
 (0)