diff --git a/go.mod b/go.mod index 7f2646cd97..4597978fb6 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module sigs.k8s.io/cluster-api-provider-vsphere go 1.22.0 -replace sigs.k8s.io/cluster-api => sigs.k8s.io/cluster-api v1.7.0-rc.0.0.20240701062357-f57b8c8ef777 +replace sigs.k8s.io/cluster-api => sigs.k8s.io/cluster-api v1.7.0-rc.0.0.20240704170423-b08f0abe312b replace github.com/vmware-tanzu/vm-operator/pkg/constants/testlabels => github.com/vmware-tanzu/vm-operator/pkg/constants/testlabels v0.0.0-20240404200847-de75746a9505 @@ -40,7 +40,7 @@ require ( k8s.io/component-base v0.30.2 k8s.io/klog/v2 v2.120.1 k8s.io/utils v0.0.0-20231127182322-b307cd553661 - sigs.k8s.io/cluster-api v1.7.0-rc.0.0.20240701062357-f57b8c8ef777 + sigs.k8s.io/cluster-api v0.0.0-00010101000000-000000000000 sigs.k8s.io/controller-runtime v0.18.4 sigs.k8s.io/kustomize/api v0.17.2 sigs.k8s.io/kustomize/kyaml v0.17.1 diff --git a/go.sum b/go.sum index c6b93df1cd..2220f79cd7 100644 --- a/go.sum +++ b/go.sum @@ -1009,8 +1009,8 @@ rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.0 h1:Tc9rS7JJoZ9sl3OpL4842oIk6lH7gWBb0JOmJ0ute7M= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.0/go.mod h1:1ewhL9l1gkPcU/IU/6rFYfikf+7Y5imWv7ARVbBOzNs= -sigs.k8s.io/cluster-api v1.7.0-rc.0.0.20240701062357-f57b8c8ef777 h1:GBOytXqP37lSBbEo3O6NVK3KwJ4B2q0apxyNobkiBNA= -sigs.k8s.io/cluster-api v1.7.0-rc.0.0.20240701062357-f57b8c8ef777/go.mod h1:IzizeknMhBnwJrdEj5tDpheegvn5xZn8n2gLxKvv7/A= +sigs.k8s.io/cluster-api v1.7.0-rc.0.0.20240704170423-b08f0abe312b h1:wkVL1dTdTEAJGdV1q3C9zXBwwCA5ueUKtEn9TLGYcRo= +sigs.k8s.io/cluster-api v1.7.0-rc.0.0.20240704170423-b08f0abe312b/go.mod h1:IzizeknMhBnwJrdEj5tDpheegvn5xZn8n2gLxKvv7/A= sigs.k8s.io/controller-runtime v0.9.0/go.mod h1:TgkfvrhhEw3PlI0BRL/5xM+89y3/yc0ZDfdbTl84si8= sigs.k8s.io/controller-runtime v0.18.4 h1:87+guW1zhvuPLh1PHybKdYFLU0YJp4FhJRmiHvm5BZw= sigs.k8s.io/controller-runtime v0.18.4/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg= diff --git a/test/e2e/cluster_upgrade_test.go b/test/e2e/cluster_upgrade_test.go index 506a7c6ad6..d90f208cd7 100644 --- a/test/e2e/cluster_upgrade_test.go +++ b/test/e2e/cluster_upgrade_test.go @@ -58,7 +58,7 @@ var _ = Describe("When upgrading a workload cluster using ClusterClass and testi }) }) -var _ = Describe("When upgrading a workload cluster using ClusterClass [supervisor] [ClusterClass]", func() { +var _ = Describe("When upgrading a workload cluster using ClusterClass [vcsim] [supervisor] [ClusterClass]", func() { // Note: This installs a cluster based on KUBERNETES_VERSION_UPGRADE_FROM and then upgrades to // KUBERNETES_VERSION_UPGRADE_TO. const specName = "k8s-upgrade" // aligned to CAPI diff --git a/test/e2e/clusterclass_changes_test.go b/test/e2e/clusterclass_changes_test.go index c07265a5ea..d11ef3ca08 100644 --- a/test/e2e/clusterclass_changes_test.go +++ b/test/e2e/clusterclass_changes_test.go @@ -21,7 +21,7 @@ import ( capie2e "sigs.k8s.io/cluster-api/test/e2e" ) -var _ = Describe("When testing ClusterClass changes [supervisor] [ClusterClass]", func() { +var _ = Describe("When testing ClusterClass changes [vcsim] [supervisor] [ClusterClass]", func() { const specName = "clusterclass-changes" // copied from CAPI Setup(specName, func(testSpecificSettingsGetter func() testSettings) { capie2e.ClusterClassChangesSpec(ctx, func() capie2e.ClusterClassChangesSpecInput { diff --git a/test/e2e/e2e_suite_test.go b/test/e2e/e2e_suite_test.go index 570ffe3c57..8a0fa6326a 100644 --- a/test/e2e/e2e_suite_test.go +++ b/test/e2e/e2e_suite_test.go @@ -272,7 +272,13 @@ var _ = SynchronizedBeforeSuite(func() []byte { Finder: vsphereFinder, })) } - bootstrapClusterProxy = framework.NewClusterProxy("bootstrap", kubeconfigPath, initScheme(), clusterProxyOptions...) + if testTarget == VCSimTestTarget { + // Use a custom cluster-proxy in VCSim mode to allow connections from the e2e test code (outside of the management cluster) + // to the fake kube-apiserver running in vcsim-controller. + bootstrapClusterProxy = vspherevcsim.NewClusterProxy("bootstrap", kubeconfigPath, initScheme(), clusterProxyOptions...) + } else { + bootstrapClusterProxy = framework.NewClusterProxy("bootstrap", kubeconfigPath, initScheme(), clusterProxyOptions...) + } ipClaimLabels := map[string]string{} for _, s := range strings.Split(ipClaimLabelsRaw, ";") { diff --git a/test/framework/vcsim/cluster_proxy.go b/test/framework/vcsim/cluster_proxy.go new file mode 100644 index 0000000000..2d785b29bc --- /dev/null +++ b/test/framework/vcsim/cluster_proxy.go @@ -0,0 +1,115 @@ +/* +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 vcsim provide helpers for vcsim controller. +package vcsim + +import ( + "context" + "net" + "net/url" + "strconv" + + . "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" + expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1" + "sigs.k8s.io/cluster-api/test/framework" + inmemoryproxy "sigs.k8s.io/cluster-api/test/infrastructure/inmemory/pkg/server/proxy" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type vcSimClusterProxy struct { + framework.ClusterProxy + isWorkloadCluster bool +} + +// NewClusterProxy creates a ClusterProxy for usage with VCSim. +func NewClusterProxy(name string, kubeconfigPath string, scheme *runtime.Scheme, options ...framework.Option) framework.ClusterProxy { + return &vcSimClusterProxy{ + ClusterProxy: framework.NewClusterProxy(name, kubeconfigPath, scheme, options...), + } +} + +// GetWorkloadCluster returns ClusterProxy for the workload cluster. +func (p *vcSimClusterProxy) GetWorkloadCluster(ctx context.Context, namespace, name string, options ...framework.Option) framework.ClusterProxy { + // Get the vcSim pod information. + pods := corev1.PodList{} + Expect(p.GetClient().List(context.Background(), &pods, client.InNamespace("vcsim-system"))).To(Succeed()) + Expect(pods.Items).To(HaveLen(1), "expecting to run vcsim with a single replica") + vcSimPod := pods.Items[0] + + // Get the port on the vcsim pod from the RESTConfig of the workload cluster. + restConfig := p.ClusterProxy.GetWorkloadCluster(ctx, namespace, name).GetRESTConfig() + u, err := url.Parse(restConfig.Host) + Expect(err).ToNot(HaveOccurred()) + port, err := strconv.Atoi(u.Port()) + Expect(err).ToNot(HaveOccurred()) + + // Create a dialer which proxies through the kube-apiserver to the vcsim pod's port where the simulated kube-apiserver + // is running. + proxyDialer, err := inmemoryproxy.NewDialer(inmemoryproxy.Proxy{ + Kind: "pods", + Namespace: vcSimPod.GetNamespace(), + ResourceName: vcSimPod.GetName(), + Port: port, + KubeConfig: p.GetRESTConfig(), + }) + Expect(err).ToNot(HaveOccurred()) + + modifierFunc := func(c *rest.Config) { + c.Dial = func(ctx context.Context, _, _ string) (net.Conn, error) { + // Always use vcSimPodName as addr. + return proxyDialer.DialContext(ctx, "", vcSimPod.GetName()) + } + } + + return &vcSimClusterProxy{ + ClusterProxy: p.ClusterProxy.GetWorkloadCluster(ctx, namespace, name, append(options, framework.WithRESTConfigModifier(modifierFunc))...), + isWorkloadCluster: true, + } +} + +// GetLogCollector returns the machine log collector for the Kubernetes cluster. +func (p *vcSimClusterProxy) GetLogCollector() framework.ClusterLogCollector { + if p.isWorkloadCluster { + return &noopLogCollector{} + } + return p.ClusterProxy.GetLogCollector() +} + +// CollectWorkloadClusterLogs collects machines and infrastructure logs from the workload cluster. +func (p *vcSimClusterProxy) CollectWorkloadClusterLogs(ctx context.Context, namespace, name, outputPath string) { + if p.isWorkloadCluster { + // Workload Clusters using VCSim do not have real backing nodes so we can't collect logs. + return + } + p.ClusterProxy.CollectWorkloadClusterLogs(ctx, namespace, name, outputPath) +} + +type noopLogCollector struct{} + +func (*noopLogCollector) CollectMachineLog(_ context.Context, _ client.Client, _ *clusterv1.Machine, _ string) error { + return nil +} +func (*noopLogCollector) CollectMachinePoolLog(_ context.Context, _ client.Client, _ *expv1.MachinePool, _ string) error { + return nil +} +func (*noopLogCollector) CollectInfrastructureLogs(_ context.Context, _ client.Client, _ *clusterv1.Cluster, _ string) error { + return nil +} diff --git a/test/go.mod b/test/go.mod index ad42a71f39..ee1a3e2559 100644 --- a/test/go.mod +++ b/test/go.mod @@ -2,9 +2,9 @@ module sigs.k8s.io/cluster-api-provider-vsphere/test go 1.22.0 -replace sigs.k8s.io/cluster-api => sigs.k8s.io/cluster-api v1.7.0-rc.0.0.20240701062357-f57b8c8ef777 +replace sigs.k8s.io/cluster-api => sigs.k8s.io/cluster-api v1.7.0-rc.0.0.20240704170423-b08f0abe312b -replace sigs.k8s.io/cluster-api/test => sigs.k8s.io/cluster-api/test v1.7.0-rc.0.0.20240701062357-f57b8c8ef777 +replace sigs.k8s.io/cluster-api/test => sigs.k8s.io/cluster-api/test v1.7.0-rc.0.0.20240704170423-b08f0abe312b replace sigs.k8s.io/cluster-api-provider-vsphere => ../ @@ -32,7 +32,7 @@ require ( k8s.io/component-base v0.30.2 k8s.io/klog/v2 v2.120.1 k8s.io/utils v0.0.0-20231127182322-b307cd553661 - sigs.k8s.io/cluster-api v1.7.0-rc.0.0.20240701062357-f57b8c8ef777 + sigs.k8s.io/cluster-api v1.7.0-rc.0.0.20240704092232-a7f5043dee2a sigs.k8s.io/cluster-api-provider-vsphere v0.0.0-00010101000000-000000000000 sigs.k8s.io/cluster-api/test v0.0.0-00010101000000-000000000000 sigs.k8s.io/controller-runtime v0.18.4 diff --git a/test/go.sum b/test/go.sum index a720585b76..566e3cc99c 100644 --- a/test/go.sum +++ b/test/go.sum @@ -1091,10 +1091,10 @@ rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.0 h1:Tc9rS7JJoZ9sl3OpL4842oIk6lH7gWBb0JOmJ0ute7M= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.0/go.mod h1:1ewhL9l1gkPcU/IU/6rFYfikf+7Y5imWv7ARVbBOzNs= -sigs.k8s.io/cluster-api v1.7.0-rc.0.0.20240701062357-f57b8c8ef777 h1:GBOytXqP37lSBbEo3O6NVK3KwJ4B2q0apxyNobkiBNA= -sigs.k8s.io/cluster-api v1.7.0-rc.0.0.20240701062357-f57b8c8ef777/go.mod h1:IzizeknMhBnwJrdEj5tDpheegvn5xZn8n2gLxKvv7/A= -sigs.k8s.io/cluster-api/test v1.7.0-rc.0.0.20240701062357-f57b8c8ef777 h1:Oe+T2sUD2IF/4FnCjvHuFk/SazgZRlT2wKdmJLbLQMI= -sigs.k8s.io/cluster-api/test v1.7.0-rc.0.0.20240701062357-f57b8c8ef777/go.mod h1:efkFHwm+FS5rTsLQjj02U4qPWj1xOCufya3axC8zNwQ= +sigs.k8s.io/cluster-api v1.7.0-rc.0.0.20240704170423-b08f0abe312b h1:wkVL1dTdTEAJGdV1q3C9zXBwwCA5ueUKtEn9TLGYcRo= +sigs.k8s.io/cluster-api v1.7.0-rc.0.0.20240704170423-b08f0abe312b/go.mod h1:IzizeknMhBnwJrdEj5tDpheegvn5xZn8n2gLxKvv7/A= +sigs.k8s.io/cluster-api/test v1.7.0-rc.0.0.20240704170423-b08f0abe312b h1:9t6L1tPTamFkpQazAfHwB8i6eXtGF5EcTQtTQPCcVyo= +sigs.k8s.io/cluster-api/test v1.7.0-rc.0.0.20240704170423-b08f0abe312b/go.mod h1:efkFHwm+FS5rTsLQjj02U4qPWj1xOCufya3axC8zNwQ= sigs.k8s.io/controller-runtime v0.9.0/go.mod h1:TgkfvrhhEw3PlI0BRL/5xM+89y3/yc0ZDfdbTl84si8= sigs.k8s.io/controller-runtime v0.18.4 h1:87+guW1zhvuPLh1PHybKdYFLU0YJp4FhJRmiHvm5BZw= sigs.k8s.io/controller-runtime v0.18.4/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg= diff --git a/test/infrastructure/vcsim/controllers/vmbootstrap_controller.go b/test/infrastructure/vcsim/controllers/vmbootstrap_controller.go index aeedcf6cbc..ecc998158d 100644 --- a/test/infrastructure/vcsim/controllers/vmbootstrap_controller.go +++ b/test/infrastructure/vcsim/controllers/vmbootstrap_controller.go @@ -240,6 +240,9 @@ func (r *vmBootstrapReconciler) reconcileBoostrapNode(ctx context.Context, clust }, }, } + if machine.Spec.Version != nil { + node.Status.NodeInfo.KubeletVersion = *machine.Spec.Version + } if util.IsControlPlaneMachine(machine) { if node.Labels == nil { node.Labels = map[string]string{}