def put(self, _id, **kw): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_ROUTINGS_PUT): return utils.format_api_error( 403, _('Unauthorized to update resource routing')) try: db_api.get_resource_routing(context, _id) except t_exceptions.ResourceNotFound: return utils.format_api_error(404, _('Resource routing not found')) if 'routing' not in kw: return utils.format_api_error(400, _('Request body not found')) update_dict = kw['routing'] # values to be updated should not be empty for field in update_dict: value = update_dict.get(field) if value is None or len(value.strip()) == 0: return utils.format_api_error( 400, _("Field %(field)s can not be empty") % {'field': field}) # the resource type should be properly provisioned. if 'resource_type' in update_dict: if not constants.is_valid_resource_type( update_dict['resource_type']): return utils.format_api_error( 400, _('There is no such resource type')) # the pod with new pod_id should exist in pod table if 'pod_id' in update_dict: new_pod_id = update_dict.get('pod_id') try: # find the pod through the pod_id and verify whether it exists db_api.get_pod(context, new_pod_id) except t_exceptions.ResourceNotFound: return utils.format_api_error( 400, _("The pod %(new_pod_id)s doesn't" " exist") % {'new_pod_id': new_pod_id}) except Exception as e: LOG.exception( 'Failed to update resource routing: ' '%(exception)s ', {'exception': e}) return utils.format_api_error( 500, _('Failed to update resource routing')) try: routing_updated = db_api.update_resource_routing( context, _id, update_dict) return {'routing': routing_updated} except Exception as e: LOG.exception( 'Failed to update resource routing: ' '%(exception)s ', {'exception': e}) return utils.format_api_error( 500, _('Failed to update resource routing'))
def put(self, _id, **kw): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_ROUTINGS_PUT): return utils.format_api_error( 403, _('Unauthorized to update resource routing')) try: db_api.get_resource_routing(context, _id) except t_exceptions.ResourceNotFound: return utils.format_api_error(404, _('Resource routing not found')) if 'routing' not in kw: return utils.format_api_error( 400, _('Request body not found')) update_dict = kw['routing'] # values to be updated should not be empty for field in update_dict: value = update_dict.get(field) if value is None or len(value.strip()) == 0: return utils.format_api_error( 400, _("Field %(field)s can not be empty") % { 'field': field}) # the resource type should be properly provisioned. if 'resource_type' in update_dict: if not constants.is_valid_resource_type( update_dict['resource_type']): return utils.format_api_error( 400, _('There is no such resource type')) # the pod with new pod_id should exist in pod table if 'pod_id' in update_dict: new_pod_id = update_dict.get('pod_id') try: # find the pod through the pod_id and verify whether it exists db_api.get_pod(context, new_pod_id) except t_exceptions.ResourceNotFound: return utils.format_api_error( 400, _("The pod %(new_pod_id)s doesn't" " exist") % {'new_pod_id': new_pod_id}) except Exception as e: LOG.exception('Failed to update resource routing: ' '%(exception)s ', {'exception': e}) return utils.format_api_error( 500, _('Failed to update resource routing')) try: routing_updated = db_api.update_resource_routing( context, _id, update_dict) return {'routing': routing_updated} except Exception as e: LOG.exception('Failed to update resource routing: ' '%(exception)s ', {'exception': e}) return utils.format_api_error( 500, _('Failed to update resource routing'))
def update_subnet(self, ctx, payload): """update bottom subnet if bottom pod id equal to POD_NOT_SPECIFIED, dispatch jobs for every mapped bottom pod via RPC, otherwise update subnet in the specified pod. :param ctx: tricircle context :param payload: dict whose key is JT_SUBNET_UPDATE and value is "top_subnet_id#bottom_pod_id" :return: None """ (b_pod_id, t_subnet_id) = payload[ constants.JT_SUBNET_UPDATE].split('#') if b_pod_id == constants.POD_NOT_SPECIFIED: mappings = db_api.get_bottom_mappings_by_top_id( ctx, t_subnet_id, constants.RT_SUBNET) b_pods = [mapping[0] for mapping in mappings] for b_pod in b_pods: self.xjob_handler.update_subnet(ctx, t_subnet_id, b_pod['pod_id']) return t_client = self._get_client() t_subnet = t_client.get_subnets(ctx, t_subnet_id) if not t_subnet: return b_pod = db_api.get_pod(ctx, b_pod_id) b_region_name = b_pod['region_name'] b_subnet_id = db_api.get_bottom_id_by_top_id_region_name( ctx, t_subnet_id, b_region_name, constants.RT_SUBNET) b_client = self._get_client(region_name=b_region_name) b_subnet = b_client.get_subnets(ctx, b_subnet_id) b_gateway_ip = b_subnet['gateway_ip'] # we need to remove the bottom subnet gateway ip from the top subnet # allaction pools b_allocation_pools = helper.NetworkHelper.get_bottom_subnet_pools( t_subnet, b_gateway_ip) # bottom gateway_ip doesn't need to be updated, because it is reserved # by top pod. # name is not allowed to be updated, because it is used by # lock_handle to retrieve bottom/local resources that have been # created but not registered in the resource routing table body = { 'subnet': {'description': t_subnet['description'], 'enable_dhcp': t_subnet['enable_dhcp'], 'allocation_pools': b_allocation_pools, 'host_routes': t_subnet['host_routes'], 'dns_nameservers': t_subnet['dns_nameservers']} } try: b_client.update_subnets(ctx, b_subnet_id, body) except q_cli_exceptions.NotFound: LOG.error(_LE('subnet: %(subnet_id)s not found, ' 'pod name: %(name)s'), {'subnet_id': b_subnet_id, 'name': b_region_name})
def get_trunks(self, context, filters=None, fields=None, sorts=None, limit=None, marker=None, page_reverse=False): ret = [] bottom_top_map = {} top_bottom_map = {} t_ctx = t_context.get_context_from_neutron_context(context) route_filters = [{'key': 'resource_type', 'comparator': 'eq', 'value': t_constants.RT_TRUNK}] routes = db_api.list_resource_routings(t_ctx, route_filters) for route in routes: bottom_top_map[route['bottom_id']] = route['top_id'] top_bottom_map[route['top_id']] = route['bottom_id'] if limit: if marker: mappings = db_api.get_bottom_mappings_by_top_id( t_ctx, marker, t_constants.RT_TRUNK) # if mapping exists, we retrieve trunk information # from bottom, otherwise from top if mappings: pod_id = mappings[0][0]['pod_id'] current_pod = db_api.get_pod(t_ctx, pod_id) ret = self._get_trunks_from_pod_with_limit( context, current_pod, bottom_top_map, top_bottom_map, filters, limit, marker) else: ret = self._get_trunks_from_top_with_limit( context, top_bottom_map, filters, limit, marker) else: current_pod = db_api.get_next_bottom_pod(t_ctx) # if current_pod exists, we retrieve trunk information # from bottom, otherwise from top if current_pod: ret = self._get_trunks_from_pod_with_limit( context, current_pod, bottom_top_map, top_bottom_map, filters, limit, None) else: ret = self._get_trunks_from_top_with_limit( context, top_bottom_map, filters, limit, None) else: pods = db_api.list_pods(t_ctx) _filters = self._transform_trunk_filters(filters, top_bottom_map) for pod in pods: if not pod['az_name']: continue client = self._get_client(pod['region_name']) pod_trunks = client.list_trunks(t_ctx, filters=_filters) ret.extend(pod_trunks) ret = self._map_trunks_from_bottom_to_top(ret, bottom_top_map) top_trunks = self._get_trunks_from_top(context, top_bottom_map, filters) ret.extend(top_trunks) return [super(TricircleTrunkPlugin, self)._fields(trunk, fields) for trunk in ret]
def setup_bottom_router(self, ctx, payload): (b_pod_id, t_router_id, t_net_id) = payload[constants.JT_ROUTER_SETUP].split('#') if b_pod_id == constants.POD_NOT_SPECIFIED: mappings = db_api.get_bottom_mappings_by_top_id( ctx, t_net_id, constants.RT_NETWORK) b_pods = [mapping[0] for mapping in mappings] for b_pod in b_pods: # NOTE(zhiyuan) we create one job for each pod to avoid # conflict caused by different workers operating the same pod self.xjob_handler.setup_bottom_router( ctx, t_net_id, t_router_id, b_pod['pod_id']) return t_client = self._get_client() t_pod = db_api.get_top_pod(ctx) t_router = t_client.get_routers(ctx, t_router_id) if not t_router: # we just end this job if top router no longer exists return t_net = t_client.get_networks(ctx, t_net_id) if not t_net: # we just end this job if top network no longer exists return project_id = t_router['tenant_id'] b_pod = db_api.get_pod(ctx, b_pod_id) t_ew_bridge_net_name = constants.ew_bridge_net_name % project_id t_ew_bridge_subnet_name = constants.ew_bridge_subnet_name % project_id t_ew_bridge_net = self._get_resource_by_name(t_client, ctx, 'network', t_ew_bridge_net_name) t_ew_bridge_subnet = self._get_resource_by_name( t_client, ctx, 'subnet', t_ew_bridge_subnet_name) ext_nets = t_client.list_networks(ctx, filters=[{'key': 'router:external', 'comparator': 'eq', 'value': True}]) ext_net_pod_names = set( [ext_net[AZ_HINTS][0] for ext_net in ext_nets]) if not ext_net_pod_names: need_ns_bridge = False elif b_pod['pod_name'] in ext_net_pod_names: need_ns_bridge = False else: need_ns_bridge = True self._setup_router_one_pod(ctx, t_pod, b_pod, t_client, t_net, t_router, t_ew_bridge_net, t_ew_bridge_subnet, need_ns_bridge) self.xjob_handler.configure_extra_routes(ctx, t_router_id)
def test_get_pod(self): self._create_pod(0, 'test_az_uuid1') self._create_pod(1, 'test_az_uuid1') self._create_pod(2, 'test_az_uuid2') pod_id = 'test_pod_uuid_0' pod = api.get_pod(self.context, pod_id) self.assertEqual(pod['pod_id'], pod_id) pod_id = 'test_pod_uuid_3' self.assertRaises( exceptions.ResourceNotFound, api.get_pod, self.context, pod_id)
def get_one(self, _id): context = t_context.extract_context_from_environ() if not t_context.is_admin_context(context): pecan.abort(400, _('Admin role required to show pods')) return try: return {'pod': db_api.get_pod(context, _id)} except t_exc.ResourceNotFound: pecan.abort(404, _('Pod not found')) return
def get_one(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_SHOW): pecan.abort(401, _('Unauthorized to show pods')) return try: return {'pod': db_api.get_pod(context, _id)} except t_exc.ResourceNotFound: pecan.abort(404, _('Pod not found')) return
def update_network(self, ctx, payload): """update bottom network if bottom pod id equal to POD_NOT_SPECIFIED, dispatch jobs for every mapped bottom pod via RPC, otherwise update network in the specified pod. :param ctx: tricircle context :param payload: dict whose key is JT_NETWORK_UPDATE and value is "top_network_id#bottom_pod_id" :return: None """ (b_pod_id, t_network_id) = payload[ constants.JT_NETWORK_UPDATE].split('#') if b_pod_id == constants.POD_NOT_SPECIFIED: mappings = db_api.get_bottom_mappings_by_top_id( ctx, t_network_id, constants.RT_NETWORK) b_pods = [mapping[0] for mapping in mappings] for b_pod in b_pods: self.xjob_handler.update_network(ctx, t_network_id, b_pod['pod_id']) return t_client = self._get_client() t_network = t_client.get_networks(ctx, t_network_id) if not t_network: return b_pod = db_api.get_pod(ctx, b_pod_id) b_region_name = b_pod['region_name'] b_client = self._get_client(region_name=b_region_name) b_network_id = db_api.get_bottom_id_by_top_id_region_name( ctx, t_network_id, b_region_name, constants.RT_NETWORK) # name is not allowed to be updated, because it is used by # lock_handle to retrieve bottom/local resources that have been # created but not registered in the resource routing table body = { 'network': { 'description': t_network['description'], 'admin_state_up': t_network['admin_state_up'], 'shared': t_network['shared'] } } try: b_client.update_networks(ctx, b_network_id, body) except q_cli_exceptions.NotFound: LOG.error(_LE('network: %(net_id)s not found,' 'pod name: %(name)s'), {'net_id': b_network_id, 'name': b_region_name})
def delete_server_port(self, ctx, payload): b_pod_id, b_port_id = payload[constants.JT_PORT_DELETE].split('#') b_pod = db_api.get_pod(ctx, b_pod_id) self._get_client(b_pod['region_name']).delete_ports(ctx, b_port_id)