import requests from flask import current_app from app import config class DigitalOcean(object): base = 'https://api.digitalocean.com/v2/' headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + config.DO_TOKEN } def make_req(self, method, endpoint, data=None): url = self.base + endpoint current_app.logger.info(f'{method.upper()} - {url}') if method == 'post': r = requests.post(url, timeout=8, headers=self.headers, json=data) elif method == 'get': r = requests.get(url, timeout=8, headers=self.headers) elif method == 'delete': r = requests.delete(url, timeout=8, headers=self.headers) else: return 'method not defined' r.raise_for_status() return r # Account meta def show_account(self): r = self.make_req('get', 'account') return r.json()['account'] # Domains and records def create_record(self, name, ip_addr, type='A'): data = { 'type': type, 'name': name, 'data': ip_addr } r = self.make_req('post', f'domains/{config.DO_DOMAIN}/records', data) return r.json()['domain_record'] def delete_record(self, record_id): if record_id: route = f'domains/{config.DO_DOMAIN}/records/{record_id}' r = self.make_req('delete', route) if r.status_code == 204: return True else: return False else: return False # SSH Keys def create_key(self, name, public_key): data = { 'name': name, 'public_key': public_key.strip() } return self.make_req('post', 'account/keys', data) def list_keys(self): return self.make_req('get', 'account/keys') # Volumes def create_volume(self, name, region): data = { 'name': name, 'size_gigabytes': int(config.DO_DROPLET_STORAGE_GB), 'region': region, 'filesystem_type': 'ext4' } r = self.make_req('post', 'volumes', data) return r.json()['volume'] def list_volumes(self): r = self.make_req('get', 'volumes') return r.json()['volumes'] def check_volume_exists(self, name, region): r = self.make_req('get', f'volumes?name={name}®ion={region}') if r.json()['volumes'] == list(): return (False, None) else: return (True, r.json()['volumes'][0]['id']) def show_volume(self, volume_id): r = self.make_req('get', f'volumes/{volume_id}') return r.json()['volume'] # Droplets def create_droplet(self, name, region, extra_vols=[]): # First check that droplet name does not exist de = self.check_droplet_exists(name) if de[0]: return self.show_droplet(de[1]) data = { 'name': name, 'region': region, 'size': config.DO_DROPLET_SIZE, 'image': config.DO_DROPLET_IMAGE, 'ssh_keys': [ int(config.DO_SSH_KEY) ], 'backups': False, 'ipv6': True, 'user_data': f'#!/bin/bash\nwget https://raw.githubusercontent.com/lalanza808/docker-monero-node/master/cloud-init.sh -q -O - | DOMAIN={name}.node.{config.DO_DOMAIN} ACME_EMAIL={config.ADMIN_EMAIL} GRAF_PASS={config.GRAF_PASS} GRAF_USER={config.GRAF_USER} bash', 'private_networking': None, 'volumes': extra_vols, 'tags': [] } r = self.make_req('post', 'droplets', data) return r.json()['droplet'] def destroy_droplet(self, droplet_id): if droplet_id: route = f'droplets/{droplet_id}/destroy_with_associated_resources/dangerous' self.headers['X-Dangerous'] = 'true' r = self.make_req('delete', route) if r.status_code == 202: return True else: return False else: return False def show_droplet(self, droplet_id): if droplet_id: r = self.make_req('get', f'droplets/{droplet_id}') return r.json()['droplet'] else: return None def check_droplet_exists(self, name): r = self.make_req('get', 'droplets') droplets = r.json()['droplets'] for d in droplets: if d['name'] == name: return (True, d['id']) return (False, None) # Pricing def get_droplet_price_usd_per_hour(self, size): sizes = { 's-1vcpu-1gb': .00744, 's-1vcpu-2gb': .015, 's-2vcpu-2gb': .022, 's-2vcpu-4gb': .030, 's-4vcpu-8gb': .060, 's-8vcpu-16gb': .119, } return sizes[size] def get_volume_price_usd_per_hour(self, size_gb): return round(0.105 * size_gb / 730, 3) do = DigitalOcean()