Skip to content

Commit fd64e36

Browse files
authored
Merge pull request #1822 from shiftstack/issue_1821
🐛 e2e: bastion tests
2 parents 5cfeccc + 4ff2cf8 commit fd64e36

File tree

5 files changed

+104
-0
lines changed

5 files changed

+104
-0
lines changed

hack/ci/cloud-init/controller.yaml.tpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@
177177
openstack flavor create --ram 4192 --disk 20 --ephemeral 5 --vcpus 2 --public --id 2 m1.small --property hw_rng:allowed='True'
178178
openstack flavor delete m1.medium
179179
openstack flavor create --ram 6144 --disk 20 --ephemeral 5 --vcpus 2 --public --id 3 m1.medium --property hw_rng:allowed='True'
180+
# Create an additional flavor for the e2e tests that will be used by the e2e bastion tests
181+
openstack flavor create --ram 512 --disk 1 --ephemeral 1 --vcpus 1 --public --id 10 m1.tiny.alt --property hw_rng:allowed='True'
180182

181183
# Adjust the CPU quota
182184
openstack quota set --cores 32 demo

test/e2e/data/e2e_conf.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ variables:
190190
EXP_CLUSTER_RESOURCE_SET: "true"
191191
OPENSTACK_BASTION_IMAGE_NAME: "cirros-0.6.1-x86_64-disk"
192192
OPENSTACK_BASTION_MACHINE_FLAVOR: "m1.tiny"
193+
OPENSTACK_BASTION_MACHINE_FLAVOR_ALT: "m1.tiny.alt"
193194
OPENSTACK_CLOUD: "capo-e2e"
194195
OPENSTACK_CLOUD_ADMIN: "capo-e2e-admin"
195196
OPENSTACK_CLOUD_CACERT_B64: "Cg=="
@@ -220,6 +221,7 @@ intervals:
220221
conformance/wait-control-plane: ["30m", "10s"]
221222
conformance/wait-worker-nodes: ["30m", "10s"]
222223
default/wait-controllers: ["3m", "10s"]
224+
default/wait-bastion: ["5m", "10s"]
223225
default/wait-cluster: ["20m", "10s"]
224226
default/wait-control-plane: ["30m", "10s"]
225227
default/wait-worker-nodes: ["30m", "10s"]

