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))
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
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
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
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
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
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
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