From 55b91ba23c34e8205f77baeffb3b361f9ba05f76 Mon Sep 17 00:00:00 2001 From: David ML Brown Jr Date: Sun, 9 Jan 2022 12:10:37 -0800 Subject: [PATCH] Add Optional Override API Endpoint This adds an optional field to the Network API to override what is being sent back to Cluster API as the API Endpoint for K8S. This is more of a, Hope you know what you are doing! feature. Signed-off-by: David ML Brown Jr --- api/v1alpha3/azurecluster_conversion.go | 1 + api/v1alpha3/zz_generated.conversion.go | 1 + api/v1alpha4/azurecluster_conversion.go | 11 +++++++ api/v1alpha4/zz_generated.conversion.go | 31 +++++++------------ api/v1beta1/types.go | 5 +++ api/v1beta1/zz_generated.deepcopy.go | 5 +++ azure/scope/cluster.go | 8 +++++ azure/scope/cluster_test.go | 15 +++++++++ ...ucture.cluster.x-k8s.io_azureclusters.yaml | 15 +++++++++ 9 files changed, 72 insertions(+), 20 deletions(-) diff --git a/api/v1alpha3/azurecluster_conversion.go b/api/v1alpha3/azurecluster_conversion.go index 8f3f0bcc029..7c5f6441263 100644 --- a/api/v1alpha3/azurecluster_conversion.go +++ b/api/v1alpha3/azurecluster_conversion.go @@ -52,6 +52,7 @@ func (src *AzureCluster) ConvertTo(dstRaw conversion.Hub) error { // nolint dst.Spec.NetworkSpec.APIServerLB.FrontendIPsCount = restored.Spec.NetworkSpec.APIServerLB.FrontendIPsCount dst.Spec.NetworkSpec.APIServerLB.IdleTimeoutInMinutes = restored.Spec.NetworkSpec.APIServerLB.IdleTimeoutInMinutes + dst.Spec.NetworkSpec.OverrideAPIEndpoint = restored.Spec.NetworkSpec.OverrideAPIEndpoint dst.Spec.CloudProviderConfigOverrides = restored.Spec.CloudProviderConfigOverrides dst.Spec.BastionSpec = restored.Spec.BastionSpec diff --git a/api/v1alpha3/zz_generated.conversion.go b/api/v1alpha3/zz_generated.conversion.go index bf30caeb822..0cc72b4c9bd 100644 --- a/api/v1alpha3/zz_generated.conversion.go +++ b/api/v1alpha3/zz_generated.conversion.go @@ -1379,6 +1379,7 @@ func autoConvert_v1beta1_NetworkSpec_To_v1alpha3_NetworkSpec(in *v1beta1.Network if err := Convert_v1beta1_LoadBalancerSpec_To_v1alpha3_LoadBalancerSpec(&in.APIServerLB, &out.APIServerLB, s); err != nil { return err } + // WARNING: in.OverrideAPIEndpoint requires manual conversion: does not exist in peer-type // WARNING: in.NodeOutboundLB requires manual conversion: does not exist in peer-type // WARNING: in.ControlPlaneOutboundLB requires manual conversion: does not exist in peer-type // WARNING: in.PrivateDNSZoneName requires manual conversion: does not exist in peer-type diff --git a/api/v1alpha4/azurecluster_conversion.go b/api/v1alpha4/azurecluster_conversion.go index f97e4e1252f..c224063f941 100644 --- a/api/v1alpha4/azurecluster_conversion.go +++ b/api/v1alpha4/azurecluster_conversion.go @@ -39,6 +39,7 @@ func (src *AzureCluster) ConvertTo(dstRaw conversion.Hub) error { // nolint // Restore list of virtual network peerings dst.Spec.NetworkSpec.Vnet.Peerings = restored.Spec.NetworkSpec.Vnet.Peerings + dst.Spec.NetworkSpec.OverrideAPIEndpoint = restored.Spec.NetworkSpec.OverrideAPIEndpoint return nil } @@ -79,3 +80,13 @@ func Convert_v1beta1_VnetSpec_To_v1alpha4_VnetSpec(in *infrav1beta1.VnetSpec, ou func Convert_v1alpha4_VnetSpec_To_v1beta1_VnetSpec(in *VnetSpec, out *infrav1beta1.VnetSpec, s apiconversion.Scope) error { return autoConvert_v1alpha4_VnetSpec_To_v1beta1_VnetSpec(in, out, s) } + +// Convert_v1alpha4_NetworkSpec_To_v1beta1_NetworkSpec is an autogenerated conversion function. +func Convert_v1alpha4_NetworkSpec_To_v1beta1_NetworkSpec(in *NetworkSpec, out *infrav1beta1.NetworkSpec, s apiconversion.Scope) error { + return autoConvert_v1alpha4_NetworkSpec_To_v1beta1_NetworkSpec(in, out, s) +} + +// Convert_v1beta1_NetworkSpec_To_v1alpha4_NetworkSpec is an autogenerated conversion function. +func Convert_v1beta1_NetworkSpec_To_v1alpha4_NetworkSpec(in *infrav1beta1.NetworkSpec, out *NetworkSpec, s apiconversion.Scope) error { + return autoConvert_v1beta1_NetworkSpec_To_v1alpha4_NetworkSpec(in, out, s) +} diff --git a/api/v1alpha4/zz_generated.conversion.go b/api/v1alpha4/zz_generated.conversion.go index 4c64345c319..9e8376c1df9 100644 --- a/api/v1alpha4/zz_generated.conversion.go +++ b/api/v1alpha4/zz_generated.conversion.go @@ -377,16 +377,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*NetworkSpec)(nil), (*v1beta1.NetworkSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha4_NetworkSpec_To_v1beta1_NetworkSpec(a.(*NetworkSpec), b.(*v1beta1.NetworkSpec), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*v1beta1.NetworkSpec)(nil), (*NetworkSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_NetworkSpec_To_v1alpha4_NetworkSpec(a.(*v1beta1.NetworkSpec), b.(*NetworkSpec), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*OSDisk)(nil), (*v1beta1.OSDisk)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha4_OSDisk_To_v1beta1_OSDisk(a.(*OSDisk), b.(*v1beta1.OSDisk), scope) }); err != nil { @@ -497,6 +487,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*NetworkSpec)(nil), (*v1beta1.NetworkSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha4_NetworkSpec_To_v1beta1_NetworkSpec(a.(*NetworkSpec), b.(*v1beta1.NetworkSpec), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*VnetSpec)(nil), (*v1beta1.VnetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha4_VnetSpec_To_v1beta1_VnetSpec(a.(*VnetSpec), b.(*v1beta1.VnetSpec), scope) }); err != nil { @@ -507,6 +502,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*v1beta1.NetworkSpec)(nil), (*NetworkSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_NetworkSpec_To_v1alpha4_NetworkSpec(a.(*v1beta1.NetworkSpec), b.(*NetworkSpec), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*v1beta1.VnetSpec)(nil), (*VnetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_VnetSpec_To_v1alpha4_VnetSpec(a.(*v1beta1.VnetSpec), b.(*VnetSpec), scope) }); err != nil { @@ -1629,11 +1629,6 @@ func autoConvert_v1alpha4_NetworkSpec_To_v1beta1_NetworkSpec(in *NetworkSpec, ou return nil } -// Convert_v1alpha4_NetworkSpec_To_v1beta1_NetworkSpec is an autogenerated conversion function. -func Convert_v1alpha4_NetworkSpec_To_v1beta1_NetworkSpec(in *NetworkSpec, out *v1beta1.NetworkSpec, s conversion.Scope) error { - return autoConvert_v1alpha4_NetworkSpec_To_v1beta1_NetworkSpec(in, out, s) -} - func autoConvert_v1beta1_NetworkSpec_To_v1alpha4_NetworkSpec(in *v1beta1.NetworkSpec, out *NetworkSpec, s conversion.Scope) error { if err := Convert_v1beta1_VnetSpec_To_v1alpha4_VnetSpec(&in.Vnet, &out.Vnet, s); err != nil { return err @@ -1642,17 +1637,13 @@ func autoConvert_v1beta1_NetworkSpec_To_v1alpha4_NetworkSpec(in *v1beta1.Network if err := Convert_v1beta1_LoadBalancerSpec_To_v1alpha4_LoadBalancerSpec(&in.APIServerLB, &out.APIServerLB, s); err != nil { return err } + // WARNING: in.OverrideAPIEndpoint requires manual conversion: does not exist in peer-type out.NodeOutboundLB = (*LoadBalancerSpec)(unsafe.Pointer(in.NodeOutboundLB)) out.ControlPlaneOutboundLB = (*LoadBalancerSpec)(unsafe.Pointer(in.ControlPlaneOutboundLB)) out.PrivateDNSZoneName = in.PrivateDNSZoneName return nil } -// Convert_v1beta1_NetworkSpec_To_v1alpha4_NetworkSpec is an autogenerated conversion function. -func Convert_v1beta1_NetworkSpec_To_v1alpha4_NetworkSpec(in *v1beta1.NetworkSpec, out *NetworkSpec, s conversion.Scope) error { - return autoConvert_v1beta1_NetworkSpec_To_v1alpha4_NetworkSpec(in, out, s) -} - func autoConvert_v1alpha4_OSDisk_To_v1beta1_OSDisk(in *OSDisk, out *v1beta1.OSDisk, s conversion.Scope) error { out.OSType = in.OSType out.DiskSizeGB = (*int32)(unsafe.Pointer(in.DiskSizeGB)) diff --git a/api/v1beta1/types.go b/api/v1beta1/types.go index 833a581e871..d007a010e66 100644 --- a/api/v1beta1/types.go +++ b/api/v1beta1/types.go @@ -19,6 +19,7 @@ package v1beta1 import ( "github.com/pkg/errors" "k8s.io/apimachinery/pkg/api/resource" + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" ) const ( @@ -75,6 +76,10 @@ type NetworkSpec struct { // +optional APIServerLB LoadBalancerSpec `json:"apiServerLB,omitempty"` + // override API Endpoint passed back to Cluster API (hope you know what you are doing, good luck!) + // +optional + OverrideAPIEndpoint *clusterv1.APIEndpoint `json:"overrideAPIEndpoint,omitempty"` + // NodeOutboundLB is the configuration for the node outbound load balancer. // +optional NodeOutboundLB *LoadBalancerSpec `json:"nodeOutboundLB,omitempty"` diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 9d520e82d0c..8e43918e4e3 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -942,6 +942,11 @@ func (in *NetworkSpec) DeepCopyInto(out *NetworkSpec) { } } in.APIServerLB.DeepCopyInto(&out.APIServerLB) + if in.OverrideAPIEndpoint != nil { + in, out := &in.OverrideAPIEndpoint, &out.OverrideAPIEndpoint + *out = new(apiv1beta1.APIEndpoint) + **out = **in + } if in.NodeOutboundLB != nil { in, out := &in.NodeOutboundLB, &out.NodeOutboundLB *out = new(LoadBalancerSpec) diff --git a/azure/scope/cluster.go b/azure/scope/cluster.go index 89d1de14625..afc77c5cdcd 100644 --- a/azure/scope/cluster.go +++ b/azure/scope/cluster.go @@ -649,6 +649,10 @@ func (s *ClusterScope) AdditionalTags() infrav1.Tags { // APIServerPort returns the APIServerPort to use when creating the load balancer. func (s *ClusterScope) APIServerPort() int32 { + netSpec := s.AzureCluster.Spec.NetworkSpec + if netSpec.OverrideAPIEndpoint != nil { + return netSpec.OverrideAPIEndpoint.Port + } if s.Cluster.Spec.ClusterNetwork != nil && s.Cluster.Spec.ClusterNetwork.APIServerPort != nil { return *s.Cluster.Spec.ClusterNetwork.APIServerPort } @@ -657,6 +661,10 @@ func (s *ClusterScope) APIServerPort() int32 { // APIServerHost returns the hostname used to reach the API server. func (s *ClusterScope) APIServerHost() string { + netSpec := s.AzureCluster.Spec.NetworkSpec + if netSpec.OverrideAPIEndpoint != nil && len(netSpec.OverrideAPIEndpoint.Host) > 0 { + return netSpec.OverrideAPIEndpoint.Host + } if s.IsAPIServerPrivate() { return azure.GeneratePrivateFQDN(s.GetPrivateDNSZoneName()) } diff --git a/azure/scope/cluster_test.go b/azure/scope/cluster_test.go index 2f6dd41b429..b47ac18eada 100644 --- a/azure/scope/cluster_test.go +++ b/azure/scope/cluster_test.go @@ -96,6 +96,21 @@ func TestAPIServerHost(t *testing.T) { }, want: "apiserver.example.private", }, + { + name: "override host returned to cluster api.", + azureCluster: infrav1.AzureCluster{ + Spec: infrav1.AzureClusterSpec{ + SubscriptionID: fakeSubscriptionID, + NetworkSpec: infrav1.NetworkSpec{ + OverrideAPIEndpoint: &clusterv1.APIEndpoint{ + Host: "apiserver.example.private", + Port: 443, + }, + }, + }, + }, + want: "apiserver.example.private", + }, } for _, tc := range tests { diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_azureclusters.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_azureclusters.yaml index af957be38ea..492e82f09e7 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_azureclusters.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_azureclusters.yaml @@ -1788,6 +1788,21 @@ spec: description: LBType defines an Azure load balancer Type. type: string type: object + overrideAPIEndpoint: + description: override API Endpoint passed back to Cluster API + (hope you know what you are doing, good luck!) + properties: + host: + description: The hostname on which the API server is serving. + type: string + port: + description: The port on which the API server is serving. + format: int32 + type: integer + required: + - host + - port + type: object privateDNSZoneName: description: PrivateDNSZoneName defines the zone name for the Azure Private DNS.