Example #1
0
    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'))
Example #2
0
    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'))
Example #3
0
    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})
Example #4
0
    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]
Example #5
0
    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)
Example #6
0
    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)
Example #7
0
    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)
Example #8
0
    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
Example #9
0
    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)
Example #10
0
    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
Example #11
0
    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
Example #12
0
    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
Example #13
0
    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})
Example #14
0
 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)