Exemple #1
0
 def __new__(cls, *args, **kwargs):
     model_query.register_hook(models_v2.Network,
                               "external_net",
                               query_hook=None,
                               filter_hook=_network_filter_hook,
                               result_filters=_network_result_filter_hook)
     return super(External_net_db_mixin, cls).__new__(cls, *args, **kwargs)
Exemple #2
0
 def __new__(cls, *args, **kwargs):
     model_query.register_hook(models_v2.Port,
                               "portbindings_port",
                               query_hook=_port_model_hook,
                               filter_hook=None,
                               result_filters=_port_result_filter_hook)
     return super(PortBindingMixin, cls).__new__(cls, *args, **kwargs)
Exemple #3
0
 def __new__(cls, *args, **kwargs):
     model_query.register_hook(
         BGPVPN,
         "bgpvpn_filter_by_resource_association",
         query_hook=None,
         filter_hook=None,
         result_filters=_list_bgpvpns_result_filter_hook)
     return super(BGPVPNPluginDb, cls).__new__(cls, *args, **kwargs)
 def __new__(cls, *args, **kwargs):
     model_query.register_hook(
         models_v2.Port,
         "portbindings_port",
         query_hook=_port_model_hook,
         filter_hook=None,
         result_filters=_port_result_filter_hook)
     return super(PortBindingMixin, cls).__new__(cls, *args, **kwargs)
 def __new__(cls, *args, **kwargs):
     model_query.register_hook(
         models_v2.Network,
         "external_net",
         query_hook=None,
         filter_hook=_network_filter_hook,
         result_filters=_network_result_filter_hook)
     return super(External_net_db_mixin, cls).__new__(cls, *args, **kwargs)
Exemple #6
0
def register_tag_hooks():
    for model in resource_model_map.values():
        method = functools.partial(_apply_tag_filters, model)
        _filter_methods.append(method)
        model_query.register_hook(model, "tag",
                                  query_hook=None,
                                  filter_hook=None,
                                  result_filters=method)
Exemple #7
0
 def __new__(cls, *args, **kwargs):
     model_query.register_hook(
         models_v2.SubnetPool,
         "implicit_subnetpool",
         query_hook=_subnetpool_model_hook,
         filter_hook=_subnetpool_filter_hook,
         result_filters=_subnetpool_result_filter_hook)
     return super(ImplicitSubnetpoolMixin,
                  cls).__new__(cls, *args, **kwargs)
Exemple #8
0
def register_tag_hooks():
    for model in resource_model_map.values():
        method = functools.partial(_apply_tag_filters, model)
        _filter_methods.append(method)
        model_query.register_hook(model,
                                  "tag",
                                  query_hook=None,
                                  filter_hook=None,
                                  result_filters=method)
 def __new__(cls, *args, **kwargs):
     rs_model_maps = standard_attr.get_standard_attr_resource_model_map()
     for model in rs_model_maps.values():
         model_query.register_hook(
             model,
             "change_since_query",
             query_hook=None,
             filter_hook=None,
             result_filters=_change_since_result_filter_hook)
     return super(TimeStamp_db_mixin, cls).__new__(cls, *args, **kwargs)
 def register_model_query_hook(model,
                               name,
                               query_hook,
                               filter_hook,
                               result_filters=None):
     _model_query.register_hook(model,
                                name,
                                query_hook,
                                filter_hook,
                                result_filters=result_filters)
Exemple #11
0
 def __new__(cls, *args, **kwargs):
     rs_model_maps = standard_attr.get_standard_attr_resource_model_map()
     for model in rs_model_maps.values():
         model_query.register_hook(
             model,
             "change_since_query",
             query_hook=None,
             filter_hook=None,
             result_filters=_change_since_result_filter_hook)
     return super(TimeStamp_db_mixin, cls).__new__(cls, *args, **kwargs)
Exemple #12
0
 def __new__(cls, *args, **kwargs):
     inst = super(TagPlugin, cls).__new__(cls, *args, **kwargs)
     inst._filter_methods = []  # prevent GC of our partial functions
     for resource, model in resource_model_map.items():
         resource_extend.register_funcs(
             resource, [_extend_tags_dict])
         method = functools.partial(tag_methods.apply_tag_filters, model)
         inst._filter_methods.append(method)
         model_query.register_hook(
             model, "tag", None, None, method)
     return inst
