diff --git a/library/cloud/digital_ocean b/library/cloud/digital_ocean index 82733ae483..31ec50888f 100644 --- a/library/cloud/digital_ocean +++ b/library/cloud/digital_ocean @@ -45,6 +45,11 @@ options: name: description: - String, this is the name of the droplet - must be formatted by hostname rules, or the name of a SSH key. + unique_name: + description: + - Bool, require unique hostnames. By default, digital ocean allows multiple hosts with the same name. Setting this to "yes" allows only one host per name. Useful for idempotence. + default: "no" + choices: [ "yes", "no" ] size_id: description: - Numeric, this is the id of the size you would like the droplet created at. @@ -211,13 +216,22 @@ class Droplet(JsonfyMixIn): return droplet @classmethod - def find(cls, id): - if not id: + def find(cls, id=None, name=None): + if not id and not name: return False + droplets = cls.list_all() + + # Check first by id. digital ocean requires that it be unique for droplet in droplets: if droplet.id == id: return droplet + + # Failing that, check by hostname. + for droplet in droplets: + if droplet.name == name: + return droplet + return False @classmethod @@ -281,7 +295,17 @@ def core(module): if command == 'droplet': Droplet.setup(client_id, api_key) if state in ('active', 'present'): - droplet = Droplet.find(module.params['id']) + + # First, try to find a droplet by id. + droplet = Droplet.find(id=module.params['id']) + + # If we couldn't find the droplet and the user is allowing unique + # hostnames, then check to see if a droplet with the specified + # hostname already exists. + if not droplet and module.params['unique_name']: + droplet = Droplet.find(name=getkeyordie('name')) + + # If both of those attempts failed, then create a new droplet. if not droplet: droplet = Droplet.add( name=getkeyordie('name'), @@ -290,18 +314,30 @@ def core(module): region_id=getkeyordie('region_id'), ssh_key_ids=module.params['ssh_key_ids'] ) + if droplet.is_powered_on(): changed = False + droplet.ensure_powered_on( wait=getkeyordie('wait'), wait_timeout=getkeyordie('wait_timeout') ) + module.exit_json(changed=changed, droplet=droplet.to_json()) elif state in ('absent', 'deleted'): - droplet = Droplet.find(getkeyordie('id')) + # First, try to find a droplet by id. + droplet = Droplet.find(id=getkeyordie('id')) + + # If we couldn't find the droplet and the user is allowing unique + # hostnames, then check to see if a droplet with the specified + # hostname already exists. + if not droplet and module.params['unique_name']: + droplet = Droplet.find(name=getkeyordie('name')) + if not droplet: module.exit_json(changed=False, msg='The droplet is not found.') + event_json = droplet.destroy() module.exit_json(changed=True, event_id=event_json['event_id']) @@ -336,6 +372,7 @@ def main(): region_id = dict(type='int'), ssh_key_ids = dict(default=''), id = dict(aliases=['droplet_id'], type='int'), + unique_name = dict(type='bool', choices=BOOLEANS, default='no'), wait = dict(type='bool', choices=BOOLEANS, default='yes'), wait_timeout = dict(default=300, type='int'), ssh_pub_key = dict(type='str'),