github.com/openshift/installer@v1.4.17/pkg/infrastructure/azure/dns.go (about) 1 package azure 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" 8 "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" 9 "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns" 10 "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns" 11 "k8s.io/utils/ptr" 12 capz "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1" 13 "sigs.k8s.io/controller-runtime/pkg/client" 14 15 "github.com/openshift/installer/pkg/asset/manifests/capiutils" 16 "github.com/openshift/installer/pkg/infrastructure/clusterapi" 17 "github.com/openshift/installer/pkg/types" 18 ) 19 20 type recordListType string 21 22 const ( 23 cname recordListType = "Cname" 24 arecord recordListType = "ARecord" 25 aaaarecord recordListType = "AaaaRecord" 26 ) 27 28 type recordList struct { 29 Name string 30 RecordType armdns.RecordType 31 RecordSet armdns.RecordSet 32 } 33 34 type recordPrivateList struct { 35 Name string 36 RecordType armprivatedns.RecordType 37 RecordSet armprivatedns.RecordSet 38 } 39 40 // Create DNS entries for azure. 41 func createDNSEntries(ctx context.Context, in clusterapi.InfraReadyInput, extLBFQDN string, resourceGroup string) error { 42 private := in.InstallConfig.Config.Publish == types.InternalPublishingStrategy 43 baseDomainResourceGroup := in.InstallConfig.Config.Azure.BaseDomainResourceGroupName 44 zone := in.InstallConfig.Config.BaseDomain 45 privatezone := in.InstallConfig.Config.ClusterDomain() 46 apiExternalName := fmt.Sprintf("api.%s", in.InstallConfig.Config.ObjectMeta.Name) 47 48 if in.InstallConfig.Config.Azure.ResourceGroupName != "" { 49 resourceGroup = in.InstallConfig.Config.Azure.ResourceGroupName 50 } 51 azureTags := make(map[string]*string) 52 for k, v := range in.InstallConfig.Config.Azure.UserTags { 53 azureTags[k] = ptr.To(v) 54 } 55 azureCluster := &capz.AzureCluster{} 56 key := client.ObjectKey{ 57 Name: in.InfraID, 58 Namespace: capiutils.Namespace, 59 } 60 if err := in.Client.Get(ctx, key, azureCluster); err != nil && azureCluster != nil { 61 return fmt.Errorf("failed to get Azure cluster: %w", err) 62 } 63 64 if len(azureCluster.Spec.NetworkSpec.APIServerLB.FrontendIPs) == 0 { 65 return fmt.Errorf("failed to get Azure cluster LB frontend IPs") 66 } 67 ipIlb := azureCluster.Spec.NetworkSpec.APIServerLB.FrontendIPs[0].PrivateIPAddress 68 // useIPv6 := false 69 // for _, network := range in.InstallConfig.Config.Networking.ServiceNetwork { 70 // if network.IP.To4() == nil { 71 // useIPv6 = true 72 // } 73 // } 74 75 privateRecords := []recordPrivateList{} 76 ttl := int64(300) 77 recordType := arecord 78 // if useIPv6 { 79 // recordType = aaaarecord 80 // } 81 privateRecords = append(privateRecords, createPrivateRecordSet("api-int", azureTags, ttl, recordType, ipIlb, "")) 82 privateRecords = append(privateRecords, createPrivateRecordSet("api", azureTags, ttl, recordType, ipIlb, "")) 83 84 session, err := in.InstallConfig.Azure.Session() 85 if err != nil { 86 return fmt.Errorf("failed to create session: %w", err) 87 } 88 subscriptionID := session.Credentials.SubscriptionID 89 cloudConfiguration := session.CloudConfig 90 91 recordSetClient, err := armdns.NewRecordSetsClient(subscriptionID, session.TokenCreds, 92 &arm.ClientOptions{ 93 ClientOptions: policy.ClientOptions{ 94 Cloud: cloudConfiguration, 95 }, 96 }, 97 ) 98 if err != nil { 99 return fmt.Errorf("failed to create public record client: %w", err) 100 } 101 privateRecordSetClient, err := armprivatedns.NewRecordSetsClient(subscriptionID, session.TokenCreds, 102 &arm.ClientOptions{ 103 ClientOptions: policy.ClientOptions{ 104 Cloud: cloudConfiguration, 105 }, 106 }, 107 ) 108 if err != nil { 109 return fmt.Errorf("failed to create private record client: %w", err) 110 } 111 112 // Create the records for api and api-int in the private zone and api.<clustername> for public zone. 113 // CAPI currently creates a record called "apiserver" instead of "api" so creating "api" for the installer in the private zone. 114 if !private { 115 cnameRecordName := apiExternalName 116 // apiExternalNameV6 := fmt.Sprintf("v6-api.%s", infraID) 117 // if useIPv6 { 118 // cnameRecordName = apiExternalNameV6 119 // } 120 publicRecords := createRecordSet(cnameRecordName, azureTags, ttl, cname, "", extLBFQDN) 121 _, err = recordSetClient.CreateOrUpdate(ctx, baseDomainResourceGroup, zone, publicRecords.Name, publicRecords.RecordType, publicRecords.RecordSet, nil) 122 if err != nil { 123 return fmt.Errorf("failed to create public record set: %w", err) 124 } 125 } 126 127 for _, record := range privateRecords { 128 _, err = privateRecordSetClient.CreateOrUpdate(ctx, resourceGroup, privatezone, record.RecordType, record.Name, record.RecordSet, nil) 129 if err != nil { 130 return fmt.Errorf("failed to create private record set: %w", err) 131 } 132 } 133 134 return nil 135 } 136 137 func createPrivateRecordSet(lbType string, azureTags map[string]*string, ttl int64, rType recordListType, ipAddress string, recordName string) (record recordPrivateList) { 138 record = recordPrivateList{ 139 Name: lbType, 140 RecordSet: armprivatedns.RecordSet{ 141 Properties: &armprivatedns.RecordSetProperties{ 142 TTL: &ttl, 143 Metadata: azureTags, 144 }, 145 }, 146 } 147 148 switch rType { 149 case cname: 150 record.RecordType = armprivatedns.RecordTypeCNAME 151 record.RecordSet.Properties.CnameRecord = &armprivatedns.CnameRecord{ 152 Cname: &recordName, 153 } 154 case arecord: 155 record.RecordType = armprivatedns.RecordTypeA 156 record.RecordSet.Properties.ARecords = []*armprivatedns.ARecord{ 157 { 158 IPv4Address: &ipAddress, 159 }, 160 } 161 case aaaarecord: 162 record.RecordType = armprivatedns.RecordTypeAAAA 163 record.RecordSet.Properties.AaaaRecords = []*armprivatedns.AaaaRecord{ 164 { 165 IPv6Address: &ipAddress, 166 }, 167 } 168 } 169 return record 170 } 171 172 func createRecordSet(lbType string, azureTags map[string]*string, ttl int64, rType recordListType, ipAddress string, recordName string) (record recordList) { 173 record = recordList{ 174 Name: lbType, 175 RecordSet: armdns.RecordSet{ 176 Properties: &armdns.RecordSetProperties{ 177 TTL: &ttl, 178 Metadata: azureTags, 179 }, 180 }, 181 } 182 183 switch rType { 184 case cname: 185 record.RecordType = armdns.RecordTypeCNAME 186 record.RecordSet.Properties.CnameRecord = &armdns.CnameRecord{ 187 Cname: &recordName, 188 } 189 case arecord: 190 record.RecordType = armdns.RecordTypeA 191 record.RecordSet.Properties.ARecords = []*armdns.ARecord{ 192 { 193 IPv4Address: &ipAddress, 194 }, 195 } 196 case aaaarecord: 197 record.RecordType = armdns.RecordTypeAAAA 198 record.RecordSet.Properties.AaaaRecords = []*armdns.AaaaRecord{ 199 { 200 IPv6Address: &ipAddress, 201 }, 202 } 203 } 204 return record 205 }