Exemple #13
0
 def __new__(cls, *args, **kwargs):
     inst = super(TagPlugin, cls).__new__(cls, *args, **kwargs)
     inst._filter_methods = []  # prevent GC of our partial functions
     for model in resource_model_map.values():
         method = functools.partial(tag_methods.apply_tag_filters, model)
         inst._filter_methods.append(method)
         model_query.register_hook(model, "tag",
                                   query_hook=None,
                                   filter_hook=None,
                                   result_filters=method)
     return inst
Exemple #14
0
 def __new__(cls, *args, **kwargs):
     inst = super(TagPlugin, cls).__new__(cls, *args, **kwargs)
     inst._filter_methods = []  # prevent GC of our partial functions
     for model in resource_model_map.values():
         method = functools.partial(tag_methods.apply_tag_filters, model)
         inst._filter_methods.append(method)
         model_query.register_hook(model, "tag",
                                   query_hook=None,
                                   filter_hook=None,
                                   result_filters=method)
     return inst
 def __init__(self):
     super(TimeStampPlugin, self).__init__()
     self.register_db_events()
     rs_model_maps = standard_attr.get_standard_attr_resource_model_map()
     for rsmap, model in rs_model_maps.items():
         resource_extend.register_funcs(
             rsmap, [self.extend_resource_dict_timestamp])
         model_query.register_hook(model, "change_since_query", None, None,
                                   self._change_since_result_filter_hook)
     # TODO(jlibosva): Move this to register_model_query_hook
     base_obj.register_filter_hook_on_model(models_v2.SubnetPool,
                                            ts_db.CHANGED_SINCE)
    def __new__(cls, *args, **kwargs):
        model_query.register_hook(
            FirewallGroup,
            "firewall_group_v2_filter_by_port_association",
            query_hook=None,
            filter_hook=None,
            result_filters=_list_firewall_groups_result_filter_hook)

        model_query.register_hook(
            FirewallPolicy,
            "firewall_policy_v2_filter_by_firewall_rule_association",
            query_hook=None,
            filter_hook=None,
            result_filters=_list_firewall_policies_result_filter_hook)
        return super(FirewallPluginDb, cls).__new__(cls, *args, **kwargs)
Exemple #17
0
class External_net_db_mixin(object):
    """Mixin class to add external network methods to db_base_plugin_v2."""
    @staticmethod
    def _network_filter_hook(context, original_model, conditions):
        if conditions is not None and not hasattr(conditions, '__iter__'):
            conditions = (conditions, )
        # Apply the external network filter only in non-admin and non-advsvc
        # context
        if db_utils.model_query_scope_is_project(context, original_model):
            # the table will already be joined to the rbac entries for the
            # shared check so we don't need to worry about ensuring that
            rbac_model = original_model.rbac_entries.property.mapper.class_
            tenant_allowed = ((rbac_model.action == 'access_as_external') &
                              (rbac_model.target_tenant == context.tenant_id) |
                              (rbac_model.target_tenant == '*'))
            conditions = expr.or_(tenant_allowed, *conditions)
        return conditions

    def _network_result_filter_hook(self, query, filters):
        vals = filters and filters.get(external_net.EXTERNAL, [])
        if not vals:
            return query
        if vals[0]:
            return query.filter(models_v2.Network.external.has())
        return query.filter(~models_v2.Network.external.has())

    model_query.register_hook(models_v2.Network, "external_net", None,
                              '_network_filter_hook',
                              '_network_result_filter_hook')

    def _network_is_external(self, context, net_id):
        return net_obj.ExternalNetwork.objects_exist(context,
                                                     network_id=net_id)

    def _extend_network_dict_l3(self, network_res, network_db):
        # Comparing with None for converting uuid into bool
        network_res[external_net.EXTERNAL] = network_db.external is not None
        return network_res

    resource_extend.register_funcs(attributes.NETWORKS,
                                   ['_extend_network_dict_l3'])

    def _process_l3_create(self, context, net_data, req_data):
        external = req_data.get(external_net.EXTERNAL)
        external_set = validators.is_attr_set(external)

        if not external_set:
            return

        if external:
            net_obj.ExternalNetwork(context,
                                    network_id=net_data['id']).create()
            context.session.add(
                rbac_db.NetworkRBAC(object_id=net_data['id'],
                                    action='access_as_external',
                                    target_tenant='*',
                                    tenant_id=net_data['tenant_id']))
            try:
                registry.notify(resources.EXTERNAL_NETWORK,
                                events.PRECOMMIT_CREATE,
                                self,
                                context=context,
                                request=req_data,
                                network=net_data)
            except c_exc.CallbackFailure as e:
                # raise the underlying exception
                raise e.errors[0].error
        net_data[external_net.EXTERNAL] = external

    def _process_l3_update(self, context, net_data, req_data, allow_all=True):
        try:
            registry.notify(resources.EXTERNAL_NETWORK,
                            events.BEFORE_UPDATE,
                            self,
                            context=context,
                            request=req_data,
                            network=net_data)
        except c_exc.CallbackFailure as e:
            # raise the underlying exception
            raise e.errors[0].error

        new_value = req_data.get(external_net.EXTERNAL)
        net_id = net_data['id']
        if not validators.is_attr_set(new_value):
            return

        if net_data.get(external_net.EXTERNAL) == new_value:
            return

        if new_value:
            net_obj.ExternalNetwork(context, network_id=net_id).create()
            net_data[external_net.EXTERNAL] = True
            if allow_all:
                context.session.add(
                    rbac_db.NetworkRBAC(object_id=net_id,
                                        action='access_as_external',
                                        target_tenant='*',
                                        tenant_id=net_data['tenant_id']))
        else:
            # must make sure we do not have any external gateway ports
            # (and thus, possible floating IPs) on this network before
            # allow it to be update to external=False
            port = context.session.query(
                models_v2.Port).filter_by(device_owner=DEVICE_OWNER_ROUTER_GW,
                                          network_id=net_data['id']).first()
            if port:
                raise external_net.ExternalNetworkInUse(net_id=net_id)

            net_obj.ExternalNetwork.delete_objects(context, network_id=net_id)
            for rbdb in (context.session.query(rbac_db.NetworkRBAC).filter_by(
                    object_id=net_id, action='access_as_external')):
                context.session.delete(rbdb)
            net_data[external_net.EXTERNAL] = False

    def _process_l3_delete(self, context, network_id):
        l3plugin = directory.get_plugin(constants.L3)
        if l3plugin:
            l3plugin.delete_disassociated_floatingips(context, network_id)

    def get_external_network_id(self, context):
        nets = self.get_networks(context, {external_net.EXTERNAL: [True]})
        if len(nets) > 1:
            raise n_exc.TooManyExternalNetworks()
        else:
            return nets[0]['id'] if nets else None

    @registry.receives('rbac-policy', [events.BEFORE_CREATE])
    def _process_ext_policy_create(self, resource, event, trigger, context,
                                   object_type, policy, **kwargs):
        if (object_type != 'network'
                or policy['action'] != 'access_as_external'):
            return
        net = self.get_network(context, policy['object_id'])
        if not context.is_admin and net['tenant_id'] != context.tenant_id:
            msg = _("Only admins can manipulate policies on networks they "
                    "do not own")
            raise n_exc.InvalidInput(error_message=msg)
        if not self._network_is_external(context, policy['object_id']):
            # we automatically convert the network into an external network
            self._process_l3_update(context,
                                    net, {external_net.EXTERNAL: True},
                                    allow_all=False)

    @registry.receives('rbac-policy',
                       (events.BEFORE_UPDATE, events.BEFORE_DELETE))
    def _validate_ext_not_in_use_by_tenant(self, resource, event, trigger,
                                           context, object_type, policy,
                                           **kwargs):
        if (object_type != 'network'
                or policy['action'] != 'access_as_external'):
            return
        new_tenant = None
        if event == events.BEFORE_UPDATE:
            new_tenant = kwargs['policy_update']['target_tenant']
            if new_tenant == policy['target_tenant']:
                # nothing to validate if the tenant didn't change
                return
        ports = context.session.query(models_v2.Port.id).filter_by(
            device_owner=DEVICE_OWNER_ROUTER_GW,
            network_id=policy['object_id'])
        router = context.session.query(l3_models.Router).filter(
            l3_models.Router.gw_port_id.in_(ports))
        rbac = rbac_db.NetworkRBAC
        if policy['target_tenant'] != '*':
            router = router.filter(
                l3_models.Router.tenant_id == policy['target_tenant'])
            # if there is a wildcard entry we can safely proceed without the
            # router lookup because they will have access either way
            if context.session.query(rbac_db.NetworkRBAC).filter(
                    rbac.object_id == policy['object_id'],
                    rbac.action == 'access_as_external',
                    rbac.target_tenant == '*').count():
                return
        else:
            # deleting the wildcard is okay as long as the tenants with
            # attached routers have their own entries and the network is
            # not the default external network.
            if net_obj.ExternalNetwork.objects_exist(
                    context, network_id=policy['object_id'], is_default=True):
                msg = _("Default external networks must be shared to "
                        "everyone.")
                raise rbac_ext.RbacPolicyInUse(object_id=policy['object_id'],
                                               details=msg)
            tenants_with_entries = (context.session.query(
                rbac.target_tenant).filter(
                    rbac.object_id == policy['object_id'],
                    rbac.action == 'access_as_external',
                    rbac.target_tenant != '*'))
            router = router.filter(
                ~l3_models.Router.tenant_id.in_(tenants_with_entries))
            if new_tenant:
                # if this is an update we also need to ignore any router
                # interfaces that belong to the new target.
                router = router.filter(
                    l3_models.Router.tenant_id != new_tenant)
        if router.count():
            msg = _("There are routers attached to this network that "
                    "depend on this policy for access.")
            raise rbac_ext.RbacPolicyInUse(object_id=policy['object_id'],
                                           details=msg)

    @registry.receives(resources.NETWORK, [events.BEFORE_DELETE])
    def _before_network_delete_handler(self, resource, event, trigger, context,
                                       network_id, **kwargs):
        self._process_l3_delete(context, network_id)
Exemple #18
0
class PortBindingMixin(portbindings_base.PortBindingBaseMixin):
    extra_binding_dict = None

    def _port_model_hook(self, context, original_model, query):
        query = query.outerjoin(
            pmodels.PortBindingPort,
            (original_model.id == pmodels.PortBindingPort.port_id))
        return query

    def _port_result_filter_hook(self, query, filters):
        values = filters and filters.get(portbindings.HOST_ID, [])
        if not values:
            return query
        query = query.filter(pmodels.PortBindingPort.host.in_(values))
        return query

    model_query.register_hook(
        models_v2.Port,
        "portbindings_port",
        '_port_model_hook',
        None,
        '_port_result_filter_hook')

    def _process_portbindings_create_and_update(self, context, port_data,
                                                port):
        binding_profile = port.get(portbindings.PROFILE)
        binding_profile_set = validators.is_attr_set(binding_profile)
        if not binding_profile_set and binding_profile is not None:
            del port[portbindings.PROFILE]

        binding_vnic = port.get(portbindings.VNIC_TYPE)
        binding_vnic_set = validators.is_attr_set(binding_vnic)
        if not binding_vnic_set and binding_vnic is not None:
            del port[portbindings.VNIC_TYPE]
        # REVISIT(irenab) Add support for vnic_type for plugins that
        # can handle more than one type.
        # Currently implemented for ML2 plugin that does not use
        # PortBindingMixin.

        host = port_data.get(portbindings.HOST_ID)
        host_set = validators.is_attr_set(host)
        with context.session.begin(subtransactions=True):
            bind_port = context.session.query(
                pmodels.PortBindingPort).filter_by(port_id=port['id']).first()
            if host_set:
                if not bind_port:
                    context.session.add(
                        pmodels.PortBindingPort(port_id=port['id'], host=host))
                else:
                    bind_port.host = host
            else:
                host = bind_port.host if bind_port else None
        self._extend_port_dict_binding_host(port, host)

    def get_port_host(self, context, port_id):
        with context.session.begin(subtransactions=True):
            bind_port = (
                context.session.query(pmodels.PortBindingPort).
                filter_by(port_id=port_id).
                first()
            )
            return bind_port.host if bind_port else None

    def _extend_port_dict_binding_host(self, port_res, host):
        super(PortBindingMixin, self).extend_port_dict_binding(
            port_res, None)
        port_res[portbindings.HOST_ID] = host

    def extend_port_dict_binding(self, port_res, port_db):
        host = port_db.portbinding.host if port_db.portbinding else None
        self._extend_port_dict_binding_host(port_res, host)
 def register_model_query_hook(model, name, query_hook, filter_hook,
                               result_filters=None):
     _model_query.register_hook(
         model, name, query_hook, filter_hook,
         result_filters=result_filters)