def test_post_bottom_pod(self, mock_context): mock_context.return_value = self.context kw = {'pod': {'pod_name': 'BottomPod', 'az_name': 'TopAZ'}} pod_id = self.controller.post(**kw)['pod']['pod_id'] with self.context.session.begin(): pod = core.get_resource(self.context, models.Pod, pod_id) self.assertEqual(pod['pod_name'], 'BottomPod') self.assertEqual(pod['az_name'], 'TopAZ') pods = core.query_resource(self.context, models.Pod, [{'key': 'pod_name', 'comparator': 'eq', 'value': 'BottomPod'}], []) self.assertEqual(len(pods), 1) ag_name = utils.get_ag_name('BottomPod') aggregates = core.query_resource(self.context, models.Aggregate, [{'key': 'name', 'comparator': 'eq', 'value': ag_name}], []) self.assertEqual(len(aggregates), 1) metadatas = core.query_resource( self.context, models.AggregateMetadata, [{'key': 'key', 'comparator': 'eq', 'value': 'availability_zone'}, {'key': 'aggregate_id', 'comparator': 'eq', 'value': aggregates[0]['id']}], []) self.assertEqual(len(metadatas), 1) self.assertEqual(metadatas[0]['value'], 'TopAZ')
def test_update_binding(self): api.create_pod(self.context, self.b_pod_4) api.create_pod(self.context, self.b_pod_3) flag = self.pod_manager.create_binding(self.context, 'new_project_pm_3', self.b_pod_3['pod_id']) self.assertEqual(flag, True) current_binding = core.query_resource(self.context, models.PodBinding, [{ 'key': 'tenant_id', 'comparator': 'eq', 'value': 'new_project_pm_3' }], []) flag = self.pod_manager.update_binding(self.context, current_binding[0], self.b_pod_4['pod_id']) self.assertEqual(flag, True) binding_q = core.query_resource(self.context, models.PodBinding, [{ 'key': 'tenant_id', 'comparator': 'eq', 'value': 'new_project_pm_3' }], []) self.assertEqual(len(binding_q), 2) self.assertEqual(binding_q[0]['pod_id'], self.b_pod_3['pod_id']) self.assertEqual(binding_q[0]['tenant_id'], 'new_project_pm_3') self.assertEqual(binding_q[0]['is_binding'], False) self.assertEqual(binding_q[1]['pod_id'], self.b_pod_4['pod_id']) self.assertEqual(binding_q[1]['tenant_id'], 'new_project_pm_3') self.assertEqual(binding_q[1]['is_binding'], True)
def get_one(self, _id): # NOTE(zhiyuan) this function handles two kinds of requests # GET /flavors/flavor_id # GET /flavors/detail context = t_context.extract_context_from_environ() if _id == 'detail': with context.session.begin(): flavors = core.query_resource(context, models.InstanceTypes, [], []) for flavor in flavors: flavor['id'] = flavor['flavorid'] del flavor['flavorid'] return {'flavors': flavors} else: with context.session.begin(): flavors = core.query_resource(context, models.InstanceTypes, [{ 'key': 'flavorid', 'comparator': 'eq', 'value': _id }], []) if not flavors: return utils.format_nova_error( 404, _('Flavor %s could not be found') % _id) flavor = flavors[0] flavor['id'] = flavor['flavorid'] del flavor['flavorid'] return {'flavor': flavor}
def test_get_current_binding_and_pod(self): api.create_pod(self.context, self.b_pod_1) api.create_pod_binding(self.context, self.project_id, self.b_pod_1['pod_id']) pod_b_1, pod_1 = self.pod_manager.get_current_binding_and_pod( self.context, self.az_name_1, self.project_id, pod_group='') binding_q = core.query_resource(self.context, models.PodBinding, [{ 'key': 'tenant_id', 'comparator': 'eq', 'value': self.project_id }], []) self.assertEqual(len(binding_q), 1) self.assertEqual(binding_q[0]['id'], pod_b_1['id']) pod_b_2, pod_2 = self.pod_manager.get_current_binding_and_pod( self.context, self.az_name_1, 'new_project_pm_1', pod_group='') binding_q = core.query_resource(self.context, models.PodBinding, [{ 'key': 'tenant_id', 'comparator': 'eq', 'value': 'new_project_pm_1' }], []) self.assertEqual(len(binding_q), 0) self.assertEqual(pod_b_2, None) self.assertEqual(pod_2, None) pod_b_3, pod_3 = self.pod_manager.get_current_binding_and_pod( self.context, 'unknown_az', self.project_id, pod_group='') binding_q = core.query_resource(self.context, models.PodBinding, [{ 'key': 'tenant_id', 'comparator': 'eq', 'value': self.project_id }], []) self.assertEqual(len(binding_q), 1) self.assertEqual(pod_b_3, None) self.assertEqual(pod_3, None) pod_b_4, pod_4 = self.pod_manager.get_current_binding_and_pod( self.context, self.az_name_1, self.project_id, pod_group='test') binding_q = core.query_resource(self.context, models.PodBinding, [{ 'key': 'tenant_id', 'comparator': 'eq', 'value': self.project_id }], []) self.assertEqual(len(binding_q), 1) self.assertEqual(pod_b_4['id'], binding_q[0]['id']) self.assertEqual(pod_4, None)
def test_job_run_expire(self): @xmanager._job_handle('fake_resource') def fake_handle(self, ctx, payload): pass fake_id = uuidutils.generate_uuid() payload = {'fake_resource': fake_id} expired_job = { 'id': uuidutils.generate_uuid(), 'type': 'fake_resource', 'timestamp': datetime.datetime.now() - datetime.timedelta(0, 120), 'status': constants.JS_Running, 'resource_id': fake_id, 'extra_id': constants.SP_EXTRA_ID } core.create_resource(self.context, models.Job, expired_job) fake_handle(None, self.context, payload=payload) jobs = core.query_resource(self.context, models.Job, [], []) expected_status = ['New', 'Fail', 'Success'] job_status = [job['status'] for job in jobs] self.assertItemsEqual(expected_status, job_status) for i in xrange(3): self.assertEqual(fake_id, jobs[i]['resource_id']) self.assertEqual('fake_resource', jobs[i]['type'])
def get_or_create_route(t_ctx, q_ctx, project_id, pod, ele, _type, list_ele_method): # use configuration option later route_expire_threshold = 30 _id = ele['id'] with t_ctx.session.begin(): routes = core.query_resource(t_ctx, models.ResourceRouting, [{ 'key': 'top_id', 'comparator': 'eq', 'value': _id }, { 'key': 'pod_id', 'comparator': 'eq', 'value': pod['pod_id'] }], []) if routes: route = routes[0] if route['bottom_id']: return route, ALL_DONE else: route_time = route['updated_at'] or route['created_at'] current_time = datetime.datetime.utcnow() delta = current_time - route_time if delta.seconds > route_expire_threshold: # NOTE(zhiyuan) cannot directly remove the route, we have # a race here that other worker is updating this route, we # need to check if the corresponding element has been # created by other worker eles = list_ele_method(t_ctx, q_ctx, pod, ele, _type) if eles: route['bottom_id'] = eles[0]['id'] core.update_resource(t_ctx, models.ResourceRouting, route['id'], route) return route, RES_DONE try: core.delete_resource(t_ctx, models.ResourceRouting, route['id']) except db_exc.ResourceNotFound: pass try: # NOTE(zhiyuan) try/except block inside a with block will cause # problem, so move them out of the block and manually handle the # session context t_ctx.session.begin() route = core.create_resource( t_ctx, models.ResourceRouting, { 'top_id': _id, 'pod_id': pod['pod_id'], 'project_id': project_id, 'resource_type': _type }) t_ctx.session.commit() return route, NONE_DONE except db_exc.DBDuplicateEntry: t_ctx.session.rollback() return None, NONE_DONE finally: t_ctx.session.close()
def get_bottom_mappings_by_tenant_pod(context, tenant_id, pod_id, resource_type): """Get resource routing for specific tenant and pod :param context: context object :param tenant_id: tenant id to look up :param pod_id: pod to look up :param resource_type: specific resource :return: a dic {top_id : route} """ route_filters = [{'key': 'pod_id', 'comparator': 'eq', 'value': pod_id}, {'key': 'project_id', 'comparator': 'eq', 'value': tenant_id}, {'key': 'resource_type', 'comparator': 'eq', 'value': resource_type}] routings = {} with context.session.begin(): routes = core.query_resource( context, models.ResourceRouting, route_filters, []) for _route in routes: if not _route['bottom_id']: continue routings[_route['top_id']] = _route return routings
def test_get_pod_by_az_tenant(self): pod1, _ = az_ag.get_pod_by_az_tenant(self.context, FAKE_AZ + FAKE_AZ, FAKE_TENANT_ID) self.assertEqual(pod1, None) pods = az_ag.list_pods_by_tenant(self.context, FAKE_TENANT_ID) self.assertEqual(len(pods), 0) # schedule one pod2, _ = az_ag.get_pod_by_az_tenant(self.context, FAKE_AZ, FAKE_TENANT_ID) pod_bindings = core.query_resource(self.context, models.PodBinding, [{ 'key': 'tenant_id', 'comparator': 'eq', 'value': FAKE_TENANT_ID }], []) self.assertIsNotNone(pod_bindings) if pod_bindings[0]['pod_id'] == FAKE_SITE_ID: self.assertEqual(pod2['pod_name'], FAKE_SITE_NAME) self.assertEqual(pod2['pod_id'], FAKE_SITE_ID) self.assertEqual(pod2['az_name'], FAKE_AZ) else: self.assertEqual(pod2['pod_name'], FAKE_SITE_NAME_2) self.assertEqual(pod2['pod_id'], FAKE_SITE_ID_2) self.assertEqual(pod2['az_name'], FAKE_AZ) # scheduled one should always be bound pod3, _ = az_ag.get_pod_by_az_tenant(self.context, FAKE_AZ, FAKE_TENANT_ID) self.assertEqual(pod2['pod_name'], pod3['pod_name']) self.assertEqual(pod2['pod_id'], pod3['pod_id']) self.assertEqual(pod2['az_name'], pod3['az_name'])
def get_bottom_mappings_by_top_id(context, top_id, resource_type): """Get resource id and pod name on bottom :param context: context object :param top_id: resource id on top :param resource_type: resource type :return: a list of tuple (pod dict, bottom_id) """ route_filters = [{ 'key': 'top_id', 'comparator': 'eq', 'value': top_id }, { 'key': 'resource_type', 'comparator': 'eq', 'value': resource_type }] mappings = [] with context.session.begin(): routes = core.query_resource(context, models.ResourceRouting, route_filters, []) for route in routes: if not route['bottom_id']: continue pod = core.get_resource(context, models.Pod, route['pod_id']) mappings.append((pod, route['bottom_id'])) return mappings
def get_running_job(context, _type, resource_id): jobs = core.query_resource( context, models.Job, [{'key': 'resource_id', 'comparator': 'eq', 'value': resource_id}, {'key': 'status', 'comparator': 'eq', 'value': constants.JS_Running}, {'key': 'type', 'comparator': 'eq', 'value': _type}], []) if jobs: return jobs[0] else: return None
def get_latest_timestamp(context, status, _type, resource_id): jobs = core.query_resource( context, models.Job, [{'key': 'status', 'comparator': 'eq', 'value': status}, {'key': 'type', 'comparator': 'eq', 'value': _type}, {'key': 'resource_id', 'comparator': 'eq', 'value': resource_id}], [('timestamp', False)]) if jobs: return jobs[0]['timestamp'] else: return None
def get_all(self): context = t_context.extract_context_from_environ() with context.session.begin(): flavors = core.query_resource(context, models.InstanceTypes, [], []) return { 'flavors': [ dict([('id', flavor['flavorid']), ('name', flavor['name'])]) for flavor in flavors ] }
def get_all_ag(context, filters=None, sorts=None): aggregates = core.query_resource(context, models.Aggregate, filters or [], sorts or []) metadatas = core.query_resource(context, models.AggregateMetadata, [{ 'key': 'key', 'comparator': 'eq', 'value': 'availability_zone' }], []) agg_meta_map = {} for metadata in metadatas: agg_meta_map[metadata['aggregate_id']] = metadata for aggregate in aggregates: extra_fields = {'availability_zone': '', 'metadata': {}} if aggregate['id'] in agg_meta_map: metadata = agg_meta_map[aggregate['id']] extra_fields['availability_zone'] = metadata['value'] extra_fields['metadata'] = {'availability_zone': metadata['value']} aggregate.update(extra_fields) return aggregates
def test_delete_error(self, mock_ctx, mock_delete): t_pod, b_pod = self._prepare_pod() mock_ctx.return_value = self.context # pass invalid id res = self.controller.delete('fake_id') self.assertEqual('Server not found', res['Error']['message']) self.assertEqual(404, res['Error']['code']) t_server_id = 't_server_id' b_server_id = 'b_server_id' with self.context.session.begin(): core.create_resource( self.context, models.ResourceRouting, { 'top_id': t_server_id, 'bottom_id': b_server_id, 'pod_id': b_pod['pod_id'], 'project_id': self.project_id, 'resource_type': constants.RT_SERVER }) mock_delete.return_value = None # pass stale server id res = self.controller.delete(t_server_id) self.assertEqual('Server not found', res['Error']['message']) self.assertEqual(404, res['Error']['code']) routes = core.query_resource(self.context, models.ResourceRouting, [{ 'key': 'top_id', 'comparator': 'eq', 'value': t_server_id }], []) # check the stale mapping is deleted self.assertEqual(0, len(routes)) with self.context.session.begin(): core.create_resource( self.context, models.ResourceRouting, { 'top_id': t_server_id, 'bottom_id': b_server_id, 'pod_id': b_pod['pod_id'], 'project_id': self.project_id, 'resource_type': constants.RT_SERVER }) # exception occurs when deleting server mock_delete.side_effect = t_exceptions.PodNotFound('pod2') res = self.controller.delete(t_server_id) self.assertEqual('Pod pod2 could not be found.', res['Error']['message']) self.assertEqual(404, res['Error']['code'])
def test_post_top_pod(self, mock_context): mock_context.return_value = self.context kw = {'pod': {'pod_name': 'TopPod', 'az_name': ''}} pod_id = self.controller.post(**kw)['pod']['pod_id'] with self.context.session.begin(): pod = core.get_resource(self.context, models.Pod, pod_id) self.assertEqual(pod['pod_name'], 'TopPod') self.assertEqual(pod['az_name'], '') pods = core.query_resource(self.context, models.Pod, [{'key': 'pod_name', 'comparator': 'eq', 'value': 'TopPod'}], []) self.assertEqual(len(pods), 1)
def _get_top_region(self, ctx): top_region_name = '' try: with ctx.session.begin(): pods = core.query_resource(ctx, models.Pod, [], []) for pod in pods: if pod['az_name'] == '' and pod['pod_name'] != '': return pod['pod_name'] except Exception as e: LOG.exception(_LE('Failed to get top region: %(exception)s '), {'exception': e}) return top_region_name return top_region_name
def list_pods_by_tenant(context, tenant_id): pod_bindings = core.query_resource(context, models.PodBinding, [{ 'key': 'tenant_id', 'comparator': 'eq', 'value': tenant_id }], []) pods = [] if pod_bindings: for pod_b in pod_bindings: pod = core.get_resource(context, models.Pod, pod_b['pod_id']) pods.append(pod) return pods
def test_create_binding(self): api.create_pod(self.context, self.b_pod_2) flag = self.pod_manager.create_binding(self.context, 'new_project_pm_2', self.b_pod_2['pod_id']) self.assertEqual(flag, True) binding_q = core.query_resource(self.context, models.PodBinding, [{ 'key': 'tenant_id', 'comparator': 'eq', 'value': 'new_project_pm_2' }], []) self.assertEqual(len(binding_q), 1) self.assertEqual(binding_q[0]['pod_id'], self.b_pod_2['pod_id']) self.assertEqual(binding_q[0]['tenant_id'], 'new_project_pm_2') self.assertEqual(binding_q[0]['is_binding'], True)
def get_all(self): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_BINDINGS_LIST): pecan.abort(401, _('Unauthorized to list bindings')) return try: with context.session.begin(): pod_bindings = core.query_resource(context, models.PodBinding, [], []) except Exception: pecan.abort(500, _('Fail to list tenant pod bindings')) return return {'pod_bindings': pod_bindings}
def get_all(self): context = t_context.extract_context_from_environ() if not t_context.is_admin_context(context): pecan.abort(400, _('Admin role required to list bindings')) return try: with context.session.begin(): pod_bindings = core.query_resource(context, models.PodBinding, [], []) except Exception: pecan.abort(500, _('Fail to list tenant pod bindings')) return return {'pod_bindings': pod_bindings}
def get_pod_by_az_tenant(context, az_name, tenant_id): pod_bindings = core.query_resource(context, models.PodBinding, [{ 'key': 'tenant_id', 'comparator': 'eq', 'value': tenant_id }], []) for pod_b in pod_bindings: pod = core.get_resource(context, models.Pod, pod_b['pod_id']) if az_name and pod['az_name'] == az_name: return pod, pod['pod_az_name'] elif az_name == '' and pod['az_name'] != '': # if the az_name is not specified, a defult bottom # pod will be selected return pod, pod['pod_az_name'] else: pass # TODO(joehuang): schedule one dynamically in the future if az_name != '': filters = [{'key': 'az_name', 'comparator': 'eq', 'value': az_name}] else: filters = None # if az_name is valid, select a pod under this az_name # if az_name is '', select the first valid bottom pod. # change to dynamic schedluing in the future pods = db_api.list_pods(context, filters=filters) for pod in pods: if pod['pod_name'] != '' and pod['az_name'] != '': try: with context.session.begin(): core.create_resource( context, models.PodBinding, { 'id': uuidutils.generate_uuid(), 'tenant_id': tenant_id, 'pod_id': pod['pod_id'], 'is_binding': True }) return pod, pod['pod_az_name'] except Exception as e: LOG.error(_LE('Fail to create pod binding: %(exception)s'), {'exception': e}) return None, None return None, None
def test_job_handle_exception(self): @xmanager._job_handle('fake_resource') def fake_handle(self, ctx, payload): raise Exception() fake_id = 'fake_id' payload = {'fake_resource': fake_id} fake_handle(None, self.context, payload=payload) jobs = core.query_resource(self.context, models.Job, [], []) expected_status = [constants.JS_New, constants.JS_Fail] job_status = [job['status'] for job in jobs] self.assertItemsEqual(expected_status, job_status) self.assertEqual(fake_id, jobs[0]['resource_id']) self.assertEqual(fake_id, jobs[1]['resource_id']) self.assertEqual('fake_resource', jobs[0]['type']) self.assertEqual('fake_resource', jobs[1]['type'])
def get_one_ag(context, aggregate_id): aggregate = core.get_resource(context, models.Aggregate, aggregate_id) metadatas = core.query_resource(context, models.AggregateMetadata, [{ 'key': 'key', 'comparator': 'eq', 'value': 'availability_zone' }, { 'key': 'aggregate_id', 'comparator': 'eq', 'value': aggregate['id'] }], []) if metadatas: aggregate['availability_zone'] = metadatas[0]['value'] aggregate['metadata'] = {'availability_zone': metadatas[0]['value']} else: aggregate['availability_zone'] = '' aggregate['metadata'] = {} return aggregate
def delete(self, _id): context = t_context.extract_context_from_environ() try: with context.session.begin(): flavors = core.query_resource(context, models.InstanceTypes, [{ 'key': 'flavorid', 'comparator': 'eq', 'value': _id }], []) if not flavors: return utils.format_nova_error( 404, _('Flavor %s could not be found') % _id) core.delete_resource(context, models.InstanceTypes, flavors[0]['id']) except Exception: return utils.format_nova_error(500, _('Failed to delete flavor')) pecan.response.status = 202 return
def list_pods(context, filters=None, sorts=None): with context.session.begin(): return core.query_resource(context, models.Pod, filters or [], sorts or [])
def get_pod_binding_by_tenant_id(context, filter_): with context.session.begin(): return core.query_resource(context, models.PodBinding, filter_, [])
def test_post(self, mock_ctx, mock_create): t_pod, b_pod = self._prepare_pod() top_net_id = 'top_net_id' top_subnet_id = 'top_subnet_id' top_sg_id = 'top_sg_id' t_net = {'id': top_net_id, 'name': 'net'} t_subnet = { 'id': top_subnet_id, 'network_id': top_net_id, 'ip_version': 4, 'cidr': '10.0.0.0/24', 'gateway_ip': '10.0.0.1', 'allocation_pools': [{ 'start': '10.0.0.2', 'end': '10.0.0.254' }], 'enable_dhcp': True } t_sg = { 'id': top_sg_id, 'name': 'default', 'description': '', 'tenant_id': self.project_id, 'security_group_rules': [ { 'remote_group_id': top_sg_id, 'direction': 'ingress', 'remote_ip_prefix': None, 'protocol': None, 'port_range_max': None, 'port_range_min': None, 'ethertype': 'IPv4' }, { 'remote_group_id': None, 'direction': 'egress', 'remote_ip_prefix': None, 'protocol': None, 'port_range_max': None, 'port_range_min': None, 'ethertype': 'IPv4' }, ] } TOP_NETS.append(t_net) TOP_SUBNETS.append(t_subnet) TOP_SGS.append(t_sg) server_name = 'test_server' image_id = 'image_id' flavor_id = 1 body = { 'server': { 'name': server_name, 'imageRef': image_id, 'flavorRef': flavor_id, 'availability_zone': b_pod['az_name'], 'networks': [{ 'uuid': top_net_id }] } } mock_create.return_value = {'id': 'bottom_server_id'} mock_ctx.return_value = self.context server_dict = self.controller.post(**body)['server'] mock_create.assert_called_with(self.context, name=server_name, image=image_id, flavor=flavor_id, nics=[{ 'net-id': top_net_id }], security_groups=['default']) with self.context.session.begin(): routes = core.query_resource(self.context, models.ResourceRouting, [{ 'key': 'resource_type', 'comparator': 'eq', 'value': 'server' }], []) self.assertEqual(1, len(routes)) self.assertEqual(server_dict['id'], routes[0]['top_id']) self.assertEqual(server_dict['id'], routes[0]['bottom_id']) self.assertEqual(b_pod['pod_id'], routes[0]['pod_id']) self.assertEqual(self.project_id, routes[0]['project_id'])
def list_pod_service_configurations(context, filters=None, sorts=None): with context.session.begin(): return core.query_resource(context, models.PodServiceConfiguration, filters or [], sorts or [])