diff --git a/api/v1alpha3/azurecluster_conversion.go b/api/v1alpha3/azurecluster_conversion.go index bfbb4d1c7a6..b646bd9ffb0 100644 --- a/api/v1alpha3/azurecluster_conversion.go +++ b/api/v1alpha3/azurecluster_conversion.go @@ -75,6 +75,15 @@ func (src *AzureCluster) ConvertTo(dstRaw conversion.Hub) error { dst.Spec.NetworkSpec.APIServerLB.FrontendIPsCount = restored.Spec.NetworkSpec.APIServerLB.FrontendIPsCount dst.Spec.NetworkSpec.APIServerLB.IdleTimeoutInMinutes = restored.Spec.NetworkSpec.APIServerLB.IdleTimeoutInMinutes + + for _, restoredFrontendIP := range restored.Spec.NetworkSpec.APIServerLB.FrontendIPs { + for i, dstFrontendIP := range dst.Spec.NetworkSpec.APIServerLB.FrontendIPs { + if restoredFrontendIP.Name == dstFrontendIP.Name && restoredFrontendIP.PublicIP != nil { + dst.Spec.NetworkSpec.APIServerLB.FrontendIPs[i].PublicIP.IPTags = restoredFrontendIP.PublicIP.IPTags + } + } + } + dst.Spec.CloudProviderConfigOverrides = restored.Spec.CloudProviderConfigOverrides dst.Spec.BastionSpec = restored.Spec.BastionSpec @@ -407,3 +416,8 @@ func Convert_v1beta1_FrontendIP_To_v1alpha3_FrontendIP(in *infrav1beta1.Frontend return nil } + +// Convert_v1beta1_PublicIPSpec_To_v1alpha3_PublicIPSpec is an autogenerated conversion function. +func Convert_v1beta1_PublicIPSpec_To_v1alpha3_PublicIPSpec(in *infrav1beta1.PublicIPSpec, out *PublicIPSpec, s apiconversion.Scope) error { + return autoConvert_v1beta1_PublicIPSpec_To_v1alpha3_PublicIPSpec(in, out, s) +} diff --git a/api/v1alpha3/zz_generated.conversion.go b/api/v1alpha3/zz_generated.conversion.go index 7d1b0e804f3..2729b8fb026 100644 --- a/api/v1alpha3/zz_generated.conversion.go +++ b/api/v1alpha3/zz_generated.conversion.go @@ -211,11 +211,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.PublicIPSpec)(nil), (*PublicIPSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_PublicIPSpec_To_v1alpha3_PublicIPSpec(a.(*v1beta1.PublicIPSpec), b.(*PublicIPSpec), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*RouteTable)(nil), (*v1beta1.RouteTable)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha3_RouteTable_To_v1beta1_RouteTable(a.(*RouteTable), b.(*v1beta1.RouteTable), scope) }); err != nil { @@ -411,6 +406,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*v1beta1.PublicIPSpec)(nil), (*PublicIPSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_PublicIPSpec_To_v1alpha3_PublicIPSpec(a.(*v1beta1.PublicIPSpec), b.(*PublicIPSpec), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*v1beta1.SecurityGroup)(nil), (*SecurityGroup)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_SecurityGroup_To_v1alpha3_SecurityGroup(a.(*v1beta1.SecurityGroup), b.(*SecurityGroup), scope) }); err != nil { @@ -1221,13 +1221,29 @@ func Convert_v1beta1_DiskEncryptionSetParameters_To_v1alpha3_DiskEncryptionSetPa func autoConvert_v1alpha3_FrontendIP_To_v1beta1_FrontendIP(in *FrontendIP, out *v1beta1.FrontendIP, s conversion.Scope) error { out.Name = in.Name // WARNING: in.PrivateIPAddress requires manual conversion: does not exist in peer-type - out.PublicIP = (*v1beta1.PublicIPSpec)(unsafe.Pointer(in.PublicIP)) + if in.PublicIP != nil { + in, out := &in.PublicIP, &out.PublicIP + *out = new(v1beta1.PublicIPSpec) + if err := Convert_v1alpha3_PublicIPSpec_To_v1beta1_PublicIPSpec(*in, *out, s); err != nil { + return err + } + } else { + out.PublicIP = nil + } return nil } func autoConvert_v1beta1_FrontendIP_To_v1alpha3_FrontendIP(in *v1beta1.FrontendIP, out *FrontendIP, s conversion.Scope) error { out.Name = in.Name - out.PublicIP = (*PublicIPSpec)(unsafe.Pointer(in.PublicIP)) + if in.PublicIP != nil { + in, out := &in.PublicIP, &out.PublicIP + *out = new(PublicIPSpec) + if err := Convert_v1beta1_PublicIPSpec_To_v1alpha3_PublicIPSpec(*in, *out, s); err != nil { + return err + } + } else { + out.PublicIP = nil + } // WARNING: in.FrontendIPClass requires manual conversion: does not exist in peer-type return nil } @@ -1398,14 +1414,10 @@ func Convert_v1alpha3_PublicIPSpec_To_v1beta1_PublicIPSpec(in *PublicIPSpec, out func autoConvert_v1beta1_PublicIPSpec_To_v1alpha3_PublicIPSpec(in *v1beta1.PublicIPSpec, out *PublicIPSpec, s conversion.Scope) error { out.Name = in.Name out.DNSName = in.DNSName + // WARNING: in.IPTags requires manual conversion: does not exist in peer-type return nil } -// Convert_v1beta1_PublicIPSpec_To_v1alpha3_PublicIPSpec is an autogenerated conversion function. -func Convert_v1beta1_PublicIPSpec_To_v1alpha3_PublicIPSpec(in *v1beta1.PublicIPSpec, out *PublicIPSpec, s conversion.Scope) error { - return autoConvert_v1beta1_PublicIPSpec_To_v1alpha3_PublicIPSpec(in, out, s) -} - func autoConvert_v1alpha3_RouteTable_To_v1beta1_RouteTable(in *RouteTable, out *v1beta1.RouteTable, s conversion.Scope) error { out.ID = in.ID out.Name = in.Name diff --git a/api/v1alpha4/azurecluster_conversion.go b/api/v1alpha4/azurecluster_conversion.go index 67ba3aef17a..b62fdcd8aeb 100644 --- a/api/v1alpha4/azurecluster_conversion.go +++ b/api/v1alpha4/azurecluster_conversion.go @@ -42,6 +42,54 @@ func (src *AzureCluster) ConvertTo(dstRaw conversion.Hub) error { // Restore list of virtual network peerings dst.Spec.NetworkSpec.Vnet.Peerings = restored.Spec.NetworkSpec.Vnet.Peerings + // Restore API Server LB IP tags. + for _, restoredFrontendIP := range restored.Spec.NetworkSpec.APIServerLB.FrontendIPs { + for i, dstFrontendIP := range dst.Spec.NetworkSpec.APIServerLB.FrontendIPs { + if restoredFrontendIP.Name == dstFrontendIP.Name && restoredFrontendIP.PublicIP != nil { + dst.Spec.NetworkSpec.APIServerLB.FrontendIPs[i].PublicIP.IPTags = restoredFrontendIP.PublicIP.IPTags + } + } + } + + // Restore outbound LB IP tags. + if restored.Spec.NetworkSpec.ControlPlaneOutboundLB != nil { + for _, restoredFrontendIP := range restored.Spec.NetworkSpec.ControlPlaneOutboundLB.FrontendIPs { + for i, dstFrontendIP := range dst.Spec.NetworkSpec.ControlPlaneOutboundLB.FrontendIPs { + if restoredFrontendIP.Name == dstFrontendIP.Name && restoredFrontendIP.PublicIP != nil { + dst.Spec.NetworkSpec.ControlPlaneOutboundLB.FrontendIPs[i].PublicIP.IPTags = restoredFrontendIP.PublicIP.IPTags + } + } + } + } + if restored.Spec.NetworkSpec.NodeOutboundLB != nil { + for _, restoredFrontendIP := range restored.Spec.NetworkSpec.NodeOutboundLB.FrontendIPs { + for i, dstFrontendIP := range dst.Spec.NetworkSpec.NodeOutboundLB.FrontendIPs { + if restoredFrontendIP.Name == dstFrontendIP.Name && restoredFrontendIP.PublicIP != nil { + dst.Spec.NetworkSpec.NodeOutboundLB.FrontendIPs[i].PublicIP.IPTags = restoredFrontendIP.PublicIP.IPTags + } + } + } + } + + // Restore NAT Gateway IP tags. + for _, restoredSubnet := range restored.Spec.NetworkSpec.Subnets { + for i, dstSubnet := range dst.Spec.NetworkSpec.Subnets { + if dstSubnet.Name == restoredSubnet.Name { + dst.Spec.NetworkSpec.Subnets[i].NatGateway.NatGatewayIP.IPTags = restoredSubnet.NatGateway.NatGatewayIP.IPTags + } + } + } + + // Restore Azure Bastion IP tags. + if restored.Spec.BastionSpec.AzureBastion != nil && dst.Spec.BastionSpec.AzureBastion != nil { + if restored.Spec.BastionSpec.AzureBastion.PublicIP.Name == dst.Spec.BastionSpec.AzureBastion.PublicIP.Name { + dst.Spec.BastionSpec.AzureBastion.PublicIP.IPTags = restored.Spec.BastionSpec.AzureBastion.PublicIP.IPTags + } + if restored.Spec.BastionSpec.AzureBastion.Subnet.NatGateway.NatGatewayIP.Name == dst.Spec.BastionSpec.AzureBastion.Subnet.NatGateway.NatGatewayIP.Name { + dst.Spec.BastionSpec.AzureBastion.Subnet.NatGateway.NatGatewayIP.IPTags = restored.Spec.BastionSpec.AzureBastion.Subnet.NatGateway.NatGatewayIP.IPTags + } + } + return nil } @@ -299,3 +347,8 @@ func Convert_v1beta1_NatGateway_To_v1alpha4_NatGateway(in *infrav1beta1.NatGatew out.Name = in.Name return nil } + +// Convert_v1beta1_PublicIPSpec_To_v1alpha4_PublicIPSpec is an autogenerated conversion function. +func Convert_v1beta1_PublicIPSpec_To_v1alpha4_PublicIPSpec(in *infrav1beta1.PublicIPSpec, out *PublicIPSpec, s apiconversion.Scope) error { + return autoConvert_v1beta1_PublicIPSpec_To_v1alpha4_PublicIPSpec(in, out, s) +} diff --git a/api/v1alpha4/zz_generated.conversion.go b/api/v1alpha4/zz_generated.conversion.go index 9ad545f810b..2ad696fda0b 100644 --- a/api/v1alpha4/zz_generated.conversion.go +++ b/api/v1alpha4/zz_generated.conversion.go @@ -332,11 +332,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.PublicIPSpec)(nil), (*PublicIPSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_PublicIPSpec_To_v1alpha4_PublicIPSpec(a.(*v1beta1.PublicIPSpec), b.(*PublicIPSpec), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*RateLimitConfig)(nil), (*v1beta1.RateLimitConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha4_RateLimitConfig_To_v1beta1_RateLimitConfig(a.(*RateLimitConfig), b.(*v1beta1.RateLimitConfig), scope) }); err != nil { @@ -497,6 +492,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*v1beta1.PublicIPSpec)(nil), (*PublicIPSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_PublicIPSpec_To_v1alpha4_PublicIPSpec(a.(*v1beta1.PublicIPSpec), b.(*PublicIPSpec), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*v1beta1.SecurityGroup)(nil), (*SecurityGroup)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_SecurityGroup_To_v1alpha4_SecurityGroup(a.(*v1beta1.SecurityGroup), b.(*SecurityGroup), scope) }); err != nil { @@ -1461,13 +1461,29 @@ func Convert_v1beta1_DiskEncryptionSetParameters_To_v1alpha4_DiskEncryptionSetPa func autoConvert_v1alpha4_FrontendIP_To_v1beta1_FrontendIP(in *FrontendIP, out *v1beta1.FrontendIP, s conversion.Scope) error { out.Name = in.Name // WARNING: in.PrivateIPAddress requires manual conversion: does not exist in peer-type - out.PublicIP = (*v1beta1.PublicIPSpec)(unsafe.Pointer(in.PublicIP)) + if in.PublicIP != nil { + in, out := &in.PublicIP, &out.PublicIP + *out = new(v1beta1.PublicIPSpec) + if err := Convert_v1alpha4_PublicIPSpec_To_v1beta1_PublicIPSpec(*in, *out, s); err != nil { + return err + } + } else { + out.PublicIP = nil + } return nil } func autoConvert_v1beta1_FrontendIP_To_v1alpha4_FrontendIP(in *v1beta1.FrontendIP, out *FrontendIP, s conversion.Scope) error { out.Name = in.Name - out.PublicIP = (*PublicIPSpec)(unsafe.Pointer(in.PublicIP)) + if in.PublicIP != nil { + in, out := &in.PublicIP, &out.PublicIP + *out = new(PublicIPSpec) + if err := Convert_v1beta1_PublicIPSpec_To_v1alpha4_PublicIPSpec(*in, *out, s); err != nil { + return err + } + } else { + out.PublicIP = nil + } // WARNING: in.FrontendIPClass requires manual conversion: does not exist in peer-type return nil } @@ -1738,14 +1754,10 @@ func Convert_v1alpha4_PublicIPSpec_To_v1beta1_PublicIPSpec(in *PublicIPSpec, out func autoConvert_v1beta1_PublicIPSpec_To_v1alpha4_PublicIPSpec(in *v1beta1.PublicIPSpec, out *PublicIPSpec, s conversion.Scope) error { out.Name = in.Name out.DNSName = in.DNSName + // WARNING: in.IPTags requires manual conversion: does not exist in peer-type return nil } -// Convert_v1beta1_PublicIPSpec_To_v1alpha4_PublicIPSpec is an autogenerated conversion function. -func Convert_v1beta1_PublicIPSpec_To_v1alpha4_PublicIPSpec(in *v1beta1.PublicIPSpec, out *PublicIPSpec, s conversion.Scope) error { - return autoConvert_v1beta1_PublicIPSpec_To_v1alpha4_PublicIPSpec(in, out, s) -} - func autoConvert_v1alpha4_RateLimitConfig_To_v1beta1_RateLimitConfig(in *RateLimitConfig, out *v1beta1.RateLimitConfig, s conversion.Scope) error { out.CloudProviderRateLimit = in.CloudProviderRateLimit out.CloudProviderRateLimitQPS = (*resource.Quantity)(unsafe.Pointer(in.CloudProviderRateLimitQPS)) diff --git a/api/v1beta1/azurecluster_validation.go b/api/v1beta1/azurecluster_validation.go index e6e5a5254f5..6ccc737e097 100644 --- a/api/v1beta1/azurecluster_validation.go +++ b/api/v1beta1/azurecluster_validation.go @@ -391,7 +391,7 @@ func validateNodeOutboundLB(lb *LoadBalancerSpec, old *LoadBalancerSpec, apiserv if len(old.FrontendIPs) == len(lb.FrontendIPs) { for i, frontEndIP := range lb.FrontendIPs { oldFrontendIP := old.FrontendIPs[i] - if oldFrontendIP.Name != frontEndIP.Name || *oldFrontendIP.PublicIP != *frontEndIP.PublicIP { + if oldFrontendIP.Name != frontEndIP.Name || !reflect.DeepEqual(*oldFrontendIP.PublicIP, *frontEndIP.PublicIP) { allErrs = append(allErrs, field.Forbidden(fldPath.Child("frontendIPs").Index(i), "Node outbound load balancer FrontendIPs cannot be modified after AzureCluster creation.")) } diff --git a/api/v1beta1/types.go b/api/v1beta1/types.go index 15f906a44a9..2693ad8136b 100644 --- a/api/v1beta1/types.go +++ b/api/v1beta1/types.go @@ -280,6 +280,16 @@ type PublicIPSpec struct { Name string `json:"name"` // +optional DNSName string `json:"dnsName,omitempty"` + // +optional + IPTags []IPTag `json:"ipTags,omitempty"` +} + +// IPTag contains the IpTag associated with the object. +type IPTag struct { + // Type specifies the IP tag type. Example: FirstPartyUsage. + Type string `json:"type"` + // Tag specifies the value of the IP tag associated with the public IP. Example: SQL. + Tag string `json:"tag"` } // VMState describes the state of an Azure virtual machine. diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 9dfb74a0672..3af8ce4867a 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -93,7 +93,7 @@ func (in *AllowedNamespaces) DeepCopy() *AllowedNamespaces { func (in *AzureBastion) DeepCopyInto(out *AzureBastion) { *out = *in in.Subnet.DeepCopyInto(&out.Subnet) - out.PublicIP = in.PublicIP + in.PublicIP.DeepCopyInto(&out.PublicIP) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureBastion. @@ -1000,7 +1000,7 @@ func (in *FrontendIP) DeepCopyInto(out *FrontendIP) { if in.PublicIP != nil { in, out := &in.PublicIP, &out.PublicIP *out = new(PublicIPSpec) - **out = **in + (*in).DeepCopyInto(*out) } out.FrontendIPClass = in.FrontendIPClass } @@ -1064,6 +1064,21 @@ func (in Futures) DeepCopy() Futures { return *out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IPTag) DeepCopyInto(out *IPTag) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPTag. +func (in *IPTag) DeepCopy() *IPTag { + if in == nil { + return nil + } + out := new(IPTag) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Image) DeepCopyInto(out *Image) { *out = *in @@ -1185,7 +1200,7 @@ func (in *ManagedDiskParameters) DeepCopy() *ManagedDiskParameters { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NatGateway) DeepCopyInto(out *NatGateway) { *out = *in - out.NatGatewayIP = in.NatGatewayIP + in.NatGatewayIP.DeepCopyInto(&out.NatGatewayIP) out.NatGatewayClassSpec = in.NatGatewayClassSpec } @@ -1332,6 +1347,11 @@ func (in *OSDisk) DeepCopy() *OSDisk { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PublicIPSpec) DeepCopyInto(out *PublicIPSpec) { *out = *in + if in.IPTags != nil { + in, out := &in.IPTags, &out.IPTags + *out = make([]IPTag, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PublicIPSpec. @@ -1566,7 +1586,7 @@ func (in *SubnetSpec) DeepCopyInto(out *SubnetSpec) { *out = *in in.SecurityGroup.DeepCopyInto(&out.SecurityGroup) out.RouteTable = in.RouteTable - out.NatGateway = in.NatGateway + in.NatGateway.DeepCopyInto(&out.NatGateway) in.SubnetClassSpec.DeepCopyInto(&out.SubnetClassSpec) } diff --git a/azure/converters/publicips.go b/azure/converters/publicips.go new file mode 100644 index 00000000000..bb7daad1074 --- /dev/null +++ b/azure/converters/publicips.go @@ -0,0 +1,38 @@ +/* +Copyright 2022 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 converters + +import ( + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network" + "github.com/Azure/go-autorest/autorest/to" + infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1" +) + +// IPTagsToSDK converts a CAPZ IP tag to an Azure SDK IP tag. +func IPTagsToSDK(ipTags []infrav1.IPTag) *[]network.IPTag { + if len(ipTags) == 0 { + return nil + } + skdIPTags := make([]network.IPTag, len(ipTags)) + for i, ipTag := range ipTags { + skdIPTags[i] = network.IPTag{ + IPTagType: to.StringPtr(ipTag.Type), + Tag: to.StringPtr(ipTag.Tag), + } + } + return &skdIPTags +} diff --git a/azure/converters/publicips_test.go b/azure/converters/publicips_test.go new file mode 100644 index 00000000000..4479ce5bbca --- /dev/null +++ b/azure/converters/publicips_test.go @@ -0,0 +1,70 @@ +/* +Copyright 2022 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 converters + +import ( + "reflect" + "testing" + + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network" + "github.com/Azure/go-autorest/autorest/to" + infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1" +) + +func TestIPTagsToSDK(t *testing.T) { + tests := []struct { + name string + ipTags []infrav1.IPTag + want *[]network.IPTag + }{ + { + name: "empty", + ipTags: []infrav1.IPTag{}, + want: nil, + }, + { + name: "list of tags", + ipTags: []infrav1.IPTag{ + { + Type: "tag", + Tag: "value", + }, + { + Type: "internal", + Tag: "foo", + }, + }, + want: &[]network.IPTag{ + { + IPTagType: to.StringPtr("tag"), + Tag: to.StringPtr("value"), + }, + { + IPTagType: to.StringPtr("internal"), + Tag: to.StringPtr("foo"), + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := IPTagsToSDK(tt.ipTags); !reflect.DeepEqual(got, tt.want) { + t.Errorf("IPTagsToSDK() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/azure/scope/cluster.go b/azure/scope/cluster.go index 882d148bae9..6282b0be191 100644 --- a/azure/scope/cluster.go +++ b/azure/scope/cluster.go @@ -143,6 +143,7 @@ func (s *ClusterScope) PublicIPSpecs() []azure.ResourceSpecGetter { Location: s.Location(), FailureDomains: s.FailureDomains(), AdditionalTags: s.AdditionalTags(), + IPTags: s.APIServerPublicIP().IPTags, }, } } @@ -167,6 +168,7 @@ func (s *ClusterScope) PublicIPSpecs() []azure.ResourceSpecGetter { Location: s.Location(), FailureDomains: s.FailureDomains(), AdditionalTags: s.AdditionalTags(), + IPTags: subnet.NatGateway.NatGatewayIP.IPTags, }) } publicIPSpecs = append(publicIPSpecs, nodeNatGatewayIPSpecs...) @@ -183,6 +185,7 @@ func (s *ClusterScope) PublicIPSpecs() []azure.ResourceSpecGetter { Location: s.Location(), FailureDomains: s.FailureDomains(), AdditionalTags: s.AdditionalTags(), + IPTags: azureBastion.PublicIP.IPTags, } publicIPSpecs = append(publicIPSpecs, azureBastionPublicIP) } diff --git a/azure/services/publicips/spec.go b/azure/services/publicips/spec.go index 6cc548095e5..b44f6083d83 100644 --- a/azure/services/publicips/spec.go +++ b/azure/services/publicips/spec.go @@ -36,6 +36,7 @@ type PublicIPSpec struct { Location string FailureDomains []string AdditionalTags infrav1.Tags + IPTags []infrav1.IPTag } // ResourceName returns the name of the public IP. @@ -91,6 +92,7 @@ func (s *PublicIPSpec) Parameters(existing interface{}) (params interface{}, err PublicIPAddressVersion: addressVersion, PublicIPAllocationMethod: network.IPAllocationMethodStatic, DNSSettings: dnsSettings, + IPTags: converters.IPTagsToSDK(s.IPTags), }, Zones: to.StringSlicePtr(s.FailureDomains), }, nil 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 c95d2fbcf14..703bebdad11 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_azureclusters.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_azureclusters.yaml @@ -1320,6 +1320,24 @@ spec: properties: dnsName: type: string + ipTags: + items: + description: IPTag contains the IpTag associated with + the object. + properties: + tag: + description: 'Tag specifies the value of the IP + tag associated with the public IP. Example: SQL.' + type: string + type: + description: 'Type specifies the IP tag type. Example: + FirstPartyUsage.' + type: string + required: + - tag + - type + type: object + type: array name: type: string required: @@ -1354,6 +1372,25 @@ spec: properties: dnsName: type: string + ipTags: + items: + description: IPTag contains the IpTag associated + with the object. + properties: + tag: + description: 'Tag specifies the value of + the IP tag associated with the public + IP. Example: SQL.' + type: string + type: + description: 'Type specifies the IP tag + type. Example: FirstPartyUsage.' + type: string + required: + - tag + - type + type: object + type: array name: type: string required: @@ -1656,6 +1693,25 @@ spec: properties: dnsName: type: string + ipTags: + items: + description: IPTag contains the IpTag associated + with the object. + properties: + tag: + description: 'Tag specifies the value of the + IP tag associated with the public IP. Example: + SQL.' + type: string + type: + description: 'Type specifies the IP tag type. + Example: FirstPartyUsage.' + type: string + required: + - tag + - type + type: object + type: array name: type: string required: @@ -1710,6 +1766,25 @@ spec: properties: dnsName: type: string + ipTags: + items: + description: IPTag contains the IpTag associated + with the object. + properties: + tag: + description: 'Tag specifies the value of the + IP tag associated with the public IP. Example: + SQL.' + type: string + type: + description: 'Type specifies the IP tag type. + Example: FirstPartyUsage.' + type: string + required: + - tag + - type + type: object + type: array name: type: string required: @@ -1762,6 +1837,25 @@ spec: properties: dnsName: type: string + ipTags: + items: + description: IPTag contains the IpTag associated + with the object. + properties: + tag: + description: 'Tag specifies the value of the + IP tag associated with the public IP. Example: + SQL.' + type: string + type: + description: 'Type specifies the IP tag type. + Example: FirstPartyUsage.' + type: string + required: + - tag + - type + type: object + type: array name: type: string required: @@ -1830,6 +1924,25 @@ spec: properties: dnsName: type: string + ipTags: + items: + description: IPTag contains the IpTag associated + with the object. + properties: + tag: + description: 'Tag specifies the value of the + IP tag associated with the public IP. Example: + SQL.' + type: string + type: + description: 'Type specifies the IP tag type. + Example: FirstPartyUsage.' + type: string + required: + - tag + - type + type: object + type: array name: type: string required: