def get_controller(self, path): """Get the request controller according to the request path this method returns a response, a controller and tenant id and parsed list of path. if the path starts with cimiv1, then this is CIMI request, the next segment in the path should indicate the controller. if the controller does not exist, then the response will indicate the error. if the controller is found, then the response will be None. if the path does not start with cimiv1, then this is not CIMI request, the controller and response will be none. the request should be forwarded to the next filter in the pipeline. """ parts = path.strip('/').split('/') # each request should have /cimiv1/tenant_id/controller_key # in its url pattern. if len(parts) >= 2: controller_key = parts[1].lower() controller = self.CONTROLLERS.get(controller_key) return None, controller, parts[0], parts[2:] else: resp = get_err_response('BadRequest') return resp, None, None, None
def POST(self, req, *parts): """ Handle Machine operations """ try: request_data = get_request_data(req.body, self.req_content_type) except Exception as error: return get_err_response('MalformedBody') request_data = request_data.get('body', {}) if request_data.get('Action'): request_data = request_data.get('Action') action = request_data.get('action', 'notexist') method = self.actions.get(action) if method: resp = getattr(self, '_' + method)(req, request_data, *parts) else: resp = get_err_response('NotImplemented') return resp
def __call__(self, env, start_response): if env.get('SCRIPT_NAME', '').startswith(self.request_prefix): path = unquote(env.get('PATH_INFO', '')) response, controller, tenant_id, parts = self.get_controller(path) if response: return response(env, start_response) elif controller: req = Request(env) ctrler = controller(self.conf, self.app, req, tenant_id, *parts) method = env.get('REQUEST_METHOD').upper() if hasattr(ctrler, method) and not method.startswith('_'): res = getattr(ctrler, method)(req, *parts) return res(env, start_response) else: res = get_err_response('NotImplemented') return res(env, start_response) else: res = get_err_response('NotImplemented') return res(env, start_response) else: return self.app(env, start_response)
def POST(self, req, *parts): """ Handle POST machine request which will create a machine """ try: request_data = get_request_data(req.body, self.req_content_type) except Exception as error: return get_err_response('MalformedBody') if request_data: data = request_data.get('body').get('MachineCreate') if not data: data = request_data.get('body') if data: new_body = {} match_up(new_body, data, 'name', 'name') keys = {'/cimiv1': '/v2', 'machineConfig': 'flavors', 'machineImage': 'images'} match_up(new_body, data, 'imageRef', 'machineTemplate/machineImage/href') new_body['imageRef'] = sub_path(new_body.get('imageRef'), keys) match_up(new_body, data, 'flavorRef', 'machineTemplate/machineConfig/href') new_body['flavorRef'] = sub_path(new_body.get('flavorRef'), keys) new_req = self._fresh_request(req) adminPass = data.get('credentials', {}).get('password') if adminPass: new_body['adminPass'] = adminPass new_req.body = json.dumps({'server':new_body}) resp = new_req.get_response(self.app) if resp.status_int == 201: # resource created successfully, we redirect the request # to query machine resp_data = json.loads(resp.body) id = resp_data.get('server').get('id') env = self._fresh_env(req) env['PATH_INFO'] = concat(self.request_prefix, '/', self.tenant_id, '/servers/', id) env['REQUEST_METHOD'] = 'GET' new_req = Request(env) resp = new_req.get_response(self.app) resp.status = 201 elif resp.status_int == 202: resp_body_data = json.loads(resp.body).get('server') id = resp_body_data.get('id') resp_data = {} match_up(resp_data, data, 'name', 'name') match_up(resp_data, data, 'description', 'description') resp_data['id'] = concat(self.tenant_id, '/machine/', id) resp_data['credentials'] = {'userName': '******', 'password': resp_body_data.get('adminPass')} if self.res_content_type == 'application/xml': response_data = {'Machine': resp_data} else: response_data = resp_data new_content = make_response_data(response_data, self.res_content_type, self.machine_metadata, self.uri_prefix) resp = Response() self._fixup_cimi_header(resp) resp.headers['Content-Type'] = self.res_content_type resp.status = 202 resp.body = new_content return resp else: return get_err_response('BadRequest') else: return get_err_response('BadRequest')