@@ -42,6 +42,7 @@ type API interface {
4242 GetMachineTypeWithZones (ctx context.Context , project , region , machineType string ) (* compute.MachineType , sets.Set [string ], error )
4343 GetPublicDomains (ctx context.Context , project string ) ([]string , error )
4444 GetDNSZone (ctx context.Context , project , baseDomain string , isPublic bool ) (* dns.ManagedZone , error )
45+ GetDNSZoneFromParams (ctx context.Context , params gcptypes.DNSZoneParams ) (* dns.ManagedZone , error )
4546 GetDNSZoneByName (ctx context.Context , project , zoneName string ) (* dns.ManagedZone , error )
4647 GetSubnetworks (ctx context.Context , network , project , region string ) ([]* compute.Subnetwork , error )
4748 GetProjects (ctx context.Context ) (map [string ]string , error )
@@ -58,6 +59,7 @@ type API interface {
5859 GetProjectTags (ctx context.Context , projectID string ) (sets.Set [string ], error )
5960 GetNamespacedTagValue (ctx context.Context , tagNamespacedName string ) (* cloudresourcemanager.TagValue , error )
6061 GetKeyRing (ctx context.Context , kmsKeyRef * gcptypes.KMSKeyReference ) (* kmspb.KeyRing , error )
62+ UpdateDNSPrivateZoneLabels (ctx context.Context , baseDomain , project , zoneName string , labels map [string ]string ) error
6163}
6264
6365// Client makes calls to the GCP API.
@@ -243,41 +245,138 @@ func (c *Client) GetPublicDomains(ctx context.Context, project string) ([]string
243245 return publicZones , nil
244246}
245247
248+ func getDNSZoneByName (ctx context.Context , svc * dns.Service , project , zoneName string ) (* dns.ManagedZone , error ) {
249+ returnedZone , err := svc .ManagedZones .Get (project , zoneName ).Context (ctx ).Do ()
250+ if err != nil {
251+ return nil , fmt .Errorf ("failed to get DNS Zones: %w" , err )
252+ }
253+ return returnedZone , nil
254+ }
255+
246256// GetDNSZoneByName returns a DNS zone matching the `zoneName` if the DNS zone exists
247257// and can be seen (correct permissions for a private zone) in the project.
248258func (c * Client ) GetDNSZoneByName (ctx context.Context , project , zoneName string ) (* dns.ManagedZone , error ) {
249- ctx , cancel := context .WithTimeout (ctx , defaultTimeout )
250- defer cancel ()
251-
252259 svc , err := c .getDNSService (ctx )
253260 if err != nil {
254261 return nil , err
255262 }
256- returnedZone , err := svc .ManagedZones .Get (project , zoneName ).Context (ctx ).Do ()
263+ return getDNSZoneByName (ctx , svc , project , zoneName )
264+ }
265+
266+ // UpdateDNSPrivateZoneLabels will find a private DNS zone in the project with the name passed in. The labels
267+ // for the zone will be updated to include the provided labels. The labels that match will be overwritten
268+ // and all other labels will remain.
269+ func (c * Client ) UpdateDNSPrivateZoneLabels (ctx context.Context , baseDomain , project , zoneName string , labels map [string ]string ) error {
270+ params := gcptypes.DNSZoneParams {
271+ Project : project ,
272+ Name : zoneName ,
273+ BaseDomain : baseDomain ,
274+ IsPublic : false ,
275+ }
276+ zone , err := c .GetDNSZoneFromParams (ctx , params )
257277 if err != nil {
258- return nil , errors .Wrap (err , "failed to get DNS Zones" )
278+ return err
279+ }
280+ if zone == nil {
281+ return fmt .Errorf ("failed to find matching DNS zone for %s in project %s" , zoneName , project )
259282 }
260- return returnedZone , nil
261- }
262283
263- // GetDNSZone returns a DNS zone for a basedomain.
264- func (c * Client ) GetDNSZone (ctx context.Context , project , baseDomain string , isPublic bool ) (* dns.ManagedZone , error ) {
265- ctx , cancel := context .WithTimeout (ctx , defaultTimeout )
266- defer cancel ()
284+ if zone .Labels == nil {
285+ zone .Labels = make (map [string ]string )
286+ }
267287
268- svc , err := c .getDNSService (ctx )
288+ for key , value := range labels {
289+ zone .Labels [key ] = value
290+ }
291+
292+ if zone .Description == "" {
293+ // It is possible to create a managed zone without a description using the GCP web console.
294+ // If the description is missing the managed zone modification will fail.
295+ zone .Description = "Used by OpenShift Installer"
296+ }
297+
298+ dnsService , err := c .getDNSService (ctx )
269299 if err != nil {
270- return nil , err
300+ return fmt .Errorf ("failed to get dns service during dns managed zone update: %w" , err )
301+ }
302+
303+ return UpdateDNSManagedZone (ctx , dnsService , project , zoneName , zone )
304+ }
305+
306+ // UpdateDNSManagedZone will update a dns managed zone with the matching name and project. The new zone
307+ // information is contained in the zone parameter.
308+ func UpdateDNSManagedZone (ctx context.Context , svc * dns.Service , project , zoneName string , zone * dns.ManagedZone ) error {
309+ _ , err := svc .ManagedZones .Update (project , zoneName , zone ).Context (ctx ).Do ()
310+ if err != nil {
311+ return fmt .Errorf ("failed updating DNS Zone %s in project %s: %w" , zoneName , project , err )
271312 }
272- if ! strings .HasSuffix (baseDomain , "." ) {
273- baseDomain = fmt .Sprintf ("%s." , baseDomain )
313+ return nil
314+ }
315+
316+ func formatBaseDomain (domain string ) string {
317+ if ! strings .HasSuffix (domain , "." ) {
318+ domain = fmt .Sprintf ("%s." , domain )
274319 }
320+ return domain
321+ }
275322
276- // currently, only private and public are supported. All peering zones are private.
323+ func getZoneVisibility ( isPublic bool ) string {
277324 visibility := "private"
278325 if isPublic {
279326 visibility = "public"
280327 }
328+ return visibility
329+ }
330+
331+ // GetDNSZoneFromParams allows the user to enter parameters found in `DNSZoneParams` to find a
332+ // dns managed zone by name or by base domain.
333+ func GetDNSZoneFromParams (ctx context.Context , svc * dns.Service , params gcptypes.DNSZoneParams ) (* dns.ManagedZone , error ) {
334+ switch {
335+ case params .Name == "" && params .BaseDomain != "" :
336+ return getDNSZone (ctx , svc , params .Project , params .BaseDomain , params .IsPublic )
337+ case params .Name != "" :
338+ managedZone , err := getDNSZoneByName (ctx , svc , params .Project , params .Name )
339+ if params .BaseDomain == "" {
340+ return managedZone , err
341+ }
342+ if err != nil {
343+ if IsNotFound (err ) {
344+ return nil , nil
345+ }
346+ return nil , err
347+ }
348+ if managedZone == nil {
349+ return nil , nil
350+ }
351+ baseDomain := formatBaseDomain (params .BaseDomain )
352+ if ! strings .HasSuffix (managedZone .DnsName , baseDomain ) {
353+ return nil , fmt .Errorf ("failed to find matching DNS zone for %s with DNS name %s" , params .Name , params .BaseDomain )
354+ }
355+ visibility := getZoneVisibility (params .IsPublic )
356+ if managedZone .Visibility != visibility {
357+ return nil , fmt .Errorf ("failed to find matching DNS zone for %s with visibility %s" , params .Name , visibility )
358+ }
359+ return managedZone , nil
360+ }
361+ return nil , fmt .Errorf ("invalid dns zone parameters, please provide a base domain or name" )
362+ }
363+
364+ // GetDNSZoneFromParams allows the user to enter parameters found in DNSZoneParams. The user must enter at
365+ // least a base domain or a zone name to make a valid request. When both fields are populated extra validation
366+ // steps occur to ensure that the correct zone is found.
367+ func (c * Client ) GetDNSZoneFromParams (ctx context.Context , params gcptypes.DNSZoneParams ) (* dns.ManagedZone , error ) {
368+ svc , err := c .getDNSService (ctx )
369+ if err != nil {
370+ return nil , err
371+ }
372+ return GetDNSZoneFromParams (ctx , svc , params )
373+ }
374+
375+ func getDNSZone (ctx context.Context , svc * dns.Service , project , baseDomain string , isPublic bool ) (* dns.ManagedZone , error ) {
376+ baseDomain = formatBaseDomain (baseDomain )
377+
378+ // currently, only private and public are supported. All peering zones are private.
379+ visibility := getZoneVisibility (isPublic )
281380
282381 req := svc .ManagedZones .List (project ).DnsName (baseDomain ).Context (ctx )
283382 var res * dns.ManagedZone
@@ -290,7 +389,7 @@ func (c *Client) GetDNSZone(ctx context.Context, project, baseDomain string, isP
290389 }
291390 return nil
292391 }); err != nil {
293- return nil , errors . Wrap ( err , "failed to list DNS Zones" )
392+ return nil , fmt . Errorf ( "failed to list DNS Zones: %w" , err )
294393 }
295394 if res == nil {
296395 if isPublic {
@@ -305,6 +404,15 @@ func (c *Client) GetDNSZone(ctx context.Context, project, baseDomain string, isP
305404 return res , nil
306405}
307406
407+ // GetDNSZone returns a DNS zone for a basedomain.
408+ func (c * Client ) GetDNSZone (ctx context.Context , project , baseDomain string , isPublic bool ) (* dns.ManagedZone , error ) {
409+ svc , err := c .getDNSService (ctx )
410+ if err != nil {
411+ return nil , err
412+ }
413+ return getDNSZone (ctx , svc , project , baseDomain , isPublic )
414+ }
415+
308416// GetRecordSets returns all the records for a DNS zone.
309417func (c * Client ) GetRecordSets (ctx context.Context , project , zone string ) ([]* dns.ResourceRecordSet , error ) {
310418 ctx , cancel := context .WithTimeout (ctx , defaultTimeout )
0 commit comments