Skip to content

Commit

Permalink
Implement E2E test for vcsim in govmomi mode
Browse files Browse the repository at this point in the history
  • Loading branch information
fabriziopandini committed Mar 4, 2024
1 parent 180146b commit 2a8ecbe
Show file tree
Hide file tree
Showing 26 changed files with 935 additions and 212 deletions.
2 changes: 0 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ GINKGO_TIMEOUT ?= 3h
E2E_CONF_FILE ?= $(abspath test/e2e/config/vsphere.yaml)
E2E_CONF_OVERRIDE_FILE ?= $(abspath test/e2e/config/config-overrides.yaml)
E2E_CAPV_MODE ?= govmomi
E2E_TARGET_TYPE ?= vcenter
E2E_IPAM_KUBECONFIG ?=
INTEGRATION_CONF_FILE ?= $(abspath test/integration/integration-dev.yaml)
E2E_TEMPLATE_DIR := $(abspath test/e2e/data/infrastructure-vsphere/)
Expand Down Expand Up @@ -585,7 +584,6 @@ e2e: $(GINKGO) $(KUSTOMIZE) $(KIND) $(GOVC) ## Run e2e tests
--e2e.skip-resource-cleanup=$(SKIP_RESOURCE_CLEANUP) \
--e2e.use-existing-cluster="$(USE_EXISTING_CLUSTER)" \
--e2e.capv-mode="$(E2E_CAPV_MODE)" \
--e2e.target-type="$(E2E_TARGET_TYPE)" \
--e2e.ipam-kubeconfig="$(E2E_IPAM_KUBECONFIG)"

