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 _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')
Exemple #3
0
    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