diff --git a/states/_modules/ovhapi.py b/states/_modules/ovhapi.py index e76d3c7..9f23566 100644 --- a/states/_modules/ovhapi.py +++ b/states/_modules/ovhapi.py @@ -21,7 +21,7 @@ def _config(): return config -def _auth(): +def authenticate(): cfg = _config() client = ovh.Client( endpoint=cfg['endpoint'], @@ -33,17 +33,19 @@ def _auth(): return client -def domain_get_zone(zone=""): +def domain_get_zone(zone="", + client=None): ''' Get DNS zone extraction zone Zone name to fetch + client + Client to use against API ''' if zone == "": raise ArgumentValueError("Zone is not defined") - client = _auth() try: results = client.get(f'/domain/zone/{zone}/export') except APIError: @@ -52,7 +54,11 @@ def domain_get_zone(zone=""): return results -def domain_get_record(zone="", fieldType="", subDomain="", target=""): +def domain_get_record(zone="", + fieldType="", + subDomain="", + target="", + client=None): ''' Record of the zone @@ -64,11 +70,12 @@ def domain_get_record(zone="", fieldType="", subDomain="", target=""): Filter the value of subDomain property (like) target Resource record target + client + Client to use against API ''' if zone == "": raise ArgumentValueError("Zone is not defined") - client = _auth() try: records = client.get(f'/domain/zone/{zone}/record', fieldType=fieldType, @@ -87,7 +94,8 @@ def domain_post_record(zone="", fieldType="", subDomain="", target="", - ttl=0): + ttl=0, + client=None): ''' Create a new DNS record @@ -101,11 +109,12 @@ def domain_post_record(zone="", Resource record target ttl Resource record ttl + client + Client to use against API ''' if zone == "": raise ArgumentValueError("Zone is not defined") - client = _auth() try: req = client.post(f'/domain/zone/{zone}/record', fieldType=fieldType, @@ -122,7 +131,9 @@ def domain_put_record(zone="", fieldType="", subDomain="", target="", - ttl=0): + ttl=0, + current=None, + client=None): ''' Update a DNS record @@ -136,31 +147,29 @@ def domain_put_record(zone="", Resource record target ttl Resource record ttl + current + Current DNS record + client + Client to use against API ''' if zone == "": raise ArgumentValueError("Zone is not defined") - client = _auth() try: - records = client.get(f'/domain/zone/{zone}/record', - fieldType=fieldType, - subDomain=subDomain) - if len(records) > 0: - for rec in records: - res = client.get(f'/domain/zone/{zone}/record/{rec}') - if res['target'] == target: - req = client.put(f'/domain/zone/{zone}/record/{rec}', - subDomain=subDomain, - target=target, - ttl=ttl) - return req + client.put(f'/domain/zone/{zone}/record/{current["id"]}', + subDomain=subDomain, + target=target, + ttl=ttl) + changed = client.get(f'/domain/zone/{zone}/record/{current["id"]}') except APIError: return "Query failed in OVH API" - - return "Error updating record" + return changed -def domain_delete_record(zone="", fieldType="", subDomain=""): +def domain_delete_record(zone="", + fieldType="", + subDomain="", + client=None): ''' Delete a DNS record (Don't forget to refresh the zone) @@ -170,12 +179,13 @@ def domain_delete_record(zone="", fieldType="", subDomain=""): Filter the value of fieldType property (like) subDomain Filter the value of subDomain property (like) + client + Client to use against API ''' if zone == "": raise ArgumentValueError("Zone is not defined") results = [] - client = _auth() try: records = client.get(f'/domain/zone/{zone}/record', fieldType=fieldType, @@ -192,17 +202,19 @@ def domain_delete_record(zone="", fieldType="", subDomain=""): return results -def domain_refresh_zone(zone=""): +def domain_refresh_zone(zone="", + client=None): ''' Apply zone modification on DNS servers zone The internal name of your zone + client + Client to use against API ''' if zone == "": raise ArgumentValueError("Zone is not defined") - client = _auth() try: req = client.post(f'/domain/zone/{zone}/refresh') except APIError: diff --git a/states/_states/ovhapi.py b/states/_states/ovhapi.py index 2d849cc..7498034 100644 --- a/states/_states/ovhapi.py +++ b/states/_states/ovhapi.py @@ -1,5 +1,7 @@ #!/usr/bin/python3 +from salt.utils.dictdiffer import deep_diff + def _error(ret, err_msg): ret['result'] = False ret['comment'] = err_msg @@ -39,40 +41,47 @@ def domain_record_present(name=None, if type(target) is not str: return _error(ret, 'Must provide target to ovhapi.domain_record_present') - # check if record exists - cur_record = __salt__['ovhapi.domain_get_record'](zone=zone, - fieldType=recordtype, - subDomain=recordname, - target=target) - if cur_record: - new_record = __salt__['ovhapi.domain_put_record'](zone=zone, - fieldType=recordtype, - subDomain=recordname, - target=target) + client = __salt__['ovhapi.authenticate']() - ret['changes'] = { - "diff": f"old record: {cur_record}, new record: {new_record}" - } - res_output = f"Updated record {recordname}" + # check if record exists + current_record = __salt__['ovhapi.domain_get_record'](zone=zone, + fieldType=recordtype, + subDomain=recordname, + target=target, + client=client) + if current_record: + new_record = __salt__['ovhapi.domain_put_record'](zone=zone, + fieldType=recordtype, + subDomain=recordname, + target=target, + current=current_record, + client=client) + + diff = deep_diff(current_record,new_record) + if diff == {}: + ret['comment'] = f"No updates on record {recordname}" + else: + ret['changes'] = { + "diff": diff + } + ret['comment'] = f"Updated record {recordname}" else: new_record = __salt__['ovhapi.domain_post_record'](zone=zone, - subDomain=recordname, - fieldType=recordtype, - target=target, - ttl=ttl) + subDomain=recordname, + fieldType=recordtype, + target=target, + ttl=ttl, + client=client) ret['changes'] = { - "diff": f"new record: {new_record}" + "diff": f"{new_record}" } - res_output = f"Created record {recordname}" - - ret['comment'] = f'Result is {res_output}' + ret['comment'] = f"Created record {recordname}" return ret def domain_zone_refresh(name="", zone=""): - res_output = "" ret = { 'name': name, 'changes': {}, @@ -80,8 +89,8 @@ def domain_zone_refresh(name="", zone=""): 'comment': 'Zone is refreshed' } - res_output = __salt__['ovhapi.domain_refresh_zone'](zone=zone) - - ret['comment'] = f'Result is {res_output}' + client = __salt__['ovhapi.authenticate']() + ret['comment'] = __salt__['ovhapi.domain_refresh_zone'](zone=zone, + client=client) return ret