def callmanager(self, service_id, method, post, data, files=[]): """Call the manager API. 'service_id': an integer holding the service id of the manager. 'method': a string representing the API method name. 'post': boolean value. True for POST method, false for GET. 'data': a dictionary representing the data to be sent to the director. 'files': sequence of (name, filename, value) tuples for data to be uploaded as files. callmanager loads the manager JSON response and returns it as a Python object. """ service = self.service_dict(service_id) # File upload if files: res = client.https_post(service['manager'], 443, '/', data, files) # POST elif post: res = client.jsonrpc_post(service['manager'], 443, '/', method, data) # GET else: res = client.jsonrpc_get(service['manager'], 443, '/', method, data) if res[0] == 200: try: data = simplejson.loads(res[1]) except simplejson.decoder.JSONDecodeError: # Not JSON, simply return what we got return res[1] return data.get('result', data) raise Exception, "Call to method %s on %s failed: %s.\nParams = %s" % ( method, service['manager'], res[1], data)
def callmanager(app_id, service_id, method, post, data, files=[]): """Call the manager API. 'service_id': an integer holding the service id of the manager. 'method': a string representing the API method name. 'post': boolean value. True for POST method, false for GET. 'data': a dictionary representing the data to be sent to the director. 'files': sequence of (name, filename, value) tuples for data to be uploaded as files. callmanager loads the manager JSON response and returns it as a Python object. """ client.conpaas_init_ssl_ctx('/etc/cpsdirector/certs', 'director') application = get_app_by_id(g.user.uid, app_id) if application is None: msg = "Application %s not found." % app_id log_error(msg) return error_response(msg) elif application.to_dict()['manager'] is None: msg = "Application %s has not started. Try to start it first." % app_id log_error(msg) return error_response(msg) application = application.to_dict() # File upload if files: data['service_id'] = service_id res = client.https_post(application['manager'], 443, '/', data, files) # POST elif post: res = client.jsonrpc_post(application['manager'], 443, '/', method, service_id, data) # GET else: res = client.jsonrpc_get(application['manager'], 443, '/', method, service_id, data) if res[0] == 200: try: data = simplejson.loads(res[1]) except simplejson.decoder.JSONDecodeError: # Not JSON, simply return what we got return res[1] return data.get('result', data) raise Exception, "Call to method %s on %s failed: %s.\nParams = %s" % (method, application['manager'], res[1], data)
def callmanager(service_id, method, post, data, files=[]): """Call the manager API. 'service_id': an integer holding the service id of the manager. 'method': a string representing the API method name. 'post': boolean value. True for POST method, false for GET. 'data': a dictionary representing the data to be sent to the director. 'files': sequence of (name, filename, value) tuples for data to be uploaded as files. callmanager loads the manager JSON response and returns it as a Python object. """ service = get_service(g.user.uid, service_id) client.conpaas_init_ssl_ctx('/etc/cpsdirector/certs', 'director') # File upload if files: res = client.https_post(service.manager, 443, '/', data, files) # POST elif post: res = client.jsonrpc_post(service.manager, 443, '/', method, data) # GET else: #res = client.jsonrpc_get(service.manager, 443, '/', method, data) if service.manager_port: node = service.manager_port.split(":") if len(node) == 2: _ip, _port = node else: _ip, _port = (service.manager, 443) res = client.jsonrpc_get(_ip, int(_port), '/', method, data) if res[0] == 200: try: data = simplejson.loads(res[1]) except simplejson.decoder.JSONDecodeError: # Not JSON, simply return what we got return res[1] return data.get('result', data) raise Exception, "Call to method %s on %s failed: %s.\nParams = %s" % ( method, service.manager, res[1], data)
def call_director(self, method, post, data=None, use_certs=True): """Call the director API. Loads the director JSON response and returns it as a Python object. If the returned data can not be decoded it is returned as it is. 'method': a string representing the API method name. 'post': boolean value. True for POST method, false for GET. 'data': a dictionary representing the data to be sent to the director. TODO: use HTTPMethod.x instead of bool for post parameter... """ if self.director_url is None: raise Exception("Cannot call the ConPaaS director:" " the director URL address is not specified.") if data is None: data = {} if not "username" in data: data["username"] = self.username if data["username"] is None: raise Exception("Cannot call the ConPaaS director:" " user name is not specified.") if use_certs: # If certificates are used, the ssl context should already have # been initialized with the user's certificates in __init__ if not client.is_ssl_ctx_initialized(): raise Exception( "Cannot call the ConPaaS director: " "user certificates are not present.\n" "Try to run 'cps-user get_certificate' " "first." ) if self.debug: self.logger.debug("User certificates are present and will be used.") else: # If not, we need to send the user's password and initialize the # ssl context with one that does not use certificates if not "password" in data: if self.password is None: data["password"] = self._get_password() else: data["password"] = self.password client.conpaas_init_ssl_ctx_no_certs() if self.debug: self.logger.debug("User certificates will NOT be used.") url = "%s/%s" % (self.director_url, method) if self.debug: if "password" in data: data_log = dict(data) # hiding password from log if data_log["password"] == "": data_log["password"] = "******" else: data_log["password"] = "******" else: data_log = data self.logger.info("Requesting '%s' with data %s." % (url, data_log)) parsed_url = urlparse.urlparse(self.director_url) try: if post: status, body = client.https_post(parsed_url.hostname, parsed_url.port or 443, url, data) else: status, body = client.https_get(parsed_url.hostname, parsed_url.port or 443, url, data) except Exception as ex: if "certificate verify failed" in str(ex): raise Exception( "The ConPaaS director's SSL certificate " "failed verification.\n" "You may be the victim of a man-in-the-middle " "attack or, if you recently changed the " "ConPaaS deployment, you need to run " "'cps-user get_certificate' first." ) if self.debug: traceback.print_exc() raise Exception("Cannot contact the director at URL '%s': %s" % (url, ex)) if status != 200: raise Exception( "Call to method '%s' on '%s' failed: HTTP status %s.\n" "Params = %s" % (method, url, status, data) ) try: res = simplejson.loads(body) except simplejson.decoder.JSONDecodeError: # Not JSON, simply return what we got if self.debug: self.logger.info("Call succeeded, result is not json.") return body if type(res) is dict and "error" in res: if self.debug: self.logger.info("Call succeeded, result contains an error") raise Exception(res["error"]) self.logger.info("Call succeeded, result is: %s" % res) return res
def call_manager(self, app_id, service_id, method, post, data=None, files=None): """Call the manager API. Loads the manager JSON response and returns it as a Python object. 'service_id': an integer holding the service id of the manager. 'method': a string representing the API method name. 'post': boolean value. True for POST method, false for GET. 'data': a dictionary representing the data to be sent to the director. 'files': sequence of (name, filename, value) tuples for data to be uploaded as files. """ application = self.application_dict(app_id) if application["manager"] is None: raise Exception("Application %s has not started. Try to start it first." % app_id) if data is None: data = {} if files is None: files = [] url = "https://%s/" % application["manager"] # Certificates are always used, the ssl context should already have # been initialized with the user's certificates in __init__ if not client.is_ssl_ctx_initialized(): raise Exception( "Cannot call the manager: " "user certificates are not present.\n" "Try to run 'cps-user get_certificate' " "first." ) if self.debug: self.logger.debug("User certificates are present and will be used.") self.logger.info( "Requesting '%s' with aid %s, sid %s, method '%s', " "data %s and %s files." % (url, app_id, service_id, method, data, len(files)) ) try: # File upload if files: status, body = client.https_post(application["manager"], 443, "/", data, files) # POST elif post: status, body = client.jsonrpc_post(application["manager"], 443, "/", method, service_id, data) # GET else: status, body = client.jsonrpc_get(application["manager"], 443, "/", method, service_id, data) except Exception as ex: if "certificate verify failed" in str(ex): raise Exception( "The ConPaaS manager's SSL certificate " "failed verification.\n" "You may be the victim of a man-in-the-middle " "attack or, if you recently changed the " "ConPaaS deployment, you need to run " "'cps-user get_certificate' first." ) if self.debug: traceback.print_exc() raise Exception("Cannot contact the manager at URL '%s': %s" % (url, ex)) if status != 200: raise Exception( "Call to method '%s' on '%s' failed: HTTP status %s.\n" "Params = %s" % (method, application["manager"], status, data) ) try: data = simplejson.loads(body) except simplejson.decoder.JSONDecodeError: # Not JSON, simply return what we got if self.debug: self.logger.info("Call succeeded, result is not json.") return body res = data.get("result", data) if type(res) is dict and "error" in res: if self.debug: self.logger.info("Call succeeded, result contains an error") raise Exception(res["error"]) self.logger.info("Call succeeded, result is: %s" % res) return res