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