def confirm_flavor(self, server_id): """Confirm given server id's VM flavor. Args: server_id (str): UUID of virtual machine Returns: dict: Full response from compute API v2.0. If server status is not "VERIFY_RESIZE", return empty dictionary. """ if type(server_id) is not str: raise TypeError while True: vm, vm_status_code = self.get_vm_detail_specified(server_id) if vm['server']['status'] == 'RESIZE': time.sleep(20) # XXX: Magic Number elif vm['server']['status'] == 'VERIFY_RESIZE': break else: raise exceptions.UnexceptedServerStatusError( 'Here, we excepted RESIZE or VERIFY_RESIZE server status' f' but current server status: {vm["server"]["status"]}') data = {'confirmResize': 'null'} res = requests.post(self.__api.compute + f'/{server_id}/action', headers=self.__headers, data=json.dumps(data)) if res.status_code != 204: raise exceptions.BadStatusCodeError( f'HTTP status code is {res.status_code}' ' but we excepted 204.') return res
def reboot_vm(self, server_id): """Reboot given server id's VM. Documentation: https://www.conoha.jp/docs/compute-reboot_vm.html Args: server_id (str): UUID of virtual machine Returns: int: HTTP status code """ if type(server_id) is not str: raise TypeError data = {'reboot': {'type': 'SOFT'}} res = requests.post(self.__api.compute + f'/{server_id}/action', headers=self.__headers, data=json.dumps(data)) if res.status_code != 202: if res.status_code == 404: raise exceptions.ServerNotFoundError( 'Given server_id\'s server not found.') elif res.status_code == 409: raise exceptions.ConflictingRequestError( res.json()['conflictingRequest']['message']) else: raise exceptions.BadStatusCodeError( f'HTTP status code is {res.status_code}' ' but we excepted 202.') self.wait_status(server_id, 'ACTIVE') return res.status_code
def get_vm_detail_specified(self, server_id): """Get details by given server id. We can see "server id" in ConoHa control panel. Move to "詳細設定->VPS設定" on VM you want to check. Here, "UUID" is "server id". Documentation: https://www.conoha.jp/docs/compute-get_vms_detail_specified.html Args: server_id (str): UUID of virtual machine Returns: dict: Full response body int: HTTP status code """ if type(server_id) is not str: raise TypeError res = requests.get(self.__api.compute + f'/{server_id}', headers=self.__headers) if res.status_code != 200: if res.status_code == 404: raise exceptions.ServerNotFoundError( f'Given UUID\'s server not found: {server_id}') else: raise exceptions.BadStatusCodeError( f'HTTP status code is {res.status_code}' ' but we excepted 200.') body = res.json() if body is None: raise exceptions.JsonDecodeError return body, res.status_code
def __get_identity(self): """Post usename, password and tenantid into identity API v2.0. Documentation: https://www.conoha.jp/docs/identity-post_tokens.html Returns: dict: Full response text from identity API v2.0. If error has occured, It returns None. """ payload = { 'auth': { 'passwordCredentials': { 'username': self.__conf['username'], 'password': self.__conf['password'] }, 'tenantId': self.__conf['tenantid'] } } res = requests.post( f'https://identity.{self.__conf["region"]}/v2.0/tokens', data=json.dumps(payload)) if res.status_code != 200: raise exceptions.BadStatusCodeError( f'HTTP status code is {res.status_code} but we excepted 200.') return res
def get_flavors_list(self): """Return flavors list Documentation: https://www.conoha.jp/docs/compute-get_flavors_list.html Returns: dict: Full response from compute API v2.0 int: HTTP status code """ res = requests.get(self.__api.flavors, headers=self.__headers) if res.status_code != 200: raise exceptions.BadStatusCodeError( f'HTTP status code is {res.status_code} but we excepted 200.') body = res.json() if body is None: raise exceptions.JsonDecodeError return body, res.status_code
def get_all_vm_details(self): """ Get all virtual machines details Documentation: https://www.conoha.jp/docs/compute-get_vms_detail.html Returns: dict: Full response body int: HTTP status code """ res = requests.get(self.__api.compute + '/detail', headers=self.__headers) if res.status_code != 200: raise exceptions.BadStatusCodeError( f'HTTP status code is {res.status_code}' ' but we excepted 200.') body = res.json() if body is None: raise exceptions.JsonDecodeError return body, res.status_code
def change_flavor(self, server_id, flavor_id): """Change flavor of given server_id's virtual machine to given flavor. Memo: We can't switch to g-512mb plan from other plan. Args: server_id (str): UUID of virtual machine flavor_id (str): id of flavor (take from `self.get_flavors()`) Returns: dict: Full response body from compute API v2.0. If server status is not "SHUTOFF", return None. """ if type(server_id) is not str: raise TypeError if type(flavor_id) is not str: raise TypeError vm, _ = self.get_vm_detail_specified(server_id) if vm['server']['flavor']['id'] == flavor_id: print('Given flavor_id is same as current flavor. Skip.') return None if vm['server']['status'] == 'SHUTOFF': data = {'resize': {'flavorRef': flavor_id}} res = requests.post(self.__api.compute + f'/{server_id}/action', headers=self.__headers, data=json.dumps(data)) if res.status_code != 202: if res.status_code == 400: raise exceptions.BadRequestError( res.json()['badRequest']['message']) else: raise exceptions.BadStatusCodeError( f'HTTP status code is {res.status_code} ' 'but we excepted 202.') return res else: print('Change flavor operation allowed until server stopped.\n' f'Current server status: {vm["server"]["status"]}') return None
def get_billing_invoices(self, limit=1): """Get billing invoices from billing API v1. Documentation: https://www.conoha.jp/docs/account-billing-invoices-list.html Args: limit (int): Number of gettings Returns: dict: Full respose body from billing API v1 int: HTTP status code """ if type(limit) is not int: raise TypeError res = requests.get(self.__api.billing + f'?limit={limit}', headers=self.__headers) if res.status_code != 200: raise exceptions.BadStatusCodeError( f'HTTP status code is {res.status_code} but we excepted 200.') body = res.json() if body is None: raise exceptions.JsonDecodeError return body, res.status_code