Exemplo n.º 1
0
    def test_get_security_group_rule_ids(self):
        """Retrieve the SG rules associated to a project (see method desc.)

        SG1 (PROJECT1)            SG2 (PROJECT2)
          rule1a (PROJECT1)         rule2a (PROJECT1)
          rule1b (PROJECT2)         rule2b (PROJECT2)

        query PROJECT1: rule1a, rule1b, rule2a
        query PROJECT2: rule1b, rule2a, rule2b
        """
        projects = [uuidutils.generate_uuid(), uuidutils.generate_uuid()]
        sgs = [
            self._create_test_security_group_id({'project_id': projects[0]}),
            self._create_test_security_group_id({'project_id': projects[1]})
        ]

        rules_per_project = collections.defaultdict(list)
        rules_per_sg = collections.defaultdict(list)
        for project, sg in itertools.product(projects, sgs):
            sgrule_fields = self.get_random_object_fields(
                securitygroup.SecurityGroupRule)
            sgrule_fields['project_id'] = project
            sgrule_fields['security_group_id'] = sg
            rule = securitygroup.SecurityGroupRule(self.context,
                                                   **sgrule_fields)
            rule.create()
            rules_per_project[project].append(rule.id)
            rules_per_sg[sg].append(rule.id)

        for idx in range(2):
            rule_ids = securitygroup.SecurityGroupRule.\
                get_security_group_rule_ids(projects[idx])
            rule_ids_ref = set(rules_per_project[projects[idx]])
            rule_ids_ref.update(set(rules_per_sg[sgs[idx]]))
            self.assertEqual(rule_ids_ref, set(rule_ids))
Exemplo n.º 2
0
    def _create_security_group_rule(self,
                                    context,
                                    security_group_rule,
                                    validate=True):
        if validate:
            sg_id = self._validate_security_group_rule(context,
                                                       security_group_rule)
        rule_dict = security_group_rule['security_group_rule']
        remote_ip_prefix = rule_dict.get('remote_ip_prefix')
        if remote_ip_prefix:
            remote_ip_prefix = utils.AuthenticIPNetwork(remote_ip_prefix)

        protocol = rule_dict.get('protocol')
        if protocol:
            # object expects strings only
            protocol = six.text_type(protocol)

        args = {
            'id': (rule_dict.get('id') or uuidutils.generate_uuid()),
            'project_id': rule_dict['tenant_id'],
            'security_group_id': rule_dict['security_group_id'],
            'direction': rule_dict['direction'],
            'remote_group_id': rule_dict.get('remote_group_id'),
            'ethertype': rule_dict['ethertype'],
            'protocol': protocol,
            'remote_ip_prefix': remote_ip_prefix,
            'description': rule_dict.get('description'),
        }

        port_range_min = self._safe_int(rule_dict['port_range_min'])
        if port_range_min is not None:
            args['port_range_min'] = port_range_min

        port_range_max = self._safe_int(rule_dict['port_range_max'])
        if port_range_max is not None:
            args['port_range_max'] = port_range_max

        kwargs = {'context': context, 'security_group_rule': args}
        self._registry_notify(resources.SECURITY_GROUP_RULE,
                              events.BEFORE_CREATE,
                              exc_cls=ext_sg.SecurityGroupConflict,
                              **kwargs)
        with db_api.CONTEXT_WRITER.using(context):
            if validate:
                self._check_for_duplicate_rules(context, sg_id,
                                                [security_group_rule])
            sg_rule = sg_obj.SecurityGroupRule(context, **args)
            sg_rule.create()

            # fetch sg_rule from db to load the sg rules with sg model
            # otherwise a DetachedInstanceError can occur for model extensions
            sg_rule = sg_obj.SecurityGroupRule.get_object(context,
                                                          id=sg_rule.id)
            res_rule_dict = self._make_security_group_rule_dict(sg_rule.db_obj)
            kwargs['security_group_rule'] = res_rule_dict
            self._registry_notify(resources.SECURITY_GROUP_RULE,
                                  events.PRECOMMIT_CREATE,
                                  exc_cls=ext_sg.SecurityGroupConflict,
                                  **kwargs)
        return res_rule_dict
Exemplo n.º 3
0
 def _create_test_security_group_with_rule(self):
     sg_obj = self._create_test_security_group()
     rule_params = {
         'project_id': sg_obj.project_id,
         'security_group_id': sg_obj.id,
         'remote_address_group_id': None
     }
     sg_rule = securitygroup.SecurityGroupRule(self.context, **rule_params)
     sg_obj.rules = [sg_rule]
     return sg_obj
Exemplo n.º 4
0
 def _create_test_security_group_with_rule(self):
     sg_obj = self._create_test_security_group()
     rule_params = {
         'project_id': sg_obj.project_id,
         'security_group_id': sg_obj.id,
         'remote_address_group_id': None,
         'remote_ip_prefix': netaddr.IPNetwork('10.0.0.120/24')
     }
     sg_rule = securitygroup.SecurityGroupRule(self.context, **rule_params)
     sg_obj.rules = [sg_rule]
     return sg_obj
