sigs.k8s.io/cluster-api-provider-azure@v1.14.3/azure/services/privateendpoints/spec.go (about) 1 /* 2 Copyright 2023 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package privateendpoints 18 19 import ( 20 "context" 21 "sort" 22 23 asonetworkv1 "github.com/Azure/azure-service-operator/v2/api/network/v1api20220701" 24 "github.com/Azure/azure-service-operator/v2/pkg/genruntime" 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 "k8s.io/utils/ptr" 27 infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1" 28 ) 29 30 // PrivateLinkServiceConnection defines the specification for a private link service connection associated with a private endpoint. 31 type PrivateLinkServiceConnection struct { 32 Name string 33 PrivateLinkServiceID string 34 GroupIDs []string 35 RequestMessage string 36 } 37 38 // PrivateEndpointSpec defines the specification for a private endpoint. 39 type PrivateEndpointSpec struct { 40 Name string 41 ResourceGroup string 42 Location string 43 CustomNetworkInterfaceName string 44 PrivateIPAddresses []string 45 SubnetID string 46 ApplicationSecurityGroups []string 47 ManualApproval bool 48 PrivateLinkServiceConnections []PrivateLinkServiceConnection 49 AdditionalTags infrav1.Tags 50 ClusterName string 51 } 52 53 // ResourceRef implements azure.ASOResourceSpecGetter. 54 func (s *PrivateEndpointSpec) ResourceRef() *asonetworkv1.PrivateEndpoint { 55 return &asonetworkv1.PrivateEndpoint{ 56 ObjectMeta: metav1.ObjectMeta{ 57 Name: s.Name, 58 }, 59 } 60 } 61 62 // Parameters implements azure.ASOResourceSpecGetter. 63 func (s *PrivateEndpointSpec) Parameters(ctx context.Context, existingPrivateEndpoint *asonetworkv1.PrivateEndpoint) (*asonetworkv1.PrivateEndpoint, error) { 64 privateEndpoint := &asonetworkv1.PrivateEndpoint{} 65 if existingPrivateEndpoint != nil { 66 privateEndpoint = existingPrivateEndpoint 67 } 68 69 if len(s.ApplicationSecurityGroups) > 0 { 70 applicationSecurityGroups := make([]asonetworkv1.ApplicationSecurityGroupSpec_PrivateEndpoint_SubResourceEmbedded, 0, len(s.ApplicationSecurityGroups)) 71 for _, applicationSecurityGroup := range s.ApplicationSecurityGroups { 72 applicationSecurityGroups = append(applicationSecurityGroups, asonetworkv1.ApplicationSecurityGroupSpec_PrivateEndpoint_SubResourceEmbedded{ 73 Reference: &genruntime.ResourceReference{ 74 ARMID: applicationSecurityGroup, 75 }, 76 }) 77 } 78 // Sort the slices in order to get the same order of elements for both new and existing application Security Groups. 79 sort.SliceStable(applicationSecurityGroups, func(i, j int) bool { 80 return applicationSecurityGroups[i].Reference.ARMID < applicationSecurityGroups[j].Reference.ARMID 81 }) 82 privateEndpoint.Spec.ApplicationSecurityGroups = applicationSecurityGroups 83 } 84 85 privateEndpoint.Spec.AzureName = s.Name 86 privateEndpoint.Spec.CustomNetworkInterfaceName = ptr.To(s.CustomNetworkInterfaceName) 87 privateEndpoint.Spec.Location = ptr.To(s.Location) 88 89 if len(s.PrivateIPAddresses) > 0 { 90 privateIPAddresses := make([]asonetworkv1.PrivateEndpointIPConfiguration, 0, len(s.PrivateIPAddresses)) 91 for _, address := range s.PrivateIPAddresses { 92 ipConfig := asonetworkv1.PrivateEndpointIPConfiguration{PrivateIPAddress: ptr.To(address)} 93 privateIPAddresses = append(privateIPAddresses, ipConfig) 94 } 95 sort.SliceStable(privateIPAddresses, func(i, j int) bool { 96 return *privateIPAddresses[i].PrivateIPAddress < *privateIPAddresses[j].PrivateIPAddress 97 }) 98 privateEndpoint.Spec.IpConfigurations = privateIPAddresses 99 } 100 101 if len(s.PrivateLinkServiceConnections) > 0 { 102 privateLinkServiceConnections := make([]asonetworkv1.PrivateLinkServiceConnection, 0, len(s.PrivateLinkServiceConnections)) 103 for _, privateLinkServiceConnection := range s.PrivateLinkServiceConnections { 104 linkServiceConnection := asonetworkv1.PrivateLinkServiceConnection{ 105 Name: ptr.To(privateLinkServiceConnection.Name), 106 PrivateLinkServiceReference: &genruntime.ResourceReference{ 107 ARMID: privateLinkServiceConnection.PrivateLinkServiceID, 108 }, 109 } 110 111 if len(privateLinkServiceConnection.GroupIDs) > 0 { 112 linkServiceConnection.GroupIds = privateLinkServiceConnection.GroupIDs 113 } 114 115 if privateLinkServiceConnection.RequestMessage != "" { 116 linkServiceConnection.RequestMessage = ptr.To(privateLinkServiceConnection.RequestMessage) 117 } 118 privateLinkServiceConnections = append(privateLinkServiceConnections, linkServiceConnection) 119 } 120 sort.SliceStable(privateLinkServiceConnections, func(i, j int) bool { 121 return *privateLinkServiceConnections[i].Name < *privateLinkServiceConnections[j].Name 122 }) 123 124 if s.ManualApproval { 125 privateEndpoint.Spec.ManualPrivateLinkServiceConnections = privateLinkServiceConnections 126 } else { 127 privateEndpoint.Spec.PrivateLinkServiceConnections = privateLinkServiceConnections 128 } 129 } 130 131 privateEndpoint.Spec.Owner = &genruntime.KnownResourceReference{ 132 Name: s.ResourceGroup, 133 } 134 135 privateEndpoint.Spec.Subnet = &asonetworkv1.Subnet_PrivateEndpoint_SubResourceEmbedded{ 136 Reference: &genruntime.ResourceReference{ 137 ARMID: s.SubnetID, 138 }, 139 } 140 141 privateEndpoint.Spec.Tags = infrav1.Build(infrav1.BuildParams{ 142 ClusterName: s.ClusterName, 143 Lifecycle: infrav1.ResourceLifecycleOwned, 144 Name: ptr.To(s.Name), 145 Additional: s.AdditionalTags, 146 }) 147 148 return privateEndpoint, nil 149 } 150 151 // WasManaged implements azure.ASOResourceSpecGetter. 152 // It always returns true since CAPZ doesn't support BYO private endpoints. 153 func (s *PrivateEndpointSpec) WasManaged(privateEndpoint *asonetworkv1.PrivateEndpoint) bool { 154 return true 155 }