@ -71,19 +71,19 @@ options:
- The type of resource record to add .
- The type of resource record to add .
required : true
required : true
choices : [ ' A ' , ' AAAA ' , ' CNAME ' , ' SRV ' , ' TXT ' , ' SOA ' , ' NS ' , ' MX ' , ' SPF ' , ' PTR ' ]
choices : [ ' A ' , ' AAAA ' , ' CNAME ' , ' SRV ' , ' TXT ' , ' SOA ' , ' NS ' , ' MX ' , ' SPF ' , ' PTR ' ]
values :
record_data :
description :
description :
- The values to use for the resource record .
- The record_data to use for the resource record .
- I ( values ) must be specified if I ( state ) is C ( present ) or
- I ( record_data ) must be specified if I ( state ) is C ( present ) or
I ( overwrite ) is C ( True ) , or the module will fail .
I ( overwrite ) is C ( True ) , or the module will fail .
- Valid values vary based on the record ' s I(type). In addition,
- Valid record_data vary based on the record ' s I(type). In addition,
resource records that contain a DNS domain name in the value
resource records that contain a DNS domain name in the value
field ( e . g . , CNAME , PTR , SRV , . etc ) MUST include a trailing dot
field ( e . g . , CNAME , PTR , SRV , . etc ) MUST include a trailing dot
in the value .
in the value .
- Individual string values for TXT records must be enclosed in
- Individual string record_data for TXT records must be enclosed in
double quotes .
double quotes .
- For resource records that have the same name but different
- For resource records that have the same name but different
values ( e . g . , multiple A records ) , they must be defined as
record_data ( e . g . , multiple A records ) , they must be defined as
multiple list entries in a single record .
multiple list entries in a single record .
required : false
required : false
aliases : [ ' value ' ]
aliases : [ ' value ' ]
@ -99,15 +99,15 @@ options:
or fail . The behavior of this option depends on I ( state ) .
or fail . The behavior of this option depends on I ( state ) .
- If I ( state ) is C ( present ) and I ( overwrite ) is C ( True ) , this
- If I ( state ) is C ( present ) and I ( overwrite ) is C ( True ) , this
module will replace an existing resource record of the same name
module will replace an existing resource record of the same name
with the provided I ( values ) . If I ( state ) is C ( present ) and
with the provided I ( record_data ) . If I ( state ) is C ( present ) and
I ( overwrite ) is C ( False ) , this module will fail if there is an
I ( overwrite ) is C ( False ) , this module will fail if there is an
existing resource record with the same name and type , but
existing resource record with the same name and type , but
different resource data .
different resource data .
- If I ( state ) is C ( absent ) and I ( overwrite ) is C ( True ) , this
- If I ( state ) is C ( absent ) and I ( overwrite ) is C ( True ) , this
module will remove the given resource record unconditionally .
module will remove the given resource record unconditionally .
If I ( state ) is C ( absent ) and I ( overwrite ) is C ( False ) , this
If I ( state ) is C ( absent ) and I ( overwrite ) is C ( False ) , this
module will fail if the provided values do not match exactly
module will fail if the provided record_data do not match exactly
with the existing resource record ' s values .
with the existing resource record ' s record_data .
required : false
required : false
choices : [ True , False ]
choices : [ True , False ]
default : False
default : False
@ -192,23 +192,23 @@ EXAMPLES = '''
record : ' api.example.com '
record : ' api.example.com '
zone_id : ' example-com '
zone_id : ' example-com '
type : A
type : A
values :
record_data :
- ' 1 0.1.2. 3'
- ' 1 92.0.2.2 3'
- ' 10.4.5.6 '
- ' 10.4.5.6 '
- ' 10.7.8.9 '
- ' 10.7.8.9 '
- ' 192.168.5.10 '
- ' 192.168.5.10 '
# Change the value of an existing record with multiple values .
# Change the value of an existing record with multiple record_data .
- gcdns_record :
- gcdns_record :
record : ' api.example.com '
record : ' api.example.com '
zone : ' example.com '
zone : ' example.com '
type : A
type : A
overwrite : true
overwrite : true
values : # WARNING: All values in a record will be replaced
record_data : # WARNING: All values in a record will be replaced
- ' 1 0.1.2. 3'
- ' 1 92.0.2.2 3'
- ' 1 0.5.5.7 ' # The changed record
- ' 1 92.0.2.42 ' # The changed record
- ' 1 0.7.8.9 '
- ' 1 98.51.100.5 '
- ' 192.168.5 .10'
- ' 203.0.113 .10'
# Safely remove a multi-line record.
# Safely remove a multi-line record.
- gcdns_record :
- gcdns_record :
@ -216,11 +216,11 @@ EXAMPLES = '''
zone_id : ' example-com '
zone_id : ' example-com '
state : absent
state : absent
type : A
type : A
values : # NOTE: All of the values must match exactly
record_data : # NOTE: All of the values must match exactly
- ' 1 0.1.2. 3'
- ' 1 92.0.2.2 3'
- ' 1 0.5.5.7 '
- ' 1 92.0.2.42 '
- ' 1 0.7.8.9 '
- ' 1 98.51.100.5 '
- ' 192.168.5 .10'
- ' 203.0.113 .10'
# Unconditionally remove a record.
# Unconditionally remove a record.
- gcdns_record :
- gcdns_record :
@ -250,7 +250,7 @@ EXAMPLES = '''
zone : ' example.com '
zone : ' example.com '
type : NS
type : NS
ttl : 21600
ttl : 21600
values :
record_data :
- ' ns-cloud-d1.googledomains.com. ' # Note the trailing dots on values
- ' ns-cloud-d1.googledomains.com. ' # Note the trailing dots on values
- ' ns-cloud-d2.googledomains.com. '
- ' ns-cloud-d2.googledomains.com. '
- ' ns-cloud-d3.googledomains.com. '
- ' ns-cloud-d3.googledomains.com. '
@ -261,7 +261,7 @@ EXAMPLES = '''
record : ' example.com '
record : ' example.com '
zone_id : ' example-com '
zone_id : ' example-com '
type : TXT
type : TXT
values :
record_data :
- ' " v=spf1 include:_spf.google.com -all " ' # A single-string TXT value
- ' " v=spf1 include:_spf.google.com -all " ' # A single-string TXT value
- ' " hello " " world " ' # A multi-string TXT value
- ' " hello " " world " ' # A multi-string TXT value
'''
'''
@ -292,7 +292,7 @@ type:
returned : success
returned : success
type : string
type : string
sample : A
sample : A
values :
record_data :
description : The resource record values
description : The resource record values
returned : success
returned : success
type : list
type : list
@ -365,8 +365,8 @@ def create_record(module, gcdns, zone, record):
record_name = module . params [ ' record ' ]
record_name = module . params [ ' record ' ]
record_type = module . params [ ' type ' ]
record_type = module . params [ ' type ' ]
ttl = module . params [ ' ttl ' ]
ttl = module . params [ ' ttl ' ]
values = module . params [ ' values ' ]
record_data = module . params [ ' record_data ' ]
data = dict ( ttl = ttl , rrdatas = values )
data = dict ( ttl = ttl , rrdatas = record_data )
# Google Cloud DNS wants the trailing dot on all DNS names.
# Google Cloud DNS wants the trailing dot on all DNS names.
if record_name [ - 1 ] != ' . ' :
if record_name [ - 1 ] != ' . ' :
@ -375,7 +375,7 @@ def create_record(module, gcdns, zone, record):
# If we found a record, we need to check if the values match.
# If we found a record, we need to check if the values match.
if record is not None :
if record is not None :
# If the record matches, we obviously don't have to change anything.
# If the record matches, we obviously don't have to change anything.
if _records_match ( record . data [ ' ttl ' ] , record . data [ ' rrdatas ' ] , ttl , values ) :
if _records_match ( record . data [ ' ttl ' ] , record . data [ ' rrdatas ' ] , ttl , record_data ) :
return False
return False
# The record doesn't match, so we need to check if we can overwrite it.
# The record doesn't match, so we need to check if we can overwrite it.
@ -397,7 +397,7 @@ def create_record(module, gcdns, zone, record):
# as its value).
# as its value).
module . fail_json (
module . fail_json (
msg = ' value is invalid for the given type: ' +
msg = ' value is invalid for the given type: ' +
" %s , got value: %s " % ( record_type , values ) ,
" %s , got value: %s " % ( record_type , record_data ) ,
changed = False
changed = False
)
)
@ -455,7 +455,7 @@ def remove_record(module, gcdns, record):
overwrite = module . boolean ( module . params [ ' overwrite ' ] )
overwrite = module . boolean ( module . params [ ' overwrite ' ] )
ttl = module . params [ ' ttl ' ]
ttl = module . params [ ' ttl ' ]
values = module . params [ ' values ' ]
record_data = module . params [ ' record_data ' ]
# If there is no record, we're obviously done.
# If there is no record, we're obviously done.
if record is None :
if record is None :
@ -464,11 +464,11 @@ def remove_record(module, gcdns, record):
# If there is an existing record, do our values match the values of the
# If there is an existing record, do our values match the values of the
# existing record?
# existing record?
if not overwrite :
if not overwrite :
if not _records_match ( record . data [ ' ttl ' ] , record . data [ ' rrdatas ' ] , ttl , values ) :
if not _records_match ( record . data [ ' ttl ' ] , record . data [ ' rrdatas ' ] , ttl , record_data ) :
module . fail_json (
module . fail_json (
msg = ' cannot delete due to non-matching ttl or values : ' +
msg = ' cannot delete due to non-matching ttl or record_data : ' +
" ttl: %d , values: %s " % ( ttl , values ) +
" ttl: %d , record_data: %s " % ( ttl , record_data ) +
" original ttl: %d , original values : %s " % ( record . data [ ' ttl ' ] , record . data [ ' rrdatas ' ] ) ,
" original ttl: %d , original record_data : %s " % ( record . data [ ' ttl ' ] , record . data [ ' rrdatas ' ] ) ,
changed = False
changed = False
)
)
@ -516,14 +516,14 @@ def _get_zone(gcdns, zone_name, zone_id):
return found_zone
return found_zone
def _records_match ( old_ttl , old_ values, new_ttl , new_values ) :
def _records_match ( old_ttl , old_ record_data, new_ttl , new_record_data ) :
""" Checks to see if original and new TTL and values match. """
""" Checks to see if original and new TTL and values match. """
matches = True
matches = True
if old_ttl != new_ttl :
if old_ttl != new_ttl :
matches = False
matches = False
if old_ values != new_values :
if old_ record_data != new_record_data :
matches = False
matches = False
return matches
return matches
@ -537,7 +537,7 @@ def _sanity_check(module):
record_type = module . params [ ' type ' ]
record_type = module . params [ ' type ' ]
state = module . params [ ' state ' ]
state = module . params [ ' state ' ]
ttl = module . params [ ' ttl ' ]
ttl = module . params [ ' ttl ' ]
values = module . params [ ' values ' ]
record_data = module . params [ ' record_data ' ]
# Apache libcloud needs to be installed and at least the minimum version.
# Apache libcloud needs to be installed and at least the minimum version.
if not HAS_LIBCLOUD :
if not HAS_LIBCLOUD :
@ -567,10 +567,10 @@ def _sanity_check(module):
module . fail_json ( msg = ' cannot update SOA records ' , changed = False )
module . fail_json ( msg = ' cannot update SOA records ' , changed = False )
# Some sanity checks depend on what value was supplied.
# Some sanity checks depend on what value was supplied.
if values is not None and ( state == ' present ' or not overwrite ) :
if record_data is not None and ( state == ' present ' or not overwrite ) :
# A records must contain valid IPv4 addresses.
# A records must contain valid IPv4 addresses.
if record_type == ' A ' :
if record_type == ' A ' :
for value in values :
for value in record_data :
try :
try :
socket . inet_aton ( value )
socket . inet_aton ( value )
except socket . error :
except socket . error :
@ -581,7 +581,7 @@ def _sanity_check(module):
# AAAA records must contain valid IPv6 addresses.
# AAAA records must contain valid IPv6 addresses.
if record_type == ' AAAA ' :
if record_type == ' AAAA ' :
for value in values :
for value in record_data :
try :
try :
socket . inet_pton ( socket . AF_INET6 , value )
socket . inet_pton ( socket . AF_INET6 , value )
except socket . error :
except socket . error :
@ -591,10 +591,10 @@ def _sanity_check(module):
)
)
# CNAME and SOA records can't have multiple values.
# CNAME and SOA records can't have multiple values.
if record_type in [ ' CNAME ' , ' SOA ' ] and len ( values ) > 1 :
if record_type in [ ' CNAME ' , ' SOA ' ] and len ( record_data ) > 1 :
module . fail_json (
module . fail_json (
msg = ' CNAME or SOA records cannot have more than one value, ' +
msg = ' CNAME or SOA records cannot have more than one value, ' +
" got: %s " % values ,
" got: %s " % record_data ,
changed = False
changed = False
)
)
@ -607,10 +607,10 @@ def _sanity_check(module):
# Values for txt records must begin and end with a double quote.
# Values for txt records must begin and end with a double quote.
if record_type == ' TXT ' :
if record_type == ' TXT ' :
for value in values :
for value in record_data :
if value [ 0 ] != ' " ' and value [ - 1 ] != ' " ' :
if value [ 0 ] != ' " ' and value [ - 1 ] != ' " ' :
module . fail_json (
module . fail_json (
msg = ' TXT values must be enclosed in double quotes, ' +
msg = ' TXT record_data must be enclosed in double quotes, ' +
' got: %s ' % value ,
' got: %s ' % value ,
changed = False
changed = False
)
)
@ -670,7 +670,7 @@ def main():
zone = dict ( type = ' str ' ) ,
zone = dict ( type = ' str ' ) ,
zone_id = dict ( type = ' str ' ) ,
zone_id = dict ( type = ' str ' ) ,
type = dict ( required = True , choices = SUPPORTED_RECORD_TYPES , type = ' str ' ) ,
type = dict ( required = True , choices = SUPPORTED_RECORD_TYPES , type = ' str ' ) ,
values = dict ( aliases = [ ' value ' ] , type = ' list ' ) ,
record_data = dict ( aliases = [ ' value ' ] , type = ' list ' ) ,
ttl = dict ( default = 300 , type = ' int ' ) ,
ttl = dict ( default = 300 , type = ' int ' ) ,
overwrite = dict ( default = False , type = ' bool ' ) ,
overwrite = dict ( default = False , type = ' bool ' ) ,
service_account_email = dict ( type = ' str ' ) ,
service_account_email = dict ( type = ' str ' ) ,
@ -679,8 +679,8 @@ def main():
project_id = dict ( type = ' str ' )
project_id = dict ( type = ' str ' )
) ,
) ,
required_if = [
required_if = [
( ' state ' , ' present ' , [ ' values ' ] ) ,
( ' state ' , ' present ' , [ ' record_data ' ] ) ,
( ' overwrite ' , False , [ ' values ' ] )
( ' overwrite ' , False , [ ' record_data ' ] )
] ,
] ,
required_one_of = [ [ ' zone ' , ' zone_id ' ] ] ,
required_one_of = [ [ ' zone ' , ' zone_id ' ] ] ,
supports_check_mode = True
supports_check_mode = True
@ -696,14 +696,14 @@ def main():
zone_id = module . params [ ' zone_id ' ]
zone_id = module . params [ ' zone_id ' ]
json_output = dict (
json_output = dict (
state = state ,
state = state ,
record = record_name ,
record = record_name ,
zone = zone_name ,
zone = zone_name ,
zone_id = zone_id ,
zone_id = zone_id ,
type = record_type ,
type = record_type ,
values = module . params [ ' values ' ] ,
record_data = module . params [ ' record_data ' ] ,
ttl = ttl ,
ttl = ttl ,
overwrite = module . boolean ( module . params [ ' overwrite ' ] )
overwrite = module . boolean ( module . params [ ' overwrite ' ] )
)
)
# Google Cloud DNS wants the trailing dot on all DNS names.
# Google Cloud DNS wants the trailing dot on all DNS names.
@ -755,20 +755,20 @@ def main():
diff [ ' before_header ' ] = ' <absent> '
diff [ ' before_header ' ] = ' <absent> '
else :
else :
diff [ ' before ' ] = dict (
diff [ ' before ' ] = dict (
record = record . data [ ' name ' ] ,
record = record . data [ ' name ' ] ,
type = record . data [ ' type ' ] ,
type = record . data [ ' type ' ] ,
values = record . data [ ' rrdatas ' ] ,
record_data = record . data [ ' rrdatas ' ] ,
ttl = record . data [ ' ttl ' ]
ttl = record . data [ ' ttl ' ]
)
)
diff [ ' before_header ' ] = " %s : %s " % ( record_type , record_name )
diff [ ' before_header ' ] = " %s : %s " % ( record_type , record_name )
# Create, remove, or modify the record.
# Create, remove, or modify the record.
if state == ' present ' :
if state == ' present ' :
diff [ ' after ' ] = dict (
diff [ ' after ' ] = dict (
record = record_name ,
record = record_name ,
type = record_type ,
type = record_type ,
values = module . params [ ' values ' ] ,
record_data = module . params [ ' record_data ' ] ,
ttl = ttl
ttl = ttl
)
)
diff [ ' after_header ' ] = " %s : %s " % ( record_type , record_name )
diff [ ' after_header ' ] = " %s : %s " % ( record_type , record_name )