def _check_ip_matches_version(item, version): if isinstance(item, list): for i in item: SubnetMixin._check_ip_matches_version(i, version) return if netaddr.IPNetwork(item).version != version: ContrailResourceHandler._raise_contrail_exception( 'BadRequest', resource='subnet', msg='Invalid IP address version')
def _subnet_neutron_to_vnc(subnet_q): if not subnet_q.get('cidr'): ContrailResourceHandler._raise_contrail_exception( 'BadRequest', msg='cidr is empty', resource='subnet') cidr = netaddr.IPNetwork(subnet_q['cidr']) pfx = str(cidr.network) pfx_len = int(cidr.prefixlen) if pfx_len == 0 and cidr.version == 4: ContrailResourceHandler._raise_contrail_exception( 'BadRequest', resource='subnet', msg="Invalid prefix len") if cidr.version != 4 and cidr.version != 6: ContrailResourceHandler._raise_contrail_exception( 'BadRequest', resource='subnet', msg='Unknown IP family') elif cidr.version != int(subnet_q['ip_version']): msg = ("cidr '%s' does not match the ip_version '%s'" % (subnet_q['cidr'], subnet_q['ip_version'])) ContrailResourceHandler._raise_contrail_exception( 'InvalidInput', error_message=msg, resource='subnet') if 'gateway_ip' in subnet_q: default_gw = subnet_q['gateway_ip'] gw_ip_obj = netaddr.IPAddress(default_gw) if default_gw != '0.0.0.0': if gw_ip_obj not in cidr or gw_ip_obj.words[-1] == 255 or ( gw_ip_obj.words[-1] == 0): ContrailResourceHandler._raise_contrail_exception( 'BadRequest', resource='subnet', msg="Invalid Gateway ip address") else: # Assigned first+1 from cidr default_gw = str(netaddr.IPAddress(cidr.first + 1)) if cidr.version == 4 and 'ipv6_address_mode' in subnet_q: ContrailResourceHandler._raise_contrail_exception( 'BadRequest', resource='subnet', msg="Invalid address mode with version") if 'allocation_pools' in subnet_q: alloc_pools = subnet_q['allocation_pools'] alloc_cidrs = [] for pool in alloc_pools: try: ip_start = netaddr.IPAddress(pool['start']) ip_end = netaddr.IPAddress(pool['end']) except netaddr.core.AddrFormatError: ContrailResourceHandler._raise_contrail_exception( 'BadRequest', resource='subnet', msg="Invalid IP address in allocation pool") if ip_start >= ip_end: ContrailResourceHandler._raise_contrail_exception( 'BadRequest', resource='subnet', msg='Invalid address in allocation pool') if ip_start not in cidr or ip_end not in cidr: ContrailResourceHandler._raise_contrail_exception( 'BadRequest', resource='subnet', msg="Pool addresses not in subnet range") # Check if the pool overlaps with other pools for rng in alloc_cidrs: if rng['start'] <= ip_start and ip_end <= rng['end']: ContrailResourceHandler._raise_contrail_exception( 'BadRequest', resource='subnet', msg='Pool addresses invalid') elif (rng['start'] >= ip_start and (rng['start'] <= ip_end)) or ( rng['end'] >= ip_start and (rng['end'] <= ip_end)): ContrailResourceHandler._raise_contrail_exception( 'OverlappingAllocationPools', pool_2="%s-%s" % (ip_start, ip_end), pool_1="%s-%s" % (rng['start'], rng['end']), subnet_cidr=str(cidr)) alloc_cidrs.append({'start': ip_start, 'end': ip_end}) gw_ip_obj = netaddr.IPAddress(default_gw) for rng in alloc_cidrs: st = rng['start'] end = rng['end'] if st <= gw_ip_obj and end >= gw_ip_obj: ContrailResourceHandler._raise_contrail_exception( 'GatewayConflictWithAllocationPools', ip_address=default_gw, pool=str(cidr), msg='Gw ip is part of allocation pools') else: # Assigned by address manager alloc_pools = None dhcp_option_list = None if 'dns_nameservers' in subnet_q and subnet_q['dns_nameservers']: dhcp_options = [] dns_servers = " ".join(subnet_q['dns_nameservers']) if dns_servers: dhcp_options.append( vnc_api.DhcpOptionType(dhcp_option_name='6', dhcp_option_value=dns_servers)) if dhcp_options: dhcp_option_list = vnc_api.DhcpOptionsListType(dhcp_options) host_route_list = None if 'host_routes' in subnet_q and subnet_q['host_routes']: host_routes = [] for host_route in subnet_q['host_routes']: SubnetMixin._check_ip_matches_version( [host_route['destination'], host_route['nexthop']], cidr.version) host_routes.append( vnc_api.RouteType(prefix=host_route['destination'], next_hop=host_route['nexthop'])) if host_routes: host_route_list = vnc_api.RouteTableType(host_routes) if 'enable_dhcp' in subnet_q: dhcp_config = subnet_q['enable_dhcp'] else: dhcp_config = None sn_name = subnet_q.get('name') subnet_vnc = vnc_api.IpamSubnetType(subnet=vnc_api.SubnetType( pfx, pfx_len), default_gateway=default_gw, enable_dhcp=dhcp_config, dns_nameservers=None, allocation_pools=alloc_pools, addr_from_start=True, dhcp_option_list=dhcp_option_list, host_routes=host_route_list, subnet_name=sn_name, subnet_uuid=str(uuid.uuid4())) return subnet_vnc
def _subnet_neutron_to_vnc(subnet_q): if not subnet_q.get('cidr'): ContrailResourceHandler._raise_contrail_exception( 'BadRequest', msg='cidr is empty', resource='subnet') cidr = netaddr.IPNetwork(subnet_q['cidr']) pfx = str(cidr.network) pfx_len = int(cidr.prefixlen) if pfx_len == 0 and cidr.version == 4: ContrailResourceHandler._raise_contrail_exception( 'BadRequest', resource='subnet', msg="Invalid prefix len") if cidr.version != 4 and cidr.version != 6: ContrailResourceHandler._raise_contrail_exception( 'BadRequest', resource='subnet', msg='Unknown IP family') elif cidr.version != int(subnet_q['ip_version']): msg = ("cidr '%s' does not match the ip_version '%s'" % (subnet_q['cidr'], subnet_q['ip_version'])) ContrailResourceHandler._raise_contrail_exception( 'InvalidInput', error_message=msg, resource='subnet') if 'gateway_ip' in subnet_q: default_gw = subnet_q['gateway_ip'] gw_ip_obj = netaddr.IPAddress(default_gw) if default_gw != '0.0.0.0': if gw_ip_obj not in cidr or gw_ip_obj.words[-1] == 255 or ( gw_ip_obj.words[-1] == 0): ContrailResourceHandler._raise_contrail_exception( 'BadRequest', resource='subnet', msg="Invalid Gateway ip address") else: # Assigned first+1 from cidr default_gw = str(netaddr.IPAddress(cidr.first + 1)) if cidr.version == 4 and 'ipv6_address_mode' in subnet_q: ContrailResourceHandler._raise_contrail_exception( 'BadRequest', resource='subnet', msg="Invalid address mode with version") if 'allocation_pools' in subnet_q: alloc_pools = subnet_q['allocation_pools'] alloc_cidrs = [] for pool in alloc_pools: try: ip_start = netaddr.IPAddress(pool['start']) ip_end = netaddr.IPAddress(pool['end']) except netaddr.core.AddrFormatError: ContrailResourceHandler._raise_contrail_exception( 'BadRequest', resource='subnet', msg="Invalid IP address in allocation pool") if ip_start >= ip_end: ContrailResourceHandler._raise_contrail_exception( 'BadRequest', resource='subnet', msg='Invalid address in allocation pool') if ip_start not in cidr or ip_end not in cidr: ContrailResourceHandler._raise_contrail_exception( 'BadRequest', resource='subnet', msg="Pool addresses not in subnet range") # Check if the pool overlaps with other pools for rng in alloc_cidrs: if rng['start'] <= ip_start and ip_end <= rng['end']: ContrailResourceHandler._raise_contrail_exception( 'BadRequest', resource='subnet', msg='Pool addresses invalid') elif (rng['start'] >= ip_start and ( rng['start'] <= ip_end)) or ( rng['end'] >= ip_start and ( rng['end'] <= ip_end)): ContrailResourceHandler._raise_contrail_exception( 'OverlappingAllocationPools', pool_2="%s-%s" % (ip_start, ip_end), pool_1="%s-%s" % (rng['start'], rng['end']), subnet_cidr=str(cidr)) alloc_cidrs.append({'start': ip_start, 'end': ip_end}) gw_ip_obj = netaddr.IPAddress(default_gw) for rng in alloc_cidrs: st = rng['start'] end = rng['end'] if st <= gw_ip_obj and end >= gw_ip_obj: ContrailResourceHandler._raise_contrail_exception( 'GatewayConflictWithAllocationPools', ip_address=default_gw, pool=str(cidr), msg='Gw ip is part of allocation pools') else: # Assigned by address manager alloc_pools = None dhcp_option_list = None if 'dns_nameservers' in subnet_q and subnet_q['dns_nameservers']: dhcp_options = [] dns_servers = " ".join(subnet_q['dns_nameservers']) if dns_servers: dhcp_options.append(vnc_api.DhcpOptionType( dhcp_option_name='6', dhcp_option_value=dns_servers)) if dhcp_options: dhcp_option_list = vnc_api.DhcpOptionsListType(dhcp_options) host_route_list = None if 'host_routes' in subnet_q and subnet_q['host_routes']: host_routes = [] for host_route in subnet_q['host_routes']: SubnetMixin._check_ip_matches_version( [host_route['destination'], host_route['nexthop']], cidr.version) host_routes.append(vnc_api.RouteType( prefix=host_route['destination'], next_hop=host_route['nexthop'])) if host_routes: host_route_list = vnc_api.RouteTableType(host_routes) if 'enable_dhcp' in subnet_q: dhcp_config = subnet_q['enable_dhcp'] else: dhcp_config = None sn_name = subnet_q.get('name') subnet_vnc = vnc_api.IpamSubnetType( subnet=vnc_api.SubnetType(pfx, pfx_len), default_gateway=default_gw, enable_dhcp=dhcp_config, dns_nameservers=None, allocation_pools=alloc_pools, addr_from_start=True, dhcp_option_list=dhcp_option_list, host_routes=host_route_list, subnet_name=sn_name, subnet_uuid=str(uuid.uuid4())) return subnet_vnc