def create_domain(self,name=None,ip_addr=None): """ This method creates a new domain name with an A record for the specified [ip_address]. :type name: string :param size: The NAME of the domain :type ip_address: string :param size: ip address for the domain's initial a record. https://api.digitalocean.com/domains/new? client_id=[your_client_id]&api_key=[your_api_key]&name=[domain]&ip_address=[ip_address] """ log.debug("Creating new domain") data = self._conn.request("/domains/new",name=name, ip_address=ip_addr) log.debug(data) domain = Domain(conn=self._conn, **data['domain']) return domain
def request(self, event, status_check=None, **kwds): if 'client_id' not in kwds: kwds['client_id'] = self.__client_id if 'api_key' not in kwds: kwds['api_key'] = self.__api_key headers = {'User-Agent': 'doto/client'} for key, value in kwds.iteritems(): log.debug("%s = %s" % (key, value)) BASEURL = "https://api.digitalocean.com" response = requests.get(BASEURL + event, headers=headers, params=kwds) log.debug('Getting ' + event) log.debug(response.url) if response.status_code == 200: data = response.json() log.debug(data) if data['status'] == 'ERROR': log.debug("Error with request: %s" % (data['message'])) error = "MSG: %s" % (data['message']) raise DOError(error) if status_check: return response.status_code return data else: #error data = response.json() error = "Status code: %d MSG: %s" % (response.status_code, data['message']) raise DOError(error)
def rebuild(self, image_id=None, use_current=False): """ This method allows you to reinstall a droplet with a default image. This is useful if you want to start again but retain the same IP address for your droplet. :type image_id: int :param image_id: ID of the image you would like to use to rebuild your droplet with :type use_current: BOOL :param use_current: Use the current image_id of the droplet during rebuild process https://api.digitalocean.com/droplets/[droplet_id]/rebuild/?image_id=[image_id]& client_id=[your_client_id]&api_key=[your_api_key] """ if use_current: image_id = self.image_id url = "/droplets/%s/rebuild" % (str(self.id)) data = self._conn.request(url,image_id=image_id) self.event_id = data['event_id'] self.update() log.debug("Rebuild: %d With: %d Event: %d" % (self.id, image_id, self.event_id)) return Event(self._conn,self.event_id)
def rebuild(self, image_id=None, use_current=False): """ This method allows you to reinstall a droplet with a default image. This is useful if you want to start again but retain the same IP address for your droplet. :type image_id: int :param image_id: ID of the image you would like to use to rebuild your droplet with :type use_current: BOOL :param use_current: Use the current image_id of the droplet during rebuild process https://api.digitalocean.com/droplets/[droplet_id]/rebuild/?image_id=[image_id]& client_id=[your_client_id]&api_key=[your_api_key] """ if use_current: image_id = self.image_id url = "/droplets/%s/rebuild" % (str(self.id)) data = self._conn.request(url, image_id=image_id) self.event_id = data['event_id'] self.update() log.debug("Rebuild: %d With: %d Event: %d" % (self.id, image_id, self.event_id)) return Event(self._conn, self.event_id)
def restore(self, image_id=None): """ This method allows you to restore a droplet with a previous image or snapshot. This will be a mirror copy of the image or snapshot to your droplet. Be sure you have backed up any necessary information prior to restore. :type image_id: int :param image_id: ID of the image you would like to use to rebuild your droplet with https://api.digitalocean.com/droplets/[droplet_id]/restore/?image_id=[image_id]& client_id=[your_client_id]&api_key=[your_api_key] """ url = "/droplets/%s/restore" % (str(self.id)) data = self._conn.request(url,image_id=image_id) self.event_id = data['event_id'] log.debug("Restoring: %d With: %d Event: %d" % (self.id, image_id, self.event_id)) self.update()
def destroy(self): """ This method allows you to destroy an image. There is no way to restore a deleted image so be careful and ensure your data is properly backed up. """ url = "/images/%s/destroy" % (str(self.id)) data = self._conn.request(url) log.debug(data)
def edit_record( self, record_id=None, record_type=None, data=None, name=None, priority=None, port=None, weight=None, ): """ This method edits an existing domain record. :type record_id: int :param record_id: ID of record you are trying to retrieve. :type record_type: String :param record_type: the type of record you would like to create. 'A', 'CNAME', 'NS', 'TXT', 'MX' or 'SRV'. :type data: String :param data: This is the value of the record. :type name: String :param name: Required for 'A', 'CNAME', 'TXT' and 'SRV' records otherwise optional :type priority: int :param priority: required for 'SRV' and 'MX' records otherwise optional :type port: int :param port: required for 'SRV' records otherwise optional :type weight: int :param weight: required for 'SRV' records. otherwise optional https://api.digitalocean.com/domains/[domain_id]/records/[record_id]/edit? client_id=[your_client_id]&api_key=[your_api_key] """ log.info("Editing Record: %d" % (record_id)) url = "/domains/%s/records/%d/edit" % (str(self.id), record_id) data = self._conn.request(url, record_type=record_type, data=data, name=name, priority=priority, port=port, weight=weight) log.debug(data) return data['record']
def event_update(self): # https://api.digitalocean.com/events/[event_id]/? # client_id=[your_client_id]&api_key=[your_api_key] url = "/events/%s" % (str(self.event_id)) data = self._request(url) log.debug("Updating Event") log.debug(data) data['event']['event_id'] = data['event']['id'] data['event']['id'] = data['event']['droplet_id'] self.__dict__.update(**data['event'])
def _request(self, event, status_check=None, **kwds): if "client_id" not in kwds: kwds["client_id"] = self._client_id if "api_key" not in kwds: kwds["api_key"] = self._api_key headers = {"User-Agent": "doto/client"} for key, value in kwds.iteritems(): log.debug("%s = %s" % (key, value)) BASEURL = "https://api.digitalocean.com" response = requests.get(BASEURL + event, headers=headers, params=kwds) log.info("Getting " + event) log.debug(response.url) if response.status_code == 200: data = response.json() log.debug(data) if data["status"] == "ERROR": log.debug("Error with request: %s" % (data["message"])) error = "MSG: %s" % (data["message"]) raise DOError(error) if status_check: return response.status_code return data else: # error data = response.json() error = "Status code: %d MSG: %s" % (response.status_code, data["message"]) raise DOError(error)
def event_update(self): # https://api.digitalocean.com/events/[event_id]/? # client_id=[your_client_id]&api_key=[your_api_key] url = "/events/%s" % (str(self.event_id)) data = self._request(url) log.debug("Updating Event") log.debug(data) #verbose because droplet_id is unnecessary self.event_id = data['event']['id'] self.percentage = data['event']['percentage'] self.action_status = data['event']['action_status'] self.event_type_id = data['event']['event_type_id']
def reboot(self): """ This method allows you to reboot a droplet. This is the preferred method to use if a server is not responding. https://api.digitalocean.com/droplets/[droplet_id]/reboot/? client_id=[your_client_id]&api_key=[your_api_key] """ url = "/droplets/%s/reboot" % (str(self.id)) data = self._conn.request(url) self.event_id = data['event_id'] log.debug("Rebooting: %d, Event: %d" % (self.id, self.event_id))
def power_cycle(self): """ This method allows you to power cycle a droplet. This will turn off the droplet and then turn it back on. https://api.digitalocean.com/droplets/[droplet_id]/power_cycle/? client_id=[your_client_id]&api_key=[your_api_key] """ url = "/droplets/%s/power_cycle" % (str(self.id)) data = self._conn.request(url) self.event_id = data['event_id'] log.debug("Power Cycle: %d, Event: %d" % (self.id, self.event_id))
def get_ssh_key(self, ssh_key_id=None): """ Delete the SSH key from your account. :type ssh_key_id: int :param ssh_key_id: The ID of the public key https://api.digitalocean.com/ssh_keys/[ssh_key_id]/destroy/? client_id=[your_client_id]&api_key=[your_api_key] """ url = "/ssh_keys/%d" % (ssh_key_id) data = self._conn.request(url) log.debug(data)
def shutdown(self): """ This method allows you to shutdown a droplet. The droplet will remain in your account. https://api.digitalocean.com/droplets/[droplet_id]/shutdown/ ?client_id=[your_client_id]&api_key=[your_api_key] """ url = "/droplets/%s/shutdown" % (str(self.id)) data = self._conn.request(url) self.event_id = data['event_id'] log.debug("Shutting Down: %d, Event: %d" % (self.id, self.event_id)) log.debug("Droplet remains active in your account")
def power_on(self): """ This method allows you to power on a previously powered off droplet. https://api.digitalocean.com/droplets/[droplet_id]/power_on/? client_id=[your_client_id]&api_key=[your_api_key] """ url = "/droplets/%s/power_on" % (str(self.id)) data = self._conn.request(url) self.event_id = data['event_id'] log.debug("Powering On: %d, Event: %d" % (self.id, self.event_id)) return Event(self._conn, self.event_id)
def password_reset(self): """ This method will reset the root password for a droplet. Please be aware that this will reboot the droplet to allow resetting the password. https://api.digitalocean.com/droplets/[droplet_id]/password_reset/? client_id=[your_client_id]&api_key=[your_api_key] """ url = "/droplets/%s/password_reset" % (str(self.id)) data = self._conn.request(url) self.event_id = data['event_id'] log.debug("Resetting Password: %d, Event: %d" % (self.id, self.event_id)) log.debug("Rebooting Droplet")
def event_update(self): """ Method to update Droplet https://api.digitalocean.com/events/[event_id]/? client_id=[your_client_id]&api_key=[your_api_key] """ url = "/events/%s" % (str(self.event_id)) data = self._request(url) log.debug("Updating Event") log.debug(data) data["event"]["event_id"] = data["event"]["id"] data["event"]["id"] = data["event"]["droplet_id"] self.__dict__.update(**data["event"])
def event_update(self): """ Method to update Image (primarily used to update ip information) https://api.digitalocean.com/events/[event_id]/? client_id=[your_client_id]&api_key=[your_api_key] """ url = "/events/%s" % (str(self.event_id)) data = self._conn.request(url) log.debug("Updating Event") log.debug(data) #verbose because droplet_id is unnecessary self.event_id = data['event']['id'] self.percentage = data['event']['percentage'] self.action_status = data['event']['action_status'] self.event_type_id = data['event']['event_type_id']
def get_record(self, record_id=None): """ This method returns the specified domain record. :type record_id: int :param record_id: ID of record you are trying to retrieve. https://api.digitalocean.com/domains/[domain_id]/records/[record_id]? client_id=[your_client_id]&api_key=[your_api_key] """ log.info("Getting Record: %d" % (record_id)) url = "/domains/%s/records/%d" % (str(self.id), record_id) data = self._conn.request(url) log.debug(data) return data['record']
def destroy(self, scrub_data=1): """ This method destroys one of your droplets - this is irreversible. :type scrub_data: bool :param scrub_data: An optional bool which will strictly write 0s to your prior partition to ensure that all data is completely erased. True by default https://api.digitalocean.com/droplets/[droplet_id]/destroy/? client_id=[your_client_id]&api_key=[your_api_key] """ url = "/droplets/%s/destroy" % (str(self.id)) data = self._conn.request(url,scrub_data=scrub_data) self.event_id = data['event_id'] log.debug("Destroying: %d, Event: %d" % (self.id, self.event_id))
def get_record(self,record_id=None): """ This method returns the specified domain record. :type record_id: int :param record_id: ID of record you are trying to retrieve. https://api.digitalocean.com/domains/[domain_id]/records/[record_id]? client_id=[your_client_id]&api_key=[your_api_key] """ log.info("Getting Record: %d" % (record_id)) url = "/domains/%s/records/%d" % (str(self.id), record_id) data = self._conn.request(url) log.debug(data) return data['record']
def destroy(self, scrub_data=1): """ This method destroys one of your droplets - this is irreversible. :type scrub_data: bool :param scrub_data: An optional bool which will strictly write 0s to your prior partition to ensure that all data is completely erased. True by default https://api.digitalocean.com/droplets/[droplet_id]/destroy/? client_id=[your_client_id]&api_key=[your_api_key] """ url = "/droplets/%s/destroy" % (str(self.id)) data = self._conn.request(url, scrub_data=scrub_data) self.event_id = data['event_id'] log.debug("Destroying: %d, Event: %d" % (self.id, self.event_id))
def get_all_records(self,table=False): """ This method returns all of your current domain records. https://api.digitalocean.com/domains/[domain_id]/records? client_id=[your_client_id]&api_key=[your_api_key] """ log.info("Getting Records") url = "/domains/%s/records" % (str(self.id)) data = self._conn.request(url) log.debug(data) if table: self._pprint_table(data['records']) return data['records']
def get_all_records(self, table=False): """ This method returns all of your current domain records. https://api.digitalocean.com/domains/[domain_id]/records? client_id=[your_client_id]&api_key=[your_api_key] """ log.info("Getting Records") url = "/domains/%s/records" % (str(self.id)) data = self._conn.request(url) log.debug(data) if table: self._pprint_table(data['records']) return data['records']
def rename(self, name=None): """ This method renames the droplet to the specified name. :type name: str :param name: Name of the new droplet https://api.digitalocean.com/droplets/[droplet_id]/rename/? client_id=[your_client_id]&api_key=[your_api_key]&name=[name] """ url = "/droplets/%s/rename" % (str(self.id)) data = self._conn.request(url, name=name) self.event_id = data['event_id'] log.debug("Renaming: %d To: %s Event: %d" % (self.id, name, self.event_id)) self.update()
def rename(self,name=None): """ This method renames the droplet to the specified name. :type name: str :param name: Name of the new droplet https://api.digitalocean.com/droplets/[droplet_id]/rename/? client_id=[your_client_id]&api_key=[your_api_key]&name=[name] """ url = "/droplets/%s/rename" % (str(self.id)) data = self._conn.request(url,name=name) self.event_id = data['event_id'] log.debug("Renaming: %d To: %s Event: %d" % (self.id, name, self.event_id)) self.update()
def edit_record(self,record_id=None, record_type=None, data=None, name=None,priority=None,port=None,weight=None, ): """ This method edits an existing domain record. :type record_id: int :param record_id: ID of record you are trying to retrieve. :type record_type: String :param record_type: the type of record you would like to create. 'A', 'CNAME', 'NS', 'TXT', 'MX' or 'SRV'. :type data: String :param data: This is the value of the record. :type name: String :param name: Required for 'A', 'CNAME', 'TXT' and 'SRV' records otherwise optional :type priority: int :param priority: required for 'SRV' and 'MX' records otherwise optional :type port: int :param port: required for 'SRV' records otherwise optional :type weight: int :param weight: required for 'SRV' records. otherwise optional https://api.digitalocean.com/domains/[domain_id]/records/[record_id]/edit? client_id=[your_client_id]&api_key=[your_api_key] """ log.info("Editing Record: %d" % (record_id)) url = "/domains/%s/records/%d/edit" % (str(self.id), record_id) data = self._conn.request(url,record_type=record_type, data=data,name=name,priority=priority, port=port,weight=weight) log.debug(data) return data['record']
def transfer_image(self, region_id=None): """ This method allows you to transfer an image to a specified region. :type image_id: int :param image_id: The ID of the image :type region_id: int :param region_id: The ID of the region to which you would like to transfer. """ # https://api.digitalocean.com/images/[image_id]/transfer/? # client_id=[your_client_id]&api_key=[your_api_key]®ion_id=[region_id] url = "/images/%s/transfer" % (str(self.id)) data = self._conn.request(url, region_id=region_id) self.event_id = data['event_id'] log.debug(data)
def create_snapshot(self,name=None): """ This method allows you to take a snapshot of the droplet once it has been powered off, which can later be restored or used to create a new droplet from the same image. Please be aware this may cause a reboot. :type name: string :param size: The NAME of the snapshot https://api.digitalocean.com/droplets/[droplet_id]/snapshot/?name=[snapshot_name]& client_id=[your_client_id]&api_key=[your_api_key] """ url = "/droplets/%s/snapshot" % (str(self.id)) data = self._conn.request(url,name=name) self.event_id = data['event_id'] log.debug("Taking Snapshot: %d, Event: %d" % (self.id, self.event_id)) return Event(self._conn, self.event_id)
def create_snapshot(self, name=None): """ This method allows you to take a snapshot of the droplet once it has been powered off, which can later be restored or used to create a new droplet from the same image. Please be aware this may cause a reboot. :type name: string :param size: The NAME of the snapshot https://api.digitalocean.com/droplets/[droplet_id]/snapshot/?name=[snapshot_name]& client_id=[your_client_id]&api_key=[your_api_key] """ url = "/droplets/%s/snapshot" % (str(self.id)) data = self._conn.request(url, name=name) self.event_id = data['event_id'] log.debug("Taking Snapshot: %d, Event: %d" % (self.id, self.event_id)) return Event(self._conn, self.event_id)
def get_domain(self, domain_id=None): """ This method displays the attributes of an image. :type image_id: int :param image_id: The ID of the image :rtype: :class:`doto.Image` :return: The newly created :class:`doto.Image`. https://api.digitalocean.com/domains/[domain_id]? client_id=[your_client_id]&api_key=[your_api_key] """ url = "/domains/%d" % (domain_id) data = self._conn.request(url) log.debug(data) return Domain(conn=self._conn, **data['domain'])
def set_backups(self, flag=True): """ This method enables/disables automatic backups which run in the background daily to backup your droplet's data. :type flag: bool :param scrub_data: A bool which enables/disables backups https://api.digitalocean.com/droplets/[droplet_id]/enable_backups/? client_id=[your_client_id]&api_key=[your_api_key] """ backup_setting = "enable_backups" if flag else "disable_backups" url = "/droplets/%s/%s" % (str(self.id), backup_setting) data = self._conn.request(url) self.event_id = data['event_id'] log.debug("Destroying: %d, Event: %d" % (self.id, self.event_id))
def get_all_droplets(self,filters=None, status_check=None, table=False, raw_data=False): """ This method returns all active droplets that are currently running in your account. All available API information is presented for each droplet. https://api.digitalocean.com/droplets/? client_id=[your_client_id]&api_key=[your_api_key] :rtype: list :return: A list of :class:`doto.Droplet` """ log.debug("Get All Droplets") data = self._conn.request("/droplets",status_check) if status_check: return data if raw_data: return data if table: self._pprint_table(data['droplets']) return droplets = data['droplets'] if filters: droplets = [Droplet(conn=self._conn, **drop) for drop in droplets] for k,v in filters.iteritems(): droplets = filter(lambda x: v in getattr(x,k), droplets) return droplets #convert dictionary to droplet objects return [Droplet(conn=self._conn, **drop) for drop in droplets]
def request(self, event, status_check=None, **kwds): if 'client_id' not in kwds: kwds['client_id'] = self.__client_id if 'api_key' not in kwds: kwds['api_key'] = self.__api_key headers = { 'User-Agent': 'doto/client' } for key, value in kwds.iteritems(): log.debug("%s = %s" % (key, value)) BASEURL = "https://api.digitalocean.com" response = requests.get(BASEURL+event,headers=headers,params=kwds) log.debug('Getting '+event) log.debug(response.url) if response.status_code == 200: data = response.json() log.debug(data) if data['status'] == 'ERROR': log.debug("Error with request: %s" % (data['message'])) error = "MSG: %s" % (data['message']) raise DOError(error) if status_check: return response.status_code return data else: #error data = response.json() error = "Status code: %d MSG: %s" % (response.status_code, data['message']) raise DOError(error)
def set_backups(self,flag=True): """ This method enables/disables automatic backups which run in the background daily to backup your droplet's data. :type flag: bool :param scrub_data: A bool which enables/disables backups https://api.digitalocean.com/droplets/[droplet_id]/enable_backups/? client_id=[your_client_id]&api_key=[your_api_key] """ backup_setting = "enable_backups" if flag else "disable_backups" url = "/droplets/%s/%s" % (str(self.id), backup_setting) data = self._conn.request(url) self.event_id = data['event_id'] log.debug("Destroying: %d, Event: %d" % (self.id, self.event_id))
def resize(self, size=None): """ This method allows you to resize a specific droplet to a different size. This will affect the number of processors and memory allocated to the droplet. REQUIRES SNAPSHOT OF DROPLET :type size: int :param size: The new SIZE id of the droplet https://api.digitalocean.com/droplets/[droplet_id]/resize/?size_id=[size_id]& client_id=[your_client_id]&api_key=[your_api_key] """ url = "/droplets/%s/resize" % (str(self.id)) data = self._conn.request(url, size=size) self.event_id = data['event_id'] log.debug("Resizing Droplet: %d, Event: %d" % (self.id, self.event_id)) log.debug("Rebooting Droplet")
def restore(self, image_id=None): """ This method allows you to restore a droplet with a previous image or snapshot. This will be a mirror copy of the image or snapshot to your droplet. Be sure you have backed up any necessary information prior to restore. :type image_id: int :param image_id: ID of the image you would like to use to rebuild your droplet with https://api.digitalocean.com/droplets/[droplet_id]/restore/?image_id=[image_id]& client_id=[your_client_id]&api_key=[your_api_key] """ url = "/droplets/%s/restore" % (str(self.id)) data = self._conn.request(url, image_id=image_id) self.event_id = data['event_id'] log.debug("Restoring: %d With: %d Event: %d" % (self.id, image_id, self.event_id)) self.update()
def resize(self,size=None): """ This method allows you to resize a specific droplet to a different size. This will affect the number of processors and memory allocated to the droplet. REQUIRES SNAPSHOT OF DROPLET :type size: int :param size: The new SIZE id of the droplet https://api.digitalocean.com/droplets/[droplet_id]/resize/?size_id=[size_id]& client_id=[your_client_id]&api_key=[your_api_key] """ url = "/droplets/%s/resize" % (str(self.id)) data = self._conn.request(url,size=size) self.event_id = data['event_id'] log.debug("Resizing Droplet: %d, Event: %d" % (self.id, self.event_id)) log.debug("Rebooting Droplet")
def create_key_pair(self, ssh_key_name=None, cli=False, dry_run=False): """ Method to create a key pair and store the public key on Digital Ocean's servers. SSH Keys are store in ~/.ssh/ NOTE: All key names are prepended with d0 to help disambiguate Digital Ocean keys :type ssh_key_name: string :param ssh_key_name: The name of the new keypair :type dry_run: cli :param dry_run: Set to True if you are using the cli utility and want the path defined ~/.ssh/my_new_key :type dry_run: bool :param dry_run: Set to True if the operation should not actually run. :rtype: dict :return: Dictionary of SSH key info and local path https://api.digitalocean.com/ssh_keys/new/?name=[ssh_key_name]&ssh_pub_key=[ssh_public_key]& client_id=[your_client_id]&api_key=[your_api_key] """ path, file = os.path.split(ssh_key_name) file = 'd0_'+file if not cli: path = pjoin(expanduser('~'), '.ssh') else: path = expanduser(path) if not os.path.isdir(path): os.makedirs(path) keyfile = pjoin(path, file) key = RSA.generate(2048,os.urandom) #public key with open(keyfile+'.pub','w') as f: f.write(key.exportKey('OpenSSH')) public_key = key.exportKey('OpenSSH') os.chmod(keyfile+'.pub', 0o0600) #private key with open(keyfile,'w') as f: f.write(key.exportKey()) os.chmod(keyfile, 0o0600) if dry_run: return data = self._conn.request("/ssh_keys/new/", name=file, ssh_pub_key=public_key) #include path to newly created file data['ssh_key']['path'] = keyfile log.debug(data['ssh_key']) return data['ssh_key']