def test_show(self): def _mock_data(): return { "keypair_id": KEYPAIR_ID1, "nova_keypair_id": "fake_key1", "gid": GID, "user_id": "noauth", "project_id": "noauth", "display_name": "fake_key1", "private_key": PRIVATE_KEY, "is_default": False, "status": "ACTIVE" } self.mox.StubOutWithMock(db, "keypair_get_by_keypair_id") self.mox.StubOutWithMock(manager.ResourceOperator, "keypair_show") db.keypair_get_by_keypair_id(IsA(context.RequestContext), GID, KEYPAIR_ID1).AndReturn(_mock_data()) manager.ResourceOperator.keypair_show(IsA(context.RequestContext), IsA(dict)).AndReturn( _mock_data()) self.mox.ReplayAll() url = "/v1/groups/" + GID + "/keypairs/" + KEYPAIR_ID1 req = get_request(url, 'GET') res = req.get_response(self.app) body = jsonutils.loads(res.body) expect = _mock_data() expect.update(name="fake_key1") self.assertEqual(res.status_code, 200) for key in body["keypair"]: self.assertEqual(expect[key], body["keypair"][key])
def test_show_keypair_not_found(self): self.mox.StubOutWithMock(db, "keypair_get_by_keypair_id") db.keypair_get_by_keypair_id( IsA(context.RequestContext), GID, KEYPAIR_ID)\ .AndRaise(exception.KeypairNotFound(keypair_id=KEYPAIR_ID)) self.mox.ReplayAll() url = "/v1/groups/" + GID + "/keypairs/" + KEYPAIR_ID req = get_request(url, 'GET') res = req.get_response(self.app) self.assertEqual(res.status_code, 404)
def test_show_not_found(self): self.mox.StubOutWithMock(db, "keypair_get_by_keypair_id") db.keypair_get_by_keypair_id(IsA( context.RequestContext), GID, KEYPAIR_ID1).AndRaise( exception.KeypairNotFound(keypair_id=KEYPAIR_ID1)) self.mox.ReplayAll() url = "/v1/groups/" + GID + "/keypairs/" + KEYPAIR_ID1 req = get_request(url, 'GET') res = req.get_response(self.app) self.assertEqual(res.status_code, 404)
def test_keypair_get_by_keypair_id(self): gid = "12345678-1234-5678-9123-123456789012" self._create_group(gid) values = [ {"keypair_id": unicode(uuid.uuid4()), "display_name": "test_keypair1"}, {"keypair_id": unicode(uuid.uuid4()), "display_name": "test_keypair2"}, ] keypairs = [self._create_keypair(gid, value) for value in values] expected = db.keypair_get_by_keypair_id( self.user_ctxt, gid, values[0]["keypair_id"]) self._assertEqualObjects(keypairs[0], expected)
def show(self, req, gid, keypair_id): try: self._uuid_check(gid=gid, keypair_id=keypair_id) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) context = req.environ["rack.context"] try: keypair = db.keypair_get_by_keypair_id(context, gid, keypair_id) except exception.KeypairNotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) return self._view_builder.show(keypair)
def test_delete_keypair_not_found(self): self.mox.StubOutWithMock(db, "process_get_all") self.mox.StubOutWithMock(db, "keypair_get_by_keypair_id") self.mox.StubOutWithMock(manager.ResourceOperator, "keypair_delete") db.process_get_all(IsA(context.RequestContext), GID, filters={ "keypair_id": KEYPAIR_ID }).AndReturn([]) db.keypair_get_by_keypair_id(IsA(context.RequestContext), GID, KEYPAIR_ID).AndReturn( {"nova_keypair_id": KEYPAIR_ID}) manager.ResourceOperator.keypair_delete(IsA( context.RequestContext), KEYPAIR_ID).AndRaise(exception.NotFound()) self.mox.ReplayAll() url = "/v1/groups/" + GID + "/keypairs/" + KEYPAIR_ID req = get_request(url, "DELETE") res = req.get_response(self.app) self.assertEqual(res.status_code, 404)
def show(self, req, gid, keypair_id): try: self._uuid_check(gid=gid, keypair_id=keypair_id) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) context = req.environ['rack.context'] try: keypair = db.keypair_get_by_keypair_id(context, gid, keypair_id) self.manager.keypair_show(context, keypair) except exception.KeypairNotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) return self._view_builder.show(keypair)
def delete(self, req, gid, keypair_id): context = req.environ['rack.context'] try: self._uuid_check(gid=gid, keypair_id=keypair_id) filters = {"keypair_id": keypair_id} processes = db.process_get_all(context, gid, filters=filters) if processes: raise exception.keypairInUse(keypair_id=keypair_id) keypair = db.keypair_get_by_keypair_id(context, gid, keypair_id) self.manager.keypair_delete(context, keypair["nova_keypair_id"]) db.keypair_delete(context, gid, keypair_id) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) except exception.keypairInUse as e: raise webob.exc.HTTPConflict(explanation=e.format_message())
def _validate(context, body, gid, is_proxy=False): proxy = db.process_get_all(context, gid, filters={"is_proxy": True}) if is_proxy: if len(proxy) > 0: msg = _("Proxy process already exists in the group %s" % gid) raise exception.InvalidInput(reason=msg) else: if len(proxy) != 1: msg = _("Proxy process does not exist in the group %s" % gid) raise webob.exc.HTTPBadRequest(explanation=msg) keyname = "proxy" if is_proxy else "process" if not self.is_valid_body(body, keyname): msg = _("Invalid request body") raise exception.InvalidInput(reason=msg) values = body[keyname] ppid = values.get("ppid") name = values.get("name") keypair_id = values.get("keypair_id") securitygroup_ids = values.get("securitygroup_ids") glance_image_id = values.get("glance_image_id") nova_flavor_id = values.get("nova_flavor_id") userdata = values.get("userdata") args = values.get("args") self._uuid_check(gid, ppid, keypair_id) pid = unicode(uuid.uuid4()) if not name: prefix = "proxy-" if is_proxy else "process-" name = prefix + pid if ppid: parent_process = db.process_get_by_pid(context, gid, ppid) nova_keypair_id = None if keypair_id: keypair = db.keypair_get_by_keypair_id(context, gid, keypair_id) nova_keypair_id = keypair["nova_keypair_id"] elif ppid: keypair_id = parent_process.get("keypair_id") if keypair_id: keypair = db.keypair_get_by_keypair_id( context, gid, keypair_id) nova_keypair_id = keypair["nova_keypair_id"] else: default_keypair = db.keypair_get_all( context, gid, filters={"is_default": True}) if default_keypair: keypair_id = default_keypair[0]["keypair_id"] nova_keypair_id = default_keypair[0]["nova_keypair_id"] if securitygroup_ids is not None and\ not isinstance(securitygroup_ids, list): msg = _("securitygroupids must be a list") raise exception.InvalidInput(reason=msg) elif securitygroup_ids: neutron_securitygroup_ids = [] for id in securitygroup_ids: self._uuid_check(securitygroup_id=id) securitygroup = db.securitygroup_get_by_securitygroup_id( context, gid, id) neutron_securitygroup_ids.append( securitygroup["neutron_securitygroup_id"]) elif ppid: securitygroups = parent_process.get("securitygroups") securitygroup_ids =\ [securitygroup["securitygroup_id"] for securitygroup in securitygroups] neutron_securitygroup_ids =\ [securitygroup["neutron_securitygroup_id"] for securitygroup in securitygroups] else: default_securitygroups = db.securitygroup_get_all( context, gid, filters={"is_default": True}) if default_securitygroups: securitygroup_ids =\ [securitygroup["securitygroup_id"] for securitygroup in default_securitygroups] neutron_securitygroup_ids =\ [securitygroup["neutron_securitygroup_id"] for securitygroup in default_securitygroups] else: msg = _("securitygroup_ids is required. Default \ securitygroup_ids are not registered.") raise exception.InvalidInput(reason=msg) if not glance_image_id and ppid: glance_image_id = parent_process.get("glance_image_id") if not nova_flavor_id and ppid: nova_flavor_id = parent_process.get("nova_flavor_id") if userdata: try: base64.b64decode(userdata) except TypeError: msg = _("userdadta must be a base64 encoded value.") raise exception.InvalidInput(reason=msg) networks = db.network_get_all(context, gid) if not networks: msg = _("Netwoks does not exist in the group %s" % gid) raise webob.exc.HTTPBadRequest(explanation=msg) network_ids =\ [network["network_id"] for network in networks] neutron_network_ids =\ [network["neutron_network_id"] for network in networks] nics = [] for id in neutron_network_ids: nics.append({"net-id": id}) if args is None: args = {} elif args is not None and\ not isinstance(args, dict): msg = _("args must be a dict.") raise exception.InvalidInput(reason=msg) else: for key in args.keys(): args[key] = str(args[key]) default_args = { "gid": gid, "pid": pid, } if ppid: default_args["ppid"] = ppid if is_proxy: default_args["rackapi_ip"] = cfg.CONF.my_ip default_args["os_username"] = cfg.CONF.os_username default_args["os_password"] = cfg.CONF.os_password default_args["os_tenant_name"] = cfg.CONF.os_tenant_name default_args["os_auth_url"] = cfg.CONF.os_auth_url default_args["os_region_name"] = cfg.CONF.os_region_name else: proxy_instance_id = proxy[0]["nova_instance_id"] default_args["proxy_ip"] = self.manager.get_process_address( context, proxy_instance_id) args.update(default_args) valid_values = {} valid_values["gid"] = gid valid_values["ppid"] = ppid valid_values["pid"] = pid valid_values["display_name"] = name valid_values["keypair_id"] = keypair_id valid_values["securitygroup_ids"] = securitygroup_ids valid_values["glance_image_id"] = glance_image_id valid_values["nova_flavor_id"] = nova_flavor_id valid_values["userdata"] = userdata valid_values["args"] = json.dumps(args) valid_values["is_proxy"] = True if is_proxy else False valid_values["network_ids"] = network_ids if is_proxy: ipc_endpoint = values.get("ipc_endpoint") shm_endpoint = values.get("shm_endpoint") fs_endpoint = values.get("fs_endpoint") if ipc_endpoint: utils.check_string_length(ipc_endpoint, 'ipc_endpoint', min_length=1, max_length=255) if shm_endpoint: utils.check_string_length(shm_endpoint, 'shm_endpoint', min_length=1, max_length=255) if fs_endpoint: utils.check_string_length(fs_endpoint, 'fs_endpoint', min_length=1, max_length=255) valid_values["ipc_endpoint"] = ipc_endpoint valid_values["shm_endpoint"] = shm_endpoint valid_values["fs_endpoint"] = fs_endpoint boot_values = {} boot_values["name"] = name boot_values["key_name"] = nova_keypair_id boot_values["security_groups"] = neutron_securitygroup_ids boot_values["image"] = glance_image_id boot_values["flavor"] = nova_flavor_id boot_values["userdata"] = userdata boot_values["meta"] = args boot_values["nics"] = nics return valid_values, boot_values
def create(self, req, body, gid): def _validate_process(context, gid, body): if not uuidutils.is_uuid_like(gid): raise exception.GroupNotFound(gid=gid) if not self.is_valid_body(body, 'process'): msg = _("Invalid request body") raise exception.InvalidInput(reason=msg) values = body["process"] ppid = values.get("ppid") keypair_id = values.get("keypair_id") name = values.get("name") glance_image_id = values.get("glance_image_id") nova_flavor_id = values.get("nova_flavor_id") securitygroup_ids = values.get("securitygroup_ids") userdata = values.get("userdata") if ppid is not None: if not uuidutils.is_uuid_like(ppid): raise exception.ProcessNotFound(pid=ppid) p_process = db.process_get_by_pid(context, gid, ppid) if keypair_id is not None: if not uuidutils.is_uuid_like(keypair_id): raise exception.KeypairNotFound(keypair_id=keypair_id) elif ppid is not None: keypair_id = p_process.get("keypair_id") if isinstance(name, six.string_types): name = name.strip() utils.check_string_length(name, 'name', min_length=1, max_length=255) elif name is not None: msg = _("name must be a String") raise exception.InvalidInput(reason=msg) if glance_image_id is None: if ppid is not None: glance_image_id = p_process.get("glance_image_id") elif not uuidutils.is_uuid_like(glance_image_id): msg = _("glance_image_id is invalid format") raise exception.InvalidInput(reason=msg) if nova_flavor_id is None and ppid is not None: nova_flavor_id = p_process.get("nova_flavor_id") utils.validate_integer(nova_flavor_id, 'nova_flavor_id') if not securitygroup_ids: if ppid is not None: securitygroup_ids = [securitygroup.get("securitygroup_id") for securitygroup in p_process.get( "securitygroups")] else: msg = _("securitygroup_ids is required") raise exception.InvalidInput(reason=msg) if isinstance(securitygroup_ids, list): for securitygroup_id in securitygroup_ids: if securitygroup_id is not None and not uuidutils\ .is_uuid_like(securitygroup_id): raise exception.SecuritygroupNotFound( securitygroup_id=securitygroup_id) else: msg = _("securitygroup_ids must be list") raise exception.InvalidInput(reason=msg) if userdata: try: userdata = base64.b64decode(userdata) except TypeError as e: raise webob.exc.HTTPBadRequest( explanation=e.format_message()) valid_values = {} valid_values_process = {} valid_values_process["gid"] = gid valid_values_process["keypair_id"] = keypair_id valid_values_process["ppid"] = ppid valid_values_process["display_name"] = name valid_values_process["glance_image_id"] = glance_image_id valid_values_process["nova_flavor_id"] = nova_flavor_id valid_values_process["is_proxy"] = False valid_values_process["app_status"] = "BUILDING" valid_values_userdata = {} valid_values_userdata["userdata"] = userdata valid_values_securitygroup = {} valid_values_securitygroup["securitygroup_ids"] = securitygroup_ids valid_values["process"] = valid_values_process valid_values["userdata"] = valid_values_userdata valid_values["securitygroup"] = valid_values_securitygroup return valid_values def _validate_metadata(metadata): if metadata is None: return {} if not isinstance(metadata, dict): msg = _("metadata must be a dict") raise exception.InvalidInput(reason=msg) return metadata try: context = req.environ['rack.context'] valid_values = _validate_process(context, gid, body) values = valid_values.get("process") securitygroup_ids = valid_values.get( "securitygroup").get("securitygroup_ids") metadata = _validate_metadata(metadata=body["process"] .get("args")) metadata.update({"proxy_ip": cfg.CONF.my_ip}) userdata = valid_values.get("userdata") values["deleted"] = 0 values["status"] = "BUILDING" values["pid"] = unicode(uuid.uuid4()) values["user_id"] = context.user_id values["project_id"] = context.project_id values["display_name"] = values[ "display_name"] or "pro-" + values["pid"] values["userdata"] = userdata.get("userdata") if values["ppid"]: db.process_get_by_pid(context, gid, values["ppid"]) if values["keypair_id"]: nova_keypair_id = db.keypair_get_by_keypair_id( context, gid, values["keypair_id"]).get("nova_keypair_id") else: nova_keypair_id = None networks = db.network_get_all(context, gid, {"status": "ACTIVE"}) if not networks: raise exception.NoNetworksFound(gid=values["gid"]) network_ids = [network["network_id"] for network in networks] process = db.process_create( context, values, network_ids, securitygroup_ids) except exception.InvalidInput as e: raise webob.exc.HTTPBadRequest(explanation=e.format_message()) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) try: host = self.scheduler_rpcapi.select_destinations( context, request_spec={}, filter_properties={}) self.operator_rpcapi.process_create( context, host["host"], pid=values["pid"], ppid=values["ppid"] or values["pid"], gid=gid, name=values["display_name"], glance_image_id=values["glance_image_id"], nova_flavor_id=values["nova_flavor_id"], nova_keypair_id=nova_keypair_id, neutron_securitygroup_ids=[securitygroup[ "neutron_securitygroup_id"] for securitygroup in process["securitygroups"]], neutron_network_ids=[network["neutron_network_id"] for network in process["networks"]], metadata=metadata, userdata=userdata.get("userdata")) except Exception as e: LOG.exception(e) pid = values["pid"] db.process_update(context, gid, pid, {"status": "ERROR"}) raise exception.ProcessCreateFailed() return self._view_builder.create(process)
def create(self, req, body, gid): def _validate_proxy(context, gid, body): if not uuidutils.is_uuid_like(gid): raise exception.GroupNotFound(gid=gid) proxy = db.process_get_not_error_status_for_proxy(context, gid) if len(proxy) > 0: msg = _("Proxy instance already exists in this group") raise exception.ProxyCreateFailed(msg) if not self.is_valid_body(body, 'proxy'): msg = _("Invalid request body") raise exception.InvalidInput(reason=msg) values = body["proxy"] keypair_id = values.get("keypair_id") name = values.get("name") glance_image_id = values.get("glance_image_id") nova_flavor_id = values.get("nova_flavor_id") securitygroup_ids = values.get("securitygroup_ids") userdata = values.get("userdata") if keypair_id is not None: if not uuidutils.is_uuid_like(keypair_id): raise exception.KeypairNotFound(keypair_id=keypair_id) if isinstance(name, six.string_types): name = name.strip() utils.check_string_length(name, 'name', min_length=1, max_length=255) elif name is not None: msg = _("name must be a String") raise exception.InvalidInput(reason=msg) if not uuidutils.is_uuid_like(glance_image_id): msg = _("glance_image_id is invalid format") raise exception.InvalidInput(reason=msg) utils.validate_integer(nova_flavor_id, 'nova_flavor_id') if not securitygroup_ids: msg = _("securitygroup_ids is required") raise exception.InvalidInput(reason=msg) if isinstance(securitygroup_ids, list): for securitygroup_id in securitygroup_ids: if securitygroup_id is not None and not uuidutils\ .is_uuid_like(securitygroup_id): raise exception.SecuritygroupNotFound( securitygroup_id=securitygroup_id) else: msg = _("securitygroup_ids must be list") raise exception.InvalidInput(reason=msg) if userdata: try: userdata = base64.b64decode(userdata) except TypeError as e: raise webob.exc.HTTPBadRequest( explanation=e.format_message()) valid_values = {} valid_values_proxy = {} valid_values_proxy["gid"] = gid valid_values_proxy["keypair_id"] = keypair_id valid_values_proxy["display_name"] = name valid_values_proxy["glance_image_id"] = glance_image_id valid_values_proxy["nova_flavor_id"] = nova_flavor_id valid_values_proxy["is_proxy"] = True valid_values_proxy["app_status"] = "BUILDING" valid_values_userdata = {} valid_values_userdata["userdata"] = userdata valid_values_securitygroup = {} valid_values_securitygroup["securitygroup_ids"] = securitygroup_ids valid_values["proxy"] = valid_values_proxy valid_values["userdata"] = valid_values_userdata valid_values["securitygroup"] = valid_values_securitygroup return valid_values def _validate_metadata(args): if args is None: return dict(roles="ipc/shm/api/proxy") else: if not isinstance(args, dict): msg = _("args must be a dict") raise exception.InvalidInput(reason=msg) if args.get("roles"): args["roles"] = args.get("roles") + "/proxy" else: args["roles"] = "ipc/shm/api/proxy" return args def _get_proxy_conf(): conf = {} expr = "(127.0.0.1|localhost)" conf.update(dict(rabbit_userid=cfg.CONF.rabbit_userid)) conf.update(dict(rabbit_password=cfg.CONF.rabbit_password)) conf.update( dict(rabbit_host=re.sub(expr, cfg.CONF.my_ip, cfg.CONF.rabbit_host))) conf.update( dict(sql_connection=re.sub(expr, cfg.CONF.my_ip, cfg.CONF.sql_connection))) return conf try: context = req.environ['rack.context'] valid_values = _validate_proxy(context, gid, body) values = valid_values.get("proxy") securitygroup_ids = valid_values.get( "securitygroup").get("securitygroup_ids") userdata = valid_values.get("userdata") args = _validate_metadata(body["proxy"].get("args")) metadata = dict(args) metadata.update(_get_proxy_conf()) values["deleted"] = 0 values["status"] = "BUILDING" values["pid"] = unicode(uuid.uuid4()) values["user_id"] = context.user_id values["project_id"] = context.project_id values["display_name"] = values[ "display_name"] or "pro-" + values["pid"] values["userdata"] = userdata.get("userdata") values["args"] = json.dumps(args) if values["keypair_id"]: nova_keypair_id = db.keypair_get_by_keypair_id( context, gid, values["keypair_id"]).get("nova_keypair_id") else: nova_keypair_id = None networks = db.network_get_all(context, gid, {"status": "ACTIVE"}) if not networks: raise exception.NoNetworksFound(gid=values["gid"]) network_ids = [network["network_id"] for network in networks] proxy = db.process_create( context, values, network_ids, securitygroup_ids) except exception.ProxyCreateFailed as e: raise webob.exc.HTTPBadRequest(explanation=e.format_message()) except exception.InvalidInput as e: raise webob.exc.HTTPBadRequest(explanation=e.format_message()) try: host = self.scheduler_rpcapi.select_destinations( context, request_spec={}, filter_properties={}) self.operator_rpcapi.process_create( context, host["host"], pid=values["pid"], ppid="", gid=gid, name=values["display_name"], glance_image_id=values["glance_image_id"], nova_flavor_id=values["nova_flavor_id"], nova_keypair_id=nova_keypair_id, neutron_securitygroup_ids=[securitygroup[ "neutron_securitygroup_id"] for securitygroup in proxy["securitygroups"]], neutron_network_ids=[network["neutron_network_id"] for network in proxy["networks"]], metadata=metadata, userdata=userdata.get("userdata")) except Exception as e: LOG.exception(e) pid = values["pid"] db.process_update(context, gid, pid, {"status": "ERROR"}) raise exception.ProcessCreateFailed() return self._view_builder.create(proxy)