Skip to content

Commit 71667a7

Browse files
Added e2e test for multiple network support
1 parent ee61587 commit 71667a7

File tree

5 files changed

+230
-0
lines changed

5 files changed

+230
-0
lines changed

test/e2e/config/cloudstack.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ providers:
102102
- sourcePath: "../data/infrastructure-cloudstack/v1beta3/cluster-template-kubernetes-version-upgrade-before.yaml"
103103
- sourcePath: "../data/infrastructure-cloudstack/v1beta3/cluster-template-kubernetes-version-upgrade-after.yaml"
104104
- sourcePath: "../data/infrastructure-cloudstack/v1beta3/cluster-template-k8s-cks.yaml"
105+
- sourcePath: "../data/infrastructure-cloudstack/v1beta3/cluster-template-multiple-templates.yaml"
105106
- sourcePath: "../data/shared/v1beta1_provider/metadata.yaml"
106107
versions:
107108
- name: v1.0.0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
bases:
2+
- ../bases/cluster-with-kcp.yaml
3+
- ../bases/md.yaml
4+
5+
patchesStrategicMerge:
6+
- ./multiple-networks.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
3+
kind: CloudStackMachineTemplate
4+
metadata:
5+
name: ${CLUSTER_NAME}-control-plane
6+
spec:
7+
template:
8+
spec:
9+
offering:
10+
name: ${CLOUDSTACK_CONTROL_PLANE_MACHINE_OFFERING}
11+
template:
12+
name: ${CLOUDSTACK_TEMPLATE_NAME}
13+
sshKey: ${CLOUDSTACK_SSH_KEY_NAME}
14+
affinity: pro
15+
networks:
16+
- name: ${CLOUDSTACK_NETWORK_NAME}
17+
- name: ${CLOUDSTACK_NEW_NETWORK_NAME}
18+
---
19+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
20+
kind: CloudStackMachineTemplate
21+
metadata:
22+
name: ${CLUSTER_NAME}-md-0
23+
spec:
24+
template:
25+
spec:
26+
offering:
27+
name: ${CLOUDSTACK_WORKER_MACHINE_OFFERING}
28+
template:
29+
name: ${CLOUDSTACK_TEMPLATE_NAME}
30+
sshKey: ${CLOUDSTACK_SSH_KEY_NAME}
31+
affinity: pro
32+
networks:
33+
- name: ${CLOUDSTACK_NETWORK_NAME}
34+
- name: ${CLOUDSTACK_NEW_NETWORK_NAME}