test/e2e/shared/defaults.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const (
3535
KubernetesVersion = "KUBERNETES_VERSION"
3636
CCMPath = "CCM"
3737
CCMResources = "CCM_RESOURCES"
38+
OpenStackBastionFlavorAlt = "OPENSTACK_BASTION_MACHINE_FLAVOR_ALT"
3839
OpenStackCloudYAMLFile = "OPENSTACK_CLOUD_YAML_FILE"
3940
OpenStackCloud = "OPENSTACK_CLOUD"
4041
OpenStackCloudAdmin = "OPENSTACK_CLOUD_ADMIN"

test/e2e/shared/openstack.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636
"github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes"
3737
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/availabilityzones"
3838
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs"
39+
"github.com/gophercloud/gophercloud/openstack/compute/v2/flavors"
3940
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
4041
"github.com/gophercloud/gophercloud/openstack/imageservice/v2/images"
4142
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers"
@@ -46,6 +47,7 @@ import (
4647
"github.com/gophercloud/gophercloud/openstack/networking/v2/ports"
4748
"github.com/gophercloud/gophercloud/openstack/networking/v2/subnets"
4849
"github.com/gophercloud/utils/openstack/clientconfig"
50+
uflavors "github.com/gophercloud/utils/openstack/compute/v2/flavors"
4951
. "github.com/onsi/ginkgo/v2"
5052
. "github.com/onsi/gomega"
5153
"gopkg.in/ini.v1"
@@ -847,3 +849,19 @@ func GetOpenStackVolume(e2eCtx *E2EContext, name string) (*volumes.Volume, error
847849

848850
return volume, nil
849851
}
852+
853+
func GetFlavorFromName(e2eCtx *E2EContext, name string) (*flavors.Flavor, error) {
854+
providerClient, clientOpts, _, err := GetTenantProviderClient(e2eCtx)
855+
if err != nil {
856+
_, _ = fmt.Fprintf(GinkgoWriter, "error creating provider client: %s\n", err)
857+
return nil, err
858+
}
859+
860+
computeClient, err := openstack.NewComputeV2(providerClient, gophercloud.EndpointOpts{Region: clientOpts.RegionName})
861+
Expect(err).NotTo(HaveOccurred())
862+
863+
flavorID, err := uflavors.IDFromName(computeClient, name)
864+
Expect(err).NotTo(HaveOccurred())
865+
866+
return flavors.Get(computeClient, flavorID).Extract()
867+
}

test/e2e/suites/e2e/e2e_test.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,87 @@ var _ = Describe("e2e tests [PR-Blocking]", func() {
162162
// We expect 4 security group rules that allow Calico traffic on the control plane
163163
// from both the control plane and worker machines and vice versa, that makes 8 rules.
164164
Expect(calicoSGRules).To(Equal(8))
165+
166+
shared.Logf("Check the bastion")
167+
openStackCluster, err = shared.ClusterForSpec(ctx, e2eCtx, namespace)
168+
Expect(err).NotTo(HaveOccurred())
169+
bastionSpec := openStackCluster.Spec.Bastion
170+
Expect(openStackCluster.Status.Bastion).NotTo(BeNil(), "OpenStackCluster.Status.Bastion has not been populated")
171+
bastionServerName := openStackCluster.Status.Bastion.Name
172+
bastionServer, err := shared.DumpOpenStackServers(e2eCtx, servers.ListOpts{Name: bastionServerName})
173+
Expect(err).NotTo(HaveOccurred())
174+
Expect(bastionServer).To(HaveLen(1), "Did not find the bastion in OpenStack")
175+
176+
shared.Logf("Disable the bastion")
177+
openStackCluster, err = shared.ClusterForSpec(ctx, e2eCtx, namespace)
178+
Expect(err).NotTo(HaveOccurred())
179+
openStackClusterDisabledBastion := openStackCluster.DeepCopy()
180+
openStackClusterDisabledBastion.Spec.Bastion.Enabled = false
181+
Expect(e2eCtx.Environment.BootstrapClusterProxy.GetClient().Update(ctx, openStackClusterDisabledBastion)).To(Succeed())
182+
Eventually(
183+
func() (bool, error) {
184+
bastionServer, err := shared.DumpOpenStackServers(e2eCtx, servers.ListOpts{Name: bastionServerName})
185+
Expect(err).NotTo(HaveOccurred())
186+
if len(bastionServer) == 0 {
187+
return true, nil
188+
}
189+
return false, errors.New("Bastion was not deleted in OpenStack")
190+
}, e2eCtx.E2EConfig.GetIntervals(specName, "wait-bastion")...,
191+
).Should(BeTrue())
192+
Eventually(
193+
func() (bool, error) {
194+
openStackCluster, err = shared.ClusterForSpec(ctx, e2eCtx, namespace)
195+
Expect(err).NotTo(HaveOccurred())
196+
if openStackCluster.Status.Bastion == nil {
197+
return true, nil
198+
}
199+
return false, errors.New("Bastion was not removed in OpenStackCluster.Status")
200+
}, e2eCtx.E2EConfig.GetIntervals(specName, "wait-bastion")...,
201+
).Should(BeTrue())
202+
203+
shared.Logf("Delete the bastion")
204+
openStackCluster, err = shared.ClusterForSpec(ctx, e2eCtx, namespace)
205+
Expect(err).NotTo(HaveOccurred())
206+
openStackClusterWithoutBastion := openStackCluster.DeepCopy()
207+
openStackClusterWithoutBastion.Spec.Bastion = nil
208+
Expect(e2eCtx.Environment.BootstrapClusterProxy.GetClient().Update(ctx, openStackClusterWithoutBastion)).To(Succeed())
209+
openStackCluster, err = shared.ClusterForSpec(ctx, e2eCtx, namespace)
210+
Expect(err).NotTo(HaveOccurred())
211+
Eventually(
212+
func() (bool, error) {
213+
openStackCluster, err = shared.ClusterForSpec(ctx, e2eCtx, namespace)
214+
Expect(err).NotTo(HaveOccurred())
215+
if openStackCluster.Spec.Bastion == nil {
216+
return true, nil
217+
}
218+
return false, errors.New("Bastion was not removed in OpenStackCluster.Spec")
219+
}, e2eCtx.E2EConfig.GetIntervals(specName, "wait-bastion")...,
220+
).Should(BeTrue())
221+
222+
shared.Logf("Create the bastion with a new flavor")
223+
bastionNewFlavorName := e2eCtx.E2EConfig.GetVariable(shared.OpenStackBastionFlavorAlt)
224+
bastionNewFlavor, err := shared.GetFlavorFromName(e2eCtx, bastionNewFlavorName)
225+
Expect(err).NotTo(HaveOccurred())
226+
openStackCluster, err = shared.ClusterForSpec(ctx, e2eCtx, namespace)
227+
Expect(err).NotTo(HaveOccurred())
228+
openStackClusterWithNewBastionFlavor := openStackCluster.DeepCopy()
229+
openStackClusterWithNewBastionFlavor.Spec.Bastion = bastionSpec
230+
openStackClusterWithNewBastionFlavor.Spec.Bastion.Instance.Flavor = bastionNewFlavorName
231+
Expect(e2eCtx.Environment.BootstrapClusterProxy.GetClient().Update(ctx, openStackClusterWithNewBastionFlavor)).To(Succeed())
232+
Eventually(
233+
func() (bool, error) {
234+
bastionServer, err := shared.DumpOpenStackServers(e2eCtx, servers.ListOpts{Name: bastionServerName, Flavor: bastionNewFlavor.ID})
235+
Expect(err).NotTo(HaveOccurred())
236+
if len(bastionServer) == 1 {
237+
return true, nil
238+
}
239+
return false, errors.New("Bastion with new flavor was not created in OpenStack")
240+
}, e2eCtx.E2EConfig.GetIntervals(specName, "wait-bastion")...,
241+
).Should(BeTrue())
242+
openStackCluster, err = shared.ClusterForSpec(ctx, e2eCtx, namespace)
243+
Expect(err).NotTo(HaveOccurred())
244+
Expect(openStackCluster.Spec.Bastion).To(Equal(openStackClusterWithNewBastionFlavor.Spec.Bastion))
245+
Expect(openStackCluster.Status.Bastion).NotTo(BeNil(), "OpenStackCluster.Status.Bastion with new flavor has not been populated")
165246
})
166247
})
167248

0 commit comments

Comments
 (0)