Exemplo n.º 5
0
 def _make_security_group_ovo(self, **kwargs):
     attrs = {'id': uuidutils.generate_uuid(), 'revision_number': 1}
     sg_rule = securitygroup.SecurityGroupRule(
         id=uuidutils.generate_uuid(),
         security_group_id=attrs['id'],
         direction='ingress',
         ethertype='IPv4', protocol='tcp',
         port_range_min=400,
         remote_group_id=attrs['id'],
         revision_number=1,
     )
     attrs['rules'] = [sg_rule]
     attrs.update(**kwargs)
     sg = securitygroup.SecurityGroup(self.ctx, **attrs)
     self.rcache.record_resource_update(self.ctx, 'SecurityGroup', sg)
     return sg
Exemplo n.º 6
0
    def create_security_group(self, context, security_group, default_sg=False):
        """Create security group.

        If default_sg is true that means we are a default security group for
        a given tenant if it does not exist.
        """
        s = security_group['security_group']
        kwargs = {
            'context': context,
            'security_group': s,
            'is_default': default_sg,
        }
        self._registry_notify(resources.SECURITY_GROUP,
                              events.BEFORE_CREATE,
                              exc_cls=ext_sg.SecurityGroupConflict,
                              payload=events.DBEventPayload(
                                  context,
                                  metadata={'is_default': default_sg},
                                  request_body=security_group,
                                  desired_state=s))

        tenant_id = s['tenant_id']
        stateful = s.get('stateful', True)

        if not default_sg:
            self._ensure_default_security_group(context, tenant_id)
        else:
            existing_def_sg_id = self._get_default_sg_id(context, tenant_id)
            if existing_def_sg_id is not None:
                # default already exists, return it
                return self.get_security_group(context, existing_def_sg_id)

        with db_api.CONTEXT_WRITER.using(context):
            delta = len(ext_sg.sg_supported_ethertypes)
            delta = delta * 2 if default_sg else delta
            reservation = quota.QUOTAS.make_reservation(
                context, tenant_id, {'security_group_rule': delta}, self)

            sg = sg_obj.SecurityGroup(context,
                                      id=s.get('id')
                                      or uuidutils.generate_uuid(),
                                      description=s['description'],
                                      project_id=tenant_id,
                                      name=s['name'],
                                      is_default=default_sg,
                                      stateful=stateful)
            sg.create()

            for ethertype in ext_sg.sg_supported_ethertypes:
                if default_sg:
                    # Allow intercommunication
                    ingress_rule = sg_obj.SecurityGroupRule(
                        context,
                        id=uuidutils.generate_uuid(),
                        project_id=tenant_id,
                        security_group_id=sg.id,
                        direction='ingress',
                        ethertype=ethertype,
                        remote_group_id=sg.id)
                    ingress_rule.create()
                    sg.rules.append(ingress_rule)

                egress_rule = sg_obj.SecurityGroupRule(
                    context,
                    id=uuidutils.generate_uuid(),
                    project_id=tenant_id,
                    security_group_id=sg.id,
                    direction='egress',
                    ethertype=ethertype)
                egress_rule.create()
                sg.rules.append(egress_rule)
            sg.obj_reset_changes(['rules'])

            quota.QUOTAS.commit_reservation(context,
                                            reservation.reservation_id)

            # fetch sg from db to load the sg rules with sg model.
            sg = sg_obj.SecurityGroup.get_object(context, id=sg.id)
            secgroup_dict = self._make_security_group_dict(sg)
            kwargs['security_group'] = secgroup_dict
            self._registry_notify(resources.SECURITY_GROUP,
                                  events.PRECOMMIT_CREATE,
                                  exc_cls=ext_sg.SecurityGroupConflict,
                                  **kwargs)

        registry.notify(resources.SECURITY_GROUP, events.AFTER_CREATE, self,
                        **kwargs)
        return secgroup_dict
Exemplo n.º 7
0
    def create_security_group(self, context, security_group, default_sg=False):
        """Create security group.

        If default_sg is true that means we are a default security group for
        a given tenant if it does not exist.
        """
        s = security_group['security_group']
        kwargs = {
            'context': context,
            'security_group': s,
            'is_default': default_sg,
        }

        self._registry_notify(resources.SECURITY_GROUP,
                              events.BEFORE_CREATE,
                              exc_cls=ext_sg.SecurityGroupConflict,
                              **kwargs)

        tenant_id = s['tenant_id']

        if not default_sg:
            self._ensure_default_security_group(context, tenant_id)
        else:
            existing_def_sg_id = self._get_default_sg_id(context, tenant_id)
            if existing_def_sg_id is not None:
                # default already exists, return it
                return self.get_security_group(context, existing_def_sg_id)

        with db_api.context_manager.writer.using(context):
            sg = sg_obj.SecurityGroup(context,
                                      id=s.get('id')
                                      or uuidutils.generate_uuid(),
                                      description=s['description'],
                                      project_id=tenant_id,
                                      name=s['name'],
                                      is_default=default_sg)
            sg.create()

            for ethertype in ext_sg.sg_supported_ethertypes:
                if default_sg:
                    # Allow intercommunication
                    ingress_rule = sg_obj.SecurityGroupRule(
                        context,
                        id=uuidutils.generate_uuid(),
                        project_id=tenant_id,
                        security_group_id=sg.id,
                        direction='ingress',
                        ethertype=ethertype,
                        remote_group_id=sg.id)
                    ingress_rule.create()
                    sg.rules.append(ingress_rule)

                egress_rule = sg_obj.SecurityGroupRule(
                    context,
                    id=uuidutils.generate_uuid(),
                    project_id=tenant_id,
                    security_group_id=sg.id,
                    direction='egress',
                    ethertype=ethertype)
                egress_rule.create()
                sg.rules.append(egress_rule)
            sg.obj_reset_changes(['rules'])

            # fetch sg from db to load the sg rules with sg model.
            sg = sg_obj.SecurityGroup.get_object(context, id=sg.id)
            secgroup_dict = self._make_security_group_dict(sg)
            kwargs['security_group'] = secgroup_dict
            self._registry_notify(resources.SECURITY_GROUP,
                                  events.PRECOMMIT_CREATE,
                                  exc_cls=ext_sg.SecurityGroupConflict,
                                  **kwargs)

        registry.notify(resources.SECURITY_GROUP, events.AFTER_CREATE, self,
                        **kwargs)
        return secgroup_dict
Exemplo n.º 8
0
    def create_security_group(self, context, security_group, default_sg=False):
        """Create security group.

        If default_sg is true that means we are a default security group for
        a given tenant if it does not exist.
        """
        s = security_group['security_group']
        self._registry_publish(resources.SECURITY_GROUP, events.BEFORE_CREATE,
                               exc_cls=ext_sg.SecurityGroupConflict,
                               payload=events.DBEventPayload(
                                   context,
                                   metadata={'is_default': default_sg},
                                   request_body=security_group,
                                   desired_state=s))

        tenant_id = s['tenant_id']
        stateful = s.get('stateful', True)

        if not default_sg:
            self._ensure_default_security_group(context, tenant_id)
        else:
            existing_def_sg_id = self._get_default_sg_id(context, tenant_id)
            if existing_def_sg_id is not None:
                # default already exists, return it
                return self.get_security_group(context, existing_def_sg_id)

        with db_api.CONTEXT_WRITER.using(context):
            delta = len(ext_sg.sg_supported_ethertypes)
            delta = delta * 2 if default_sg else delta
            quota.QUOTAS.quota_limit_check(context, tenant_id,
                                           security_group_rule=delta)

            sg = sg_obj.SecurityGroup(
                context, id=s.get('id') or uuidutils.generate_uuid(),
                description=s['description'], project_id=tenant_id,
                name=s['name'], is_default=default_sg, stateful=stateful)
            sg.create()

            for ethertype in ext_sg.sg_supported_ethertypes:
                if default_sg:
                    # Allow intercommunication
                    ingress_rule = sg_obj.SecurityGroupRule(
                        context, id=uuidutils.generate_uuid(),
                        project_id=tenant_id, security_group_id=sg.id,
                        direction='ingress', ethertype=ethertype,
                        remote_group_id=sg.id)
                    ingress_rule.create()
                    sg.rules.append(ingress_rule)

                egress_rule = sg_obj.SecurityGroupRule(
                    context, id=uuidutils.generate_uuid(),
                    project_id=tenant_id, security_group_id=sg.id,
                    direction='egress', ethertype=ethertype)
                egress_rule.create()
                sg.rules.append(egress_rule)
            sg.obj_reset_changes(['rules'])

            # fetch sg from db to load the sg rules with sg model.
            # NOTE(slaweq): With new system/project scopes it may happen that
            # project admin will try to list security groups for different
            # project and during that call Neutron will ensure that default
            # security group is created. In such case elevated context needs to
            # be used here otherwise, SG will not be found and error 500 will
            # be returned through the API
            get_context = context.elevated() if default_sg else context
            sg = sg_obj.SecurityGroup.get_object(get_context, id=sg.id)
            secgroup_dict = self._make_security_group_dict(sg)
            self._registry_publish(resources.SECURITY_GROUP,
                                   events.PRECOMMIT_CREATE,
                                   exc_cls=ext_sg.SecurityGroupConflict,
                                   payload=events.DBEventPayload(
                                       context,
                                       resource_id=sg.id,
                                       metadata={'is_default': default_sg},
                                       states=(secgroup_dict,)))

        registry.publish(resources.SECURITY_GROUP, events.AFTER_CREATE,
                         self, payload=events.DBEventPayload(
                             context,
                             resource_id=secgroup_dict['id'],
                             metadata={'is_default': default_sg},
                             states=(secgroup_dict,)))

        return secgroup_dict