Esempio n. 1
0
def delete_ag(context, aggregate_id):
    core.delete_resources(context, models.AggregateMetadata,
                          [{'key': 'aggregate_id',
                            'comparator': 'eq',
                            'value': aggregate_id}])
    core.delete_resource(context, models.Aggregate, aggregate_id)
    return
Esempio n. 2
0
    def get_one(self, _id):
        context = t_context.extract_context_from_environ()

        if _id == 'detail':
            return {'volumes': self._get_all(context)}

        # TODO(joehuang): get the release of top and bottom
        t_release = cons.R_MITAKA
        b_release = cons.R_MITAKA

        b_headers = hclient.convert_header(t_release, b_release,
                                           request.headers)

        s_ctx = hclient.get_res_routing_ref(context, _id, request.url,
                                            cons.ST_CINDER)
        if not s_ctx:
            return utils.format_cinder_error(
                404,
                _('Volume %s could not be found.') % _id)

        if s_ctx['b_url'] == '':
            return utils.format_cinder_error(
                404, _('Bottom Pod endpoint incorrect'))

        resp = hclient.forward_req(context, 'GET', b_headers, s_ctx['b_url'],
                                   request.body)

        b_ret_body = jsonutils.loads(resp.content)

        b_status = resp.status_code
        response.status = b_status
        if b_status == 200:
            if b_ret_body.get('volume') is not None:
                b_vol_ret = b_ret_body['volume']
                ret_vol = hclient.convert_object(b_release,
                                                 t_release,
                                                 b_vol_ret,
                                                 res_type=cons.RT_VOLUME)

                pod = utils.get_pod_by_top_id(context, _id)
                if pod:
                    ret_vol['availability_zone'] = pod['az_name']

                return {'volume': ret_vol}

        # resource not find but routing exist, remove the routing
        if b_status == 404:
            filters = [{
                'key': 'top_id',
                'comparator': 'eq',
                'value': _id
            }, {
                'key': 'resource_type',
                'comparator': 'eq',
                'value': cons.RT_VOLUME
            }]
            with context.session.begin():
                core.delete_resources(context, models.ResourceRouting, filters)
        return b_ret_body
Esempio n. 3
0
def delete_mappings_by_bottom_id(context, bottom_id):
    with context.session.begin():
        core.delete_resources(context,
                              models.ResourceRouting,
                              filters=[{
                                  'key': 'bottom_id',
                                  'comparator': 'eq',
                                  'value': bottom_id
                              }])
Esempio n. 4
0
def delete_ag(context, aggregate_id):
    core.delete_resources(context, models.AggregateMetadata,
                          [{
                              'key': 'aggregate_id',
                              'comparator': 'eq',
                              'value': aggregate_id
                          }])
    core.delete_resource(context, models.Aggregate, aggregate_id)
    return
Esempio n. 5
0
 def _remove_stale_mapping(context, server_id):
     filters = [{'key': 'top_id', 'comparator': 'eq', 'value': server_id},
                {'key': 'resource_type',
                 'comparator': 'eq',
                 'value': constants.RT_SERVER}]
     with context.session.begin():
         core.delete_resources(context,
                               models.ResourceRouting,
                               filters)
Esempio n. 6
0
 def remove_router_interface(self):
     context = t_context.extract_context_from_environ()
     body = {"core_router_interface": request.context['request_data']}
     attr_info = body_validation.RESOURCE_ATTRIBUTE_MAP.get(self.resource)
     body_validation.BodyValidationHook.check_request_body(
         body, True, "core_router_interface", attr_info)
     fabric = request.context['request_data']['fabric']
     try:
         with context.session.begin():
             core.get_resource(context, models.CoreRouter,
                               self.core_router_id)
             interface_filters = [{
                 'key': 'core_router_id',
                 'comparator': 'eq',
                 'value': self.core_router_id
             }, {
                 'key': 'fabric',
                 'comparator': 'eq',
                 'value': fabric
             }]
             interfaces = core.query_resource(context,
                                              models.CoreRouterInterface,
                                              interface_filters, [])
             if (not len(interfaces) > 0):
                 raise t_exceptions.CoreRouterInterfaceDeleteNotFound(
                     core_router_id=self.core_router_id, fabric=fabric)
             core.delete_resources(context, models.CoreRouterInterface,
                                   interface_filters)
             return_object = m.SuccessMessage(result={})
             return return_object.to_dict()
     except t_exceptions.ResourceNotFound as e:
         LOG.exception(
             'Failed to delete core_router_interface : '
             'core_router_id %(core_router_id)s ,'
             '%(exception)s ', {
                 'core_router_id': self.core_router_id,
                 'exception': e
             })
         return m.CoreRouterNotFound(
             core_router_id=self.core_router_id).to_dict()
     except t_exceptions.CoreRouterInterfaceDeleteNotFound:
         return m.CoreRouterInterfaceNotFound(
             core_router_id=self.core_router_id, fabric=fabric).to_dict()
     except Exception as e:
         LOG.exception(
             'Failed to delete core_router_interface :'
             'core_router_id: %(core_router_id)s,'
             'fabric: %(fabric)s,'
             '%(exception)s ', {
                 'core_router_id': self.core_router_id,
                 'fabric': fabric,
                 'exception': e
             })
         return_object = m.FailureMessage()
         return return_object.to_dict()
Esempio n. 7
0
    def get_one(self, _id):
        context = t_context.extract_context_from_environ()

        if _id == 'detail':
            return {'volumes': self._get_all(context)}

        # TODO(joehuang): get the release of top and bottom
        t_release = 'MITATA'
        b_release = 'MITATA'

        b_headers = self._convert_header(t_release,
                                         b_release,
                                         request.headers)

        s_ctx = self._get_res_routing_ref(context, _id, request.url)
        if not s_ctx:
            return Response(_('Failed to find resource'), 404)

        if s_ctx['b_url'] == '':
            return Response(_('bottom pod endpoint incorrect'), 404)

        resp = hclient.forward_req(context, 'GET',
                                   b_headers,
                                   s_ctx['b_url'],
                                   request.body)

        b_ret_body = jsonutils.loads(resp.content)

        b_status = resp.status_code
        response.status = b_status
        if b_status == 200:
            if b_ret_body.get('volume') is not None:
                b_vol_ret = b_ret_body['volume']
                ret_vol = self._convert_object(b_release, t_release,
                                               b_vol_ret,
                                               res_type=cons.RT_VOLUME)

                pod = self._get_pod_by_top_id(context, _id)
                if pod:
                    ret_vol['availability_zone'] = pod['az_name']

                return {'volume': ret_vol}

        # resource not find but routing exist, remove the routing
        if b_status == 404:
            filters = [{'key': 'top_id', 'comparator': 'eq', 'value': _id},
                       {'key': 'resource_type',
                        'comparator': 'eq',
                        'value': cons.RT_VOLUME}]
            with context.session.begin():
                core.delete_resources(context,
                                      models.ResourceRouting,
                                      filters)
        return b_ret_body