## --------------------------------------
Expand Down
3 changes: 1 addition & 2 deletions hack/e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ on_exit() {
do
echo "Cleaning up VSPHERE_PASSWORD from file ${file}"
sed -i "s/${VSPHERE_PASSWORD}/REDACTED/g" "${file}"
done
done || true
# Move all artifacts to the original artifacts location.
mv "${ARTIFACTS}"/* "${ORIGINAL_ARTIFACTS}/"
fi
Expand All @@ -76,7 +76,6 @@ export VSPHERE_SSH_PRIVATE_KEY="/root/ssh/.private-key/private-key"
export E2E_CONF_FILE="${REPO_ROOT}/test/e2e/config/vsphere.yaml"
export E2E_CONF_OVERRIDE_FILE=""
export E2E_CAPV_MODE="${CAPV_MODE:-govmomi}"
export E2E_TARGET_TYPE="${TARGET_TYPE:-vmc}"
export ARTIFACTS="${ARTIFACTS:-${REPO_ROOT}/_artifacts}"
export DOCKER_IMAGE_TAR="/tmp/images/image.tar"
export GC_KIND="false"
Expand Down
14 changes: 11 additions & 3 deletions internal/test/helpers/vcsim/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,20 @@ const (

// DefaultStoragePolicyName is the name of the default storage policy that exists when starting a new vcsim instance.
DefaultStoragePolicyName = "vSAN Default Storage Policy"
)

// DefaultVMTemplateName is the name of the default VM template the vcsim controller adds to new vcsim instance.
var (
// DefaultVMTemplates is the name of the default VM templates the vcsim controller adds to new vcsim instance.
// Note: There are no default templates when starting a new vcsim instance.
// Note: For the sake of testing with vcsim the template doesn't really matter (nor the version of K8s hosted on it)
// so the vcsim controller creates only a VM template with a well-known name.
DefaultVMTemplateName = "ubuntu-2204-kube-vX"
// but we must provide at least the templates that are expected by test cluster classes.
DefaultVMTemplates = []string{
// NOTE: this list must be kept in sync with templates we are using in cluster classes.
// IMPORTANT: keep this list sorted from oldest to newest.
// TODO: consider if we want to make this extensible via the vCenterSimulator CR.
"ubuntu-2204-kube-v1.28.0",
"ubuntu-2204-kube-v1.29.0",
}
)

// DatacenterName provide a function to compute vcsim datacenter names given its index.
Expand Down
13 changes: 13 additions & 0 deletions test/e2e/config/vsphere.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ images:
loadBehavior: tryLoad
- name: gcr.io/k8s-staging-capi-vsphere/cluster-api-vsphere-controller-{ARCH}:dev
loadBehavior: mustLoad
- name: gcr.io/k8s-staging-capi-vsphere/cluster-api-vcsim-controller-{ARCH}:dev
loadBehavior: mustLoad
- name: quay.io/jetstack/cert-manager-cainjector:v1.12.2
loadBehavior: tryLoad
- name: quay.io/jetstack/cert-manager-webhook:v1.12.2
Expand Down Expand Up @@ -160,6 +162,17 @@ providers:
- sourcePath: "../../../test/e2e/data/infrastructure-vsphere/v1.8/clusterclass-quick-start.yaml"
- sourcePath: "../data/shared/v1.8/v1beta1_provider/metadata.yaml"

- name: vcsim
type: InfrastructureProvider
versions:
- name: v1.10.99
# Use manifest from source files
value: ../../../../cluster-api-provider-vsphere/test/infrastructure/vcsim/config/default
contract: v1beta1
files:
# Add cluster templates
- sourcePath: "../data/shared/main/v1beta1_provider/metadata.yaml"

variables:
# Ensure all Kubernetes versions used here are covered in patch-vsphere-template.yaml
KUBERNETES_VERSION: "v1.29.0"
Expand Down
60 changes: 52 additions & 8 deletions test/e2e/e2e_setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ import (

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"k8s.io/apimachinery/pkg/types"
"k8s.io/utils/ptr"
. "sigs.k8s.io/cluster-api/test/framework/ginkgoextensions"
"sigs.k8s.io/yaml"

"sigs.k8s.io/cluster-api-provider-vsphere/test/framework/ip"
vsphereip "sigs.k8s.io/cluster-api-provider-vsphere/test/framework/ip"
vspherevcsim "sigs.k8s.io/cluster-api-provider-vsphere/test/framework/vcsim"
vcsimv1 "sigs.k8s.io/cluster-api-provider-vsphere/test/infrastructure/vcsim/api/v1alpha1"
)

type setupOptions struct {
Expand Down Expand Up @@ -63,14 +65,49 @@ func Setup(specName string, f func(testSpecificClusterctlConfigPathGetter func()

var (
testSpecificClusterctlConfigPath string
testSpecificIPAddressClaims []types.NamespacedName
testSpecificIPAddressClaims vsphereip.AddressClaims
testSpecificVariables map[string]string
)
BeforeEach(func() {
Byf("Setting up test env for %s", specName)

Byf("Getting IP for %s", strings.Join(append([]string{"CONTROL_PLANE_ENDPOINT_IP"}, options.additionalIPVariableNames...), ","))
testSpecificIPAddressClaims, testSpecificVariables = ipAddressManager.ClaimIPs(ctx, ip.WithGateway(options.gatewayIPVariableName), ip.WithIP(options.additionalIPVariableNames...))
switch testTarget {
case VCenterTestTarget:
Byf("Getting IP for %s", strings.Join(append([]string{"CONTROL_PLANE_ENDPOINT_IP"}, options.additionalIPVariableNames...), ","))
// get IPs from the in cluster address manager
testSpecificIPAddressClaims, testSpecificVariables = inClusterAddressManager.ClaimIPs(ctx, vsphereip.WithGateway(options.gatewayIPVariableName), vsphereip.WithIP(options.additionalIPVariableNames...))
case VCSimTestTarget:
Byf("Getting IP for %s", strings.Join(append([]string{vsphereip.ControlPlaneEndpointIPVariable}, options.additionalIPVariableNames...), ","))

// get IPs from the vcsim controller
testSpecificIPAddressClaims, testSpecificVariables = vcsimAddressManager.ClaimIPs(ctx, vsphereip.WithIP(options.additionalIPVariableNames...))

Byf("Creating a vcsim server for %s", specName)

// variables for govmomi mode derived from the vCenterSimulator
vCenterSimulator, err := vspherevcsim.Get(ctx, bootstrapClusterProxy.GetClient())
Expect(err).ToNot(HaveOccurred(), "Failed to create VCenterSimulator")

for k, v := range vCenterSimulator.GovmomiVariables() {
// unset corresponding env variable (that in CI contains VMC data), so we are sure we use the value for vcsim
if strings.HasPrefix(k, "VSPHERE_") {
Expect(os.Unsetenv(k)).To(Succeed())
}

testSpecificVariables[k] = v
}

// variables for govmomi mode derived from envVar.Spec.Cluster
// NOTE: picking Datacenter, Cluster, Datastore that exists by default in vcsim
clusterEnvVarSpec := vcsimv1.ClusterEnvVarSpec{
Datacenter: ptr.To[int32](0), // DC0
Cluster: ptr.To[int32](0), // C0
Datastore: ptr.To[int32](0), // LocalDS_0
}

for k, v := range clusterEnvVarSpec.GovmomiVariables() {
testSpecificVariables[k] = v
}
}

// Create a new clusterctl config file based on the passed file and add the new variables for the IPs.
testSpecificClusterctlConfigPath = fmt.Sprintf("%s-%s.yaml", strings.TrimSuffix(clusterctlConfigPath, ".yaml"), specName)
Expand All @@ -83,13 +120,20 @@ func Setup(specName string, f func(testSpecificClusterctlConfigPathGetter func()
})
defer AfterEach(func() {
Byf("Cleaning up test env for %s", specName)
Expect(ipAddressManager.Cleanup(ctx, testSpecificIPAddressClaims)).To(Succeed())
switch testTarget {
case VCenterTestTarget:
// cleanup IPs/controlPlaneEndpoint created by the in cluster ipam provider.
Expect(inClusterAddressManager.Cleanup(ctx, testSpecificIPAddressClaims)).To(Succeed())
case VCSimTestTarget:
// cleanup IPs/controlPlaneEndpoint created by the vcsim controller manager.
Expect(vcsimAddressManager.Cleanup(ctx, testSpecificIPAddressClaims)).To(Succeed())
}
})

// NOTE: it is required to use a function to pass the testSpecificClusterctlConfigPath value into the test func,
// so when the test is executed the func could get the value set into the BeforeEach block above.
// If instead we pass the value directly, the test func will get the value at the moment of the initial parsing of
// the Ginkgo node tree, which is an empty string (the BeforeEach block above is not run during initial parsing).
// the Ginkgo node tree, which is an empty string (the BeforeEach block above are not run during initial parsing).
f(func() string { return testSpecificClusterctlConfigPath })
}

Expand Down
Loading

0 comments on commit 2a8ecbe

Please sign in to comment.