@ -58,7 +58,9 @@ def main():
api_token = dict ( required = False , type = ' str ' , no_log = True , aliases = [ ' access_token ' ] ) ,
name = dict ( required = True , type = ' str ' ) ,
value = dict ( type = ' str ' ) ,
values = dict ( type = ' list ' ) ,
ttl = dict ( default = 300 , type = ' int ' ) ,
purge = dict ( required = False , type = ' bool ' , default = True , aliases = [ ' replace ' , ' overwrite ' , ' solo ' ] ) ,
type = dict ( required = True , type = ' str ' , choices = [ " A " , " AAAA " , " NS " , " MX " , " CNAME " , " RP " , " TXT " , " SOA " , " HINFO " , " SRV " , " DANE " , " TLSA " , " DS " , " CAA " ] ) ,
state = dict ( type = ' str ' , default = ' present ' , choices = [ ' present ' , ' absent ' ] )
)
@ -66,8 +68,13 @@ def main():
module = AnsibleModule (
argument_spec = argument_spec ,
required_if = [ [ ' state ' , ' present ' , [ ' value ' ] ] ] ,
mutually_exclusive = [
[ ' zone_id ' , ' zone_name ' ] ,
[ ' value ' , ' values ' ]
] ,
required_one_of = [
[ ' zone_id ' , ' zone_name ' ]
[ ' zone_id ' , ' zone_name ' ] ,
[ ' value ' , ' values ' ]
] ,
supports_check_mode = True
)
@ -77,6 +84,10 @@ def main():
zone_id = module . params . get ( " zone_id " )
zone_name = module . params . get ( " zone_name " )
state = module . params . get ( " state " )
purge = module . params . get ( " purge " )
value = module . params . get ( " values " ,
[ module . params . get ( " value " ) ]
)
if zone_id is None :
zones = dns . get_zone_info ( )
@ -86,7 +97,7 @@ def main():
future_record = {
' name ' : module . params . get ( " name " ) ,
' value ' : module . params . get ( " value" ) ,
' value ' : value ,
' type ' : module . params . get ( " type " ) ,
' ttl ' : int ( module . params . get ( " ttl " ) ) ,
' zone_id ' : zone_id
@ -102,60 +113,94 @@ def main():
record_changed = False
record_exists = False
change = False
past_record = None
record_obj = {
' records ' : { } ,
' all_values ' : [ ]
}
# check all existing records
for record in records . json ( ) [ ' records ' ] :
if not record . get ( ' ttl ' ) :
record [ ' ttl ' ] = 300
record [ ' ttl ' ] = 300
record_obj [ ' record ' ] [ record . get ( ' value ' ) ] [ ' req ' ] = record
record_obj [ ' record ' ] [ record . get ( ' value ' ) ] [ ' id ' ] = record . get ( ' id ' )
record_obj [ ' all_values ' ] . append ( record . get ( ' value ' ) )
record_obj [ ' records ' ] [ record . get ( ' value ' ) ] [ ' change ' ] = False
record_obj [ ' records ' ] [ record . get ( ' value ' ) ] [ ' remove ' ] = False
record_obj [ ' records ' ] [ record . get ( ' value ' ) ] [ ' create ' ] = False
# same name, same key
if all ( item in record . items ( ) for item in find_record . items ( ) ) :
record_exists = True
record_id = record . get ( ' id ' )
past_record = record
if not all ( item in record . items ( ) for item in future_record . items ( ) ) :
record_changed = True
else :
this_record = { ' record ' : record }
break
# when existing record is not in requested record -> remove
if record . get ( ' value ' ) not in future_record . get ( ' value ' ) :
record_obj [ ' records ' ] [ record . get ( ' value ' ) ] [ ' remove ' ] = True
# when existing record is in requested record, but ttl is different -> change
elif record . get ( ' ttl ' ) != future_record . get ( ' ttl ' ) :
record_obj [ ' records ' ] [ record . get ( ' value ' ) ] [ ' change ' ] = True
record_obj [ ' records ' ] [ record . get ( ' value ' ) ] [ ' req ' ] = {
' name ' : module . params . get ( " name " ) ,
' value ' : record . get ( ' value ' ) ,
' type ' : module . params . get ( " type " ) ,
' ttl ' : int ( module . params . get ( " ttl " ) ) ,
' zone_id ' : zone_id
}
if state == ' present ' :
if not record_exists :
record_id = None
this_record = { ' record ' : future_record }
change = True
if not module . check_mode :
r = dns . create_record ( future_record )
record_id = r . json ( ) [ ' record ' ] [ ' id ' ]
this_record = r . json ( )
elif record_changed :
change = True
this_record = { ' record ' : future_record }
if not module . check_mode :
r = dns . update_record ( future_record , record_id )
this_record = r . json ( )
if state == ' absent ' :
if record_exists :
change = True
if not module . check_mode :
r = dns . delete_record ( record_id )
else :
change = False
this_record = { ' record ' : None }
record_id = None
if past_record is None :
past_record = { }
else :
past_record . pop ( ' id ' )
past_record . pop ( ' created ' )
past_record . pop ( ' modified ' )
diff = dict (
before = yaml . safe_dump ( past_record ) ,
after = yaml . safe_dump ( this_record . get ( ' record ' ) )
)
module . exit_json ( changed = change , record_id = record_id , record_info = this_record , past_record = past_record , diff = diff )
# check all requested records
for record in future_record . get ( ' value ' ) :
# only when not already covered -> new records: create
if record not in record_obj . get ( ' all_values ' ) :
record_obj [ ' records ' ] [ record ] [ ' create ' ] = True
record_obj [ ' records ' ] [ record ] [ ' change ' ] = False
record_obj [ ' records ' ] [ record ] [ ' remove ' ] = False
record_obj [ ' records ' ] [ record ] [ ' req ' ] = {
' name ' : module . params . get ( " name " ) ,
' value ' : record ,
' type ' : module . params . get ( " type " ) ,
' ttl ' : int ( module . params . get ( " ttl " ) ) ,
' zone_id ' : zone_id
}
if state == ' present ' :
for key in record_obj [ ' records ' ] :
if record_obj [ ' records ' ] . get ( key ) . get ( ' create ' ) :
r = dns . create_record ( record_obj [ ' records ' ] . get ( key ) . get ( ' req ' ) )
change = True
elif record_obj [ ' records ' ] . get ( key ) . get ( ' change ' ) :
r = dns . update_record ( future_record , record_obj [ ' records ' ] . get ( key ) . get ( ' req ' ) )
change = True
elif record_obj [ ' records ' ] . get ( key ) . get ( ' remove ' ) and purge :
r = dns . delete_record ( record_obj [ ' records ' ] . get ( key ) . get ( ' id ' ) )
change = True
elif state == ' absent ' :
for key in record_obj [ ' records ' ] :
# when state is absent, we must remove records
# where a change is detected
# where `create` is detected, record does not exist
# where `remove` is detected, record is not requested to be removed
if record_obj [ ' records ' ] . get ( key ) . get ( ' change ' ) :
r = dns . delete_record ( record_obj [ ' records ' ] . get ( key ) . get ( ' id ' ) )
change = True
# TODO: postprocessing of return values and `--diff` feature
# if past_record is None:
# past_record = {}
# else:
# past_record.pop('id')
# past_record.pop('created')
# past_record.pop('modified')
# diff = dict(
# before=yaml.safe_dump(past_record),
# after=yaml.safe_dump(this_record.get('record'))
# )
module . exit_json ( changed = change , record_info = this_record , past_record = past_record , diff = diff )
if __name__ == ' __main__ ' :