Esempio n. 8
0
def delete_pre_created_resource_mapping(context, name):
    with context.session.begin():
        entries = core.query_resource(
            context, models.ResourceRouting,
            filters=[{'key': 'top_id', 'comparator': 'eq',
                      'value': name}], sorts=[])
        if entries:
            core.delete_resources(
                context, models.ResourceRouting,
                filters=[{'key': 'top_id', 'comparator': 'eq',
                          'value': entries[0]['bottom_id']}])
            core.delete_resource(context, models.ResourceRouting,
                                 entries[0]['id'])
Esempio n. 9
0
def delete_mappings_by_top_id(context, top_id, pod_id=None):
    """Delete resource routing entry based on top resource ID

    If pod ID is also provided, only entry in the specific pod will be deleted

    :param context: context object
    :param top_id: top resource ID
    :param pod_id: optional pod ID
    :return: None
    """
    filters = [{'key': 'top_id', 'comparator': 'eq', 'value': top_id}]
    if pod_id:
        filters.append({'key': 'pod_id', 'comparator': 'eq', 'value': pod_id})
    with context.session.begin():
        core.delete_resources(context, models.ResourceRouting, filters=filters)
Esempio n. 10
0
def delete_mappings_by_top_id(context, top_id, pod_id=None):
    """Delete resource routing entry based on top resource ID

    If pod ID is also provided, only entry in the specific pod will be deleted

    :param context: context object
    :param top_id: top resource ID
    :param pod_id: optional pod ID
    :return: None
    """
    filters = [{'key': 'top_id', 'comparator': 'eq', 'value': top_id}]
    if pod_id:
        filters.append({'key': 'pod_id', 'comparator': 'eq', 'value': pod_id})
    with context.session.begin():
        core.delete_resources(context, models.ResourceRouting, filters=filters)
Esempio n. 11
0
    def delete_security_group(self, context, sg_id):
        LOG.debug("lyman--enter delete security group")
        t_ctx = t_context.get_context_from_neutron_context(context)
        # check the sg whether in security group
        super(TricircleSecurityGroupMixin, self).\
            get_security_group(context, sg_id)
        # check the sg whether in deleting
        dict_para = {'resource_id': sg_id, 'resource_type': t_constants.RT_SG}

        nt_utils.check_resource_not_in_deleting(context, dict_para)
        try:
            with t_ctx.session.begin():
                core.create_resource(t_ctx, models.DeletingResources,
                                     dict_para)
            for pod, bottom_security_group_id in (
                    self.helper.get_real_shadow_resource_iterator(
                        t_ctx, t_constants.RT_SG, sg_id)):
                self._get_client(pod['region_name']). \
                    delete_security_groups(t_ctx, bottom_security_group_id)
                with t_ctx.session.begin():
                    core.delete_resources(t_ctx,
                                          models.ResourceRouting,
                                          filters=[{
                                              'key': 'top_id',
                                              'comparator': 'eq',
                                              'value': sg_id
                                          }, {
                                              'key': 'pod_id',
                                              'comparator': 'eq',
                                              'value': pod['pod_id']
                                          }])

            with t_ctx.session.begin():
                super(TricircleSecurityGroupMixin, self). \
                    delete_security_group(context, sg_id)
        except Exception:
            raise
        finally:
            with t_ctx.session.begin():
                core.delete_resources(t_ctx,
                                      models.DeletingResources,
                                      filters=[{
                                          'key': 'resource_id',
                                          'comparator': 'eq',
                                          'value': sg_id
                                      }])
Esempio n. 12
0
    def delete_security_group(self, context, sg_id):
        LOG.debug("lyman--enter delete security group")
        t_ctx = t_context.get_context_from_neutron_context(context)
        # check the sg whether in security group
        super(TricircleSecurityGroupMixin, self).\
            get_security_group(context, sg_id)
        # check the sg whether in deleting
        dict_para = {'resource_id': sg_id, 'resource_type': t_constants.RT_SG}

        nt_utils.check_resource_not_in_deleting(context, dict_para)
        try:
            with t_ctx.session.begin():
                core.create_resource(
                    t_ctx, models.DeletingResources, dict_para)
            for pod, bottom_security_group_id in (
                    self.helper.get_real_shadow_resource_iterator(
                        t_ctx, t_constants.RT_SG, sg_id)):
                self._get_client(pod['region_name']). \
                    delete_security_groups(t_ctx, bottom_security_group_id)
                with t_ctx.session.begin():
                    core.delete_resources(
                        t_ctx, models.ResourceRouting,
                        filters=[{'key': 'top_id', 'comparator': 'eq',
                                  'value': sg_id},
                                 {'key': 'pod_id', 'comparator': 'eq',
                                  'value': pod['pod_id']}])

            with t_ctx.session.begin():
                super(TricircleSecurityGroupMixin, self). \
                    delete_security_group(context, sg_id)
        except Exception:
            raise
        finally:
            with t_ctx.session.begin():
                core.delete_resources(
                    t_ctx, models.DeletingResources,
                    filters=[{
                        'key': 'resource_id', 'comparator': 'eq',
                        'value': sg_id}])
Esempio n. 13
0
def delete_mappings_by_bottom_id(context, bottom_id):
    with context.session.begin():
        core.delete_resources(
            context, models.ResourceRouting,
            filters=[{'key': 'bottom_id', 'comparator': 'eq',
                      'value': bottom_id}])
Esempio n. 14
0
    def _update_core_router_routes(self, context, core_router_id, core_router):
        try:
            with context.session.begin(subtransactions=True):

                def _combine(ht):
                    return "{}_{}".format(ht['destination'], ht['nexthop'])

                old_route_list = self._get_routes_by_core_router_id(
                    context, core_router_id)

                new_route_set = set(
                    [_combine(route) for route in core_router['routes']])

                old_route_set = set(
                    [_combine(route) for route in old_route_list])

                new_routes = []
                for route_str in old_route_set - new_route_set:
                    for route in old_route_list:
                        if _combine(route) == route_str:
                            destination = self.filter_to_str(
                                common_utils.AuthenticIPNetwork(
                                    route_str.partition("_")[0]))
                            nexthop = self.filter_to_str(
                                netaddr.IPAddress(route_str.partition("_")[2]))
                            route_filters = [{
                                'key': 'core_router_id',
                                'comparator': 'eq',
                                'value': core_router_id
                            }, {
                                'key': 'destination',
                                'comparator': 'eq',
                                'value': destination
                            }, {
                                'key': 'nexthop',
                                'comparator': 'eq',
                                'value': nexthop
                            }]
                            core.delete_resources(context,
                                                  models.CoreRouterRoute,
                                                  route_filters)
                for route_str in new_route_set - old_route_set:
                    destination = self.filter_to_str(
                        common_utils.AuthenticIPNetwork(
                            route_str.partition("_")[0]))
                    nexthop = self.filter_to_str(
                        netaddr.IPAddress(route_str.partition("_")[2]))
                    new_core_routerroute = core.create_resource(
                        context, models.CoreRouterRoute, {
                            'core_router_id': core_router_id,
                            'destination': destination,
                            'nexthop': nexthop
                        })

                for route_str in new_route_set:
                    new_routes.append({
                        'destination':
                        route_str.partition("_")[0],
                        'nexthop':
                        route_str.partition("_")[2]
                    })
                del core_router["routes"]
                return new_routes
        except Exception as e:
            LOG.exception(
                'Failed to update core_routerroute : '
                'core_router_id %(core_router_id)s: '
                '%(exception)s', {
                    'core_router_id': core_router_id,
                    'exception': e
                })
            raise t_exceptions.CoreRouterRoutesUpdateException()
Esempio n. 15
0
    def _setup_router_one_pod(self, ctx, t_pod, b_pod, t_client, t_net,
                              t_router, t_bridge_net, t_bridge_subnet,
                              is_ext_net_pod):
        # NOTE(zhiyuan) after the bridge network combination, external network
        # is attached to a separate router, which is created in central plugin,
        # so is_ext_net_pod is not used in the current implementation, but we
        # choose to keep this parameter since it's an important attribute of a
        # pod and we may need to use it later.
        b_client = self._get_client(b_pod['region_name'])

        is_distributed = t_router.get('distributed', False)
        router_body = {'router': {'name': t_router['id'],
                                  'distributed': is_distributed}}
        project_id = t_router['tenant_id']

        # create bottom router in target bottom pod
        _, b_router_id = self.helper.prepare_bottom_element(
            ctx, project_id, b_pod, t_router, constants.RT_ROUTER, router_body)

        # create top bridge port
        q_ctx = None  # no need to pass neutron context when using client
        t_bridge_port_id = self.helper.get_bridge_interface(
            ctx, q_ctx, project_id, t_pod, t_bridge_net['id'], b_router_id)

        # create bottom bridge port
        # if target bottom pod is hosting real external network, we create
        # another bottom router and attach the bridge network as internal
        # network, but this work is done by central plugin when user sets
        # router gateway.
        t_bridge_port = t_client.get_ports(ctx, t_bridge_port_id)
        (is_new, b_bridge_port_id, b_bridge_subnet_id,
         b_bridge_net_id) = self.helper.get_bottom_bridge_elements(
            ctx, project_id, b_pod, t_bridge_net, True, t_bridge_subnet, None)

        # we attach the bridge port as router gateway
        # add_gateway is update operation, which can run multiple times
        gateway_ip = t_bridge_port['fixed_ips'][0]['ip_address']
        b_client.action_routers(
            ctx, 'add_gateway', b_router_id,
            {'network_id': b_bridge_net_id,
             'enable_snat': False,
             'external_fixed_ips': [{'subnet_id': b_bridge_subnet_id,
                                     'ip_address': gateway_ip}]})

        # attach internal port to bottom router
        t_ports = self._get_router_interfaces(t_client, ctx, t_router['id'],
                                              t_net['id'])
        b_net_id = db_api.get_bottom_id_by_top_id_region_name(
            ctx, t_net['id'], b_pod['region_name'], constants.RT_NETWORK)
        if b_net_id:
            b_ports = self._get_router_interfaces(b_client, ctx, b_router_id,
                                                  b_net_id)
        else:
            b_ports = []
        if not t_ports and b_ports:
            # remove redundant bottom interface
            b_port = b_ports[0]
            request_body = {'port_id': b_port['id']}
            b_client.action_routers(ctx, 'remove_interface', b_router_id,
                                    request_body)
        elif t_ports and not b_ports:
            # create new bottom interface
            t_port = t_ports[0]

            # only consider ipv4 address currently
            t_subnet_id = t_port['fixed_ips'][0]['subnet_id']
            t_subnet = t_client.get_subnets(ctx, t_subnet_id)

            if CONF.enable_api_gateway:
                (b_net_id,
                 subnet_map) = self.helper.prepare_bottom_network_subnets(
                    ctx, q_ctx, project_id, b_pod, t_net, [t_subnet])
            else:
                (b_net_id,
                 subnet_map) = (t_net['id'], {t_subnet['id']: t_subnet['id']})

            # the gateway ip of bottom subnet is set to the ip of t_port, so
            # we just attach the bottom subnet to the bottom router and neutron
            # server in the bottom pod will create the interface for us, using
            # the gateway ip.
            b_client.action_routers(ctx, 'add_interface', b_router_id,
                                    {'subnet_id': subnet_map[t_subnet_id]})

        if not t_router['external_gateway_info']:
            return

        # handle floatingip
        t_ext_net_id = t_router['external_gateway_info']['network_id']
        t_fips = t_client.list_floatingips(ctx, [{'key': 'floating_network_id',
                                                  'comparator': 'eq',
                                                  'value': t_ext_net_id}])
        # skip unbound top floatingip
        t_ip_fip_map = dict([(fip['floating_ip_address'],
                              fip) for fip in t_fips if fip['port_id']])
        mappings = db_api.get_bottom_mappings_by_top_id(ctx, t_ext_net_id,
                                                        constants.RT_NETWORK)
        # bottom external network should exist
        b_ext_pod, b_ext_net_id = mappings[0]
        b_ext_client = self._get_client(b_ext_pod['region_name'])
        b_fips = b_ext_client.list_floatingips(
            ctx, [{'key': 'floating_network_id', 'comparator': 'eq',
                   'value': b_ext_net_id}])
        b_ip_fip_map = dict([(fip['floating_ip_address'],
                              fip) for fip in b_fips])
        add_fips = [ip for ip in t_ip_fip_map if ip not in b_ip_fip_map]
        del_fips = [ip for ip in b_ip_fip_map if ip not in t_ip_fip_map]

        for add_fip in add_fips:
            fip = t_ip_fip_map[add_fip]
            t_int_port_id = fip['port_id']
            b_int_port_id = db_api.get_bottom_id_by_top_id_region_name(
                ctx, t_int_port_id, b_pod['region_name'], constants.RT_PORT)
            if not b_int_port_id:
                LOG.warning(_LW('Port %(port_id)s associated with floating ip '
                                '%(fip)s is not mapped to bottom pod'),
                            {'port_id': t_int_port_id, 'fip': add_fip})
                continue
            t_int_port = t_client.get_ports(ctx, t_int_port_id)
            if t_int_port['network_id'] != t_net['id']:
                # only handle floating ip association for the given top network
                continue

            if b_ext_pod['pod_id'] != b_pod['pod_id']:
                # if the internal port is not located in the external network
                # pod, we need to create a copied port in that pod for floating
                # ip association purpose
                t_int_net_id = t_int_port['network_id']
                t_int_subnet_id = t_int_port['fixed_ips'][0]['subnet_id']
                port_body = {
                    'port': {
                        'tenant_id': project_id,
                        'admin_state_up': True,
                        'name': constants.shadow_port_name % t_int_port['id'],
                        'network_id': t_int_net_id,
                        'fixed_ips': [{'ip_address': t_int_port[
                            'fixed_ips'][0]['ip_address']}]
                    }
                }
                self.helper.prepare_bottom_element(
                    ctx, project_id, b_ext_pod, t_int_port,
                    constants.RT_SD_PORT, port_body)
                # create routing entries for copied network and subnet so we
                # can easily find them during central network and subnet
                # deletion, create_resource_mapping will catch DBDuplicateEntry
                # exception and ignore it so it's safe to call this function
                # multiple times
                db_api.create_resource_mapping(ctx, t_int_net_id, t_int_net_id,
                                               b_ext_pod['pod_id'], project_id,
                                               constants.RT_SD_NETWORK)
                db_api.create_resource_mapping(ctx, t_int_subnet_id,
                                               t_int_subnet_id,
                                               b_ext_pod['pod_id'], project_id,
                                               constants.RT_SD_SUBNET)

            self._safe_create_bottom_floatingip(
                ctx, b_pod, b_ext_client, b_ext_net_id, add_fip,
                b_int_port_id)

        for del_fip in del_fips:
            fip = b_ip_fip_map[del_fip]
            if b_ext_pod['pod_id'] != b_pod['pod_id'] and fip['port_id']:
                # expire the routing entry for copy port
                with ctx.session.begin():
                    core.update_resources(
                        ctx, models.ResourceRouting,
                        [{'key': 'bottom_id', 'comparator': 'eq',
                          'value': fip['port_id']},
                         {'key': 'resource_type', 'comparator': 'eq',
                          'value': constants.RT_SD_PORT}],
                        {'bottom_id': None,
                         'created_at': constants.expire_time,
                         'updated_at': constants.expire_time})
                # delete copy port
                b_ext_client.delete_ports(ctx, fip['port_id'])
                # delete the expired entry, even if this deletion fails, we
                # still have a chance that lock_handle module will delete it
                with ctx.session.begin():
                    core.delete_resources(ctx, models.ResourceRouting,
                                          [{'key': 'top_id',
                                            'comparator': 'eq',
                                            'value': fip['port_id']},
                                           {'key': 'resource_type',
                                            'comparator': 'eq',
                                            'value': constants.RT_SD_PORT}])
                    # delete port before floating ip disassociation, copy
                    # network and copy subnet are deleted during central
                    # network and subnet deletion
            b_ext_client.delete_floatingips(ctx, fip['id'])
