mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Refactor Digital Ocean Domain (#29179)
* Remove dopy dependency * Use DigitalOceanHelper class * Incorportated BondAnthony's changes Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
This commit is contained in:
parent
11580947f8
commit
2caddf0212
1 changed files with 90 additions and 124 deletions
|
@ -27,10 +27,11 @@ options:
|
||||||
- Indicate desired state of the target.
|
- Indicate desired state of the target.
|
||||||
default: present
|
default: present
|
||||||
choices: ['present', 'absent']
|
choices: ['present', 'absent']
|
||||||
api_token:
|
oauth_token:
|
||||||
description:
|
description:
|
||||||
- DigitalOcean api token.
|
- DigitalOcean api token.
|
||||||
version_added: "1.9.5"
|
version_added: "1.9.5"
|
||||||
|
aliases: ['api_token']
|
||||||
id:
|
id:
|
||||||
description:
|
description:
|
||||||
- Numeric, the droplet id you want to operate on.
|
- Numeric, the droplet id you want to operate on.
|
||||||
|
@ -42,13 +43,12 @@ options:
|
||||||
- The IP address to point a domain at.
|
- The IP address to point a domain at.
|
||||||
|
|
||||||
notes:
|
notes:
|
||||||
- Two environment variables can be used, DO_API_KEY and DO_API_TOKEN. They both refer to the v2 token.
|
- Environment variables DO_OAUTH_TOKEN can be used for the oauth_token.
|
||||||
- As of Ansible 1.9.5 and 2.0, Version 2 of the DigitalOcean API is used, this removes C(client_id) and C(api_key) options in favor of C(api_token).
|
- As of Ansible 1.9.5 and 2.0, Version 2 of the DigitalOcean API is used, this removes C(client_id) and C(api_key) options in favor of C(oauth_token).
|
||||||
- If you are running Ansible 1.9.4 or earlier you might not be able to use the included version of this module as the API version used has been retired.
|
- If you are running Ansible 1.9.4 or earlier you might not be able to use the included version of this module as the API version used has been retired.
|
||||||
|
|
||||||
requirements:
|
requirements:
|
||||||
- "python >= 2.6"
|
- "python >= 2.6"
|
||||||
- dopy
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,151 +79,119 @@ EXAMPLES = '''
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
try:
|
|
||||||
from dopy.manager import DoError, DoManager
|
|
||||||
HAS_DOPY = True
|
|
||||||
except ImportError as e:
|
|
||||||
HAS_DOPY = False
|
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.digital_ocean import DigitalOceanHelper
|
||||||
from ansible.module_utils._text import to_native
|
from ansible.module_utils._text import to_native
|
||||||
|
from ansible.module_utils.basic import env_fallback
|
||||||
|
|
||||||
|
|
||||||
class JsonfyMixIn(object):
|
class DoManager(DigitalOceanHelper, object):
|
||||||
|
def __init__(self, module):
|
||||||
|
super(DoManager, self).__init__(module)
|
||||||
|
self.domain_name = module.params.get('name', None)
|
||||||
|
self.domain_ip = module.params.get('ip', None)
|
||||||
|
self.domain_id = module.params.get('id', None)
|
||||||
|
|
||||||
def to_json(self):
|
@staticmethod
|
||||||
return self.__dict__
|
def jsonify(response):
|
||||||
|
return response.status_code, response.json
|
||||||
|
|
||||||
|
def all_domains(self):
|
||||||
|
resp = self.get('domains/')
|
||||||
|
return resp
|
||||||
|
|
||||||
class DomainRecord(JsonfyMixIn):
|
def find(self):
|
||||||
manager = None
|
if self.domain_name is None and self.domain_id is None:
|
||||||
|
|
||||||
def __init__(self, json):
|
|
||||||
self.__dict__.update(json)
|
|
||||||
update_attr = __init__
|
|
||||||
|
|
||||||
def update(self, data=None, record_type=None):
|
|
||||||
json = self.manager.edit_domain_record(self.domain_id,
|
|
||||||
self.id,
|
|
||||||
record_type if record_type is not None else self.record_type,
|
|
||||||
data if data is not None else self.data)
|
|
||||||
self.__dict__.update(json)
|
|
||||||
return self
|
|
||||||
|
|
||||||
def destroy(self):
|
|
||||||
json = self.manager.destroy_domain_record(self.domain_id, self.id)
|
|
||||||
return json
|
|
||||||
|
|
||||||
|
|
||||||
class Domain(JsonfyMixIn):
|
|
||||||
manager = None
|
|
||||||
|
|
||||||
def __init__(self, domain_json):
|
|
||||||
self.__dict__.update(domain_json)
|
|
||||||
|
|
||||||
def destroy(self):
|
|
||||||
self.manager.destroy_domain(self.name)
|
|
||||||
|
|
||||||
def records(self):
|
|
||||||
json = self.manager.all_domain_records(self.name)
|
|
||||||
return map(DomainRecord, json)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def add(cls, name, ip):
|
|
||||||
json = cls.manager.new_domain(name, ip)
|
|
||||||
return cls(json)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def setup(cls, api_token):
|
|
||||||
cls.manager = DoManager(None, api_token, api_version=2)
|
|
||||||
DomainRecord.manager = cls.manager
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def list_all(cls):
|
|
||||||
domains = cls.manager.all_domains()
|
|
||||||
return map(cls, domains)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def find(cls, name=None, id=None):
|
|
||||||
if name is None and id is None:
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
domains = Domain.list_all()
|
domains = self.all_domains()
|
||||||
|
status, json = self.jsonify(domains)
|
||||||
if id is not None:
|
for domain in json['domains']:
|
||||||
for domain in domains:
|
if domain['name'] == self.domain_name:
|
||||||
if domain.id == id:
|
return True
|
||||||
return domain
|
|
||||||
|
|
||||||
if name is not None:
|
|
||||||
for domain in domains:
|
|
||||||
if domain.name == name:
|
|
||||||
return domain
|
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def add(self):
|
||||||
|
params = {'name': self.domain_name, 'ip_address': self.domain_ip}
|
||||||
|
resp = self.post('domains/', data=params)
|
||||||
|
status = resp.status_code
|
||||||
|
json = resp.json
|
||||||
|
if status == 201:
|
||||||
|
return json['domain']
|
||||||
|
else:
|
||||||
|
return json
|
||||||
|
|
||||||
|
def all_domain_records(self):
|
||||||
|
resp = self.get('domains/%s/records/' % self.domain_name)
|
||||||
|
return resp.json
|
||||||
|
|
||||||
|
def domain_record(self):
|
||||||
|
resp = self.get('domains/%s' % self.domain_name)
|
||||||
|
status, json = self.jsonify(resp)
|
||||||
|
return json
|
||||||
|
|
||||||
|
def destroy_domain(self):
|
||||||
|
resp = self.delete('domains/%s' % self.domain_name)
|
||||||
|
status, json = self.jsonify(resp)
|
||||||
|
if status == 204:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return json
|
||||||
|
|
||||||
|
def edit_domain_record(self):
|
||||||
|
params = {'name': self.domain_name}
|
||||||
|
resp = self.put('domains/%s/records/%s' % (self.domain_name, self.domain_id), data=params)
|
||||||
|
return resp['domain_record']
|
||||||
|
|
||||||
|
|
||||||
def core(module):
|
def core(module):
|
||||||
def getkeyordie(k):
|
do_manager = DoManager(module)
|
||||||
v = module.params[k]
|
state = module.params.get('state')
|
||||||
if v is None:
|
|
||||||
module.fail_json(msg='Unable to load %s' % k)
|
|
||||||
return v
|
|
||||||
|
|
||||||
try:
|
|
||||||
api_token = module.params['api_token'] or os.environ['DO_API_TOKEN'] or os.environ['DO_API_KEY']
|
|
||||||
except KeyError as e:
|
|
||||||
module.fail_json(msg='Unable to load %s' % e.message)
|
|
||||||
|
|
||||||
state = module.params['state']
|
|
||||||
|
|
||||||
Domain.setup(api_token)
|
|
||||||
if state in ('present'):
|
|
||||||
domain = Domain.find(id=module.params["id"])
|
|
||||||
|
|
||||||
|
domain = do_manager.find()
|
||||||
|
if state == 'present':
|
||||||
if not domain:
|
if not domain:
|
||||||
domain = Domain.find(name=getkeyordie("name"))
|
domain = do_manager.add()
|
||||||
|
if 'message' in domain:
|
||||||
if not domain:
|
module.fail_json(changed=False, msg=domain['message'])
|
||||||
domain = Domain.add(getkeyordie("name"),
|
else:
|
||||||
getkeyordie("ip"))
|
module.exit_json(changed=True, domain=domain)
|
||||||
module.exit_json(changed=True, domain=domain.to_json())
|
|
||||||
else:
|
else:
|
||||||
records = domain.records()
|
records = do_manager.all_domain_records()
|
||||||
at_record = None
|
at_record = None
|
||||||
for record in records:
|
for record in records['domain_records']:
|
||||||
if record.name == "@" and record.type == 'A':
|
if record['name'] == "@" and record['type'] == 'A':
|
||||||
at_record = record
|
at_record = record
|
||||||
|
|
||||||
if not at_record.data == getkeyordie("ip"):
|
if not at_record['data'] == module.params.get('ip'):
|
||||||
record.update(data=getkeyordie("ip"), record_type='A')
|
do_manager.edit_domain_record()
|
||||||
module.exit_json(changed=True, domain=Domain.find(id=record.id).to_json())
|
module.exit_json(changed=True, domain=do_manager.find())
|
||||||
|
else:
|
||||||
module.exit_json(changed=False, domain=domain.to_json())
|
module.exit_json(changed=False, domain=do_manager.domain_record())
|
||||||
|
|
||||||
elif state in ('absent'):
|
|
||||||
domain = None
|
|
||||||
if "id" in module.params:
|
|
||||||
domain = Domain.find(id=module.params["id"])
|
|
||||||
|
|
||||||
if not domain and "name" in module.params:
|
|
||||||
domain = Domain.find(name=module.params["name"])
|
|
||||||
|
|
||||||
|
elif state == 'absent':
|
||||||
if not domain:
|
if not domain:
|
||||||
module.exit_json(changed=False, msg="Domain not found.")
|
module.fail_json(changed=False, msg="Domain not found")
|
||||||
|
else:
|
||||||
event_json = domain.destroy()
|
delete_event = do_manager.destroy_domain()
|
||||||
module.exit_json(changed=True, event=event_json)
|
if not delete_event:
|
||||||
|
module.fail_json(changed=False, msg=delete_event['message'])
|
||||||
|
else:
|
||||||
|
module.exit_json(changed=True, event=None)
|
||||||
|
delete_event = do_manager.destroy_domain()
|
||||||
|
module.exit_json(changed=delete_event)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
module = AnsibleModule(
|
module = AnsibleModule(
|
||||||
argument_spec=dict(
|
argument_spec=dict(
|
||||||
state=dict(choices=['present', 'absent'], default='present'),
|
state=dict(choices=['present', 'absent'], default='present'),
|
||||||
api_token=dict(aliases=['API_TOKEN'], no_log=True),
|
oauth_token=dict(
|
||||||
|
aliases=['API_TOKEN'],
|
||||||
|
no_log=True,
|
||||||
|
fallback=(env_fallback, ['DO_API_TOKEN', 'DO_API_KEY', 'DO_OAUTH_TOKEN'])
|
||||||
|
),
|
||||||
name=dict(type='str'),
|
name=dict(type='str'),
|
||||||
id=dict(aliases=['droplet_id'], type='int'),
|
id=dict(aliases=['droplet_id'], type='int'),
|
||||||
ip=dict(type='str'),
|
ip=dict(type='str'),
|
||||||
|
@ -232,12 +200,10 @@ def main():
|
||||||
['id', 'name'],
|
['id', 'name'],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
if not HAS_DOPY:
|
|
||||||
module.fail_json(msg='dopy required for this module')
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
core(module)
|
core(module)
|
||||||
except (DoError, Exception) as e:
|
except Exception as e:
|
||||||
module.fail_json(msg=to_native(e), exception=traceback.format_exc())
|
module.fail_json(msg=to_native(e), exception=traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue