github.com/openshift/installer@v1.4.17/pkg/asset/installconfig/azure/dns.go (about) 1 package azure 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "time" 8 9 survey "github.com/AlecAivazis/survey/v2" 10 azdns "github.com/Azure/azure-sdk-for-go/profiles/2018-03-01/dns/mgmt/dns" 11 "github.com/Azure/go-autorest/autorest/to" 12 ) 13 14 // DNSConfig exposes functions to choose the DNS settings 15 type DNSConfig struct { 16 session *Session 17 } 18 19 // ZonesGetter fetches the DNS zones available for the installer 20 type ZonesGetter interface { 21 GetAllPublicZones() (map[string]string, error) 22 } 23 24 // ZonesClient wraps the azure ZonesClient internal 25 type ZonesClient struct { 26 azureClient azdns.ZonesClient 27 } 28 29 // RecordSetsClient wraps the azure RecordSetsClient internal 30 type RecordSetsClient struct { 31 azureClient azdns.RecordSetsClient 32 } 33 34 // Zone represents an Azure DNS Zone 35 type Zone struct { 36 ID string 37 Name string 38 } 39 40 func (z Zone) String() string { 41 return z.Name 42 } 43 44 // GetDNSZoneID returns the Azure DNS zone resourceID 45 // by interpolating the subscriptionID, the resource group and the zone name 46 func (config DNSConfig) GetDNSZoneID(rgName string, zoneName string) string { 47 return fmt.Sprintf( 48 "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/dnszones/%s", 49 config.session.Credentials.SubscriptionID, 50 rgName, 51 zoneName) 52 } 53 54 // GetPrivateDNSZoneID returns the Azure Private DNS zone resourceID 55 // by interpolating the subscriptionID, the resource group and the zone name 56 func (config DNSConfig) GetPrivateDNSZoneID(rgName string, zoneName string) string { 57 return fmt.Sprintf( 58 "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/privateDnsZones/%s", 59 config.session.Credentials.SubscriptionID, 60 rgName, 61 zoneName) 62 } 63 64 // GetDNSZone returns a DNS zone selected by survey 65 func (config DNSConfig) GetDNSZone() (*Zone, error) { 66 //call azure api using the session to retrieve available base domain 67 zonesClient := newZonesClient(config.session) 68 allZones, _ := zonesClient.GetAllPublicZones() 69 if len(allZones) == 0 { 70 return nil, errors.New("no public dns zone found in your subscription") 71 } 72 zoneNames := []string{} 73 for zoneName := range allZones { 74 zoneNames = append(zoneNames, zoneName) 75 } 76 77 var zoneName string 78 err := survey.Ask([]*survey.Question{ 79 { 80 Prompt: &survey.Select{ 81 Message: "Base Domain", 82 Help: "The base domain of the cluster. All DNS records will be sub-domains of this base and will also include the cluster name.\n\nIf you don't see you intended base-domain listed, create a new Azure DNS Zone and rerun the installer.", 83 Options: zoneNames, 84 }, 85 }, 86 }, &zoneName) 87 if err != nil { 88 return nil, fmt.Errorf("failed UserInput: %w", err) 89 } 90 91 return &Zone{ 92 ID: allZones[zoneName], 93 Name: zoneName, 94 }, nil 95 96 } 97 98 // GetDNSRecordSet gets a record set for the zone identified by publicZoneID 99 func (config DNSConfig) GetDNSRecordSet(rgName string, zoneName string, relativeRecordSetName string, recordType azdns.RecordType) (*azdns.RecordSet, error) { 100 recordsetsClient := newRecordSetsClient(config.session) 101 return recordsetsClient.GetRecordSet(rgName, zoneName, relativeRecordSetName, recordType) 102 } 103 104 // NewDNSConfig returns a new DNSConfig struct that helps configuring the DNS 105 // by querying your subscription and letting you choose 106 // which domain you wish to use for the cluster 107 func NewDNSConfig(ssn *Session) *DNSConfig { 108 return &DNSConfig{session: ssn} 109 } 110 111 func newZonesClient(session *Session) ZonesGetter { 112 azureClient := azdns.NewZonesClientWithBaseURI(session.Environment.ResourceManagerEndpoint, session.Credentials.SubscriptionID) 113 azureClient.Authorizer = session.Authorizer 114 return &ZonesClient{azureClient: azureClient} 115 } 116 117 func newRecordSetsClient(session *Session) *RecordSetsClient { 118 azureClient := azdns.NewRecordSetsClientWithBaseURI(session.Environment.ResourceManagerEndpoint, session.Credentials.SubscriptionID) 119 azureClient.Authorizer = session.Authorizer 120 return &RecordSetsClient{azureClient: azureClient} 121 } 122 123 // GetAllPublicZones get all public zones from the current subscription 124 func (client *ZonesClient) GetAllPublicZones() (map[string]string, error) { 125 ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second) 126 defer cancel() 127 allZones := map[string]string{} 128 for zonesPage, err := client.azureClient.List(ctx, to.Int32Ptr(100)); zonesPage.NotDone(); err = zonesPage.NextWithContext(ctx) { 129 if err != nil { 130 return nil, err 131 } 132 //TODO: filter out private zone and show only public zones. 133 //the property is present in the REST api response, but not mapped yet in the stable SDK (present in preview) 134 //https://github.com/Azure/azure-sdk-for-go/blob/07f918ba2d513bbc5b75bc4caac845e10f27449e/services/preview/dns/mgmt/2018-03-01-preview/dns/models.go#L857 135 for _, zone := range zonesPage.Values() { 136 allZones[to.String(zone.Name)] = to.String(zone.ID) 137 } 138 } 139 return allZones, nil 140 } 141 142 // GetRecordSet gets an Azure DNS recordset by zone, name and recordset type 143 func (client *RecordSetsClient) GetRecordSet(rgName string, zoneName string, relativeRecordSetName string, recordType azdns.RecordType) (*azdns.RecordSet, error) { 144 ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second) 145 defer cancel() 146 147 recordset, err := client.azureClient.Get(ctx, rgName, zoneName, relativeRecordSetName, recordType) 148 if err != nil { 149 return nil, err 150 } 151 152 return &recordset, nil 153 }