Esempio n. 16
0
    def put(self, _id, **kw):
        context = t_context.extract_context_from_environ()

        # TODO(joehuang): Implement API multi-version compatibility
        # currently _convert_header and _convert_object are both dummy
        # functions and API versions are hard coded. After multi-version
        # compatibility is implemented, API versions will be retrieved from
        # top and bottom API server, also, _convert_header and _convert_object
        # will do the real job to convert the request header and body
        # according to the API versions.
        t_release = cons.R_MITAKA
        b_release = cons.R_MITAKA

        s_ctx = self._get_res_routing_ref(context, _id, request.url)
        if not s_ctx:
            return Response(_('Resource not found'), 404)

        if s_ctx['b_url'] == '':
            return Response(_('Bottom pod endpoint incorrect'), 404)

        b_headers = self._convert_header(t_release,
                                         b_release,
                                         request.headers)

        t_vol = kw['volume']

        # add or remove key-value in the request for diff. version
        b_vol_req = self._convert_object(t_release, b_release, t_vol,
                                         res_type=cons.RT_VOLUME)

        b_body = jsonutils.dumps({'volume': b_vol_req})

        resp = hclient.forward_req(context, 'PUT',
                                   b_headers,
                                   s_ctx['b_url'],
                                   b_body)

        b_status = resp.status_code
        b_ret_body = jsonutils.loads(resp.content)
        response.status = b_status

        if b_status == 200:
            if b_ret_body.get('volume') is not None:
                b_vol_ret = b_ret_body['volume']
                ret_vol = self._convert_object(b_release, t_release,
                                               b_vol_ret,
                                               res_type=cons.RT_VOLUME)

                pod = self._get_pod_by_top_id(context, _id)
                if pod:
                    ret_vol['availability_zone'] = pod['az_name']

                return {'volume': ret_vol}

        # resource not found but routing exist, remove the routing
        if b_status == 404:
            filters = [{'key': 'top_id', 'comparator': 'eq', 'value': _id},
                       {'key': 'resource_type',
                        'comparator': 'eq',
                        'value': cons.RT_VOLUME}]
            with context.session.begin():
                core.delete_resources(context,
                                      models.ResourceRouting,
                                      filters)
        return b_ret_body
Esempio n. 17
0
    def _setup_router_one_pod(self, ctx, t_pod, b_pod, t_client, t_net,
                              t_router, t_ew_bridge_net, t_ew_bridge_subnet,
                              need_ns_bridge):
        b_client = self._get_client(b_pod['pod_name'])

        router_body = {'router': {'name': t_router['id'],
                                  'distributed': False}}
        project_id = t_router['tenant_id']

        # create bottom router in target bottom pod
        _, b_router_id = self.helper.prepare_bottom_element(
            ctx, project_id, b_pod, t_router, 'router', router_body)

        # handle E-W networking
        # create top E-W bridge port
        q_ctx = None  # no need to pass neutron context when using client
        t_ew_bridge_port_id = self.helper.get_bridge_interface(
            ctx, q_ctx, project_id, t_pod, t_ew_bridge_net['id'],
            b_router_id, None, True)

        # create bottom E-W bridge port
        t_ew_bridge_port = t_client.get_ports(ctx, t_ew_bridge_port_id)
        (is_new, b_ew_bridge_port_id,
         _, _) = self.helper.get_bottom_bridge_elements(
            ctx, project_id, b_pod, t_ew_bridge_net, False, t_ew_bridge_subnet,
            t_ew_bridge_port)

        # attach bottom E-W bridge port to bottom router
        if is_new:
            # only attach bridge port the first time
            b_client.action_routers(ctx, 'add_interface', b_router_id,
                                    {'port_id': b_ew_bridge_port_id})
        else:
            # still need to check if the bridge port is bound
            port = b_client.get_ports(ctx, b_ew_bridge_port_id)
            if not port.get('device_id'):
                b_client.action_routers(ctx, 'add_interface', b_router_id,
                                        {'port_id': b_ew_bridge_port_id})

        # handle N-S networking
        if need_ns_bridge:
            t_ns_bridge_net_name = constants.ns_bridge_net_name % project_id
            t_ns_bridge_subnet_name = constants.ns_bridge_subnet_name % (
                project_id)
            t_ns_bridge_net = self._get_resource_by_name(
                t_client, ctx, 'network', t_ns_bridge_net_name)
            t_ns_bridge_subnet = self._get_resource_by_name(
                t_client, ctx, 'subnet', t_ns_bridge_subnet_name)
            # create bottom N-S bridge network and subnet
            (_, _, b_ns_bridge_subnet_id,
             b_ns_bridge_net_id) = self.helper.get_bottom_bridge_elements(
                ctx, project_id, b_pod, t_ns_bridge_net, True,
                t_ns_bridge_subnet, None)
            # create top N-S bridge gateway port
            t_ns_bridge_gateway_id = self.helper.get_bridge_interface(
                ctx, q_ctx, project_id, t_pod, t_ns_bridge_net['id'],
                b_router_id, None, False)
            t_ns_bridge_gateway = t_client.get_ports(ctx,
                                                     t_ns_bridge_gateway_id)
            # add external gateway for bottom router
            # add gateway is update operation, can run multiple times
            gateway_ip = t_ns_bridge_gateway['fixed_ips'][0]['ip_address']
            b_client.action_routers(
                ctx, 'add_gateway', b_router_id,
                {'network_id': b_ns_bridge_net_id,
                 'external_fixed_ips': [{'subnet_id': b_ns_bridge_subnet_id,
                                         'ip_address': gateway_ip}]})

        # attach internal port to bottom router
        t_ports = self._get_router_interfaces(t_client, ctx, t_router['id'],
                                              t_net['id'])
        b_net_id = db_api.get_bottom_id_by_top_id_pod_name(
            ctx, t_net['id'], b_pod['pod_name'], constants.RT_NETWORK)
        if b_net_id:
            b_ports = self._get_router_interfaces(b_client, ctx, b_router_id,
                                                  b_net_id)
        else:
            b_ports = []
        if not t_ports and b_ports:
            # remove redundant bottom interface
            b_port = b_ports[0]
            request_body = {'port_id': b_port['id']}
            b_client.action_routers(ctx, 'remove_interface', b_router_id,
                                    request_body)
        elif t_ports and not b_ports:
            # create new bottom interface
            t_port = t_ports[0]

            # only consider ipv4 address currently
            t_subnet_id = t_port['fixed_ips'][0]['subnet_id']
            t_subnet = t_client.get_subnets(ctx, t_subnet_id)

            (b_net_id,
             subnet_map) = self.helper.prepare_bottom_network_subnets(
                ctx, q_ctx, project_id, b_pod, t_net, [t_subnet])

            # the gateway ip of bottom subnet is set to the ip of t_port, so
            # we just attach the bottom subnet to the bottom router and neutron
            # server in the bottom pod will create the interface for us, using
            # the gateway ip.
            b_client.action_routers(ctx, 'add_interface', b_router_id,
                                    {'subnet_id': subnet_map[t_subnet_id]})

        if not t_router['external_gateway_info']:
            return

        # handle floatingip
        t_ext_net_id = t_router['external_gateway_info']['network_id']
        t_fips = t_client.list_floatingips(ctx, [{'key': 'floating_network_id',
                                                  'comparator': 'eq',
                                                  'value': t_ext_net_id}])
        # skip unbound top floatingip
        t_ip_fip_map = dict([(fip['floating_ip_address'],
                              fip) for fip in t_fips if fip['port_id']])
        mappings = db_api.get_bottom_mappings_by_top_id(ctx, t_ext_net_id,
                                                        constants.RT_NETWORK)
        # bottom external network should exist
        b_ext_pod, b_ext_net_id = mappings[0]
        b_ext_client = self._get_client(b_ext_pod['pod_name'])
        b_fips = b_ext_client.list_floatingips(
            ctx, [{'key': 'floating_network_id', 'comparator': 'eq',
                   'value': b_ext_net_id}])
        # skip unbound bottom floatingip
        b_ip_fip_map = dict([(fip['floating_ip_address'],
                              fip) for fip in b_fips if fip['port_id']])
        add_fips = [ip for ip in t_ip_fip_map if ip not in b_ip_fip_map]
        del_fips = [ip for ip in b_ip_fip_map if ip not in t_ip_fip_map]

        for add_fip in add_fips:
            fip = t_ip_fip_map[add_fip]
            t_int_port_id = fip['port_id']
            b_int_port_id = db_api.get_bottom_id_by_top_id_pod_name(
                ctx, t_int_port_id, b_pod['pod_name'], constants.RT_PORT)
            if not b_int_port_id:
                LOG.warning(_LW('Port %(port_id)s associated with floating ip '
                                '%(fip)s is not mapped to bottom pod'),
                            {'port_id': t_int_port_id, 'fip': add_fip})
                continue
            t_int_port = t_client.get_ports(ctx, t_int_port_id)
            if t_int_port['network_id'] != t_net['id']:
                # only handle floating ip association for the given top network
                continue
            if need_ns_bridge:
                # create top N-S bridge interface port
                t_ns_bridge_port_id = self.helper.get_bridge_interface(
                    ctx, q_ctx, project_id, t_pod, t_ns_bridge_net['id'], None,
                    b_int_port_id, False)
                t_ns_bridge_port = t_client.get_ports(ctx, t_ns_bridge_port_id)
                b_ext_bridge_net_id = db_api.get_bottom_id_by_top_id_pod_name(
                    ctx, t_ns_bridge_net['id'], b_ext_pod['pod_name'],
                    constants.RT_NETWORK)
                port_body = {
                    'port': {
                        'tenant_id': project_id,
                        'admin_state_up': True,
                        'name': 'ns_bridge_port',
                        'network_id': b_ext_bridge_net_id,
                        'fixed_ips': [{'ip_address': t_ns_bridge_port[
                            'fixed_ips'][0]['ip_address']}]
                    }
                }
                _, b_ns_bridge_port_id = self.helper.prepare_bottom_element(
                    ctx, project_id, b_ext_pod, t_ns_bridge_port,
                    constants.RT_PORT, port_body)
                self._safe_create_bottom_floatingip(
                    ctx, b_ext_pod, b_ext_client, b_ext_net_id, add_fip,
                    b_ns_bridge_port_id)
                self._safe_create_bottom_floatingip(
                    ctx, b_pod, b_client, b_ns_bridge_net_id,
                    t_ns_bridge_port['fixed_ips'][0]['ip_address'],
                    b_int_port_id)
            else:
                self._safe_create_bottom_floatingip(
                    ctx, b_pod, b_client, b_ext_net_id, add_fip,
                    b_int_port_id)

        for del_fip in del_fips:
            fip = b_ip_fip_map[del_fip]
            if need_ns_bridge:
                b_ns_bridge_port = b_ext_client.get_ports(ctx, fip['port_id'])
                entries = core.query_resource(
                    ctx, models.ResourceRouting,
                    [{'key': 'bottom_id', 'comparator': 'eq',
                      'value': b_ns_bridge_port['id']},
                     {'key': 'pod_id', 'comparator': 'eq',
                      'value': b_ext_pod['pod_id']}], [])
                t_ns_bridge_port_id = entries[0]['top_id']
                b_int_fips = b_client.list_floatingips(
                    ctx,
                    [{'key': 'floating_ip_address',
                      'comparator': 'eq',
                      'value': b_ns_bridge_port['fixed_ips'][0]['ip_address']},
                     {'key': 'floating_network_id',
                      'comparator': 'eq',
                      'value': b_ns_bridge_net_id}])
                if b_int_fips:
                    b_client.delete_floatingips(ctx, b_int_fips[0]['id'])
                b_ext_client.update_floatingips(
                    ctx, fip['id'], {'floatingip': {'port_id': None}})

                # for bridge port, we have two resource routing entries, one
                # for bridge port in top pod, another for bridge port in bottom
                # pod. calling t_client.delete_ports will delete bridge port in
                # bottom pod as well as routing entry for it, but we also need
                # to remove routing entry for bridge port in top pod, bridge
                # network will be deleted when deleting router

                # first we update the routing entry to set bottom_id to None
                # and expire the entry, so if we succeed to delete the bridge
                # port next, this expired entry will be deleted; otherwise, we
                # fail to delete the bridge port, when the port is accessed via
                # lock_handle module, that module will find the port and update
                # the entry
                with ctx.session.begin():
                    core.update_resources(
                        ctx, models.ResourceRouting,
                        [{'key': 'bottom_id', 'comparator': 'eq',
                          'value': t_ns_bridge_port_id}],
                        {'bottom_id': None,
                         'created_at': constants.expire_time,
                         'updated_at': constants.expire_time})
                # delete bridge port
                t_client.delete_ports(ctx, t_ns_bridge_port_id)
                # delete the expired entry, even if this deletion fails, we
                # still have a chance that lock_handle module will delete it
                with ctx.session.begin():
                    core.delete_resources(ctx, models.ResourceRouting,
                                          [{'key': 'bottom_id',
                                            'comparator': 'eq',
                                            'value': t_ns_bridge_port_id}])
            else:
                b_client.update_floatingips(ctx, fip['id'],
                                            {'floatingip': {'port_id': None}})
Esempio n. 18
0
    def _update_route_entry_destination_cidrs(self, context, route_entry_id,
                                              route_entry):
        def _combine(ht):
            return "{}".format(ht['destination'])

        try:
            with context.session.begin(subtransactions=True):

                old_route_list = self._get_destination_cidrs_by_route_entry_id(
                    context, route_entry_id)

                new_route_set = set([
                    _combine(route)
                    for route in route_entry['destination_cidr_list']
                ])

                old_route_set = set(
                    [_combine(route) for route in old_route_list])

                new_routes = []
                for route_str in old_route_set - new_route_set:
                    for route in old_route_list:
                        if _combine(route) == route_str:
                            destination = self.filter_to_str(
                                common_utils.AuthenticIPNetwork(
                                    route_str.partition("_")[0]))
                            route_filters = [{
                                'key': 'route_entry_id',
                                'comparator': 'eq',
                                'value': route_entry_id
                            }, {
                                'key': 'destination',
                                'comparator': 'eq',
                                'value': destination
                            }]
                            core.delete_resources(context,
                                                  models.DestinationCidr,
                                                  route_filters)
                for route_str in new_route_set - old_route_set:
                    destination = self.filter_to_str(
                        common_utils.AuthenticIPNetwork(
                            route_str.partition("_")[0]))
                    new_core_routerroute = core.create_resource(
                        context, models.DestinationCidr, {
                            'route_entry_id': route_entry_id,
                            'destination': destination
                        })

                for route_str in new_route_set:
                    new_routes.append({'destination': route_str})
                del route_entry["destination_cidr_list"]
                return new_routes
        except Exception as e:
            LOG.exception(
                'Failed to update destination_cidr: '
                'route_entry_id %(route_entry_id)s: '
                '%(exception)s', {
                    'route_entry_id': route_entry_id,
                    'exception': e
                })
            raise t_exceptions.RouteEntryDestinationCidrsUpdateException()
Esempio n. 19
0
    def _setup_router_one_pod(self, ctx, t_pod, b_pod, t_client, t_net,
                              t_router, t_ew_bridge_net, t_ew_bridge_subnet,
                              need_ns_bridge):
        b_client = self._get_client(b_pod['pod_name'])

        router_body = {'router': {'name': t_router['id'],
                                  'distributed': False}}
        project_id = t_router['tenant_id']

        # create bottom router in target bottom pod
        _, b_router_id = self.helper.prepare_bottom_element(
            ctx, project_id, b_pod, t_router, 'router', router_body)

        # handle E-W networking
        # create top E-W bridge port
        q_ctx = None  # no need to pass neutron context when using client
        t_ew_bridge_port_id = self.helper.get_bridge_interface(
            ctx, q_ctx, project_id, t_pod, t_ew_bridge_net['id'],
            b_router_id, None, True)

        # create bottom E-W bridge port
        t_ew_bridge_port = t_client.get_ports(ctx, t_ew_bridge_port_id)
        (is_new, b_ew_bridge_port_id,
         _, _) = self.helper.get_bottom_bridge_elements(
            ctx, project_id, b_pod, t_ew_bridge_net, False, t_ew_bridge_subnet,
            t_ew_bridge_port)

        # attach bottom E-W bridge port to bottom router
        if is_new:
            # only attach bridge port the first time
            b_client.action_routers(ctx, 'add_interface', b_router_id,
                                    {'port_id': b_ew_bridge_port_id})
        else:
            # still need to check if the bridge port is bound
            port = b_client.get_ports(ctx, b_ew_bridge_port_id)
            if not port.get('device_id'):
                b_client.action_routers(ctx, 'add_interface', b_router_id,
                                        {'port_id': b_ew_bridge_port_id})

        # handle N-S networking
        if need_ns_bridge:
            t_ns_bridge_net_name = constants.ns_bridge_net_name % project_id
            t_ns_bridge_subnet_name = constants.ns_bridge_subnet_name % (
                project_id)
            t_ns_bridge_net = self._get_resource_by_name(
                t_client, ctx, 'network', t_ns_bridge_net_name)
            t_ns_bridge_subnet = self._get_resource_by_name(
                t_client, ctx, 'subnet', t_ns_bridge_subnet_name)
            # create bottom N-S bridge network and subnet
            (_, _, b_ns_bridge_subnet_id,
             b_ns_bridge_net_id) = self.helper.get_bottom_bridge_elements(
                ctx, project_id, b_pod, t_ns_bridge_net, True,
                t_ns_bridge_subnet, None)
            # create top N-S bridge gateway port
            t_ns_bridge_gateway_id = self.helper.get_bridge_interface(
                ctx, q_ctx, project_id, t_pod, t_ns_bridge_net['id'],
                b_router_id, None, False)
            t_ns_bridge_gateway = t_client.get_ports(ctx,
                                                     t_ns_bridge_gateway_id)
            # add external gateway for bottom router
            # add gateway is update operation, can run multiple times
            gateway_ip = t_ns_bridge_gateway['fixed_ips'][0]['ip_address']
            b_client.action_routers(
                ctx, 'add_gateway', b_router_id,
                {'network_id': b_ns_bridge_net_id,
                 'external_fixed_ips': [{'subnet_id': b_ns_bridge_subnet_id,
                                         'ip_address': gateway_ip}]})

        # attach internal port to bottom router
        t_ports = self._get_router_interfaces(t_client, ctx, t_router['id'],
                                              t_net['id'])
        b_net_id = db_api.get_bottom_id_by_top_id_pod_name(
            ctx, t_net['id'], b_pod['pod_name'], constants.RT_NETWORK)
        if b_net_id:
            b_ports = self._get_router_interfaces(b_client, ctx, b_router_id,
                                                  b_net_id)
        else:
            b_ports = []
        if not t_ports and b_ports:
            # remove redundant bottom interface
            b_port = b_ports[0]
            request_body = {'port_id': b_port['id']}
            b_client.action_routers(ctx, 'remove_interface', b_router_id,
                                    request_body)
        elif t_ports and not b_ports:
            # create new bottom interface
            t_port = t_ports[0]

            # only consider ipv4 address currently
            t_subnet_id = t_port['fixed_ips'][0]['subnet_id']
            t_subnet = t_client.get_subnets(ctx, t_subnet_id)

            if CONF.enable_api_gateway:
                (b_net_id,
                 subnet_map) = self.helper.prepare_bottom_network_subnets(
                    ctx, q_ctx, project_id, b_pod, t_net, [t_subnet])
            else:
                (b_net_id,
                 subnet_map) = (t_net['id'], {t_subnet['id']: t_subnet['id']})

            # the gateway ip of bottom subnet is set to the ip of t_port, so
            # we just attach the bottom subnet to the bottom router and neutron
            # server in the bottom pod will create the interface for us, using
            # the gateway ip.
            b_client.action_routers(ctx, 'add_interface', b_router_id,
                                    {'subnet_id': subnet_map[t_subnet_id]})

        if not t_router['external_gateway_info']:
            return

        # handle floatingip
        t_ext_net_id = t_router['external_gateway_info']['network_id']
        t_fips = t_client.list_floatingips(ctx, [{'key': 'floating_network_id',
                                                  'comparator': 'eq',
                                                  'value': t_ext_net_id}])
        # skip unbound top floatingip
        t_ip_fip_map = dict([(fip['floating_ip_address'],
                              fip) for fip in t_fips if fip['port_id']])
        mappings = db_api.get_bottom_mappings_by_top_id(ctx, t_ext_net_id,
                                                        constants.RT_NETWORK)
        # bottom external network should exist
        b_ext_pod, b_ext_net_id = mappings[0]
        b_ext_client = self._get_client(b_ext_pod['pod_name'])
        b_fips = b_ext_client.list_floatingips(
            ctx, [{'key': 'floating_network_id', 'comparator': 'eq',
                   'value': b_ext_net_id}])
        b_ip_fip_map = dict([(fip['floating_ip_address'],
                              fip) for fip in b_fips])
        add_fips = [ip for ip in t_ip_fip_map if ip not in b_ip_fip_map]
        del_fips = [ip for ip in b_ip_fip_map if ip not in t_ip_fip_map]

        for add_fip in add_fips:
            fip = t_ip_fip_map[add_fip]
            t_int_port_id = fip['port_id']
            b_int_port_id = db_api.get_bottom_id_by_top_id_pod_name(
                ctx, t_int_port_id, b_pod['pod_name'], constants.RT_PORT)
            if not b_int_port_id:
                LOG.warning(_LW('Port %(port_id)s associated with floating ip '
                                '%(fip)s is not mapped to bottom pod'),
                            {'port_id': t_int_port_id, 'fip': add_fip})
                continue
            t_int_port = t_client.get_ports(ctx, t_int_port_id)
            if t_int_port['network_id'] != t_net['id']:
                # only handle floating ip association for the given top network
                continue
            if need_ns_bridge:
                # create top N-S bridge interface port
                t_ns_bridge_port_id = self.helper.get_bridge_interface(
                    ctx, q_ctx, project_id, t_pod, t_ns_bridge_net['id'], None,
                    b_int_port_id, False)
                t_ns_bridge_port = t_client.get_ports(ctx, t_ns_bridge_port_id)
                b_ext_bridge_net_id = db_api.get_bottom_id_by_top_id_pod_name(
                    ctx, t_ns_bridge_net['id'], b_ext_pod['pod_name'],
                    constants.RT_NETWORK)
                port_body = {
                    'port': {
                        'tenant_id': project_id,
                        'admin_state_up': True,
                        'name': 'ns_bridge_port',
                        'network_id': b_ext_bridge_net_id,
                        'fixed_ips': [{'ip_address': t_ns_bridge_port[
                            'fixed_ips'][0]['ip_address']}]
                    }
                }
                _, b_ns_bridge_port_id = self.helper.prepare_bottom_element(
                    ctx, project_id, b_ext_pod, t_ns_bridge_port,
                    constants.RT_PORT, port_body)
                # swap these two lines
                self._safe_create_bottom_floatingip(
                    ctx, b_pod, b_client, b_ns_bridge_net_id,
                    t_ns_bridge_port['fixed_ips'][0]['ip_address'],
                    b_int_port_id)
                self._safe_create_bottom_floatingip(
                    ctx, b_ext_pod, b_ext_client, b_ext_net_id, add_fip,
                    b_ns_bridge_port_id)
            else:
                self._safe_create_bottom_floatingip(
                    ctx, b_pod, b_client, b_ext_net_id, add_fip,
                    b_int_port_id)

        for del_fip in del_fips:
            fip = b_ip_fip_map[del_fip]
            if not fip['port_id']:
                b_ext_client.delete_floatingips(ctx, fip['id'])
                continue
            if need_ns_bridge:
                b_ns_bridge_port = b_ext_client.get_ports(ctx, fip['port_id'])
                entries = core.query_resource(
                    ctx, models.ResourceRouting,
                    [{'key': 'bottom_id', 'comparator': 'eq',
                      'value': b_ns_bridge_port['id']},
                     {'key': 'pod_id', 'comparator': 'eq',
                      'value': b_ext_pod['pod_id']}], [])
                t_ns_bridge_port_id = entries[0]['top_id']
                b_int_fips = b_client.list_floatingips(
                    ctx,
                    [{'key': 'floating_ip_address',
                      'comparator': 'eq',
                      'value': b_ns_bridge_port['fixed_ips'][0]['ip_address']},
                     {'key': 'floating_network_id',
                      'comparator': 'eq',
                      'value': b_ns_bridge_net_id}])
                if b_int_fips:
                    b_client.delete_floatingips(ctx, b_int_fips[0]['id'])

                # for bridge port, we have two resource routing entries, one
                # for bridge port in top pod, another for bridge port in bottom
                # pod. calling t_client.delete_ports will delete bridge port in
                # bottom pod as well as routing entry for it, but we also need
                # to remove routing entry for bridge port in top pod, bridge
                # network will be deleted when deleting router

                # first we update the routing entry to set bottom_id to None
                # and expire the entry, so if we succeed to delete the bridge
                # port next, this expired entry will be deleted; otherwise, we
                # fail to delete the bridge port, when the port is accessed via
                # lock_handle module, that module will find the port and update
                # the entry
                with ctx.session.begin():
                    core.update_resources(
                        ctx, models.ResourceRouting,
                        [{'key': 'bottom_id', 'comparator': 'eq',
                          'value': t_ns_bridge_port_id}],
                        {'bottom_id': None,
                         'created_at': constants.expire_time,
                         'updated_at': constants.expire_time})
                # delete bridge port
                t_client.delete_ports(ctx, t_ns_bridge_port_id)
                # delete the expired entry, even if this deletion fails, we
                # still have a chance that lock_handle module will delete it
                with ctx.session.begin():
                    core.delete_resources(ctx, models.ResourceRouting,
                                          [{'key': 'bottom_id',
                                            'comparator': 'eq',
                                            'value': t_ns_bridge_port_id}])
            b_ext_client.delete_floatingips(ctx, fip['id'])
Esempio n. 20
0
    def put(self, _id, **kw):
        context = t_context.extract_context_from_environ()

        # TODO(joehuang): Implement API multi-version compatibility
        # currently _convert_header and _convert_object are both dummy
        # functions and API versions are hard coded. After multi-version
        # compatibility is implemented, API versions will be retrieved from
        # top and bottom API server, also, _convert_header and _convert_object
        # will do the real job to convert the request header and body
        # according to the API versions.
        t_release = cons.R_MITAKA
        b_release = cons.R_MITAKA

        s_ctx = self._get_res_routing_ref(context, _id, request.url)
        if not s_ctx:
            return Response(_('Resource not found'), 404)

        if s_ctx['b_url'] == '':
            return Response(_('Bottom pod endpoint incorrect'), 404)

        b_headers = self._convert_header(t_release, b_release, request.headers)

        t_vol = kw['volume']

        # add or remove key-value in the request for diff. version
        b_vol_req = self._convert_object(t_release,
                                         b_release,
                                         t_vol,
                                         res_type=cons.RT_VOLUME)

        b_body = jsonutils.dumps({'volume': b_vol_req})

        resp = hclient.forward_req(context, 'PUT', b_headers, s_ctx['b_url'],
                                   b_body)

        b_status = resp.status_code
        b_ret_body = jsonutils.loads(resp.content)
        response.status = b_status

        if b_status == 200:
            if b_ret_body.get('volume') is not None:
                b_vol_ret = b_ret_body['volume']
                ret_vol = self._convert_object(b_release,
                                               t_release,
                                               b_vol_ret,
                                               res_type=cons.RT_VOLUME)

                pod = self._get_pod_by_top_id(context, _id)
                if pod:
                    ret_vol['availability_zone'] = pod['az_name']

                return {'volume': ret_vol}

        # resource not found but routing exist, remove the routing
        if b_status == 404:
            filters = [{
                'key': 'top_id',
                'comparator': 'eq',
                'value': _id
            }, {
                'key': 'resource_type',
                'comparator': 'eq',
                'value': cons.RT_VOLUME
            }]
            with context.session.begin():
                core.delete_resources(context, models.ResourceRouting, filters)
        return b_ret_body