diff --git a/Makefile b/Makefile index 6ccff05abf..83157745c7 100644 --- a/Makefile +++ b/Makefile @@ -188,6 +188,7 @@ e2e-templates: $(addprefix $(E2E_NO_ARTIFACT_TEMPLATES_DIR)/, \ cluster-template-multi-network.yaml \ cluster-template-without-lb.yaml \ cluster-template.yaml \ + cluster-template-topology.yaml \ cluster-template-flatcar.yaml \ cluster-template-k8s-upgrade.yaml \ cluster-template-flatcar-sysext.yaml \ diff --git a/templates/cluster-template-development.yaml b/templates/cluster-template-topology.yaml similarity index 86% rename from templates/cluster-template-development.yaml rename to templates/cluster-template-topology.yaml index df62668d33..d83ca03eae 100644 --- a/templates/cluster-template-development.yaml +++ b/templates/cluster-template-topology.yaml @@ -1,25 +1,20 @@ -apiVersion: cluster.x-k8s.io/v1beta1 +apiVersion: cluster.x-k8s.io/v1beta2 kind: Cluster metadata: name: ${CLUSTER_NAME} spec: topology: - class: dev-test - version: ${KUBERNETES_VERSION} + classRef: + name: dev-test controlPlane: replicas: ${CONTROL_PLANE_MACHINE_COUNT} - workers: - machineDeployments: - - class: default-worker - name: md-0 - replicas: ${WORKER_MACHINE_COUNT} variables: - name: identityRef value: - name: ${CLOUD_CONFIG_SECRET:=dev-test-cloud-config} cloudName: ${OPENSTACK_CLOUD:=capo-e2e} - - name: imageName - value: ${IMAGE_NAME:=flatcar_production} + name: ${CLOUD_CONFIG_SECRET:=dev-test-cloud-config} + - name: imageRef + value: ${IMAGE_REF:=node-image} - name: addImageVersion value: ${ADD_IMAGE_VERSION:=false} - name: injectIgnitionSysext @@ -32,6 +27,12 @@ spec: spec: flavor: ${OPENSTACK_BASTION_FLAVOR:=m1.small} image: - filter: + imageRef: name: ${OPENSTACK_BASTION_IMAGE_NAME:=ubuntu-24.04} sshKeyName: ${OPENSTACK_SSH_KEY_NAME:=""} + version: ${KUBERNETES_VERSION} + workers: + machineDeployments: + - class: default-worker + name: md-0 + replicas: ${WORKER_MACHINE_COUNT} diff --git a/templates/clusterclass-dev-test.yaml b/templates/clusterclass-dev-test.yaml index eff4f62ae3..220d4b0661 100644 --- a/templates/clusterclass-dev-test.yaml +++ b/templates/clusterclass-dev-test.yaml @@ -5,7 +5,7 @@ metadata: spec: controlPlane: templateRef: - apiVersion: controlplane.cluster.x-k8s.io/v1beta1 + apiVersion: controlplane.cluster.x-k8s.io/v1beta2 kind: KubeadmControlPlaneTemplate name: dev-test-control-plane machineInfrastructure: @@ -23,7 +23,7 @@ spec: - class: default-worker bootstrap: templateRef: - apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 + apiVersion: bootstrap.cluster.x-k8s.io/v1beta2 kind: KubeadmConfigTemplate name: dev-test-default-worker-bootstraptemplate infrastructure: @@ -53,16 +53,22 @@ spec: type: string description: | The base name of the OpenStack image that is used for creating the servers. - This will be combined with the k8s version to create the full name. E.g. imageName-v1.31.2. - default: "ubuntu-2404-kube" - name: addImageVersion required: false schema: openAPIV3Schema: type: boolean description: | - Add a suffix with the Kubernetes version to the imageName. E.g. imageName-v1.32.2. + Add a suffix with the Kubernetes version to the imageName or imageRef. E.g. imageName-v1.32.2. default: true + - name: imageRef + required: false + schema: + openAPIV3Schema: + type: string + description: | + The name of the ORC Image object that is used for creating the servers. + default: "node-image" - name: injectIgnitionSysext required: false schema: @@ -109,6 +115,12 @@ spec: name: type: string description: "Name of the image to use for bastion" + imageRef: + type: object + properties: + name: + type: string + description: "Name of the ORC Image to use for bastion" sshKeyName: type: string description: "SSH key pair name for bastion access" @@ -120,8 +132,9 @@ spec: type: string description: "Availability zone for the bastion host" patches: - - name: image - description: "Sets the OpenStack image that is used for creating the servers." + - name: imageName + description: "Sets the OpenStack image that is used for creating the servers using a name filter." + enabledIf: "{{ if .imageName }}true{{ end }}" definitions: - selector: apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 @@ -129,11 +142,13 @@ spec: matchResources: controlPlane: true jsonPatches: + - op: remove + path: /spec/template/spec/image/imageRef - op: add - path: /spec/template/spec/image/filter/name + path: /spec/template/spec/image/filter valueFrom: template: | - {{ .imageName }}{{ if .addImageVersion }}-{{ .builtin.controlPlane.version }}{{ end }} + name: {{ .imageName }}{{ if .addImageVersion }}-{{ .builtin.controlPlane.version }}{{ end }} - selector: apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: OpenStackMachineTemplate @@ -142,11 +157,41 @@ spec: names: - default-worker jsonPatches: + - op: remove + path: /spec/template/spec/image/imageRef - op: add - path: /spec/template/spec/image/filter/name + path: /spec/template/spec/image/filter valueFrom: template: | - {{ .imageName }}{{ if .addImageVersion }}-{{ .builtin.machineDeployment.version }}{{ end }} + name: {{ .imageName }}{{ if .addImageVersion }}-{{ .builtin.machineDeployment.version }}{{ end }} + - name: imageRef + description: "Sets the OpenStack image that is used for creating the servers using an ORC Image reference." + enabledIf: "{{ if .imageRef }}true{{ end }}" + definitions: + - selector: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: OpenStackMachineTemplate + matchResources: + controlPlane: true + jsonPatches: + - op: replace + path: /spec/template/spec/image/imageRef/name + valueFrom: + template: | + {{ .imageRef }}{{ if .addImageVersion }}-{{ .builtin.controlPlane.version }}{{ end }} + - selector: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: OpenStackMachineTemplate + matchResources: + machineDeploymentClass: + names: + - default-worker + jsonPatches: + - op: replace + path: /spec/template/spec/image/imageRef/name + valueFrom: + template: | + {{ .imageRef }}{{ if .addImageVersion }}-{{ .builtin.controlPlane.version }}{{ end }} - name: identityRef description: "Sets the OpenStack identity reference." definitions: @@ -193,7 +238,7 @@ spec: enabledIf: "{{ .injectIgnitionSysext }}" definitions: - selector: - apiVersion: controlplane.cluster.x-k8s.io/v1beta1 + apiVersion: controlplane.cluster.x-k8s.io/v1beta2 kind: KubeadmControlPlaneTemplate matchResources: controlPlane: true @@ -211,12 +256,18 @@ spec: nodeRegistration: name: $${COREOS_OPENSTACK_HOSTNAME} kubeletExtraArgs: - provider-id: openstack:///$${COREOS_OPENSTACK_INSTANCE_UUID} + - name: cloud-provider + value: external + - name: provider-id + value: openstack:///$${COREOS_OPENSTACK_INSTANCE_UUID} joinConfiguration: nodeRegistration: name: $${COREOS_OPENSTACK_HOSTNAME} kubeletExtraArgs: - provider-id: openstack:///$${COREOS_OPENSTACK_INSTANCE_UUID} + - name: cloud-provider + value: external + - name: provider-id + value: openstack:///$${COREOS_OPENSTACK_INSTANCE_UUID} format: ignition ignition: containerLinuxConfig: @@ -233,16 +284,16 @@ spec: mode: 0644 contents: remote: - url: https://github.com/flatcar/sysext-bakery/releases/download/latest/kubernetes-{{ $minor }}.conf + url: https://extensions.flatcar.org/extensions/kubernetes/kubernetes-{{ $minor }}.conf - path: /etc/sysupdate.d/noop.conf mode: 0644 contents: remote: - url: https://github.com/flatcar/sysext-bakery/releases/download/latest/noop.conf + url: https://extensions.flatcar.org/extensions/noop.conf - path: /opt/extensions/kubernetes/kubernetes-{{ .builtin.controlPlane.version }}-x86-64.raw contents: remote: - url: https://github.com/flatcar/sysext-bakery/releases/download/latest/kubernetes-{{ .builtin.controlPlane.version }}-x86-64.raw + url: https://extensions.flatcar.org/extensions/kubernetes-{{ .builtin.controlPlane.version }}-x86-64.raw systemd: units: - name: systemd-sysupdate.service @@ -277,7 +328,7 @@ spec: [Service] EnvironmentFile=/run/metadata/flatcar - selector: - apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 + apiVersion: bootstrap.cluster.x-k8s.io/v1beta2 kind: KubeadmConfigTemplate matchResources: machineDeploymentClass: @@ -297,7 +348,10 @@ spec: nodeRegistration: name: $${COREOS_OPENSTACK_HOSTNAME} kubeletExtraArgs: - provider-id: openstack:///$${COREOS_OPENSTACK_INSTANCE_UUID} + - name: cloud-provider + value: external + - name: provider-id + value: openstack:///$${COREOS_OPENSTACK_INSTANCE_UUID} format: ignition ignition: containerLinuxConfig: @@ -314,16 +368,16 @@ spec: mode: 0644 contents: remote: - url: https://github.com/flatcar/sysext-bakery/releases/download/latest/kubernetes-{{ $minor }}.conf + url: https://extensions.flatcar.org/extensions/kubernetes/kubernetes-{{ $minor }}.conf - path: /etc/sysupdate.d/noop.conf mode: 0644 contents: remote: - url: https://github.com/flatcar/sysext-bakery/releases/download/latest/noop.conf + url: https://extensions.flatcar.org/extensions/noop.conf - path: /opt/extensions/kubernetes/kubernetes-{{ .builtin.machineDeployment.version }}-x86-64.raw contents: remote: - url: https://github.com/flatcar/sysext-bakery/releases/download/latest/kubernetes-{{ .builtin.machineDeployment.version }}-x86-64.raw + url: https://extensions.flatcar.org/extensions/kubernetes-{{ .builtin.machineDeployment.version }}-x86-64.raw systemd: units: - name: systemd-sysupdate.service @@ -365,7 +419,6 @@ metadata: spec: template: spec: - files: [] joinConfiguration: nodeRegistration: kubeletExtraArgs: @@ -382,6 +435,11 @@ metadata: spec: template: spec: + rollout: + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 kubeadmConfigSpec: clusterConfiguration: controllerManager: @@ -454,8 +512,8 @@ spec: spec: flavor: ${OPENSTACK_CONTROL_PLANE_MACHINE_FLAVOR:=m1.medium} image: - filter: - name: overridden-by-patch + imageRef: + name: node-image sshKeyName: ${OPENSTACK_SSH_KEY_NAME:=""} --- apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 @@ -467,6 +525,6 @@ spec: spec: flavor: ${OPENSTACK_NODE_MACHINE_FLAVOR:=m1.small} image: - filter: - name: overridden-by-patch + imageRef: + name: node-image sshKeyName: ${OPENSTACK_SSH_KEY_NAME:=""} diff --git a/test/e2e/data/e2e_conf.yaml b/test/e2e/data/e2e_conf.yaml index 9914f0eb09..2ae1850898 100644 --- a/test/e2e/data/e2e_conf.yaml +++ b/test/e2e/data/e2e_conf.yaml @@ -171,6 +171,7 @@ providers: - sourcePath: "./infrastructure-openstack-no-artifact/cluster-template.yaml" - sourcePath: "./infrastructure-openstack-no-artifact/cluster-template-without-lb.yaml" - sourcePath: "./infrastructure-openstack-no-artifact/cluster-template-cluster-identity.yaml" + - sourcePath: "../../../templates/clusterclass-dev-test.yaml" replacements: - old: gcr.io/k8s-staging-capi-openstack/capi-openstack-controller:dev new: gcr.io/k8s-staging-capi-openstack/capi-openstack-controller:e2e @@ -246,6 +247,7 @@ variables: E2E_IMAGE_URL: "http://10.0.3.15/capo-e2e-image.tar" # The default user for SSH connections from bastion to machines SSH_USER_MACHINE: "ubuntu" + CLUSTER_TOPOLOGY: "true" EXP_KUBEADM_BOOTSTRAP_FORMAT_IGNITION: "true" # The Flatcar image produced by the image-builder OPENSTACK_FLATCAR_IMAGE_NAME: "flatcar-stable-4152.2.3-kube-v1.33.1" diff --git a/test/e2e/data/kustomize/components/common/kustomization.yaml b/test/e2e/data/kustomize/components/common/kustomization.yaml index 211dc0e4de..61582df596 100644 --- a/test/e2e/data/kustomize/components/common/kustomization.yaml +++ b/test/e2e/data/kustomize/components/common/kustomization.yaml @@ -1,7 +1,7 @@ apiVersion: kustomize.config.k8s.io/v1alpha1 kind: Component -resources: -- images.yaml +components: +- ../images patches: # Set AZ and enable bastion - target: diff --git a/test/e2e/data/kustomize/components/common/images.yaml b/test/e2e/data/kustomize/components/images/images.yaml similarity index 100% rename from test/e2e/data/kustomize/components/common/images.yaml rename to test/e2e/data/kustomize/components/images/images.yaml diff --git a/test/e2e/data/kustomize/components/images/kustomization.yaml b/test/e2e/data/kustomize/components/images/kustomization.yaml new file mode 100644 index 0000000000..daa515fd83 --- /dev/null +++ b/test/e2e/data/kustomize/components/images/kustomization.yaml @@ -0,0 +1,4 @@ +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component +resources: +- images.yaml diff --git a/test/e2e/data/kustomize/topology/cluster.yaml b/test/e2e/data/kustomize/topology/cluster.yaml new file mode 100644 index 0000000000..477715f266 --- /dev/null +++ b/test/e2e/data/kustomize/topology/cluster.yaml @@ -0,0 +1,40 @@ +# Rather than editing the cluster-template, which include already variables, +# we simply create a new cluster-template with the correct variables for e2e. +apiVersion: cluster.x-k8s.io/v1beta2 +kind: Cluster +metadata: + name: ${CLUSTER_NAME} +spec: + topology: + classRef: + name: dev-test + version: ${KUBERNETES_VERSION} + controlPlane: + replicas: ${CONTROL_PLANE_MACHINE_COUNT} + workers: + machineDeployments: + - class: default-worker + name: md-0 + replicas: ${WORKER_MACHINE_COUNT} + variables: + - name: identityRef + value: + name: ${CLUSTER_NAME}-cloud-config + cloudName: ${OPENSTACK_CLOUD} + - name: imageRef + value: node-image + - name: addImageVersion + value: false + - name: injectIgnitionSysext + value: true + - name: allowedCIDRs + value: ${OPENSTACK_API_SERVER_ALLOWED_CIDRS:=[]} + - name: bastion + value: + enabled: ${OPENSTACK_BASTION_ENABLED:=false} + spec: + flavor: ${OPENSTACK_BASTION_FLAVOR:=m1.small} + image: + imageRef: + name: bastion-image + sshKeyName: ${OPENSTACK_SSH_KEY_NAME:=""} diff --git a/test/e2e/data/kustomize/topology/kustomization.yaml b/test/e2e/data/kustomize/topology/kustomization.yaml new file mode 100644 index 0000000000..b2ad517cd4 --- /dev/null +++ b/test/e2e/data/kustomize/topology/kustomization.yaml @@ -0,0 +1,24 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- cluster.yaml +- secret.yaml + +components: +- ../components/images +- ../components/cluster-resource-sets + +patches: +- target: + group: openstack.k-orc.cloud + version: v1alpha1 + kind: Image + name: node-image + patch: |- + - op: replace + path: /spec/resource/name + value: ${FLATCAR_IMAGE_NAME} + - op: replace + path: /spec/resource/content/download/url + value: ${FLATCAR_IMAGE_URL} diff --git a/test/e2e/data/kustomize/topology/secret.yaml b/test/e2e/data/kustomize/topology/secret.yaml new file mode 100644 index 0000000000..2d6641ada9 --- /dev/null +++ b/test/e2e/data/kustomize/topology/secret.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +data: + cacert: ${OPENSTACK_CLOUD_CACERT_B64} + clouds.yaml: ${OPENSTACK_CLOUD_YAML_B64} +kind: Secret +metadata: + labels: + clusterctl.cluster.x-k8s.io/move: "true" + name: ${CLUSTER_NAME}-cloud-config diff --git a/test/e2e/shared/defaults.go b/test/e2e/shared/defaults.go index e14af48925..e8821ac83e 100644 --- a/test/e2e/shared/defaults.go +++ b/test/e2e/shared/defaults.go @@ -52,6 +52,7 @@ const ( OpenStackNodeMachineFlavor = "OPENSTACK_NODE_MACHINE_FLAVOR" SSHUserMachine = "SSH_USER_MACHINE" FlavorDefault = "" + FlavorTopology = "topology" FlavorNoBastion = "no-bastion" FlavorWithoutLB = "without-lb" FlavorMultiNetwork = "multi-network" diff --git a/test/e2e/suites/e2e/quick_start_test.go b/test/e2e/suites/e2e/quick_start_test.go new file mode 100644 index 0000000000..1a8d3d379e --- /dev/null +++ b/test/e2e/suites/e2e/quick_start_test.go @@ -0,0 +1,43 @@ +//go:build e2e +// +build e2e + +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package e2e + +import ( + "context" + + . "github.com/onsi/ginkgo/v2" + "k8s.io/utils/ptr" + capi_e2e "sigs.k8s.io/cluster-api/test/e2e" + + "sigs.k8s.io/cluster-api-provider-openstack/test/e2e/shared" +) + +var _ = Describe("When following the Cluster API quick-start with ClusterClass [PR-Blocking] [ClusterClass]", func() { + capi_e2e.QuickStartSpec(context.TODO(), func() capi_e2e.QuickStartSpecInput { + return capi_e2e.QuickStartSpecInput{ + E2EConfig: e2eCtx.E2EConfig, + ClusterctlConfigPath: e2eCtx.Environment.ClusterctlConfigPath, + BootstrapClusterProxy: e2eCtx.Environment.BootstrapClusterProxy, + ArtifactFolder: e2eCtx.Settings.ArtifactFolder, + SkipCleanup: false, + Flavor: ptr.To(shared.FlavorTopology), + } + }) +})