diff --git a/test/e2e/config/operator.yaml b/test/e2e/config/operator.yaml index 9a28f442..a4b851c7 100644 --- a/test/e2e/config/operator.yaml +++ b/test/e2e/config/operator.yaml @@ -14,6 +14,7 @@ intervals: default/wait-capz-create-cluster: ["35m", "30s"] default/wait-capv-create-cluster: ["30m", "30s"] default/wait-gitea: ["3m", "10s"] + default/wait-gitpush: ["3m", "10s"] default/wait-consistently: ["30s", "5s"] default/wait-getservice: ["5m", "30s"] default/wait-eks-delete: ["35m", "30s"] @@ -34,7 +35,7 @@ variables: RANCHER_FEATURES: "" RANCHER_PATH: "rancher-latest/rancher" CPI_IMAGE_K8S_VERSION: "v1.27.0" - RKE2_VERSION: "v1.26.8+rke2r1" + RKE2_VERSION: "v1.28.1+rke2r1" RANCHER_REPO_NAME: "rancher-latest" RANCHER_URL: "https://releases.rancher.com/server-charts/latest" CERT_MANAGER_URL: "https://charts.jetstack.io" diff --git a/test/e2e/const.go b/test/e2e/const.go index fe2ade11..4c745119 100644 --- a/test/e2e/const.go +++ b/test/e2e/const.go @@ -81,6 +81,9 @@ var ( //go:embed data/cluster-templates/vsphere-kubeadm.yaml CAPIvSphereKubeadm []byte + //go:embed data/cluster-templates/vsphere-rke2.yaml + CAPIvSphereRKE2 []byte + //go:embed data/gitea/ingress.yaml GiteaIngress []byte ) diff --git a/test/e2e/data/cluster-templates/vsphere-rke2.yaml b/test/e2e/data/cluster-templates/vsphere-rke2.yaml new file mode 100644 index 00000000..47f6dc00 --- /dev/null +++ b/test/e2e/data/cluster-templates/vsphere-rke2.yaml @@ -0,0 +1,1034 @@ +--- +apiVersion: cluster.x-k8s.io/v1beta1 +kind: Cluster +metadata: + namespace: ${NAMESPACE} + name: ${CLUSTER_NAME} + labels: + cluster.x-k8s.io/cluster-name: ${CLUSTER_NAME} +spec: + clusterNetwork: + pods: + cidrBlocks: + - 10.0.0.0/16 + serviceDomain: cluster.local + controlPlaneRef: + apiVersion: controlplane.cluster.x-k8s.io/v1beta1 + kind: RKE2ControlPlane + name: ${CLUSTER_NAME} + infrastructureRef: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: VSphereCluster + name: ${CLUSTER_NAME} +--- +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: VSphereCluster +metadata: + name: ${CLUSTER_NAME} + namespace: ${NAMESPACE} +spec: + controlPlaneEndpoint: + host: ${CONTROL_PLANE_ENDPOINT_IP} + port: 6443 + identityRef: + kind: Secret + name: ${CLUSTER_NAME} + server: ${VSPHERE_SERVER} + thumbprint: ${VSPHERE_TLS_THUMBPRINT} +--- +apiVersion: controlplane.cluster.x-k8s.io/v1beta1 +kind: RKE2ControlPlane +metadata: + name: ${CLUSTER_NAME} + namespace: ${NAMESPACE} +spec: + serverConfig: + disableComponents: + kubernetesComponents: + - cloudController + files: + - path: "/var/lib/rancher/rke2/server/manifests/coredns-config.yaml" + owner: "root:root" + permissions: "0640" + content: | + apiVersion: helm.cattle.io/v1 + kind: HelmChartConfig + metadata: + name: rke2-coredns + namespace: kube-system + spec: + valuesContent: |- + tolerations: + - key: "node.cloudprovider.kubernetes.io/uninitialized" + value: "true" + effect: "NoSchedule" + - path: "/var/lib/rancher/rke2/server/manifests/kubevip.yaml" + owner: "root:root" + permissions: "0640" + content: | + apiVersion: v1 + kind: ServiceAccount + metadata: + name: kube-vip + namespace: kube-system + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + annotations: + rbac.authorization.kubernetes.io/autoupdate: "true" + name: system:kube-vip-role + rules: + - apiGroups: [""] + resources: ["services", "services/status", "nodes"] + verbs: ["list","get","watch", "update"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["list", "get", "watch", "update", "create"] + --- + kind: ClusterRoleBinding + apiVersion: rbac.authorization.k8s.io/v1 + metadata: + name: system:kube-vip-binding + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:kube-vip-role + subjects: + - kind: ServiceAccount + name: kube-vip + namespace: kube-system + --- + apiVersion: v1 + kind: Pod + metadata: + creationTimestamp: null + name: kube-vip + namespace: kube-system + spec: + tolerations: + - effect: NoSchedule + key: node.cloudprovider.kubernetes.io/uninitialized + operator: Exists + containers: + - args: + - manager + env: + - name: cp_enable + value: "true" + - name: vip_interface + value: eth0 + - name: address + value: ${CONTROL_PLANE_ENDPOINT_IP} + - name: port + value: "6443" + - name: vip_arp + value: "true" + - name: vip_leaderelection + value: "true" + - name: vip_leaseduration + value: "15" + - name: vip_renewdeadline + value: "10" + - name: vip_retryperiod + value: "2" + image: ghcr.io/kube-vip/kube-vip:v0.5.5 + imagePullPolicy: IfNotPresent + name: kube-vip + resources: {} + securityContext: + capabilities: + add: + - NET_ADMIN + - NET_RAW + volumeMounts: + - mountPath: /etc/rancher/rke2/rke2.yaml + name: kubeconfig + hostAliases: + - hostnames: + - kubernetes + ip: 127.0.0.1 + hostNetwork: true + serviceAccountName: kube-vip + volumes: + - hostPath: + path: /etc/rancher/rke2/rke2.yaml + type: File + name: kubeconfig + replicas: ${CONTROL_PLANE_MACHINE_COUNT} + infrastructureRef: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: VSphereMachineTemplate + name: vsphere-controlplane + nodeDrainTimeout: 2m + preRKE2Commands: + - sleep 30 #fix to give OS time to become ready + version: ${RKE2_VERSION} + agentConfig: + additionalUserData: + config: | + users: + - name: capv + sudo: ALL=(ALL) NOPASSWD:ALL + ssh-authorized-keys: + - '${VSPHERE_SSH_AUTHORIZED_KEY}' + kubelet: + extraArgs: + - --cloud-provider=external + registrationMethod: "internal-first" + rolloutStrategy: + type: "RollingUpdate" + rollingUpdate: + maxSurge: 1 +--- +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: VSphereMachineTemplate +metadata: + name: vsphere-controlplane + namespace: ${NAMESPACE} +spec: + template: + spec: + cloneMode: linkedClone + datacenter: ${VSPHERE_DATACENTER} + datastore: ${VSPHERE_DATASTORE} + diskGiB: 25 + folder: ${VSPHERE_FOLDER} + memoryMiB: 8192 + network: + devices: + - dhcp4: true + networkName: ${VSPHERE_NETWORK} + numCPUs: 2 + os: Linux + resourcePool: "${VSPHERE_RESOURCE_POOL}" + server: ${VSPHERE_SERVER} + storagePolicyName: "" + template: ${VSPHERE_TEMPLATE} + thumbprint: ${VSPHERE_TLS_THUMBPRINT} +--- +apiVersion: cluster.x-k8s.io/v1beta1 +kind: MachineDeployment +metadata: + labels: + cluster.x-k8s.io/cluster-name: ${NAMESPACE} + name: worker-md-0 + namespace: ${NAMESPACE} +spec: + clusterName: ${CLUSTER_NAME} + replicas: ${WORKER_MACHINE_COUNT} + selector: + matchLabels: {} + template: + metadata: + labels: + cluster.x-k8s.io/cluster-name: ${CLUSTER_NAME} + spec: + version: ${RKE2_VERSION} + clusterName: ${CLUSTER_NAME} + bootstrap: + configRef: + apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 + kind: RKE2ConfigTemplate + name: rke2-agent + namespace: ${NAMESPACE} + infrastructureRef: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: VSphereMachineTemplate + name: vsphere-worker + namespace: ${NAMESPACE} +--- +apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 +kind: RKE2ConfigTemplate +metadata: + namespace: ${NAMESPACE} + name: rke2-agent +spec: + template: + spec: + preRKE2Commands: + - sleep 30 # fix to give OS time to become ready + agentConfig: + kubelet: + extraArgs: + - "--cloud-provider=external" +--- +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: VSphereMachineTemplate +metadata: + name: vsphere-worker + namespace: ${NAMESPACE} +spec: + template: + spec: + cloneMode: linkedClone + datacenter: ${VSPHERE_DATACENTER} + datastore: ${VSPHERE_DATASTORE} + diskGiB: 25 + folder: ${VSPHERE_FOLDER} + memoryMiB: 8192 + network: + devices: + - dhcp4: true + networkName: ${VSPHERE_NETWORK} + numCPUs: 2 + os: Linux + resourcePool: "${VSPHERE_RESOURCE_POOL}" + server: ${VSPHERE_SERVER} + storagePolicyName: "" + template: ${VSPHERE_TEMPLATE} + thumbprint: ${VSPHERE_TLS_THUMBPRINT} +--- +apiVersion: addons.cluster.x-k8s.io/v1beta1 +kind: ClusterResourceSet +metadata: + labels: + cluster.x-k8s.io/cluster-name: ${CLUSTER_NAME} + name: ${CLUSTER_NAME}-crs-0 + namespace: ${NAMESPACE} +spec: + clusterSelector: + matchLabels: + cluster.x-k8s.io/cluster-name: ${CLUSTER_NAME} + resources: + - kind: Secret + name: vsphere-csi-controller + - kind: ConfigMap + name: vsphere-csi-controller-role + - kind: ConfigMap + name: vsphere-csi-controller-binding + - kind: Secret + name: csi-vsphere-config + - kind: ConfigMap + name: csi.vsphere.vmware.com + - kind: ConfigMap + name: vsphere-csi-node + - kind: ConfigMap + name: vsphere-csi-controller + - kind: Secret + name: cloud-controller-manager + - kind: Secret + name: cloud-provider-vsphere-credentials + - kind: ConfigMap + name: cpi-manifests +--- +apiVersion: v1 +kind: Secret +metadata: + name: ${CLUSTER_NAME} + namespace: ${NAMESPACE} +stringData: + password: ${VSPHERE_PASSWORD} + username: ${VSPHERE_USERNAME} +--- +apiVersion: v1 +kind: Secret +metadata: + name: vsphere-csi-controller + namespace: ${NAMESPACE} +stringData: + data: | + apiVersion: v1 + kind: ServiceAccount + metadata: + name: vsphere-csi-controller + namespace: kube-system +type: addons.cluster.x-k8s.io/resource-set +--- +apiVersion: v1 +data: + data: | + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + name: vsphere-csi-controller-role + rules: + - apiGroups: + - storage.k8s.io + resources: + - csidrivers + verbs: + - create + - delete + - apiGroups: + - "" + resources: + - nodes + - pods + - secrets + - configmaps + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - persistentvolumes + verbs: + - get + - list + - watch + - update + - create + - delete + - patch + - apiGroups: + - storage.k8s.io + resources: + - volumeattachments + verbs: + - get + - list + - watch + - update + - patch + - apiGroups: + - storage.k8s.io + resources: + - volumeattachments/status + verbs: + - patch + - apiGroups: + - "" + resources: + - persistentvolumeclaims + verbs: + - get + - list + - watch + - update + - apiGroups: + - storage.k8s.io + resources: + - storageclasses + - csinodes + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - events + verbs: + - list + - watch + - create + - update + - patch + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - watch + - list + - delete + - update + - create + - apiGroups: + - snapshot.storage.k8s.io + resources: + - volumesnapshots + verbs: + - get + - list + - apiGroups: + - snapshot.storage.k8s.io + resources: + - volumesnapshotcontents + verbs: + - get + - list +kind: ConfigMap +metadata: + name: vsphere-csi-controller-role + namespace: ${NAMESPACE} +--- +apiVersion: v1 +data: + data: | + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRoleBinding + metadata: + name: vsphere-csi-controller-binding + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: vsphere-csi-controller-role + subjects: + - kind: ServiceAccount + name: vsphere-csi-controller + namespace: kube-system +kind: ConfigMap +metadata: + name: vsphere-csi-controller-binding + namespace: ${NAMESPACE} +--- +apiVersion: v1 +kind: Secret +metadata: + name: csi-vsphere-config + namespace: ${NAMESPACE} +stringData: + data: | + apiVersion: v1 + kind: Secret + metadata: + name: csi-vsphere-config + namespace: kube-system + stringData: + csi-vsphere.conf: |+ + [Global] + cluster-id = "default/${CLUSTER_NAME}" + + [VirtualCenter "${VSPHERE_SERVER}"] + user = "${VSPHERE_USERNAME}" + password = "${VSPHERE_PASSWORD}" + datacenters = "${VSPHERE_DATACENTER}" + insecure-flag = 1 + + + [Network] + public-network = "${VSPHERE_NETWORK}" + + type: Opaque +type: addons.cluster.x-k8s.io/resource-set +--- +apiVersion: v1 +data: + data: | + apiVersion: storage.k8s.io/v1 + kind: CSIDriver + metadata: + name: csi.vsphere.vmware.com + spec: + attachRequired: true +kind: ConfigMap +metadata: + name: csi.vsphere.vmware.com + namespace: ${NAMESPACE} +--- +apiVersion: v1 +data: + data: | + apiVersion: apps/v1 + kind: DaemonSet + metadata: + name: vsphere-csi-node + namespace: kube-system + spec: + selector: + matchLabels: + app: vsphere-csi-node + template: + metadata: + labels: + app: vsphere-csi-node + role: vsphere-csi + spec: + containers: + - args: + - --v=5 + - --csi-address=$(ADDRESS) + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + env: + - name: ADDRESS + value: /csi/csi.sock + - name: DRIVER_REG_SOCK_PATH + value: /var/lib/kubelet/plugins/csi.vsphere.vmware.com/csi.sock + image: quay.io/k8scsi/csi-node-driver-registrar:v2.0.1 + lifecycle: + preStop: + exec: + command: + - /bin/sh + - -c + - rm -rf /registration/csi.vsphere.vmware.com-reg.sock /csi/csi.sock + name: node-driver-registrar + resources: {} + securityContext: + privileged: true + volumeMounts: + - mountPath: /csi + name: plugin-dir + - mountPath: /registration + name: registration-dir + - env: + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + - name: X_CSI_MODE + value: node + - name: X_CSI_SPEC_REQ_VALIDATION + value: "false" + - name: VSPHERE_CSI_CONFIG + value: /etc/cloud/csi-vsphere.conf + - name: LOGGER_LEVEL + value: PRODUCTION + - name: X_CSI_LOG_LEVEL + value: INFO + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + image: gcr.io/cloud-provider-vsphere/csi/release/driver:v2.1.0 + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 10 + periodSeconds: 5 + timeoutSeconds: 3 + name: vsphere-csi-node + ports: + - containerPort: 9808 + name: healthz + protocol: TCP + resources: {} + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - SYS_ADMIN + privileged: true + volumeMounts: + - mountPath: /etc/cloud + name: vsphere-config-volume + - mountPath: /csi + name: plugin-dir + - mountPath: /var/lib/kubelet + mountPropagation: Bidirectional + name: pods-mount-dir + - mountPath: /dev + name: device-dir + - args: + - --csi-address=/csi/csi.sock + image: quay.io/k8scsi/livenessprobe:v2.1.0 + name: liveness-probe + resources: {} + volumeMounts: + - mountPath: /csi + name: plugin-dir + dnsPolicy: Default + tolerations: + - effect: NoSchedule + operator: Exists + - effect: NoExecute + operator: Exists + volumes: + - name: vsphere-config-volume + secret: + secretName: csi-vsphere-config + - hostPath: + path: /var/lib/kubelet/plugins_registry + type: Directory + name: registration-dir + - hostPath: + path: /var/lib/kubelet/plugins/csi.vsphere.vmware.com/ + type: DirectoryOrCreate + name: plugin-dir + - hostPath: + path: /var/lib/kubelet + type: Directory + name: pods-mount-dir + - hostPath: + path: /dev + name: device-dir + updateStrategy: + type: RollingUpdate +kind: ConfigMap +metadata: + name: vsphere-csi-node + namespace: ${NAMESPACE} +--- +apiVersion: v1 +data: + data: | + apiVersion: apps/v1 + kind: Deployment + metadata: + name: vsphere-csi-controller + namespace: kube-system + spec: + replicas: 1 + selector: + matchLabels: + app: vsphere-csi-controller + template: + metadata: + labels: + app: vsphere-csi-controller + role: vsphere-csi + spec: + containers: + - args: + - --v=4 + - --timeout=300s + - --csi-address=$(ADDRESS) + - --leader-election + env: + - name: ADDRESS + value: /csi/csi.sock + image: quay.io/k8scsi/csi-attacher:v3.0.0 + name: csi-attacher + resources: {} + volumeMounts: + - mountPath: /csi + name: socket-dir + - env: + - name: CSI_ENDPOINT + value: unix:///var/lib/csi/sockets/pluginproxy/csi.sock + - name: X_CSI_MODE + value: controller + - name: VSPHERE_CSI_CONFIG + value: /etc/cloud/csi-vsphere.conf + - name: LOGGER_LEVEL + value: PRODUCTION + - name: X_CSI_LOG_LEVEL + value: INFO + image: gcr.io/cloud-provider-vsphere/csi/release/driver:v2.1.0 + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 10 + periodSeconds: 5 + timeoutSeconds: 3 + name: vsphere-csi-controller + ports: + - containerPort: 9808 + name: healthz + protocol: TCP + resources: {} + volumeMounts: + - mountPath: /etc/cloud + name: vsphere-config-volume + readOnly: true + - mountPath: /var/lib/csi/sockets/pluginproxy/ + name: socket-dir + - args: + - --csi-address=$(ADDRESS) + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + image: quay.io/k8scsi/livenessprobe:v2.1.0 + name: liveness-probe + resources: {} + volumeMounts: + - mountPath: /var/lib/csi/sockets/pluginproxy/ + name: socket-dir + - args: + - --leader-election + env: + - name: X_CSI_FULL_SYNC_INTERVAL_MINUTES + value: "30" + - name: LOGGER_LEVEL + value: PRODUCTION + - name: VSPHERE_CSI_CONFIG + value: /etc/cloud/csi-vsphere.conf + image: gcr.io/cloud-provider-vsphere/csi/release/syncer:v2.1.0 + name: vsphere-syncer + resources: {} + volumeMounts: + - mountPath: /etc/cloud + name: vsphere-config-volume + readOnly: true + - args: + - --v=4 + - --timeout=300s + - --csi-address=$(ADDRESS) + - --leader-election + - --default-fstype=ext4 + env: + - name: ADDRESS + value: /csi/csi.sock + image: quay.io/k8scsi/csi-provisioner:v2.0.0 + name: csi-provisioner + resources: {} + volumeMounts: + - mountPath: /csi + name: socket-dir + dnsPolicy: Default + serviceAccountName: vsphere-csi-controller + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/master + operator: Exists + volumes: + - name: vsphere-config-volume + secret: + secretName: csi-vsphere-config + - emptyDir: {} + name: socket-dir +kind: ConfigMap +metadata: + name: vsphere-csi-controller + namespace: ${NAMESPACE} +--- +apiVersion: v1 +kind: Secret +metadata: + name: cloud-controller-manager + namespace: ${NAMESPACE} +stringData: + data: | + apiVersion: v1 + kind: ServiceAccount + metadata: + name: cloud-controller-manager + namespace: kube-system +type: addons.cluster.x-k8s.io/resource-set +--- +apiVersion: v1 +kind: Secret +metadata: + name: cloud-provider-vsphere-credentials + namespace: ${NAMESPACE} +stringData: + data: | + apiVersion: v1 + kind: Secret + metadata: + name: cloud-provider-vsphere-credentials + namespace: kube-system + stringData: + ${VSPHERE_SERVER}.password: ${VSPHERE_PASSWORD} + ${VSPHERE_SERVER}.username: ${VSPHERE_USERNAME} + type: Opaque +type: addons.cluster.x-k8s.io/resource-set +--- +apiVersion: v1 +data: + data: | + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + labels: + component: cloud-controller-manager + vsphere-cpi-infra: role + name: system:cloud-controller-manager + rules: + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - update + - apiGroups: + - "" + resources: + - nodes + verbs: + - '*' + - apiGroups: + - "" + resources: + - nodes/status + verbs: + - patch + - apiGroups: + - "" + resources: + - services + verbs: + - list + - patch + - update + - watch + - apiGroups: + - "" + resources: + - services/status + verbs: + - patch + - apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - create + - get + - list + - watch + - update + - apiGroups: + - "" + resources: + - persistentvolumes + verbs: + - get + - list + - watch + - update + - apiGroups: + - "" + resources: + - endpoints + verbs: + - create + - get + - list + - watch + - update + - apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - watch + - list + - update + - create + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRoleBinding + metadata: + labels: + component: cloud-controller-manager + vsphere-cpi-infra: cluster-role-binding + name: system:cloud-controller-manager + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:cloud-controller-manager + subjects: + - kind: ServiceAccount + name: cloud-controller-manager + namespace: kube-system + - kind: User + name: cloud-controller-manager + --- + apiVersion: v1 + data: + vsphere.conf: | + global: + port: 443 + secretName: cloud-provider-vsphere-credentials + secretNamespace: kube-system + thumbprint: '${VSPHERE_TLS_THUMBPRINT}' + vcenter: + ${VSPHERE_SERVER}: + datacenters: + - '${VSPHERE_DATACENTER}' + server: '${VSPHERE_SERVER}' + kind: ConfigMap + metadata: + name: vsphere-cloud-config + namespace: kube-system + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + labels: + component: cloud-controller-manager + vsphere-cpi-infra: role-binding + name: servicecatalog.k8s.io:apiserver-authentication-reader + namespace: kube-system + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader + subjects: + - kind: ServiceAccount + name: cloud-controller-manager + namespace: kube-system + - kind: User + name: cloud-controller-manager + --- + apiVersion: apps/v1 + kind: DaemonSet + metadata: + labels: + component: cloud-controller-manager + tier: control-plane + name: vsphere-cloud-controller-manager + namespace: kube-system + spec: + selector: + matchLabels: + name: vsphere-cloud-controller-manager + template: + metadata: + labels: + component: cloud-controller-manager + name: vsphere-cloud-controller-manager + tier: control-plane + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node-role.kubernetes.io/control-plane + operator: Exists + - matchExpressions: + - key: node-role.kubernetes.io/master + operator: Exists + containers: + - args: + - --v=2 + - --cloud-provider=vsphere + - --cloud-config=/etc/cloud/vsphere.conf + image: gcr.io/cloud-provider-vsphere/cpi/release/manager:${CPI_IMAGE_K8S_VERSION} + name: vsphere-cloud-controller-manager + resources: + requests: + cpu: 200m + volumeMounts: + - mountPath: /etc/cloud + name: vsphere-config-volume + readOnly: true + hostNetwork: true + priorityClassName: system-node-critical + securityContext: + runAsUser: 1001 + serviceAccountName: cloud-controller-manager + tolerations: + - effect: NoSchedule + key: node.cloudprovider.kubernetes.io/uninitialized + value: "true" + - effect: NoSchedule + key: node-role.kubernetes.io/master + operator: Exists + - effect: NoSchedule + key: node-role.kubernetes.io/control-plane + operator: Exists + - effect: NoSchedule + key: node.kubernetes.io/not-ready + operator: Exists + volumes: + - configMap: + name: vsphere-cloud-config + name: vsphere-config-volume + updateStrategy: + type: RollingUpdate +kind: ConfigMap +metadata: + name: cpi-manifests + namespace: ${NAMESPACE} +--- +apiVersion: v1 +kind: Secret +metadata: + name: ${CLUSTER_NAME} + namespace: ${NAMESPACE} +stringData: + password: ${VSPHERE_PASSWORD} + username: ${VSPHERE_USERNAME} +--- \ No newline at end of file diff --git a/test/e2e/specs/import_gitops.go b/test/e2e/specs/import_gitops.go index 952e9489..47083a8b 100644 --- a/test/e2e/specs/import_gitops.go +++ b/test/e2e/specs/import_gitops.go @@ -237,6 +237,7 @@ func CreateUsingGitOpsSpec(ctx context.Context, inputGetter func() CreateUsingGi Username: input.E2EConfig.GetVariable(e2e.GiteaUserNameVar), Password: input.E2EConfig.GetVariable(e2e.GiteaUserPasswordVar), CommitMessage: "ci: add clusters bundle", + GitPushWait: input.E2EConfig.GetIntervals(input.BootstrapClusterProxy.GetName(), "wait-gitpush"), }) By("Applying GitRepo") diff --git a/test/e2e/specs/import_gitops_mgmtv3.go b/test/e2e/specs/import_gitops_mgmtv3.go index 8cc6e6a0..0b7b4f3b 100644 --- a/test/e2e/specs/import_gitops_mgmtv3.go +++ b/test/e2e/specs/import_gitops_mgmtv3.go @@ -257,6 +257,7 @@ func CreateMgmtV3UsingGitOpsSpec(ctx context.Context, inputGetter func() CreateM Username: input.E2EConfig.GetVariable(e2e.GiteaUserNameVar), Password: input.E2EConfig.GetVariable(e2e.GiteaUserPasswordVar), CommitMessage: "ci: add clusters bundle", + GitPushWait: input.E2EConfig.GetIntervals(input.BootstrapClusterProxy.GetName(), "wait-gitpush"), }) By("Applying GitRepo") diff --git a/test/e2e/specs/migrate_gitops_provv1_mgmtv3.go b/test/e2e/specs/migrate_gitops_provv1_mgmtv3.go index d45092d2..1517e8a0 100644 --- a/test/e2e/specs/migrate_gitops_provv1_mgmtv3.go +++ b/test/e2e/specs/migrate_gitops_provv1_mgmtv3.go @@ -301,6 +301,7 @@ func MigrateToV3UsingGitOpsSpec(ctx context.Context, inputGetter func() MigrateT Username: input.E2EConfig.GetVariable(e2e.GiteaUserNameVar), Password: input.E2EConfig.GetVariable(e2e.GiteaUserPasswordVar), CommitMessage: "ci: add clusters bundle", + GitPushWait: input.E2EConfig.GetIntervals(input.BootstrapClusterProxy.GetName(), "wait-gitpush"), }) By("Applying GitRepo") diff --git a/test/e2e/suites/import-gitops/import_gitops_test.go b/test/e2e/suites/import-gitops/import_gitops_test.go index ca9b40a5..84293a3b 100644 --- a/test/e2e/suites/import-gitops/import_gitops_test.go +++ b/test/e2e/suites/import-gitops/import_gitops_test.go @@ -181,3 +181,36 @@ var _ = Describe("[vSphere] [Kubeadm] Create and delete CAPI cluster functionali } }) }) + +var _ = Describe("[vSphere] [RKE2] Create and delete CAPI cluster functionality should work with namespace auto-import", Label(e2e.LocalTestLabel), func() { + BeforeEach(func() { + SetClient(setupClusterResult.BootstrapClusterProxy.GetClient()) + SetContext(ctx) + }) + + specs.CreateUsingGitOpsSpec(ctx, func() specs.CreateUsingGitOpsSpecInput { + return specs.CreateUsingGitOpsSpecInput{ + E2EConfig: e2eConfig, + BootstrapClusterProxy: setupClusterResult.BootstrapClusterProxy, + ClusterctlConfigPath: flagVals.ConfigPath, + ClusterctlBinaryPath: flagVals.ClusterctlBinaryPath, + ArtifactFolder: flagVals.ArtifactFolder, + ClusterTemplate: e2e.CAPIvSphereRKE2, + ClusterName: "cluster-vsphere-rke2", + ControlPlaneMachineCount: ptr.To[int](1), + WorkerMachineCount: ptr.To[int](1), + GitAddr: giteaResult.GitAddress, + GitAuthSecretName: e2e.AuthSecretName, + SkipCleanup: false, + SkipDeletionTest: false, + LabelNamespace: true, + RancherServerURL: hostName, + CAPIClusterCreateWaitName: "wait-capv-create-cluster", + DeleteClusterWaitName: "wait-vsphere-delete", + AdditionalTemplateVariables: map[string]string{ + "NAMESPACE": "default", + "VIP_NETWORK_INTERFACE": "", + }, + } + }) +}) diff --git a/test/framework/git_helper.go b/test/framework/git_helper.go index 3cfe6170..f9bf6bc1 100644 --- a/test/framework/git_helper.go +++ b/test/framework/git_helper.go @@ -72,6 +72,7 @@ type GitCommitAndPushInput struct { Username string Password string CommitMessage string + GitPushWait []interface{} } // GitCommitAndPush will commit the files for a repo and push the changes to the origin. @@ -111,4 +112,12 @@ func GitCommitAndPush(ctx context.Context, input GitCommitAndPushInput) { } err = repo.Push(pushOptions) Expect(err).ShouldNot(HaveOccurred(), "Failed pushing changes") + + Eventually(func() error { + err := repo.Push(pushOptions) + if err.Error() == "already up-to-date" { + return nil + } + return err + }, input.GitPushWait...).Should(Succeed(), "Failed to connect to workload cluster using CAPI kubeconfig") }