|
| 1 | +""" Copyright (c) Trainline Limited, 2016. All rights reserved. See LICENSE.txt in the project root for license information. """ |
| 2 | +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 |
| 3 | + |
| 4 | +import time |
| 5 | +import requests |
| 6 | +from environment_manager.utils import LogWrapper |
| 7 | + |
| 8 | +class EMApi(object): |
| 9 | + """Defines all api calls and treats them like an object to give proper interfacing""" |
| 10 | + |
| 11 | + def __init__(self, server=None, user=None, password=None, retries=5): |
| 12 | + """ Initialise new API object """ |
| 13 | + self.server = server |
| 14 | + self.user = user |
| 15 | + self.password = password |
| 16 | + self.retries = retries |
| 17 | + self.token = None |
| 18 | + # Sanitise input |
| 19 | + if server is None or user is None or password is None: |
| 20 | + raise ValueError('EMApi(server=SERVERNAME, user=USERNAME, password=PASSWORD, [retries=N])') |
| 21 | + if server == '' or user == '' or password == '': |
| 22 | + raise ValueError('EMApi(server=SERVERNAME, user=USERNAME, password=PASSWORD, [retries=N])') |
| 23 | + |
| 24 | + def _api_auth(self): |
| 25 | + """ Function to authenticate in Environment Manager """ |
| 26 | + log = LogWrapper() |
| 27 | + log.info('Authenticating in EM with user %s' % self.user) |
| 28 | + # Build base url |
| 29 | + base_url = 'https://%s' % self.server |
| 30 | + # Request token |
| 31 | + token_payload = {'grant_type': 'password', |
| 32 | + 'username': self.user, |
| 33 | + 'password': self.password} |
| 34 | + token = None |
| 35 | + no_token = True |
| 36 | + retries = 0 |
| 37 | + while no_token and retries < self.retries: |
| 38 | + em_token_url = '%s/api/token' % base_url |
| 39 | + em_token = requests.post(em_token_url, data=token_payload, timeout=5, verify=False) |
| 40 | + if int(str(em_token.status_code)[:1]) == 2: |
| 41 | + token = em_token.text |
| 42 | + no_token = False |
| 43 | + else: |
| 44 | + log.debug('Could not authenticate, trying again: %s' % em_token.status_code) |
| 45 | + time.sleep(2) |
| 46 | + retries += 1 |
| 47 | + if token is not None: |
| 48 | + # Got token now lets get URL |
| 49 | + token_bearer = 'Bearer %s' % token |
| 50 | + return token_bearer |
| 51 | + else: |
| 52 | + raise SystemError('Could not authenticate against Environment Manager') |
| 53 | + |
| 54 | + def query(self, query_endpoint=None, retries=5, backoff=2): |
| 55 | + """ Function to querying Environment Manager """ |
| 56 | + log = LogWrapper() |
| 57 | + if query_endpoint is None: |
| 58 | + log.info('No query endpoint specified, cant just go and query nothing') |
| 59 | + raise SyntaxError('No query endpoint specified, cant just go and query nothing') |
| 60 | + retry_num = 0 |
| 61 | + while retry_num < retries: |
| 62 | + retry_num += 1 |
| 63 | + log.debug('Going through query iteration %s out of %s' % (retry_num, retries)) |
| 64 | + token = self._api_auth() |
| 65 | + log.debug('Using token %s for auth' % token) |
| 66 | + # Build base url |
| 67 | + base_url = 'https://%s' % self.server |
| 68 | + request_url = '%s%s' % (base_url, query_endpoint) |
| 69 | + log.debug('Calling URL %s' % request_url) |
| 70 | + request = requests.get(request_url, headers={'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': token}, timeout=30, verify=False) |
| 71 | + if int(str(request.status_code)[:1]) == 2: |
| 72 | + return request.json() |
| 73 | + else: |
| 74 | + log.info('Got a status %s from EM, cant serve, retrying' % request.status_code) |
| 75 | + log.debug(request.request.headers) |
| 76 | + log.debug(request.__dict__) |
| 77 | + time.sleep(backoff) |
| 78 | + # General one if we exceeded our retries |
| 79 | + raise SystemError('Max number of retries (%s) querying Environment Manager, will abort for now' % retries) |
| 80 | + |
| 81 | + ####################################################### |
| 82 | + # This is a full API implementation based on EM docs # |
| 83 | + ####################################################### |
| 84 | + |
| 85 | + ## Accounts |
| 86 | + |
| 87 | + ## AMI |
| 88 | + |
| 89 | + ## ASG |
| 90 | + def get_asgs(self, account='Non-Prod', **kwargs): |
| 91 | + """ Get list of ASGs from EM """ |
| 92 | + request_endpoint = '/api/v1/asgs?account=%s' % account |
| 93 | + return self.query(request_endpoint, **kwargs) |
| 94 | + |
| 95 | + ## Audit |
| 96 | + |
| 97 | + ## Cluster |
| 98 | + |
| 99 | + ## Deployment |
| 100 | + |
| 101 | + ## Deployment Map |
| 102 | + |
| 103 | + ## Environment |
| 104 | + def get_environment_asg_servers(self, environment=None, asgname=None, **kwargs): |
| 105 | + """ Get list of servers belonging to an environment ASG """ |
| 106 | + if environment is None or asgname is None: |
| 107 | + raise SyntaxError('Either environment or asgname has not been specified') |
| 108 | + request_endpoint = '/api/v1/environments/%s/servers/%s' % (environment, asgname) |
| 109 | + return self.query(request_endpoint, **kwargs) |
| 110 | + |
| 111 | + ## Environment Type |
| 112 | + |
| 113 | + ## Export |
| 114 | + |
| 115 | + ## Import |
| 116 | + |
| 117 | + ## Instance |
| 118 | + |
| 119 | + ## Load Balancers |
| 120 | + def get_lb_settings(self, **kwargs): |
| 121 | + """ Get list of Services from EM """ |
| 122 | + request_endpoint = '/api/v1/config/lb-settings' |
| 123 | + return self.query(request_endpoint, **kwargs) |
| 124 | + |
| 125 | + ## Package |
| 126 | + |
| 127 | + ## Permissions |
| 128 | + |
| 129 | + ## Service |
| 130 | + def get_services(self, **kwargs): |
| 131 | + """ Get list of Services from EM """ |
| 132 | + request_endpoint = '/api/v1/config/services' |
| 133 | + return self.query(request_endpoint, **kwargs) |
| 134 | + |
| 135 | + ## Status |
| 136 | + |
| 137 | + ## Target State |
| 138 | + |
| 139 | + ## Upstream |
| 140 | + def get_upstreams(self, **kwargs): |
| 141 | + """ Get list of Upstreams from EM """ |
| 142 | + request_endpoint = '/api/v1/config/upstreams' |
| 143 | + return self.query(request_endpoint, **kwargs) |
0 commit comments