@@ -43,6 +43,7 @@ import (
4343 ctrl "sigs.k8s.io/controller-runtime"
4444 "sigs.k8s.io/controller-runtime/pkg/client"
4545
46+ vmwarev1 "sigs.k8s.io/cluster-api-provider-vsphere/apis/vmware/v1beta1"
4647 topologyv1 "sigs.k8s.io/cluster-api-provider-vsphere/internal/apis/topology/v1alpha1"
4748 "sigs.k8s.io/cluster-api-provider-vsphere/pkg/session"
4849 vcsimv1 "sigs.k8s.io/cluster-api-provider-vsphere/test/infrastructure/vcsim/api/v1alpha1"
@@ -361,6 +362,63 @@ func ReconcileDependencies(ctx context.Context, c client.Client, dependenciesCon
361362 return retryError
362363 }
363364
365+ // Create the supervisor service in kube-system for the servicediscovery controller to discover and set an IP address
366+ // for the headless service. When using kind as management cluster, the cluster-info configmap in kube-public contains a
367+ // hostname instead of an IP address which does not work for the servicediscovery controller.
368+ supervisorAPIServerVIPService := & corev1.Service {
369+ ObjectMeta : metav1.ObjectMeta {
370+ Name : vmwarev1 .SupervisorLoadBalancerSvcName ,
371+ Namespace : vmwarev1 .SupervisorLoadBalancerSvcNamespace ,
372+ },
373+ Spec : corev1.ServiceSpec {
374+ Type : corev1 .ServiceTypeLoadBalancer ,
375+ Ports : []corev1.ServicePort {
376+ {
377+ Name : "kube-apiserver" ,
378+ Protocol : corev1 .ProtocolTCP ,
379+ Port : 6443 ,
380+ },
381+ },
382+ },
383+ }
384+ _ = wait .PollUntilContextTimeout (ctx , 250 * time .Millisecond , 5 * time .Second , true , func (ctx context.Context ) (bool , error ) {
385+ retryError = nil
386+ if err := c .Get (ctx , client .ObjectKeyFromObject (supervisorAPIServerVIPService ), supervisorAPIServerVIPService ); err != nil {
387+ if ! apierrors .IsNotFound (err ) {
388+ retryError = errors .Wrapf (err , "failed to get vm-operator service %s" , klog .KObj (supervisorAPIServerVIPService ))
389+ return false , nil
390+ }
391+ if err := c .Create (ctx , supervisorAPIServerVIPService ); err != nil {
392+ retryError = errors .Wrapf (err , "failed to create vm-operator service %s" , klog .KObj (supervisorAPIServerVIPService ))
393+ return false , nil
394+ }
395+ log .Info ("Created vm-operator service" , "Service" , klog .KObj (supervisorAPIServerVIPService ))
396+ }
397+ return true , nil
398+ })
399+ if retryError != nil {
400+ return retryError
401+ }
402+ supervisorAPIServerVIPService .Status = corev1.ServiceStatus {
403+ LoadBalancer : corev1.LoadBalancerStatus {Ingress : []corev1.LoadBalancerIngress {
404+ // Note: this creates a unusable service. During test no application should try to reach out to this.
405+ // 192.0.2.2 is part of the link-local subnet 192.0.2.0/24 which is reserved for documentation and testing.
406+ {IP : "192.0.2.2" },
407+ }},
408+ }
409+ _ = wait .PollUntilContextTimeout (ctx , 250 * time .Millisecond , 5 * time .Second , true , func (ctx context.Context ) (bool , error ) {
410+ retryError = nil
411+ if err := c .Status ().Update (ctx , supervisorAPIServerVIPService ); err != nil {
412+ retryError = errors .Wrapf (err , "failed to update vm-operator service status %s" , klog .KObj (supervisorAPIServerVIPService ))
413+ return false , nil
414+ }
415+ log .Info ("Updated vm-operator service status" , "Service" , klog .KObj (supervisorAPIServerVIPService ))
416+ return true , nil
417+ })
418+ if retryError != nil {
419+ return retryError
420+ }
421+
364422 // Create VirtualMachineClass in K8s
365423 for _ , vmc := range config .Spec .VirtualMachineClasses {
366424 vmClass := & vmoprv1.VirtualMachineClass {
0 commit comments