Skip to content
Snippets Groups Projects
Commit 70b665bf authored by Arie Peterson's avatar Arie Peterson
Browse files

Merge branch '5-get_droplets_by_name-ignores-name-parameter' into 'master'

Resolve "get_droplets_by_name ignores name parameter"

Closes #5

See merge request !2
parents b9adfa6a 9b7e5f5a
No related branches found
No related tags found
1 merge request!2Resolve "get_droplets_by_name ignores name parameter"
...@@ -14,6 +14,7 @@ import requests ...@@ -14,6 +14,7 @@ import requests
from tabulate import tabulate from tabulate import tabulate
from pytz import timezone from pytz import timezone
# Helper functions # Helper functions
def request_api(resource: str, request_type: str = 'GET', def request_api(resource: str, request_type: str = 'GET',
data: str = ''): data: str = ''):
...@@ -51,11 +52,9 @@ def request_api(resource: str, request_type: str = 'GET', ...@@ -51,11 +52,9 @@ def request_api(resource: str, request_type: str = 'GET',
if response.content: if response.content:
log.debug('Response: %s\n', response.json()) log.debug('Response: %s\n', response.json())
return json.loads(response.content.decode('utf-8')) return json.loads(response.content.decode('utf-8'))
else: return None
return None raise requests.HTTPError('WARNING: Got response code ',
else: response.status_code, response.text)
raise requests.HTTPError('WARNING: Got response code ',
response.status_code, response.text)
# API calls # API calls
...@@ -92,8 +91,12 @@ def create_domain_record(domain: str, name: str, data: str, ...@@ -92,8 +91,12 @@ def create_domain_record(domain: str, name: str, data: str,
return response['domain_record'] return response['domain_record']
def create_droplet(name: str, ssh_key_id: int, region: str = 'ams1', def create_droplet(name: str, # pylint: disable=too-many-arguments
size: int = 2048, disk: int = 20, image: int = 18): ssh_key_id: int,
region: str = 'ams1',
size: int = 2048,
disk: int = 20,
image: int = 18):
"""Create a droplet. """Create a droplet.
Required values: Required values:
...@@ -120,36 +123,37 @@ def create_droplet(name: str, ssh_key_id: int, region: str = 'ams1', ...@@ -120,36 +123,37 @@ def create_droplet(name: str, ssh_key_id: int, region: str = 'ams1',
return response return response
def delete_domain_record(domain: str, id: int): def delete_domain_record(domain: str, record_id: int):
"""Delete a domain record.""" """Delete a domain record."""
log.info('Deleting domain record %s', id) log.info('Deleting domain record %s', record_id)
response = request_api('domains/{0}/records/{1}'.format(domain, id), response = request_api('domains/{0}/records/{1}'.format(domain, record_id),
'DELETE') 'DELETE')
return response return response
def delete_domain_records_by_name(domain: str, name_regex: str): def delete_domain_records_by_name(domain: str, name_regex: str):
"""Delete all domain records in a given domain matching a regex. r"""Delete all domain records in a given domain matching a regex.
Examples: Examples:
delete_domain_records_by_name('openappstack.net', '^\*.ci-') delete_domain_records_by_name('openappstack.net', '^\*.ci-')
delete_domain_records_by_name('openappstack.net', '^ci-') delete_domain_records_by_name('openappstack.net', '^ci-')
""" """
all = get_domain_records_by_name(domain, name_regex) all_records = get_domain_records_by_name(domain, name_regex)
for record in all: for record in all_records:
delete_domain_record(domain, record['id']) delete_domain_record(domain, record['id'])
def delete_droplet(id: int): def delete_droplet(droplet_id: int):
"""Delete a droplet. Droplet needs to be stopped first.""" """Delete a droplet. Droplet needs to be stopped first."""
log.info('Deleting %s', id) log.info('Deleting %s', droplet_id)
response = request_api('droplets/{0}'.format(id), 'DELETE') response = request_api('droplets/{0}'.format(droplet_id), 'DELETE')
return response return response
def get_domain_record(domain: str, id: int): def get_domain_record(domain: str, droplet_id: int):
"""Get details for given domain record.""" """Get details for given domain record."""
response = request_api('domains/{0}/records/{1}'.format(domain, id)) response = request_api('domains/{0}/records/{1}'.format(domain, droplet_id))
return response['domain_record'] return response['domain_record']
...@@ -206,14 +210,15 @@ def get_droplets_by_name(name_regex: str): ...@@ -206,14 +210,15 @@ def get_droplets_by_name(name_regex: str):
get_droplets_by_name(name_regex='^ci\d+') get_droplets_by_name(name_regex='^ci\d+')
""" """
all_droplets = get_droplets() all_droplets = get_droplets()
log.debug(all_droplets)
matching = [droplet for droplet in all_droplets matching = [droplet for droplet in all_droplets
if re.match('^ci+', droplet['name'])] if re.match(name_regex, droplet['name'])]
return matching return matching
def get_droplet(id: int): def get_droplet(droplet_id: int):
"""Get information about specified droplet.""" """Get information about specified droplet."""
response = request_api('droplets/{0}'.format(id)) response = request_api('droplets/{0}'.format(droplet_id))
return response['droplet'] return response['droplet']
...@@ -223,11 +228,13 @@ def list_domain_records(domain: str): ...@@ -223,11 +228,13 @@ def list_domain_records(domain: str):
log.debug(json.dumps(records, sort_keys=True, indent=2)) log.debug(json.dumps(records, sort_keys=True, indent=2))
table_records = [[ table_records = [
record['id'], record['name'], record['type'], record['data']] [
for record in records] record['id'], record['name'], record['type'], record['data']
] for record in records
]
log.info(tabulate(table_records, log.info(tabulate(table_records,
headers=['ID', 'Name', 'Type', 'Data'])) headers=['ID', 'Name', 'Type', 'Data']))
def list_droplets(): def list_droplets():
...@@ -249,79 +256,87 @@ def list_droplets(): ...@@ -249,79 +256,87 @@ def list_droplets():
headers=['ID', 'Name', 'IPv4', 'Status'])) headers=['ID', 'Name', 'IPv4', 'Status']))
def shutdown_droplet(id: int): def shutdown_droplet(droplet_id: int):
"""Shut down specified droplet (through a power_off call).""" """Shut down specified droplet (through a power_off call)."""
log.info('Shutting down %s', id) log.info('Shutting down %s', droplet_id)
data = {"type": "power_off"} data = {"type": "power_off"}
response = request_api('droplets/{0}/actions'.format(id), 'POST', data) response = request_api('droplets/{0}/actions'.format(droplet_id), 'POST', data)
return response return response
def status_droplet(id: int): def status_droplet(droplet_id: int):
"""Get status of specified droplet.""" """Get status of specified droplet."""
response = get_droplet(id) response = get_droplet(droplet_id)
return response['status'] return response['status']
def terminate_droplet(id: int): def terminate_droplet(droplet_id: int):
"""Terminate a droplet by powering it down and deleting it.""" """Terminate a droplet by powering it down and deleting it."""
shutdown_droplet(id) shutdown_droplet(droplet_id)
wait_for_state(id, 'stopped') wait_for_state(droplet_id, 'stopped')
delete_droplet(id) delete_droplet(droplet_id)
def terminate_droplets_by_name(name_regex: str, ndays: int = 0, domain: str = 'openappstack.net'): def terminate_droplets_by_name(name_regex: str, ndays: int = 0,
domain: str = 'openappstack.net'):
r""" r"""
Terminate droplets matching a regex and for x days older than current day. Terminate droplets matching a regex and for x days older than current day.
Droplets defined on the env variable NO_TERMINATE_DROPLETS will not be delated
Droplets defined on the env variable NO_TERMINATE_DROPLETS will not be
delated
Example how to terminate all CI instances: Example how to terminate all CI instances:
terminate_old_droplets(name_regex='^ci\d+', ndays=5) terminate_old_droplets(name_regex='^ci\d+', ndays=5)
will match i.e 'ci1234' , 'ci1', with a creation time older than 5 days will match i.e 'ci1234' , 'ci1', with a creation time older than 5 days
""" """
threshold_time = (datetime.now(tz=timezone('Europe/Stockholm')) -
threshold_time = (datetime.now(tz=timezone('Europe/Stockholm')) - timedelta(days=ndays)).strftime("%Y-%m-%dT%H:%M:%S+00:00") timedelta(days=ndays)).\
all = get_droplets() strftime("%Y-%m-%dT%H:%M:%S+00:00")
all_droplets = get_droplets()
noterminate_droplets = [] noterminate_droplets = []
if 'NO_TERMINATE_DROPLETS' in os.environ: if 'NO_TERMINATE_DROPLETS' in os.environ:
noterminate_droplets = os.environ['NO_TERMINATE_DROPLETS'].split(',') noterminate_droplets = os.environ['NO_TERMINATE_DROPLETS'].split(',')
for droplet in all: for droplet in all_droplets:
if droplet['name'] not in noterminate_droplets: if droplet['name'] not in noterminate_droplets:
if re.match(name_regex, droplet['name']): if re.match(name_regex, droplet['name']):
if droplet['created_at'] < threshold_time: if droplet['created_at'] < threshold_time:
delete_domain_records_by_name(domain, '^\*.'+droplet['name']) delete_domain_records_by_name(
domain, r'^\*.'+droplet['name'])
delete_domain_records_by_name(domain, '^'+droplet['name']) delete_domain_records_by_name(domain, '^'+droplet['name'])
terminate_droplet(droplet['id']) terminate_droplet(droplet['id'])
def wait_for_ssh(ip: str):
def wait_for_ssh(droplet_ip: str):
"""Wait for ssh to be reachable on port 22.""" """Wait for ssh to be reachable on port 22."""
log.info('Waiting for ssh to become available on ip %s', ip) log.info('Waiting for ssh to become available on ip %s', droplet_ip)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while sock.connect_ex((ip, 22)) != 0: while sock.connect_ex((droplet_ip, 22)) != 0:
sleep(1) sleep(1)
log.info('SSH became available on ip %s', droplet_ip)
def wait_for_state(id: int, state): def wait_for_state(droplet_id: int, state):
"""Wait for a droplet to reach a certain state.""" """Wait for a droplet to reach a certain state."""
log.info('Waiting for droplet %s to reach %s state...', id, state) log.info('Waiting for droplet %s to reach %s state...', droplet_id, state)
status = status_droplet(id) status = status_droplet(droplet_id)
log.debug(status) log.debug(status)
while status != state: while status != state:
sleep(1) sleep(1)
status = status_droplet(id) status = status_droplet(droplet_id)
# When called from from ipython, setup # When called from from ipython, setup
# logging to console # logging to console
try: try:
__IPYTHON__ __IPYTHON__ # pylint: disable=pointless-statement
log = logging.getLogger() log = logging.getLogger() # pylint: disable=invalid-name
log.addHandler(logging.StreamHandler()) log.addHandler(logging.StreamHandler())
log.setLevel(logging.INFO) log.setLevel(logging.INFO)
except NameError: except NameError:
log = logging.getLogger(__name__) log = logging.getLogger(__name__) # pylint: disable=invalid-name
...@@ -5,7 +5,7 @@ with open("README.md", "r") as fh: ...@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
setuptools.setup( setuptools.setup(
name="greenhost_cloud", name="greenhost_cloud",
version="0.1.0", version="0.1.1",
author="Greenhost", author="Greenhost",
author_email="info@greenhost.net", author_email="info@greenhost.net",
description="Create and manipulate Greenhost VPSs via the command line or python functions.", description="Create and manipulate Greenhost VPSs via the command line or python functions.",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment