def create(self, req, body): context = _authorize_context(req) sg_rule = self._from_body(body, 'security_group_rule') group_id = sg_rule.get('group_id') source_group = {} try: parent_group_id = security_group_api.validate_id( sg_rule.get('parent_group_id')) security_group = security_group_api.get( context, None, parent_group_id, map_exception=True) if group_id is not None: group_id = security_group_api.validate_id(group_id) source_group = security_group_api.get( context, id=group_id) new_rule = self._rule_args_to_dict(context, to_port=sg_rule.get('to_port'), from_port=sg_rule.get('from_port'), ip_protocol=sg_rule.get('ip_protocol'), cidr=sg_rule.get('cidr'), group_id=group_id) except (exception.Invalid, exception.InvalidCidr) as exp: raise exc.HTTPBadRequest(explanation=exp.format_message()) except exception.SecurityGroupNotFound as exp: raise exc.HTTPNotFound(explanation=exp.format_message()) if new_rule is None: msg = _("Not enough parameters to build a valid rule.") raise exc.HTTPBadRequest(explanation=msg) new_rule['parent_group_id'] = security_group['id'] if 'cidr' in new_rule: net, prefixlen = netutils.get_net_and_prefixlen(new_rule['cidr']) if net not in ('0.0.0.0', '::') and prefixlen == '0': msg = _("Bad prefix for network in cidr %s") % new_rule['cidr'] raise exc.HTTPBadRequest(explanation=msg) group_rule_data = None try: if group_id: group_rule_data = {'name': source_group.get('name'), 'tenant_id': source_group.get('project_id')} security_group_rule = ( security_group_api.create_security_group_rule( context, security_group, new_rule)) except exception.Invalid as exp: raise exc.HTTPBadRequest(explanation=exp.format_message()) except exception.SecurityGroupNotFound as exp: raise exc.HTTPNotFound(explanation=exp.format_message()) except exception.SecurityGroupLimitExceeded as exp: raise exc.HTTPForbidden(explanation=exp.format_message()) formatted_rule = self._format_security_group_rule(context, security_group_rule, group_rule_data) return {"security_group_rule": formatted_rule}
def update(self, req, id, body): """Update a security group.""" context = req.environ['nova.context'] context.can(sg_policies.POLICY_NAME % 'update', target={'project_id': context.project_id}) try: id = security_group_api.validate_id(id) security_group = security_group_api.get(context, id) except exception.SecurityGroupNotFound as exp: raise exc.HTTPNotFound(explanation=exp.format_message()) except exception.Invalid as exp: raise exc.HTTPBadRequest(explanation=exp.format_message()) security_group_data = self._from_body(body, 'security_group') group_name = security_group_data.get('name', None) group_description = security_group_data.get('description', None) try: security_group_api.validate_property(group_name, 'name', None) security_group_api.validate_property(group_description, 'description', None) group_ref = security_group_api.update_security_group( context, security_group, group_name, group_description) except exception.SecurityGroupNotFound as exp: raise exc.HTTPNotFound(explanation=exp.format_message()) except exception.Invalid as exp: raise exc.HTTPBadRequest(explanation=exp.format_message()) return { 'security_group': self._format_security_group(context, group_ref) }
def update(self, req, id, body): """Update a security group.""" context = _authorize_context(req) try: id = security_group_api.validate_id(id) security_group = security_group_api.get( context, None, id, map_exception=True) except exception.SecurityGroupNotFound as exp: raise exc.HTTPNotFound(explanation=exp.format_message()) except exception.Invalid as exp: raise exc.HTTPBadRequest(explanation=exp.format_message()) security_group_data = self._from_body(body, 'security_group') group_name = security_group_data.get('name', None) group_description = security_group_data.get('description', None) try: security_group_api.validate_property(group_name, 'name', None) security_group_api.validate_property( group_description, 'description', None) group_ref = security_group_api.update_security_group( context, security_group, group_name, group_description) except exception.SecurityGroupNotFound as exp: raise exc.HTTPNotFound(explanation=exp.format_message()) except exception.Invalid as exp: raise exc.HTTPBadRequest(explanation=exp.format_message()) return {'security_group': self._format_security_group(context, group_ref)}
def _get_group_rule_data_by_rule_group_id(self, context, groups): group_rule_data_by_rule_group_id = {} # Pre-populate with the group information itself in case any of the # rule group IDs are the in-scope groups. for group in groups: group_rule_data_by_rule_group_id[group['id']] = { 'name': group.get('name'), 'tenant_id': group.get('project_id')} for group in groups: for rule in group['rules']: rule_group_id = rule['group_id'] if (rule_group_id and rule_group_id not in group_rule_data_by_rule_group_id): try: source_group = security_group_api.get( context, id=rule['group_id']) group_rule_data_by_rule_group_id[rule_group_id] = { 'name': source_group.get('name'), 'tenant_id': source_group.get('project_id')} except exception.SecurityGroupNotFound: LOG.debug("Security Group %s does not exist", rule_group_id) # Use a sentinel so we don't process this group again. group_rule_data_by_rule_group_id[rule_group_id] = ( SG_NOT_FOUND) return group_rule_data_by_rule_group_id
def delete(self, req, id): """Delete a security group.""" context = _authorize_context(req) try: id = security_group_api.validate_id(id) security_group = security_group_api.get(context, id) security_group_api.destroy(context, security_group) except exception.SecurityGroupNotFound as exp: raise exc.HTTPNotFound(explanation=exp.format_message()) except exception.Invalid as exp: raise exc.HTTPBadRequest(explanation=exp.format_message())
def delete(self, req, id): """Delete a security group.""" context = req.environ['nova.context'] context.can(sg_policies.POLICY_NAME % 'delete', target={'project_id': context.project_id}) try: id = security_group_api.validate_id(id) security_group = security_group_api.get(context, id) security_group_api.destroy(context, security_group) except exception.SecurityGroupNotFound as exp: raise exc.HTTPNotFound(explanation=exp.format_message()) except exception.Invalid as exp: raise exc.HTTPBadRequest(explanation=exp.format_message())
def show(self, req, id): """Return data about the given security group.""" context = _authorize_context(req) try: id = security_group_api.validate_id(id) security_group = security_group_api.get( context, None, id, map_exception=True) except exception.SecurityGroupNotFound as exp: raise exc.HTTPNotFound(explanation=exp.format_message()) except exception.Invalid as exp: raise exc.HTTPBadRequest(explanation=exp.format_message()) return {'security_group': self._format_security_group(context, security_group)}
def delete(self, req, id): context = _authorize_context(req) try: id = security_group_api.validate_id(id) rule = security_group_api.get_rule(context, id) group_id = rule['parent_group_id'] security_group = security_group_api.get(context, group_id) security_group_api.remove_rules(context, security_group, [rule['id']]) except exception.SecurityGroupNotFound as exp: raise exc.HTTPNotFound(explanation=exp.format_message()) except exception.NoUniqueMatch as exp: raise exc.HTTPConflict(explanation=exp.format_message()) except exception.Invalid as exp: raise exc.HTTPBadRequest(explanation=exp.format_message())
def delete(self, req, id): context = req.environ['nova.context'] context.can(sg_policies.POLICY_NAME % 'rule:delete', target={'project_id': context.project_id}) try: id = security_group_api.validate_id(id) rule = security_group_api.get_rule(context, id) group_id = rule['parent_group_id'] security_group = security_group_api.get(context, group_id) security_group_api.remove_rules(context, security_group, [rule['id']]) except exception.SecurityGroupNotFound as exp: raise exc.HTTPNotFound(explanation=exp.format_message()) except exception.NoUniqueMatch as exp: raise exc.HTTPConflict(explanation=exp.format_message()) except exception.Invalid as exp: raise exc.HTTPBadRequest(explanation=exp.format_message())
def show(self, req, id): """Return data about the given security group.""" context = req.environ['nova.context'] context.can(sg_policies.POLICY_NAME % 'show', target={'project_id': context.project_id}) try: id = security_group_api.validate_id(id) security_group = security_group_api.get(context, id) except exception.SecurityGroupNotFound as exp: raise exc.HTTPNotFound(explanation=exp.format_message()) except exception.Invalid as exp: raise exc.HTTPBadRequest(explanation=exp.format_message()) return { 'security_group': self._format_security_group(context, security_group) }
def _format_security_group_rule(self, context, rule, group_rule_data=None): """Return a security group rule in desired API response format. If group_rule_data is passed in that is used rather than querying for it. """ sg_rule = {} sg_rule['id'] = rule['id'] sg_rule['parent_group_id'] = rule['parent_group_id'] sg_rule['ip_protocol'] = rule['protocol'] sg_rule['from_port'] = rule['from_port'] sg_rule['to_port'] = rule['to_port'] sg_rule['group'] = {} sg_rule['ip_range'] = {} if group_rule_data: sg_rule['group'] = group_rule_data elif rule['group_id']: try: source_group = security_group_api.get(context, id=rule['group_id']) except exception.SecurityGroupNotFound: # NOTE(arosen): There is a possible race condition that can # occur here if two api calls occur concurrently: one that # lists the security groups and another one that deletes a # security group rule that has a group_id before the # group_id is fetched. To handle this if # SecurityGroupNotFound is raised we return None instead # of the rule and the caller should ignore the rule. LOG.debug("Security Group ID %s does not exist", rule['group_id']) return sg_rule['group'] = { 'name': source_group.get('name'), 'tenant_id': source_group.get('project_id') } else: sg_rule['ip_range'] = {'cidr': rule['cidr']} return sg_rule
def test_get_with_name_duplicated(self): sg_name = 'web_server' expected_sg_id = '85cc3048-abc3-43cc-89b3-377341426ac5' expected_sg = { 'security_group': { 'name': sg_name, 'id': expected_sg_id, 'tenant_id': self.context.project_id, 'description': 'server', 'rules': [] } } self.mocked_client.show_security_group.return_value = expected_sg with mock.patch.object(neutronv20, 'find_resourceid_by_name_or_id', return_value=expected_sg_id): observed_sg = sg_api.get(self.context, name=sg_name) expected_sg['security_group']['project_id'] = self.context.project_id del expected_sg['security_group']['tenant_id'] self.assertEqual(expected_sg['security_group'], observed_sg) self.mocked_client.show_security_group.assert_called_once_with( expected_sg_id)