Ejemplo n.º 1
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']
        if (cfg.CONF.SECURITYGROUP.proxy_mode and not context.is_admin):
            raise ext_sg.SecurityGroupProxyModeNotAdmin()
        if (cfg.CONF.SECURITYGROUP.proxy_mode and not s.get('external_id')):
            raise ext_sg.SecurityGroupProxyMode()
        if not cfg.CONF.SECURITYGROUP.proxy_mode and s.get('external_id'):
            raise ext_sg.SecurityGroupNotProxyMode()

        tenant_id = self._get_tenant_id_for_create(context, s)

        # if in proxy mode a default security group will be created by source
        if not default_sg and not cfg.CONF.SECURITYGROUP.proxy_mode:
            self._ensure_default_security_group(context, tenant_id,
                                                security_group)
        if s.get('external_id'):
            try:
                # Check if security group already exists
                sg = self.get_security_group(context, s.get('external_id'))
                if sg:
                    raise ext_sg.SecurityGroupAlreadyExists(
                        name=sg.get('name', ''),
                        external_id=s.get('external_id'))
            except ext_sg.SecurityGroupNotFound:
                pass

        with context.session.begin(subtransactions=True):
            security_group_db = SecurityGroup(id=s.get('id')
                                              or (utils.str_uuid()),
                                              description=s['description'],
                                              tenant_id=tenant_id,
                                              name=s['name'],
                                              external_id=s.get('external_id'))
            context.session.add(security_group_db)
            if s.get('name') == 'default':
                for ethertype in self.sg_supported_ethertypes:
                    # Allow all egress traffic
                    db = SecurityGroupRule(id=utils.str_uuid(),
                                           tenant_id=tenant_id,
                                           security_group=security_group_db,
                                           direction='egress',
                                           ethertype=ethertype)
                    context.session.add(db)
                    # Allow intercommunication
                    db = SecurityGroupRule(id=utils.str_uuid(),
                                           tenant_id=tenant_id,
                                           security_group=security_group_db,
                                           direction='ingress',
                                           source_group=security_group_db,
                                           ethertype=ethertype)
                    context.session.add(db)

        return self._make_security_group_dict(security_group_db)
Ejemplo n.º 2
0
    def _validate_security_group_rules(self, context, security_group_rule):
        """Check that rules being installed all belong to the same security
        group, source_group_id/security_group_id belong to the same tenant,
        and rules are valid.
        """

        if (cfg.CONF.SECURITYGROUP.proxy_mode and not context.is_admin):
            raise ext_sg.SecurityGroupProxyModeNotAdmin()

        new_rules = set()
        tenant_ids = set()
        for rules in security_group_rule['security_group_rules']:
            rule = rules.get('security_group_rule')
            new_rules.add(rule['security_group_id'])

            if (cfg.CONF.SECURITYGROUP.proxy_mode
                    and not rule.get('external_id')):
                raise ext_sg.SecurityGroupProxyMode()
            if (not cfg.CONF.SECURITYGROUP.proxy_mode
                    and rule.get('external_id')):
                raise ext_sg.SecurityGroupNotProxyMode()

            # Check that protocol/ethertype are valid
            protocol = rule.get('protocol')
            if protocol and protocol not in self.sg_supported_protocols:
                raise ext_sg.SecurityGroupInvalidProtocolType(value=protocol)
            ethertype = rule.get('ethertype')
            if ethertype and ethertype not in self.sg_supported_ethertypes:
                raise ext_sg.SecurityGroupInvalidEtherType(value=ethertype)

            # Check that port_range's are valid
            if (rule['port_range_min'] is None
                    and rule['port_range_max'] is None):
                pass
            elif (rule['port_range_min'] is not None
                  and rule['port_range_min'] <= rule['port_range_max']):
                if not rule['protocol']:
                    raise ext_sg.SecurityGroupProtocolRequiredWithPorts()
            else:
                raise ext_sg.SecurityGroupInvalidPortRange()

            if rule['source_ip_prefix'] and rule['source_group_id']:
                raise ext_sg.SecurityGroupSourceGroupAndIpPrefix()

            if rule['tenant_id'] not in tenant_ids:
                tenant_ids.add(rule['tenant_id'])
            source_group_id = rule.get('source_group_id')
            # Check that source_group_id exists for tenant
            if source_group_id:
                self.get_security_group(context,
                                        source_group_id,
                                        tenant_id=rule['tenant_id'])
        if len(new_rules) > 1:
            raise ext_sg.SecurityGroupNotSingleGroupRules()
        security_group_id = new_rules.pop()

        # Confirm single tenant and that the tenant has permission
        # to add rules to this security group.
        if len(tenant_ids) > 1:
            raise ext_sg.SecurityGroupRulesNotSingleTenant()
        for tenant_id in tenant_ids:
            self.get_security_group(context,
                                    security_group_id,
                                    tenant_id=tenant_id)
        return security_group_id