test/e2e/multiple_networks.go

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package e2e
18+
19+
import (
20+
"context"
21+
"fmt"
22+
"os"
23+
"path/filepath"
24+
"strings"
25+
26+
"github.com/apache/cloudstack-go/v2/cloudstack"
27+
"github.com/blang/semver"
28+
. "github.com/onsi/ginkgo/v2"
29+
. "github.com/onsi/gomega"
30+
corev1 "k8s.io/api/core/v1"
31+
"k8s.io/utils/pointer"
32+
33+
"sigs.k8s.io/cluster-api/test/framework/clusterctl"
34+
"sigs.k8s.io/cluster-api/util"
35+
)
36+
37+
// MultipleNetworksSpec implements a spec that creates a cluster with nodes having multiple NICs.
38+
func MultipleNetworksSpec(ctx context.Context, inputGetter func() CommonSpecInput) {
39+
var (
40+
specName = "multiple-networks"
41+
input CommonSpecInput
42+
namespace *corev1.Namespace
43+
cancelWatches context.CancelFunc
44+
clusterResources *clusterctl.ApplyClusterTemplateAndWaitResult
45+
)
46+
47+
BeforeEach(func() {
48+
Expect(ctx).NotTo(BeNil(), "ctx is required for %s spec", specName)
49+
input = inputGetter()
50+
51+
csClient := CreateCloudStackClient(ctx, input.BootstrapClusterProxy.GetKubeconfigPath())
52+
version, err := GetACSVersion(csClient)
53+
54+
if err != nil || version == "" {
55+
Skip("Failed to get CloudStack's version")
56+
}
57+
58+
v, err := semver.ParseTolerant(strings.Join(strings.Split(version, ".")[0:3], "."))
59+
60+
if err != nil {
61+
Skip("Failed to parse CloudStack version " + version)
62+
}
63+
64+
expectedRange, _ := semver.ParseRange(">=4.19.0")
65+
66+
if !expectedRange(v) {
67+
Skip("Cloudstack version " + version + " is less than 4.19.")
68+
}
69+
70+
Expect(input.E2EConfig).ToNot(BeNil(), "Invalid argument. input.E2EConfig can't be nil when calling %s spec", specName)
71+
Expect(input.ClusterctlConfigPath).To(BeAnExistingFile(), "Invalid argument. input.ClusterctlConfigPath must be an existing file when calling %s spec", specName)
72+
Expect(input.BootstrapClusterProxy).ToNot(BeNil(), "Invalid argument. input.BootstrapClusterProxy can't be nil when calling %s spec", specName)
73+
Expect(os.MkdirAll(input.ArtifactFolder, 0750)).To(Succeed(), "Invalid argument. input.ArtifactFolder can't be created for %s spec", specName)
74+
75+
Expect(input.E2EConfig.Variables).To(HaveKey(KubernetesVersion))
76+
77+
// Setup a Namespace where to host objects for this spec and create a watcher for the namespace events.
78+
namespace, cancelWatches = setupSpecNamespace(ctx, specName, input.BootstrapClusterProxy, input.ArtifactFolder)
79+
clusterResources = new(clusterctl.ApplyClusterTemplateAndWaitResult)
80+
})
81+
82+
It("Should create a workload cluster", func() {
83+
By("Creating a workload cluster")
84+
85+
clusterName := fmt.Sprintf("%s-%s", specName, util.RandomString(6))
86+
87+
clusterctl.ApplyClusterTemplateAndWait(ctx, clusterctl.ApplyClusterTemplateAndWaitInput{
88+
ClusterProxy: input.BootstrapClusterProxy,
89+
CNIManifestPath: input.E2EConfig.GetVariable(CNIPath),
90+
ConfigCluster: clusterctl.ConfigClusterInput{
91+
LogFolder: filepath.Join(input.ArtifactFolder, "clusters", input.BootstrapClusterProxy.GetName()),
92+
ClusterctlConfigPath: input.ClusterctlConfigPath,
93+
KubeconfigPath: input.BootstrapClusterProxy.GetKubeconfigPath(),
94+
InfrastructureProvider: clusterctl.DefaultInfrastructureProvider,
95+
Flavor: specName,
96+
Namespace: namespace.Name,
97+
ClusterName: clusterName,
98+
KubernetesVersion: input.E2EConfig.GetVariable(KubernetesVersion),
99+
ControlPlaneMachineCount: pointer.Int64Ptr(1),
100+
WorkerMachineCount: pointer.Int64Ptr(1),
101+
},
102+
WaitForClusterIntervals: input.E2EConfig.GetIntervals(specName, "wait-cluster"),
103+
WaitForControlPlaneIntervals: input.E2EConfig.GetIntervals(specName, "wait-control-plane"),
104+
WaitForMachineDeployments: input.E2EConfig.GetIntervals(specName, "wait-worker-nodes"),
105+
}, clusterResources)
106+
107+
By("checking cks resource is created on ACS")
108+
// Get details from ACS
109+
csClient := CreateCloudStackClient(ctx, input.BootstrapClusterProxy.GetKubeconfigPath())
110+
lkcp := csClient.Kubernetes.NewListKubernetesClustersParams()
111+
lkcp.SetListall(true)
112+
113+
clusters, err := csClient.Kubernetes.ListKubernetesClusters(lkcp)
114+
115+
if err != nil {
116+
Fail("Failed to get Kubernetes clusters from ACS")
117+
}
118+
119+
var cluster *cloudstack.KubernetesCluster
120+
121+
for _, d := range clusters.KubernetesClusters {
122+
if strings.HasPrefix(d.Name, fmt.Sprintf("%s - %s", clusterName, clusterName)) {
123+
cluster = d
124+
}
125+
}
126+
127+
Expect(cluster).ShouldNot(BeNil(), "Couldn't find the external managed kubernetes in ACS")
128+
Expect(len(cluster.Virtualmachines)).Should(Equal(2), "Expected 2 VMs in the cluster, found %d", len(cluster.Virtualmachines))
129+
130+
By("Verifying that each VM has two NICs")
131+
CheckIfNodesHaveTwoNICs(cluster)
132+
133+
By("PASSED!")
134+
})
135+
136+
AfterEach(func() {
137+
// Dumps all the resources in the spec namespace, then cleanups the cluster object and the spec namespace itself.
138+
dumpSpecResourcesAndCleanup(ctx, specName, input.BootstrapClusterProxy, input.ArtifactFolder, namespace, cancelWatches, clusterResources.Cluster, input.E2EConfig.GetIntervals, input.SkipCleanup)
139+
})
140+
}
141+
142+
func CheckIfNodesHaveTwoNICs(cluster *cloudstack.KubernetesCluster) {
143+
for _, vm := range cluster.Virtualmachines {
144+
if len(vm.Nic) < 2 {
145+
Fail(fmt.Sprintf("VM %q has fewer than 2 NICs. Found: %d", vm.Name, len(vm.Nic)))
146+
}
147+
By(fmt.Sprintf("VM %q has %d NICs", vm.Name, len(vm.Nic)))
148+
}
149+
}

test/e2e/multiple_networks_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//go:build e2e
2+
// +build e2e
3+
4+
/*
5+
Copyright 2021 The Kubernetes Authors.
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
*/
19+
20+
package e2e
21+
22+
import (
23+
"context"
24+
25+
. "github.com/onsi/ginkgo/v2"
26+
)
27+
28+
var _ = Describe("Test with multiple networks for nodes", func() {
29+
30+
MultipleNetworksSpec(context.TODO(), func() CommonSpecInput {
31+
return CommonSpecInput{
32+
E2EConfig: e2eConfig,
33+
ClusterctlConfigPath: clusterctlConfigPath,
34+
BootstrapClusterProxy: bootstrapClusterProxy,
35+
ArtifactFolder: artifactFolder,
36+
SkipCleanup: skipCleanup,
37+
}
38+
})
39+
40+
})

0 commit comments

Comments
 (0)