mirror of
https://github.com/retspen/webvirtcloud
synced 2024-12-25 15:45:23 +00:00
commit
9977c650db
20 changed files with 15412 additions and 15050 deletions
|
@ -1,4 +1,4 @@
|
||||||
FROM phusion/baseimage:focal-1.0.0
|
FROM phusion/baseimage:focal-1.1.0
|
||||||
|
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
EXPOSE 6080
|
EXPOSE 6080
|
||||||
|
|
|
@ -32,7 +32,7 @@ WebVirtCloud is a virtualization web interface for admins and users. It can dele
|
||||||
|
|
||||||
## Quick Install with Installer (Beta)
|
## Quick Install with Installer (Beta)
|
||||||
|
|
||||||
Install an OS and run specified commands. Installer supported OSes: Ubuntu 18.04, Debian 10, Centos/OEL/RHEL 8.
|
Install an OS and run specified commands. Installer supported OSes: Ubuntu 18.04/20.04, Debian 10/11, Centos/OEL/RHEL 8.
|
||||||
It can be installed on a virtual machine, physical host or on a KVM host.
|
It can be installed on a virtual machine, physical host or on a KVM host.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Django==3.2.10
|
Django==3.2.11
|
||||||
django_bootstrap5==21.2
|
django_bootstrap5==21.2
|
||||||
django-icons==21.1
|
django-icons==21.1
|
||||||
django-login-required-middleware==0.7
|
django-login-required-middleware==0.7
|
||||||
|
|
|
@ -4,4 +4,4 @@ django-debug-toolbar==3.2.4
|
||||||
pycodestyle==2.8.0
|
pycodestyle==2.8.0
|
||||||
pyflakes==2.4.0
|
pyflakes==2.4.0
|
||||||
pylint==2.12.2
|
pylint==2.12.2
|
||||||
yapf==0.31.0
|
yapf==0.32.0
|
||||||
|
|
|
@ -342,15 +342,17 @@ def migrate(request, pk):
|
||||||
compress = request.POST.get("compress", False)
|
compress = request.POST.get("compress", False)
|
||||||
postcopy = request.POST.get("postcopy", False)
|
postcopy = request.POST.get("postcopy", False)
|
||||||
|
|
||||||
new_compute = Compute.objects.get(id=compute_id)
|
current_host = instance.compute.hostname
|
||||||
|
target_host = Compute.objects.get(id=compute_id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
utils.migrate_instance(new_compute, instance, request.user, live, unsafe, xml_del, offline)
|
utils.migrate_instance(target_host, instance, request.user, live, unsafe, xml_del, offline)
|
||||||
except libvirtError as err:
|
except libvirtError as err:
|
||||||
messages.error(request, err)
|
messages.error(request, err)
|
||||||
|
|
||||||
msg = _("Instance is migrated to %(hostname)s") % {"hostname": new_compute.hostname}
|
migration_method = "live" if live is True else "offline"
|
||||||
addlogmsg(request.user.username, instance.compute.hostname, instance.name, msg)
|
msg = _("Instance is migrated(%(method)s) to %(hostname)s") % {"hostname": target_host.hostname, "method": migration_method}
|
||||||
|
addlogmsg(request.user.username, current_host, instance.name, msg)
|
||||||
|
|
||||||
return redirect(request.META.get("HTTP_REFERER"))
|
return redirect(request.META.get("HTTP_REFERER"))
|
||||||
|
|
||||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
|
@ -6,128 +6,131 @@ Further Information might be available at:
|
||||||
https://github.com/haypo/python-ipy
|
https://github.com/haypo/python-ipy
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__version__ = "1.00"
|
__version__ = '1.01'
|
||||||
|
|
||||||
import bisect
|
import bisect
|
||||||
import collections
|
|
||||||
import sys
|
|
||||||
import types
|
import types
|
||||||
|
try:
|
||||||
|
import collections.abc as collections_abc
|
||||||
|
except ImportError:
|
||||||
|
import collections as collections_abc
|
||||||
|
|
||||||
# Definition of the Ranges for IPv4 IPs
|
# Definition of the Ranges for IPv4 IPs
|
||||||
# this should include www.iana.org/assignments/ipv4-address-space
|
# this should include www.iana.org/assignments/ipv4-address-space
|
||||||
# and www.iana.org/assignments/multicast-addresses
|
# and www.iana.org/assignments/multicast-addresses
|
||||||
IPv4ranges = {
|
IPv4ranges = {
|
||||||
"0": "PUBLIC", # fall back
|
'0': 'PUBLIC', # fall back
|
||||||
"00000000": "PRIVATE", # 0/8
|
'00000000': 'PRIVATE', # 0/8
|
||||||
"00001010": "PRIVATE", # 10/8
|
'00001010': 'PRIVATE', # 10/8
|
||||||
"0110010001": "CARRIER_GRADE_NAT", # 100.64/10
|
'0110010001': 'CARRIER_GRADE_NAT', #100.64/10
|
||||||
"01111111": "LOOPBACK", # 127.0/8
|
'01111111': 'LOOPBACK', # 127.0/8
|
||||||
"1": "PUBLIC", # fall back
|
'1': 'PUBLIC', # fall back
|
||||||
"1010100111111110": "PRIVATE", # 169.254/16
|
'1010100111111110': 'PRIVATE', # 169.254/16
|
||||||
"101011000001": "PRIVATE", # 172.16/12
|
'101011000001': 'PRIVATE', # 172.16/12
|
||||||
"1100000010101000": "PRIVATE", # 192.168/16
|
'1100000010101000': 'PRIVATE', # 192.168/16
|
||||||
"111": "RESERVED", # 224/3
|
'111': 'RESERVED', # 224/3
|
||||||
}
|
}
|
||||||
|
|
||||||
# Definition of the Ranges for IPv6 IPs
|
# Definition of the Ranges for IPv6 IPs
|
||||||
# http://www.iana.org/assignments/ipv6-address-space/
|
# http://www.iana.org/assignments/ipv6-address-space/
|
||||||
# http://www.iana.org/assignments/ipv6-unicast-address-assignments/
|
# http://www.iana.org/assignments/ipv6-unicast-address-assignments/
|
||||||
# http://www.iana.org/assignments/ipv6-multicast-addresses/
|
# http://www.iana.org/assignments/ipv6-multicast-addresses/
|
||||||
IPv6ranges = {
|
IPv6ranges = {
|
||||||
"00000000": "RESERVED", # ::/8
|
'00000000' : 'RESERVED', # ::/8
|
||||||
"0" * 96: "RESERVED", # ::/96 Formerly IPV4COMP [RFC4291]
|
'0' * 96 : 'RESERVED', # ::/96 Formerly IPV4COMP [RFC4291]
|
||||||
"0" * 128: "UNSPECIFIED", # ::/128
|
'0' * 128 : 'UNSPECIFIED', # ::/128
|
||||||
"0" * 127 + "1": "LOOPBACK", # ::1/128
|
'0' * 127 + '1' : 'LOOPBACK', # ::1/128
|
||||||
"0" * 80 + "1" * 16: "IPV4MAP", # ::ffff:0:0/96
|
'0' * 80 + '1' * 16 : 'IPV4MAP', # ::ffff:0:0/96
|
||||||
"00000000011001001111111110011011" + "0" * 64: "WKP46TRANS", # 0064:ff9b::/96 Well-Known-Prefix [RFC6052]
|
'00000000011001001111111110011011' + '0' * 64 : 'WKP46TRANS', # 0064:ff9b::/96 Well-Known-Prefix [RFC6052]
|
||||||
"00000001": "UNASSIGNED", # 0100::/8
|
'00000001' : 'UNASSIGNED', # 0100::/8
|
||||||
"0000001": "RESERVED", # 0200::/7 Formerly NSAP [RFC4048]
|
'0000001' : 'RESERVED', # 0200::/7 Formerly NSAP [RFC4048]
|
||||||
"0000010": "RESERVED", # 0400::/7 Formerly IPX [RFC3513]
|
'0000010' : 'RESERVED', # 0400::/7 Formerly IPX [RFC3513]
|
||||||
"0000011": "RESERVED", # 0600::/7
|
'0000011' : 'RESERVED', # 0600::/7
|
||||||
"00001": "RESERVED", # 0800::/5
|
'00001' : 'RESERVED', # 0800::/5
|
||||||
"0001": "RESERVED", # 1000::/4
|
'0001' : 'RESERVED', # 1000::/4
|
||||||
"001": "GLOBAL-UNICAST", # 2000::/3 [RFC4291]
|
'001' : 'GLOBAL-UNICAST', # 2000::/3 [RFC4291]
|
||||||
"00100000000000010000000": "SPECIALPURPOSE", # 2001::/23 [RFC4773]
|
'00100000000000010000000' : 'SPECIALPURPOSE', # 2001::/23 [RFC4773]
|
||||||
"00100000000000010000000000000000": "TEREDO", # 2001::/32 [RFC4380]
|
'00100000000000010000000000000000' : 'TEREDO', # 2001::/32 [RFC4380]
|
||||||
"00100000000000010000000000000010" + "0" * 16: "BMWG", # 2001:0002::/48 Benchmarking [RFC5180]
|
'00100000000000010000000000000010' + '0' * 16 : 'BMWG', # 2001:0002::/48 Benchmarking [RFC5180]
|
||||||
"0010000000000001000000000001": "ORCHID", # 2001:0010::/28 (Temp until 2014-03-21) [RFC4843]
|
'0010000000000001000000000001' : 'ORCHID', # 2001:0010::/28 (Temp until 2014-03-21) [RFC4843]
|
||||||
"00100000000000010000001": "ALLOCATED APNIC", # 2001:0200::/23
|
'00100000000000010000001' : 'ALLOCATED APNIC', # 2001:0200::/23
|
||||||
"00100000000000010000010": "ALLOCATED ARIN", # 2001:0400::/23
|
'00100000000000010000010' : 'ALLOCATED ARIN', # 2001:0400::/23
|
||||||
"00100000000000010000011": "ALLOCATED RIPE NCC", # 2001:0600::/23
|
'00100000000000010000011' : 'ALLOCATED RIPE NCC', # 2001:0600::/23
|
||||||
"00100000000000010000100": "ALLOCATED RIPE NCC", # 2001:0800::/23
|
'00100000000000010000100' : 'ALLOCATED RIPE NCC', # 2001:0800::/23
|
||||||
"00100000000000010000101": "ALLOCATED RIPE NCC", # 2001:0a00::/23
|
'00100000000000010000101' : 'ALLOCATED RIPE NCC', # 2001:0a00::/23
|
||||||
"00100000000000010000110": "ALLOCATED APNIC", # 2001:0c00::/23
|
'00100000000000010000110' : 'ALLOCATED APNIC', # 2001:0c00::/23
|
||||||
"00100000000000010000110110111000": "DOCUMENTATION", # 2001:0db8::/32 [RFC3849]
|
'00100000000000010000110110111000' : 'DOCUMENTATION', # 2001:0db8::/32 [RFC3849]
|
||||||
"00100000000000010000111": "ALLOCATED APNIC", # 2001:0e00::/23
|
'00100000000000010000111' : 'ALLOCATED APNIC', # 2001:0e00::/23
|
||||||
"00100000000000010001001": "ALLOCATED LACNIC", # 2001:1200::/23
|
'00100000000000010001001' : 'ALLOCATED LACNIC', # 2001:1200::/23
|
||||||
"00100000000000010001010": "ALLOCATED RIPE NCC", # 2001:1400::/23
|
'00100000000000010001010' : 'ALLOCATED RIPE NCC', # 2001:1400::/23
|
||||||
"00100000000000010001011": "ALLOCATED RIPE NCC", # 2001:1600::/23
|
'00100000000000010001011' : 'ALLOCATED RIPE NCC', # 2001:1600::/23
|
||||||
"00100000000000010001100": "ALLOCATED ARIN", # 2001:1800::/23
|
'00100000000000010001100' : 'ALLOCATED ARIN', # 2001:1800::/23
|
||||||
"00100000000000010001101": "ALLOCATED RIPE NCC", # 2001:1a00::/23
|
'00100000000000010001101' : 'ALLOCATED RIPE NCC', # 2001:1a00::/23
|
||||||
"0010000000000001000111": "ALLOCATED RIPE NCC", # 2001:1c00::/22
|
'0010000000000001000111' : 'ALLOCATED RIPE NCC', # 2001:1c00::/22
|
||||||
"00100000000000010010": "ALLOCATED RIPE NCC", # 2001:2000::/20
|
'00100000000000010010' : 'ALLOCATED RIPE NCC', # 2001:2000::/20
|
||||||
"001000000000000100110": "ALLOCATED RIPE NCC", # 2001:3000::/21
|
'001000000000000100110' : 'ALLOCATED RIPE NCC', # 2001:3000::/21
|
||||||
"0010000000000001001110": "ALLOCATED RIPE NCC", # 2001:3800::/22
|
'0010000000000001001110' : 'ALLOCATED RIPE NCC', # 2001:3800::/22
|
||||||
"0010000000000001001111": "RESERVED", # 2001:3c00::/22 Possible future allocation to RIPE NCC
|
'0010000000000001001111' : 'RESERVED', # 2001:3c00::/22 Possible future allocation to RIPE NCC
|
||||||
"00100000000000010100000": "ALLOCATED RIPE NCC", # 2001:4000::/23
|
'00100000000000010100000' : 'ALLOCATED RIPE NCC', # 2001:4000::/23
|
||||||
"00100000000000010100001": "ALLOCATED AFRINIC", # 2001:4200::/23
|
'00100000000000010100001' : 'ALLOCATED AFRINIC', # 2001:4200::/23
|
||||||
"00100000000000010100010": "ALLOCATED APNIC", # 2001:4400::/23
|
'00100000000000010100010' : 'ALLOCATED APNIC', # 2001:4400::/23
|
||||||
"00100000000000010100011": "ALLOCATED RIPE NCC", # 2001:4600::/23
|
'00100000000000010100011' : 'ALLOCATED RIPE NCC', # 2001:4600::/23
|
||||||
"00100000000000010100100": "ALLOCATED ARIN", # 2001:4800::/23
|
'00100000000000010100100' : 'ALLOCATED ARIN', # 2001:4800::/23
|
||||||
"00100000000000010100101": "ALLOCATED RIPE NCC", # 2001:4a00::/23
|
'00100000000000010100101' : 'ALLOCATED RIPE NCC', # 2001:4a00::/23
|
||||||
"00100000000000010100110": "ALLOCATED RIPE NCC", # 2001:4c00::/23
|
'00100000000000010100110' : 'ALLOCATED RIPE NCC', # 2001:4c00::/23
|
||||||
"00100000000000010101": "ALLOCATED RIPE NCC", # 2001:5000::/20
|
'00100000000000010101' : 'ALLOCATED RIPE NCC', # 2001:5000::/20
|
||||||
"0010000000000001100": "ALLOCATED APNIC", # 2001:8000::/19
|
'0010000000000001100' : 'ALLOCATED APNIC', # 2001:8000::/19
|
||||||
"00100000000000011010": "ALLOCATED APNIC", # 2001:a000::/20
|
'00100000000000011010' : 'ALLOCATED APNIC', # 2001:a000::/20
|
||||||
"00100000000000011011": "ALLOCATED APNIC", # 2001:b000::/20
|
'00100000000000011011' : 'ALLOCATED APNIC', # 2001:b000::/20
|
||||||
"0010000000000010": "6TO4", # 2002::/16 "6to4" [RFC3056]
|
'0010000000000010' : '6TO4', # 2002::/16 "6to4" [RFC3056]
|
||||||
"001000000000001100": "ALLOCATED RIPE NCC", # 2003::/18
|
'001000000000001100' : 'ALLOCATED RIPE NCC', # 2003::/18
|
||||||
"001001000000": "ALLOCATED APNIC", # 2400::/12
|
'001001000000' : 'ALLOCATED APNIC', # 2400::/12
|
||||||
"001001100000": "ALLOCATED ARIN", # 2600::/12
|
'001001100000' : 'ALLOCATED ARIN', # 2600::/12
|
||||||
"00100110000100000000000": "ALLOCATED ARIN", # 2610::/23
|
'00100110000100000000000' : 'ALLOCATED ARIN', # 2610::/23
|
||||||
"00100110001000000000000": "ALLOCATED ARIN", # 2620::/23
|
'00100110001000000000000' : 'ALLOCATED ARIN', # 2620::/23
|
||||||
"001010000000": "ALLOCATED LACNIC", # 2800::/12
|
'001010000000' : 'ALLOCATED LACNIC', # 2800::/12
|
||||||
"001010100000": "ALLOCATED RIPE NCC", # 2a00::/12
|
'001010100000' : 'ALLOCATED RIPE NCC', # 2a00::/12
|
||||||
"001011000000": "ALLOCATED AFRINIC", # 2c00::/12
|
'001011000000' : 'ALLOCATED AFRINIC', # 2c00::/12
|
||||||
"00101101": "RESERVED", # 2d00::/8
|
'00101101' : 'RESERVED', # 2d00::/8
|
||||||
"0010111": "RESERVED", # 2e00::/7
|
'0010111' : 'RESERVED', # 2e00::/7
|
||||||
"0011": "RESERVED", # 3000::/4
|
'0011' : 'RESERVED', # 3000::/4
|
||||||
"010": "RESERVED", # 4000::/3
|
'010' : 'RESERVED', # 4000::/3
|
||||||
"011": "RESERVED", # 6000::/3
|
'011' : 'RESERVED', # 6000::/3
|
||||||
"100": "RESERVED", # 8000::/3
|
'100' : 'RESERVED', # 8000::/3
|
||||||
"101": "RESERVED", # a000::/3
|
'101' : 'RESERVED', # a000::/3
|
||||||
"110": "RESERVED", # c000::/3
|
'110' : 'RESERVED', # c000::/3
|
||||||
"1110": "RESERVED", # e000::/4
|
'1110' : 'RESERVED', # e000::/4
|
||||||
"11110": "RESERVED", # f000::/5
|
'11110' : 'RESERVED', # f000::/5
|
||||||
"111110": "RESERVED", # f800::/6
|
'111110' : 'RESERVED', # f800::/6
|
||||||
"1111110": "ULA", # fc00::/7 [RFC4193]
|
'1111110' : 'ULA', # fc00::/7 [RFC4193]
|
||||||
"111111100": "RESERVED", # fe00::/9
|
'111111100' : 'RESERVED', # fe00::/9
|
||||||
"1111111010": "LINKLOCAL", # fe80::/10
|
'1111111010' : 'LINKLOCAL', # fe80::/10
|
||||||
"1111111011": "RESERVED", # fec0::/10 Formerly SITELOCAL [RFC4291]
|
'1111111011' : 'RESERVED', # fec0::/10 Formerly SITELOCAL [RFC4291]
|
||||||
"11111111": "MULTICAST", # ff00::/8
|
'11111111' : 'MULTICAST', # ff00::/8
|
||||||
"1111111100000001": "NODE-LOCAL MULTICAST", # ff01::/16
|
'1111111100000001' : 'NODE-LOCAL MULTICAST', # ff01::/16
|
||||||
"1111111100000010": "LINK-LOCAL MULTICAST", # ff02::/16
|
'1111111100000010' : 'LINK-LOCAL MULTICAST', # ff02::/16
|
||||||
"1111111100000100": "ADMIN-LOCAL MULTICAST", # ff04::/16
|
'1111111100000100' : 'ADMIN-LOCAL MULTICAST', # ff04::/16
|
||||||
"1111111100000101": "SITE-LOCAL MULTICAST", # ff05::/16
|
'1111111100000101' : 'SITE-LOCAL MULTICAST', # ff05::/16
|
||||||
"1111111100001000": "ORG-LOCAL MULTICAST", # ff08::/16
|
'1111111100001000' : 'ORG-LOCAL MULTICAST', # ff08::/16
|
||||||
"1111111100001110": "GLOBAL MULTICAST", # ff0e::/16
|
'1111111100001110' : 'GLOBAL MULTICAST', # ff0e::/16
|
||||||
"1111111100001111": "RESERVED MULTICAST", # ff0f::/16
|
'1111111100001111' : 'RESERVED MULTICAST', # ff0f::/16
|
||||||
"111111110011": "PREFIX-BASED MULTICAST", # ff30::/12 [RFC3306]
|
'111111110011' : 'PREFIX-BASED MULTICAST', # ff30::/12 [RFC3306]
|
||||||
"111111110111": "RP-EMBEDDED MULTICAST", # ff70::/12 [RFC3956]
|
'111111110111' : 'RP-EMBEDDED MULTICAST', # ff70::/12 [RFC3956]
|
||||||
}
|
}
|
||||||
|
|
||||||
MAX_IPV4_ADDRESS = 0xFFFFFFFF
|
MAX_IPV4_ADDRESS = 0xffffffff
|
||||||
MAX_IPV6_ADDRESS = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
MAX_IPV6_ADDRESS = 0xffffffffffffffffffffffffffffffff
|
||||||
IPV6_TEST_MAP = 0xFFFFFFFFFFFFFFFFFFFFFFFF00000000
|
IPV6_TEST_MAP = 0xffffffffffffffffffffffff00000000
|
||||||
IPV6_MAP_MASK = 0x00000000000000000000FFFF00000000
|
IPV6_MAP_MASK = 0x00000000000000000000ffff00000000
|
||||||
|
|
||||||
if sys.version_info >= (3,):
|
try:
|
||||||
|
INT_TYPES = (int, long)
|
||||||
|
STR_TYPES = (str, unicode)
|
||||||
|
xrange
|
||||||
|
except NameError:
|
||||||
INT_TYPES = (int,)
|
INT_TYPES = (int,)
|
||||||
STR_TYPES = (str,)
|
STR_TYPES = (str,)
|
||||||
xrange = range
|
xrange = range
|
||||||
else:
|
|
||||||
INT_TYPES = (int, long)
|
|
||||||
STR_TYPES = (str, unicode)
|
|
||||||
|
|
||||||
|
|
||||||
class IPint(object):
|
class IPint(object):
|
||||||
|
@ -202,7 +205,7 @@ class IPint(object):
|
||||||
elif isinstance(data, STR_TYPES):
|
elif isinstance(data, STR_TYPES):
|
||||||
# TODO: refactor me!
|
# TODO: refactor me!
|
||||||
# splitting of a string into IP and prefixlen et. al.
|
# splitting of a string into IP and prefixlen et. al.
|
||||||
x = data.split("-")
|
x = data.split('-')
|
||||||
if len(x) == 2:
|
if len(x) == 2:
|
||||||
# a.b.c.0-a.b.c.255 specification ?
|
# a.b.c.0-a.b.c.255 specification ?
|
||||||
(ip, last) = x
|
(ip, last) = x
|
||||||
|
@ -219,10 +222,10 @@ class IPint(object):
|
||||||
# make sure the broadcast is the same as the last ip
|
# make sure the broadcast is the same as the last ip
|
||||||
# otherwise it will return /16 for something like:
|
# otherwise it will return /16 for something like:
|
||||||
# 192.168.0.0-192.168.191.255
|
# 192.168.0.0-192.168.191.255
|
||||||
if IP("%s/%s" % (ip, 32 - netbits)).broadcast().int() != last:
|
if IP('%s/%s' % (ip, 32-netbits)).broadcast().int() != last:
|
||||||
raise ValueError("the range %s is not on a network boundary." % data)
|
raise ValueError("the range %s is not on a network boundary." % data)
|
||||||
elif len(x) == 1:
|
elif len(x) == 1:
|
||||||
x = data.split("/")
|
x = data.split('/')
|
||||||
# if no prefix is given use defaults
|
# if no prefix is given use defaults
|
||||||
if len(x) == 1:
|
if len(x) == 1:
|
||||||
ip = x[0]
|
ip = x[0]
|
||||||
|
@ -231,7 +234,7 @@ class IPint(object):
|
||||||
raise ValueError("only one '/' allowed in IP Address")
|
raise ValueError("only one '/' allowed in IP Address")
|
||||||
else:
|
else:
|
||||||
(ip, prefixlen) = x
|
(ip, prefixlen) = x
|
||||||
if prefixlen.find(".") != -1:
|
if prefixlen.find('.') != -1:
|
||||||
# check if the user might have used a netmask like
|
# check if the user might have used a netmask like
|
||||||
# a.b.c.d/255.255.255.0
|
# a.b.c.d/255.255.255.0
|
||||||
(netmask, vers) = parseAddress(prefixlen)
|
(netmask, vers) = parseAddress(prefixlen)
|
||||||
|
@ -255,7 +258,8 @@ class IPint(object):
|
||||||
if make_net:
|
if make_net:
|
||||||
self.ip = self.ip & _prefixlenToNetmask(self._prefixlen, self._ipversion)
|
self.ip = self.ip & _prefixlenToNetmask(self._prefixlen, self._ipversion)
|
||||||
|
|
||||||
if not _checkNetaddrWorksWithPrefixlen(self.ip, self._prefixlen, self._ipversion):
|
if not _checkNetaddrWorksWithPrefixlen(self.ip,
|
||||||
|
self._prefixlen, self._ipversion):
|
||||||
raise ValueError("%s has invalid prefix length (%s)" % (repr(self), self._prefixlen))
|
raise ValueError("%s has invalid prefix length (%s)" % (repr(self), self._prefixlen))
|
||||||
else:
|
else:
|
||||||
raise TypeError("Unsupported data type: %s" % type(data))
|
raise TypeError("Unsupported data type: %s" % type(data))
|
||||||
|
@ -313,12 +317,13 @@ class IPint(object):
|
||||||
want == 3 -lastip 1.2.3.0-1.2.3.255
|
want == 3 -lastip 1.2.3.0-1.2.3.255
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if (self._ipversion == 4 and self._prefixlen == 32) or (self._ipversion == 6 and self._prefixlen == 128):
|
if (self._ipversion == 4 and self._prefixlen == 32) or \
|
||||||
|
(self._ipversion == 6 and self._prefixlen == 128):
|
||||||
if self.NoPrefixForSingleIp:
|
if self.NoPrefixForSingleIp:
|
||||||
want = 0
|
want = 0
|
||||||
if want is None:
|
if want == None:
|
||||||
want = self.WantPrefixLen
|
want = self.WantPrefixLen
|
||||||
if want is None:
|
if want == None:
|
||||||
want = 1
|
want = 1
|
||||||
if want:
|
if want:
|
||||||
if want == 2:
|
if want == 2:
|
||||||
|
@ -333,7 +338,7 @@ class IPint(object):
|
||||||
# default
|
# default
|
||||||
return "/%d" % (self._prefixlen)
|
return "/%d" % (self._prefixlen)
|
||||||
else:
|
else:
|
||||||
return ""
|
return ''
|
||||||
|
|
||||||
# We have different flavours to convert to:
|
# We have different flavours to convert to:
|
||||||
# strFullsize 127.0.0.1 2001:0658:022a:cafe:0200:c0ff:fe8d:08fa
|
# strFullsize 127.0.0.1 2001:0658:022a:cafe:0200:c0ff:fe8d:08fa
|
||||||
|
@ -342,7 +347,7 @@ class IPint(object):
|
||||||
# strHex 0x7F000001 0x20010658022ACAFE0200C0FFFE8D08FA
|
# strHex 0x7F000001 0x20010658022ACAFE0200C0FFFE8D08FA
|
||||||
# strDec 2130706433 42540616829182469433547974687817795834
|
# strDec 2130706433 42540616829182469433547974687817795834
|
||||||
|
|
||||||
def strBin(self, wantprefixlen=None):
|
def strBin(self, wantprefixlen = None):
|
||||||
"""Return a string representation as a binary value.
|
"""Return a string representation as a binary value.
|
||||||
|
|
||||||
>>> print(IP('127.0.0.1').strBin())
|
>>> print(IP('127.0.0.1').strBin())
|
||||||
|
@ -352,12 +357,12 @@ class IPint(object):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
bits = _ipVersionToLen(self._ipversion)
|
bits = _ipVersionToLen(self._ipversion)
|
||||||
if self.WantPrefixLen is None and wantprefixlen is None:
|
if self.WantPrefixLen == None and wantprefixlen == None:
|
||||||
wantprefixlen = 0
|
wantprefixlen = 0
|
||||||
ret = _intToBin(self.ip)
|
ret = _intToBin(self.ip)
|
||||||
return "0" * (bits - len(ret)) + ret + self._printPrefix(wantprefixlen)
|
return '0' * (bits - len(ret)) + ret + self._printPrefix(wantprefixlen)
|
||||||
|
|
||||||
def strCompressed(self, wantprefixlen=None):
|
def strCompressed(self, wantprefixlen = None):
|
||||||
"""Return a string representation in compressed format using '::' Notation.
|
"""Return a string representation in compressed format using '::' Notation.
|
||||||
|
|
||||||
>>> IP('127.0.0.1').strCompressed()
|
>>> IP('127.0.0.1').strCompressed()
|
||||||
|
@ -368,18 +373,18 @@ class IPint(object):
|
||||||
'ffff:ffff:ffff:ffff:ffff:f:f:fffc/127'
|
'ffff:ffff:ffff:ffff:ffff:f:f:fffc/127'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.WantPrefixLen is None and wantprefixlen is None:
|
if self.WantPrefixLen == None and wantprefixlen == None:
|
||||||
wantprefixlen = 1
|
wantprefixlen = 1
|
||||||
|
|
||||||
if self._ipversion == 4:
|
if self._ipversion == 4:
|
||||||
return self.strFullsize(wantprefixlen)
|
return self.strFullsize(wantprefixlen)
|
||||||
else:
|
else:
|
||||||
if self.ip >> 32 == 0xFFFF:
|
if self.ip >> 32 == 0xffff:
|
||||||
ipv4 = intToIp(self.ip & MAX_IPV4_ADDRESS, 4)
|
ipv4 = intToIp(self.ip & MAX_IPV4_ADDRESS, 4)
|
||||||
text = "::ffff:" + ipv4 + self._printPrefix(wantprefixlen)
|
text = "::ffff:" + ipv4 + self._printPrefix(wantprefixlen)
|
||||||
return text
|
return text
|
||||||
# find the longest sequence of '0'
|
# find the longest sequence of '0'
|
||||||
hextets = [int(x, 16) for x in self.strFullsize(0).split(":")]
|
hextets = [int(x, 16) for x in self.strFullsize(0).split(':')]
|
||||||
# every element of followingzeros will contain the number of zeros
|
# every element of followingzeros will contain the number of zeros
|
||||||
# following the corresponding element of hextets
|
# following the corresponding element of hextets
|
||||||
followingzeros = [0] * 8
|
followingzeros = [0] * 8
|
||||||
|
@ -390,19 +395,19 @@ class IPint(object):
|
||||||
if max(followingzeros) > 1:
|
if max(followingzeros) > 1:
|
||||||
# genererate string with the longest number of zeros cut out
|
# genererate string with the longest number of zeros cut out
|
||||||
# now we need hextets as strings
|
# now we need hextets as strings
|
||||||
hextets = [x for x in self.strNormal(0).split(":")]
|
hextets = [x for x in self.strNormal(0).split(':')]
|
||||||
while compressionpos < len(hextets) and hextets[compressionpos] == "0":
|
while compressionpos < len(hextets) and hextets[compressionpos] == '0':
|
||||||
del hextets[compressionpos]
|
del(hextets[compressionpos])
|
||||||
hextets.insert(compressionpos, "")
|
hextets.insert(compressionpos, '')
|
||||||
if compressionpos + 1 >= len(hextets):
|
if compressionpos + 1 >= len(hextets):
|
||||||
hextets.append("")
|
hextets.append('')
|
||||||
if compressionpos == 0:
|
if compressionpos == 0:
|
||||||
hextets = [""] + hextets
|
hextets = [''] + hextets
|
||||||
return ":".join(hextets) + self._printPrefix(wantprefixlen)
|
return ':'.join(hextets) + self._printPrefix(wantprefixlen)
|
||||||
else:
|
else:
|
||||||
return self.strNormal(0) + self._printPrefix(wantprefixlen)
|
return self.strNormal(0) + self._printPrefix(wantprefixlen)
|
||||||
|
|
||||||
def strNormal(self, wantprefixlen=None):
|
def strNormal(self, wantprefixlen = None):
|
||||||
"""Return a string representation in the usual format.
|
"""Return a string representation in the usual format.
|
||||||
|
|
||||||
>>> print(IP('127.0.0.1').strNormal())
|
>>> print(IP('127.0.0.1').strNormal())
|
||||||
|
@ -411,19 +416,21 @@ class IPint(object):
|
||||||
2001:658:22a:cafe:200:0:0:1
|
2001:658:22a:cafe:200:0:0:1
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.WantPrefixLen is None and wantprefixlen is None:
|
if self.WantPrefixLen == None and wantprefixlen == None:
|
||||||
wantprefixlen = 1
|
wantprefixlen = 1
|
||||||
|
|
||||||
if self._ipversion == 4:
|
if self._ipversion == 4:
|
||||||
ret = self.strFullsize(0)
|
ret = self.strFullsize(0)
|
||||||
elif self._ipversion == 6:
|
elif self._ipversion == 6:
|
||||||
ret = ":".join(["%x" % x for x in [int(x, 16) for x in self.strFullsize(0).split(":")]])
|
ret = ':'.join(["%x" % x for x in [int(x, 16) for x in self.strFullsize(0).split(':')]])
|
||||||
else:
|
else:
|
||||||
raise ValueError("only IPv4 and IPv6 supported")
|
raise ValueError("only IPv4 and IPv6 supported")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return ret + self._printPrefix(wantprefixlen)
|
return ret + self._printPrefix(wantprefixlen)
|
||||||
|
|
||||||
def strFullsize(self, wantprefixlen=None):
|
def strFullsize(self, wantprefixlen = None):
|
||||||
"""Return a string representation in the non-mangled format.
|
"""Return a string representation in the non-mangled format.
|
||||||
|
|
||||||
>>> print(IP('127.0.0.1').strFullsize())
|
>>> print(IP('127.0.0.1').strFullsize())
|
||||||
|
@ -432,12 +439,12 @@ class IPint(object):
|
||||||
2001:0658:022a:cafe:0200:0000:0000:0001
|
2001:0658:022a:cafe:0200:0000:0000:0001
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.WantPrefixLen is None and wantprefixlen is None:
|
if self.WantPrefixLen == None and wantprefixlen == None:
|
||||||
wantprefixlen = 1
|
wantprefixlen = 1
|
||||||
|
|
||||||
return intToIp(self.ip, self._ipversion) + self._printPrefix(wantprefixlen)
|
return intToIp(self.ip, self._ipversion) + self._printPrefix(wantprefixlen)
|
||||||
|
|
||||||
def strHex(self, wantprefixlen=None):
|
def strHex(self, wantprefixlen = None):
|
||||||
"""Return a string representation in hex format in lower case.
|
"""Return a string representation in hex format in lower case.
|
||||||
|
|
||||||
>>> print(IP('127.0.0.1').strHex())
|
>>> print(IP('127.0.0.1').strHex())
|
||||||
|
@ -446,13 +453,13 @@ class IPint(object):
|
||||||
0x20010658022acafe0200000000000001
|
0x20010658022acafe0200000000000001
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.WantPrefixLen is None and wantprefixlen is None:
|
if self.WantPrefixLen == None and wantprefixlen == None:
|
||||||
wantprefixlen = 0
|
wantprefixlen = 0
|
||||||
|
|
||||||
x = "0x%x" % self.ip
|
x = '0x%x' % self.ip
|
||||||
return x + self._printPrefix(wantprefixlen)
|
return x + self._printPrefix(wantprefixlen)
|
||||||
|
|
||||||
def strDec(self, wantprefixlen=None):
|
def strDec(self, wantprefixlen = None):
|
||||||
"""Return a string representation in decimal format.
|
"""Return a string representation in decimal format.
|
||||||
|
|
||||||
>>> print(IP('127.0.0.1').strDec())
|
>>> print(IP('127.0.0.1').strDec())
|
||||||
|
@ -461,10 +468,10 @@ class IPint(object):
|
||||||
42540616829182469433547762482097946625
|
42540616829182469433547762482097946625
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.WantPrefixLen is None and wantprefixlen is None:
|
if self.WantPrefixLen == None and wantprefixlen == None:
|
||||||
wantprefixlen = 0
|
wantprefixlen = 0
|
||||||
|
|
||||||
x = "%d" % self.ip
|
x = '%d' % self.ip
|
||||||
return x + self._printPrefix(wantprefixlen)
|
return x + self._printPrefix(wantprefixlen)
|
||||||
|
|
||||||
def iptype(self):
|
def iptype(self):
|
||||||
|
@ -499,6 +506,7 @@ class IPint(object):
|
||||||
return iprange[bits[:i]]
|
return iprange[bits[:i]]
|
||||||
return "unknown"
|
return "unknown"
|
||||||
|
|
||||||
|
|
||||||
def netmask(self):
|
def netmask(self):
|
||||||
"""Return netmask as an integer.
|
"""Return netmask as an integer.
|
||||||
|
|
||||||
|
@ -512,6 +520,7 @@ class IPint(object):
|
||||||
|
|
||||||
return ((2 ** self._prefixlen) - 1) << locallen
|
return ((2 ** self._prefixlen) - 1) << locallen
|
||||||
|
|
||||||
|
|
||||||
def strNetmask(self):
|
def strNetmask(self):
|
||||||
"""Return netmask as an string. Mostly useful for IPv6.
|
"""Return netmask as an string. Mostly useful for IPv6.
|
||||||
|
|
||||||
|
@ -543,6 +552,7 @@ class IPint(object):
|
||||||
locallen = bits - self._prefixlen
|
locallen = bits - self._prefixlen
|
||||||
return 2 ** locallen
|
return 2 ** locallen
|
||||||
|
|
||||||
|
|
||||||
def __nonzero__(self):
|
def __nonzero__(self):
|
||||||
"""All IPy objects should evaluate to true in boolean context.
|
"""All IPy objects should evaluate to true in boolean context.
|
||||||
Ordinarily they do, but if handling a default route expressed as
|
Ordinarily they do, but if handling a default route expressed as
|
||||||
|
@ -579,8 +589,10 @@ class IPint(object):
|
||||||
raise ValueError("Only adjacent networks can be added together.")
|
raise ValueError("Only adjacent networks can be added together.")
|
||||||
ret = IP(self.int(), ipversion=self._ipversion)
|
ret = IP(self.int(), ipversion=self._ipversion)
|
||||||
ret._prefixlen = self.prefixlen() - 1
|
ret._prefixlen = self.prefixlen() - 1
|
||||||
if not _checkNetaddrWorksWithPrefixlen(ret.ip, ret._prefixlen, ret._ipversion):
|
if not _checkNetaddrWorksWithPrefixlen(ret.ip, ret._prefixlen,
|
||||||
raise ValueError("The resulting %s has invalid prefix length (%s)" % (repr(ret), ret._prefixlen))
|
ret._ipversion):
|
||||||
|
raise ValueError("The resulting %s has invalid prefix length (%s)"
|
||||||
|
% (repr(ret), ret._prefixlen))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def __sub__(self, other):
|
def __sub__(self, other):
|
||||||
|
@ -619,6 +631,8 @@ class IPint(object):
|
||||||
|
|
||||||
return self.ip + int(key)
|
return self.ip + int(key)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def __contains__(self, item):
|
def __contains__(self, item):
|
||||||
"""Called to implement membership test operators.
|
"""Called to implement membership test operators.
|
||||||
|
|
||||||
|
@ -645,6 +659,7 @@ class IPint(object):
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def overlaps(self, item):
|
def overlaps(self, item):
|
||||||
"""Check if two IP address ranges overlap.
|
"""Check if two IP address ranges overlap.
|
||||||
|
|
||||||
|
@ -670,6 +685,7 @@ class IPint(object):
|
||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""Dispatch to the prefered String Representation.
|
"""Dispatch to the prefered String Representation.
|
||||||
|
|
||||||
|
@ -677,6 +693,7 @@ class IPint(object):
|
||||||
|
|
||||||
return self.strCompressed()
|
return self.strCompressed()
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
"""Print a representation of the Object.
|
"""Print a representation of the Object.
|
||||||
|
|
||||||
|
@ -688,7 +705,8 @@ class IPint(object):
|
||||||
IP('10.0.0.0/24')
|
IP('10.0.0.0/24')
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return "IPint('%s')" % (self.strCompressed(1))
|
return("IPint('%s')" % (self.strCompressed(1)))
|
||||||
|
|
||||||
|
|
||||||
def __cmp__(self, other):
|
def __cmp__(self, other):
|
||||||
"""Called by comparison operations.
|
"""Called by comparison operations.
|
||||||
|
@ -773,7 +791,7 @@ class IPint(object):
|
||||||
thehash = int(-1)
|
thehash = int(-1)
|
||||||
ip = self.ip
|
ip = self.ip
|
||||||
while ip > 0:
|
while ip > 0:
|
||||||
thehash = thehash ^ (ip & 0x7FFFFFFF)
|
thehash = thehash ^ (ip & 0x7fffffff)
|
||||||
ip = ip >> 32
|
ip = ip >> 32
|
||||||
thehash = thehash ^ self._prefixlen
|
thehash = thehash ^ self._prefixlen
|
||||||
return int(thehash)
|
return int(thehash)
|
||||||
|
@ -807,17 +825,17 @@ class IP(IPint):
|
||||||
|
|
||||||
>>> IP('10.0.0.0/8').netmask()
|
>>> IP('10.0.0.0/8').netmask()
|
||||||
IP('255.0.0.0')
|
IP('255.0.0.0')
|
||||||
"""
|
"""
|
||||||
return IP(IPint.netmask(self), ipversion=self._ipversion)
|
return IP(IPint.netmask(self), ipversion=self._ipversion)
|
||||||
|
|
||||||
def _getIPv4Map(self):
|
def _getIPv4Map(self):
|
||||||
if self._ipversion != 6:
|
if self._ipversion != 6:
|
||||||
return None
|
return None
|
||||||
if (self.ip >> 32) != 0xFFFF:
|
if (self.ip >> 32) != 0xffff:
|
||||||
return None
|
return None
|
||||||
ipv4 = self.ip & MAX_IPV4_ADDRESS
|
ipv4 = self.ip & MAX_IPV4_ADDRESS
|
||||||
if self._prefixlen != 128:
|
if self._prefixlen != 128:
|
||||||
ipv4 = "%s/%s" % (ipv4, 32 - (128 - self._prefixlen))
|
ipv4 = '%s/%s' % (ipv4, 32-(128-self._prefixlen))
|
||||||
return IP(ipv4, ipversion=4)
|
return IP(ipv4, ipversion=4)
|
||||||
|
|
||||||
def reverseNames(self):
|
def reverseNames(self):
|
||||||
|
@ -846,17 +864,17 @@ class IP(IPint):
|
||||||
if self._ipversion == 4:
|
if self._ipversion == 4:
|
||||||
ret = []
|
ret = []
|
||||||
# TODO: Refactor. Add support for IPint objects
|
# TODO: Refactor. Add support for IPint objects
|
||||||
if self.len() < 2 ** 8:
|
if self.len() < 2**8:
|
||||||
for x in self:
|
for x in self:
|
||||||
ret.append(x.reverseName())
|
ret.append(x.reverseName())
|
||||||
elif self.len() < 2 ** 16:
|
elif self.len() < 2**16:
|
||||||
for i in xrange(0, self.len(), 2 ** 8):
|
for i in xrange(0, self.len(), 2**8):
|
||||||
ret.append(self[i].reverseName()[2:])
|
ret.append(self[i].reverseName()[2:])
|
||||||
elif self.len() < 2 ** 24:
|
elif self.len() < 2**24:
|
||||||
for i in xrange(0, self.len(), 2 ** 16):
|
for i in xrange(0, self.len(), 2**16):
|
||||||
ret.append(self[i].reverseName()[4:])
|
ret.append(self[i].reverseName()[4:])
|
||||||
else:
|
else:
|
||||||
for i in xrange(0, self.len(), 2 ** 24):
|
for i in xrange(0, self.len(), 2**24):
|
||||||
ret.append(self[i].reverseName()[6:])
|
ret.append(self[i].reverseName()[6:])
|
||||||
return ret
|
return ret
|
||||||
elif self._ipversion == 6:
|
elif self._ipversion == 6:
|
||||||
|
@ -868,7 +886,7 @@ class IP(IPint):
|
||||||
raise NotImplementedError("can't create IPv6 reverse names at sub nibble level")
|
raise NotImplementedError("can't create IPv6 reverse names at sub nibble level")
|
||||||
s = list(s)
|
s = list(s)
|
||||||
s.reverse()
|
s.reverse()
|
||||||
s = ".".join(s)
|
s = '.'.join(s)
|
||||||
first_nibble_index = int(32 - (self._prefixlen // 4)) * 2
|
first_nibble_index = int(32 - (self._prefixlen // 4)) * 2
|
||||||
return ["%s.ip6.arpa." % s[first_nibble_index:]]
|
return ["%s.ip6.arpa." % s[first_nibble_index:]]
|
||||||
else:
|
else:
|
||||||
|
@ -893,34 +911,31 @@ class IP(IPint):
|
||||||
|
|
||||||
if self._ipversion == 4:
|
if self._ipversion == 4:
|
||||||
s = self.strFullsize(0)
|
s = self.strFullsize(0)
|
||||||
s = s.split(".")
|
s = s.split('.')
|
||||||
s.reverse()
|
s.reverse()
|
||||||
first_byte_index = int(4 - (self._prefixlen // 8))
|
first_byte_index = int(4 - (self._prefixlen // 8))
|
||||||
if self._prefixlen % 8 != 0:
|
if self._prefixlen % 8 != 0:
|
||||||
nibblepart = "%s-%s" % (
|
nibblepart = "%s-%s" % (s[3-(self._prefixlen // 8)], intToIp(self.ip + self.len() - 1, 4).split('.')[-1])
|
||||||
s[3 - (self._prefixlen // 8)],
|
nibblepart += '.'
|
||||||
intToIp(self.ip + self.len() - 1, 4).split(".")[-1],
|
|
||||||
)
|
|
||||||
nibblepart += "."
|
|
||||||
else:
|
else:
|
||||||
nibblepart = ""
|
nibblepart = ""
|
||||||
|
|
||||||
s = ".".join(s[first_byte_index:])
|
s = '.'.join(s[first_byte_index:])
|
||||||
return "%s%s.in-addr.arpa." % (nibblepart, s)
|
return "%s%s.in-addr.arpa." % (nibblepart, s)
|
||||||
|
|
||||||
elif self._ipversion == 6:
|
elif self._ipversion == 6:
|
||||||
ipv4 = self._getIPv4Map()
|
ipv4 = self._getIPv4Map()
|
||||||
if ipv4 is not None:
|
if ipv4 is not None:
|
||||||
return ipv4.reverseName()
|
return ipv4.reverseName()
|
||||||
s = "%032x" % self.ip
|
s = '%032x' % self.ip
|
||||||
if self._prefixlen % 4 != 0:
|
if self._prefixlen % 4 != 0:
|
||||||
nibblepart = "%s-%x" % (s[self._prefixlen :], self.ip + self.len() - 1)
|
nibblepart = "%s-%x" % (s[self._prefixlen:], self.ip + self.len() - 1)
|
||||||
nibblepart += "."
|
nibblepart += '.'
|
||||||
else:
|
else:
|
||||||
nibblepart = ""
|
nibblepart = ""
|
||||||
s = list(s)
|
s = list(s)
|
||||||
s.reverse()
|
s.reverse()
|
||||||
s = ".".join(s)
|
s = '.'.join(s)
|
||||||
first_nibble_index = int(32 - (self._prefixlen // 4)) * 2
|
first_nibble_index = int(32 - (self._prefixlen // 4)) * 2
|
||||||
return "%s%s.ip6.arpa." % (nibblepart, s[first_nibble_index:])
|
return "%s%s.ip6.arpa." % (nibblepart, s[first_nibble_index:])
|
||||||
else:
|
else:
|
||||||
|
@ -935,9 +950,9 @@ class IP(IPint):
|
||||||
>>> print(IP('127.0.0.1').make_net('255.0.0.0'))
|
>>> print(IP('127.0.0.1').make_net('255.0.0.0'))
|
||||||
127.0.0.0/8
|
127.0.0.0/8
|
||||||
"""
|
"""
|
||||||
if "/" in str(netmask):
|
if '/' in str(netmask):
|
||||||
raise ValueError("invalid netmask (%s)" % netmask)
|
raise ValueError("invalid netmask (%s)" % netmask)
|
||||||
return IP("%s/%s" % (self, netmask), make_net=True)
|
return IP('%s/%s' % (self, netmask), make_net=True)
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
"""Called to implement evaluation of self[key].
|
"""Called to implement evaluation of self[key].
|
||||||
|
@ -966,7 +981,7 @@ class IP(IPint):
|
||||||
IP('10.0.0.0/8')
|
IP('10.0.0.0/8')
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return "IP('%s')" % (self.strCompressed(1))
|
return("IP('%s')" % (self.strCompressed(1)))
|
||||||
|
|
||||||
def get_mac(self):
|
def get_mac(self):
|
||||||
"""
|
"""
|
||||||
|
@ -978,15 +993,15 @@ class IP(IPint):
|
||||||
"""
|
"""
|
||||||
if self._ipversion != 6:
|
if self._ipversion != 6:
|
||||||
return None
|
return None
|
||||||
if (self.ip & 0x20000FFFF000000) != 0x20000FFFE000000:
|
if (self.ip & 0x20000ffff000000) != 0x20000fffe000000:
|
||||||
return None
|
return None
|
||||||
return "%02x:%02x:%02x:%02x:%02x:%02x" % (
|
return '%02x:%02x:%02x:%02x:%02x:%02x' % (
|
||||||
(((self.ip >> 56) & 0xFF) & 0xFD),
|
(((self.ip >> 56) & 0xff) & 0xfd),
|
||||||
(self.ip >> 48) & 0xFF,
|
(self.ip >> 48) & 0xff,
|
||||||
(self.ip >> 40) & 0xFF,
|
(self.ip >> 40) & 0xff,
|
||||||
(self.ip >> 16) & 0xFF,
|
(self.ip >> 16) & 0xff,
|
||||||
(self.ip >> 8) & 0xFF,
|
(self.ip >> 8) & 0xff,
|
||||||
self.ip & 0xFF,
|
self.ip & 0xff,
|
||||||
)
|
)
|
||||||
|
|
||||||
def v46map(self):
|
def v46map(self):
|
||||||
|
@ -1001,23 +1016,25 @@ class IP(IPint):
|
||||||
IP('192.168.1.1')
|
IP('192.168.1.1')
|
||||||
"""
|
"""
|
||||||
if self._ipversion == 4:
|
if self._ipversion == 4:
|
||||||
return IP(str(IPV6_MAP_MASK + self.ip) + "/%s" % (self._prefixlen + 96))
|
return IP(str(IPV6_MAP_MASK + self.ip) +
|
||||||
|
"/%s" % (self._prefixlen + 96))
|
||||||
else:
|
else:
|
||||||
if self.ip & IPV6_TEST_MAP == IPV6_MAP_MASK:
|
if self.ip & IPV6_TEST_MAP == IPV6_MAP_MASK:
|
||||||
return IP(str(self.ip - IPV6_MAP_MASK) + "/%s" % (self._prefixlen - 96))
|
return IP(str(self.ip - IPV6_MAP_MASK) +
|
||||||
raise ValueError("%s cannot be converted to an IPv4 address." % repr(self))
|
"/%s" % (self._prefixlen - 96))
|
||||||
|
raise ValueError("%s cannot be converted to an IPv4 address."
|
||||||
|
% repr(self))
|
||||||
|
|
||||||
|
class IPSet(collections_abc.MutableSet):
|
||||||
class IPSet(collections.MutableSet):
|
|
||||||
def __init__(self, iterable=[]):
|
def __init__(self, iterable=[]):
|
||||||
# Make sure it's iterable, otherwise wrap
|
# Make sure it's iterable, otherwise wrap
|
||||||
if not isinstance(iterable, collections.Iterable):
|
if not isinstance(iterable, collections_abc.Iterable):
|
||||||
raise TypeError("'%s' object is not iterable" % type(iterable).__name__)
|
raise TypeError("'%s' object is not iterable" % type(iterable).__name__)
|
||||||
|
|
||||||
# Make sure we only accept IP objects
|
# Make sure we only accept IP objects
|
||||||
for prefix in iterable:
|
for prefix in iterable:
|
||||||
if not isinstance(prefix, IP):
|
if not isinstance(prefix, IP):
|
||||||
raise ValueError("Only IP objects can be added to an IPSet")
|
raise ValueError('Only IP objects can be added to an IPSet')
|
||||||
|
|
||||||
# Store and optimize
|
# Store and optimize
|
||||||
self.prefixes = iterable[:]
|
self.prefixes = iterable[:]
|
||||||
|
@ -1026,7 +1043,7 @@ class IPSet(collections.MutableSet):
|
||||||
def __contains__(self, ip):
|
def __contains__(self, ip):
|
||||||
valid_masks = self.prefixtable.keys()
|
valid_masks = self.prefixtable.keys()
|
||||||
if isinstance(ip, IP):
|
if isinstance(ip, IP):
|
||||||
# Don't dig through more-specific ranges
|
#Don't dig through more-specific ranges
|
||||||
ip_mask = ip._prefixlen
|
ip_mask = ip._prefixlen
|
||||||
valid_masks = [x for x in valid_masks if x <= ip_mask]
|
valid_masks = [x for x in valid_masks if x <= ip_mask]
|
||||||
for mask in sorted(valid_masks):
|
for mask in sorted(valid_masks):
|
||||||
|
@ -1078,20 +1095,20 @@ class IPSet(collections.MutableSet):
|
||||||
return IPSet(result)
|
return IPSet(result)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "%s([" % self.__class__.__name__ + ", ".join(map(repr, self.prefixes)) + "])"
|
return '%s([' % self.__class__.__name__ + ', '.join(map(repr, self.prefixes)) + '])'
|
||||||
|
|
||||||
def len(self):
|
def len(self):
|
||||||
return sum(prefix.len() for prefix in self.prefixes)
|
return sum(prefix.len() for prefix in self.prefixes)
|
||||||
|
|
||||||
def add(self, value):
|
def add(self, value):
|
||||||
# Make sure it's iterable, otherwise wrap
|
# Make sure it's iterable, otherwise wrap
|
||||||
if not isinstance(value, collections.Iterable):
|
if not isinstance(value, collections_abc.Iterable):
|
||||||
value = [value]
|
value = [value]
|
||||||
|
|
||||||
# Check type
|
# Check type
|
||||||
for prefix in value:
|
for prefix in value:
|
||||||
if not isinstance(prefix, IP):
|
if not isinstance(prefix, IP):
|
||||||
raise ValueError("Only IP objects can be added to an IPSet")
|
raise ValueError('Only IP objects can be added to an IPSet')
|
||||||
|
|
||||||
# Append and optimize
|
# Append and optimize
|
||||||
self.prefixes.extend(value)
|
self.prefixes.extend(value)
|
||||||
|
@ -1099,7 +1116,7 @@ class IPSet(collections.MutableSet):
|
||||||
|
|
||||||
def discard(self, value):
|
def discard(self, value):
|
||||||
# Make sure it's iterable, otherwise wrap
|
# Make sure it's iterable, otherwise wrap
|
||||||
if not isinstance(value, collections.Iterable):
|
if not isinstance(value, collections_abc.Iterable):
|
||||||
value = [value]
|
value = [value]
|
||||||
|
|
||||||
# This is much faster than iterating over the addresses
|
# This is much faster than iterating over the addresses
|
||||||
|
@ -1109,7 +1126,7 @@ class IPSet(collections.MutableSet):
|
||||||
# Remove
|
# Remove
|
||||||
for del_prefix in value:
|
for del_prefix in value:
|
||||||
if not isinstance(del_prefix, IP):
|
if not isinstance(del_prefix, IP):
|
||||||
raise ValueError("Only IP objects can be removed from an IPSet")
|
raise ValueError('Only IP objects can be removed from an IPSet')
|
||||||
|
|
||||||
# First check if this prefix contains anything in our list
|
# First check if this prefix contains anything in our list
|
||||||
found = False
|
found = False
|
||||||
|
@ -1129,7 +1146,7 @@ class IPSet(collections.MutableSet):
|
||||||
found = False
|
found = False
|
||||||
for i in range(len(self.prefixes)):
|
for i in range(len(self.prefixes)):
|
||||||
if del_prefix in self.prefixes[i]:
|
if del_prefix in self.prefixes[i]:
|
||||||
self.prefixes[i : i + 1] = self.prefixes[i] - del_prefix
|
self.prefixes[i:i+1] = self.prefixes[i] - del_prefix
|
||||||
break
|
break
|
||||||
|
|
||||||
self.optimize()
|
self.optimize()
|
||||||
|
@ -1160,7 +1177,7 @@ class IPSet(collections.MutableSet):
|
||||||
while i < addrlen:
|
while i < addrlen:
|
||||||
# Everything that might be inside this prefix follows
|
# Everything that might be inside this prefix follows
|
||||||
# directly behind it
|
# directly behind it
|
||||||
j = i + 1
|
j = i+1
|
||||||
while j < addrlen and self.prefixes[j] in self.prefixes[i]:
|
while j < addrlen and self.prefixes[j] in self.prefixes[i]:
|
||||||
# Mark for deletion by overwriting with None
|
# Mark for deletion by overwriting with None
|
||||||
self.prefixes[j] = None
|
self.prefixes[j] = None
|
||||||
|
@ -1184,7 +1201,7 @@ class IPSet(collections.MutableSet):
|
||||||
# prefix length and differ only on the last bit of the prefix
|
# prefix length and differ only on the last bit of the prefix
|
||||||
addrlen = len(self.prefixes)
|
addrlen = len(self.prefixes)
|
||||||
i = 0
|
i = 0
|
||||||
while i < addrlen - 1:
|
while i < addrlen-1:
|
||||||
j = i + 1
|
j = i + 1
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -1207,7 +1224,6 @@ class IPSet(collections.MutableSet):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
self.prefixtable[address._prefixlen] = [address]
|
self.prefixtable[address._prefixlen] = [address]
|
||||||
|
|
||||||
|
|
||||||
def _parseAddressIPv6(ipstr):
|
def _parseAddressIPv6(ipstr):
|
||||||
"""
|
"""
|
||||||
Internal function used by parseAddress() to parse IPv6 address with ':'.
|
Internal function used by parseAddress() to parse IPv6 address with ':'.
|
||||||
|
@ -1274,16 +1290,16 @@ def _parseAddressIPv6(ipstr):
|
||||||
fill_pos = len(items)
|
fill_pos = len(items)
|
||||||
index += 2
|
index += 2
|
||||||
continue
|
continue
|
||||||
pos = text.find(":")
|
pos = text.find(':')
|
||||||
if pos == 0:
|
if pos == 0:
|
||||||
# Invalid IPv6, eg. '1::2:'
|
# Invalid IPv6, eg. '1::2:'
|
||||||
raise ValueError("%r: Invalid IPv6 address" % ipstr)
|
raise ValueError("%r: Invalid IPv6 address" % ipstr)
|
||||||
if pos != -1:
|
if pos != -1:
|
||||||
items.append(text[:pos])
|
items.append(text[:pos])
|
||||||
if text[pos : pos + 2] == "::":
|
if text[pos:pos+2] == "::":
|
||||||
index += pos
|
index += pos
|
||||||
else:
|
else:
|
||||||
index += pos + 1
|
index += pos+1
|
||||||
|
|
||||||
if index == len(ipstr):
|
if index == len(ipstr):
|
||||||
# Invalid IPv6, eg. '1::2:'
|
# Invalid IPv6, eg. '1::2:'
|
||||||
|
@ -1292,13 +1308,13 @@ def _parseAddressIPv6(ipstr):
|
||||||
items.append(text)
|
items.append(text)
|
||||||
break
|
break
|
||||||
|
|
||||||
if items and "." in items[-1]:
|
if items and '.' in items[-1]:
|
||||||
# IPv6 ending with IPv4 like '::ffff:192.168.0.1'
|
# IPv6 ending with IPv4 like '::ffff:192.168.0.1'
|
||||||
if (fill_pos is not None) and not (fill_pos <= len(items) - 1):
|
if (fill_pos is not None) and not (fill_pos <= len(items)-1):
|
||||||
# Invalid IPv6: 'ffff:192.168.0.1::'
|
# Invalid IPv6: 'ffff:192.168.0.1::'
|
||||||
raise ValueError("%r: Invalid IPv6 address: '::' after IPv4" % ipstr)
|
raise ValueError("%r: Invalid IPv6 address: '::' after IPv4" % ipstr)
|
||||||
value = parseAddress(items[-1])[0]
|
value = parseAddress(items[-1])[0]
|
||||||
items = items[:-1] + ["%04x" % (value >> 16), "%04x" % (value & 0xFFFF)]
|
items = items[:-1] + ["%04x" % (value >> 16), "%04x" % (value & 0xffff)]
|
||||||
|
|
||||||
# Expand fill_pos to fill with '0'
|
# Expand fill_pos to fill with '0'
|
||||||
# ['1','2'] with fill_pos=1 => ['1', '0', '0', '0', '0', '0', '0', '2']
|
# ['1','2'] with fill_pos=1 => ['1', '0', '0', '0', '0', '0', '0', '2']
|
||||||
|
@ -1306,7 +1322,7 @@ def _parseAddressIPv6(ipstr):
|
||||||
diff = 8 - len(items)
|
diff = 8 - len(items)
|
||||||
if diff <= 0:
|
if diff <= 0:
|
||||||
raise ValueError("%r: Invalid IPv6 address: '::' is not needed" % ipstr)
|
raise ValueError("%r: Invalid IPv6 address: '::' is not needed" % ipstr)
|
||||||
items = items[:fill_pos] + ["0"] * diff + items[fill_pos:]
|
items = items[:fill_pos] + ['0']*diff + items[fill_pos:]
|
||||||
|
|
||||||
# Here we have a list of 8 strings
|
# Here we have a list of 8 strings
|
||||||
if len(items) != 8:
|
if len(items) != 8:
|
||||||
|
@ -1319,7 +1335,7 @@ def _parseAddressIPv6(ipstr):
|
||||||
for item in items:
|
for item in items:
|
||||||
try:
|
try:
|
||||||
item = int(item, 16)
|
item = int(item, 16)
|
||||||
error = not (0 <= item <= 0xFFFF)
|
error = not(0 <= item <= 0xffff)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
error = True
|
error = True
|
||||||
if error:
|
if error:
|
||||||
|
@ -1328,7 +1344,6 @@ def _parseAddressIPv6(ipstr):
|
||||||
index += 1
|
index += 1
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def parseAddress(ipstr, ipversion=0):
|
def parseAddress(ipstr, ipversion=0):
|
||||||
"""
|
"""
|
||||||
Parse a string and return the corresponding IP address (as integer)
|
Parse a string and return the corresponding IP address (as integer)
|
||||||
|
@ -1383,7 +1398,7 @@ def parseAddress(ipstr, ipversion=0):
|
||||||
except ValueError:
|
except ValueError:
|
||||||
intval = None
|
intval = None
|
||||||
|
|
||||||
if ipstr.startswith("0x") and hexval is not None:
|
if ipstr.startswith('0x') and hexval is not None:
|
||||||
if hexval > MAX_IPV6_ADDRESS:
|
if hexval > MAX_IPV6_ADDRESS:
|
||||||
raise ValueError("IP Address can't be larger than %x: %x" % (MAX_IPV6_ADDRESS, hexval))
|
raise ValueError("IP Address can't be larger than %x: %x" % (MAX_IPV6_ADDRESS, hexval))
|
||||||
if hexval <= MAX_IPV4_ADDRESS:
|
if hexval <= MAX_IPV4_ADDRESS:
|
||||||
|
@ -1391,19 +1406,19 @@ def parseAddress(ipstr, ipversion=0):
|
||||||
else:
|
else:
|
||||||
return (hexval, 6)
|
return (hexval, 6)
|
||||||
|
|
||||||
if ipstr.find(":") != -1:
|
if ipstr.find(':') != -1:
|
||||||
return (_parseAddressIPv6(ipstr), 6)
|
return (_parseAddressIPv6(ipstr), 6)
|
||||||
|
|
||||||
elif len(ipstr) == 32 and hexval is not None:
|
elif len(ipstr) == 32 and hexval is not None:
|
||||||
# assume IPv6 in pure hexadecimal notation
|
# assume IPv6 in pure hexadecimal notation
|
||||||
return (hexval, 6)
|
return (hexval, 6)
|
||||||
|
|
||||||
elif ipstr.find(".") != -1 or (intval is not None and intval < 256 and ipversion != 6):
|
elif ipstr.find('.') != -1 or (intval is not None and intval < 256 and ipversion != 6):
|
||||||
# assume IPv4 ('127' gets interpreted as '127.0.0.0')
|
# assume IPv4 ('127' gets interpreted as '127.0.0.0')
|
||||||
bytes = ipstr.split(".")
|
bytes = ipstr.split('.')
|
||||||
if len(bytes) > 4:
|
if len(bytes) > 4:
|
||||||
raise ValueError("IPv4 Address with more than 4 bytes")
|
raise ValueError("IPv4 Address with more than 4 bytes")
|
||||||
bytes += ["0"] * (4 - len(bytes))
|
bytes += ['0'] * (4 - len(bytes))
|
||||||
bytes = [int(x) for x in bytes]
|
bytes = [int(x) for x in bytes]
|
||||||
for x in bytes:
|
for x in bytes:
|
||||||
if x > 255 or x < 0:
|
if x > 255 or x < 0:
|
||||||
|
@ -1433,12 +1448,12 @@ def intToIp(ip, version):
|
||||||
if ip < 0:
|
if ip < 0:
|
||||||
raise ValueError("IPs can't be negative: %d" % (ip))
|
raise ValueError("IPs can't be negative: %d" % (ip))
|
||||||
|
|
||||||
ret = ""
|
ret = ''
|
||||||
if version == 4:
|
if version == 4:
|
||||||
if ip > MAX_IPV4_ADDRESS:
|
if ip > MAX_IPV4_ADDRESS:
|
||||||
raise ValueError("IPv4 Address can't be larger than %x: %x" % (MAX_IPV4_ADDRESS, ip))
|
raise ValueError("IPv4 Address can't be larger than %x: %x" % (MAX_IPV4_ADDRESS, ip))
|
||||||
for l in xrange(4):
|
for l in xrange(4):
|
||||||
ret = str(ip & 0xFF) + "." + ret
|
ret = str(ip & 0xff) + '.' + ret
|
||||||
ip = ip >> 8
|
ip = ip >> 8
|
||||||
ret = ret[:-1]
|
ret = ret[:-1]
|
||||||
elif version == 6:
|
elif version == 6:
|
||||||
|
@ -1448,14 +1463,13 @@ def intToIp(ip, version):
|
||||||
for x in xrange(1, 33):
|
for x in xrange(1, 33):
|
||||||
ret = l[-x] + ret
|
ret = l[-x] + ret
|
||||||
if x % 4 == 0:
|
if x % 4 == 0:
|
||||||
ret = ":" + ret
|
ret = ':' + ret
|
||||||
ret = ret[1:]
|
ret = ret[1:]
|
||||||
else:
|
else:
|
||||||
raise ValueError("only IPv4 and IPv6 supported")
|
raise ValueError("only IPv4 and IPv6 supported")
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def _ipVersionToLen(version):
|
def _ipVersionToLen(version):
|
||||||
"""Return number of bits in address for a certain IP version.
|
"""Return number of bits in address for a certain IP version.
|
||||||
|
|
||||||
|
@ -1489,25 +1503,10 @@ def _countFollowingZeros(l):
|
||||||
return 1 + _countFollowingZeros(l[1:])
|
return 1 + _countFollowingZeros(l[1:])
|
||||||
|
|
||||||
|
|
||||||
_BitTable = {
|
_BitTable = {'0': '0000', '1': '0001', '2': '0010', '3': '0011',
|
||||||
"0": "0000",
|
'4': '0100', '5': '0101', '6': '0110', '7': '0111',
|
||||||
"1": "0001",
|
'8': '1000', '9': '1001', 'a': '1010', 'b': '1011',
|
||||||
"2": "0010",
|
'c': '1100', 'd': '1101', 'e': '1110', 'f': '1111'}
|
||||||
"3": "0011",
|
|
||||||
"4": "0100",
|
|
||||||
"5": "0101",
|
|
||||||
"6": "0110",
|
|
||||||
"7": "0111",
|
|
||||||
"8": "1000",
|
|
||||||
"9": "1001",
|
|
||||||
"a": "1010",
|
|
||||||
"b": "1011",
|
|
||||||
"c": "1100",
|
|
||||||
"d": "1101",
|
|
||||||
"e": "1110",
|
|
||||||
"f": "1111",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def _intToBin(val):
|
def _intToBin(val):
|
||||||
"""Return the binary representation of an integer as string."""
|
"""Return the binary representation of an integer as string."""
|
||||||
|
@ -1515,15 +1514,14 @@ def _intToBin(val):
|
||||||
if val < 0:
|
if val < 0:
|
||||||
raise ValueError("Only positive values allowed")
|
raise ValueError("Only positive values allowed")
|
||||||
s = "%x" % val
|
s = "%x" % val
|
||||||
ret = ""
|
ret = ''
|
||||||
for x in s:
|
for x in s:
|
||||||
ret += _BitTable[x]
|
ret += _BitTable[x]
|
||||||
# remove leading zeros
|
# remove leading zeros
|
||||||
while ret[0] == "0" and len(ret) > 1:
|
while ret[0] == '0' and len(ret) > 1:
|
||||||
ret = ret[1:]
|
ret = ret[1:]
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def _count1Bits(num):
|
def _count1Bits(num):
|
||||||
"""Find the highest bit set to 1 in an integer."""
|
"""Find the highest bit set to 1 in an integer."""
|
||||||
ret = 0
|
ret = 0
|
||||||
|
@ -1532,7 +1530,6 @@ def _count1Bits(num):
|
||||||
ret += 1
|
ret += 1
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def _count0Bits(num):
|
def _count0Bits(num):
|
||||||
"""Find the highest bit set to 0 in an integer."""
|
"""Find the highest bit set to 0 in an integer."""
|
||||||
|
|
||||||
|
@ -1575,7 +1572,7 @@ def _checkPrefix(ip, prefixlen, version):
|
||||||
zbits = bits + 1
|
zbits = bits + 1
|
||||||
else:
|
else:
|
||||||
zbits = _count0Bits(ip)
|
zbits = _count0Bits(ip)
|
||||||
if zbits < bits - prefixlen:
|
if zbits < bits - prefixlen:
|
||||||
return 0
|
return 0
|
||||||
else:
|
else:
|
||||||
return 1
|
return 1
|
||||||
|
@ -1604,7 +1601,7 @@ def _checkNetmask(netmask, masklen):
|
||||||
def _checkNetaddrWorksWithPrefixlen(net, prefixlen, version):
|
def _checkNetaddrWorksWithPrefixlen(net, prefixlen, version):
|
||||||
"""Check if a base addess of a network is compatible with a prefixlen"""
|
"""Check if a base addess of a network is compatible with a prefixlen"""
|
||||||
try:
|
try:
|
||||||
return net & _prefixlenToNetmask(prefixlen, version) == net
|
return (net & _prefixlenToNetmask(prefixlen, version) == net)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -1632,7 +1629,7 @@ def _prefixlenToNetmask(prefixlen, version):
|
||||||
return 0
|
return 0
|
||||||
elif prefixlen < 0:
|
elif prefixlen < 0:
|
||||||
raise ValueError("Prefixlen must be > 0")
|
raise ValueError("Prefixlen must be > 0")
|
||||||
return ((2 << prefixlen - 1) - 1) << (_ipVersionToLen(version) - prefixlen)
|
return ((2<<prefixlen-1)-1) << (_ipVersionToLen(version) - prefixlen)
|
||||||
|
|
||||||
|
|
||||||
def _remove_subprefix(prefix, subprefix):
|
def _remove_subprefix(prefix, subprefix):
|
||||||
|
@ -1646,8 +1643,8 @@ def _remove_subprefix(prefix, subprefix):
|
||||||
|
|
||||||
# Start cutting in half, recursively
|
# Start cutting in half, recursively
|
||||||
prefixes = [
|
prefixes = [
|
||||||
IP("%s/%d" % (prefix[0], prefix._prefixlen + 1)),
|
IP('%s/%d' % (prefix[0], prefix._prefixlen + 1)),
|
||||||
IP("%s/%d" % (prefix[int(prefix.len() / 2)], prefix._prefixlen + 1)),
|
IP('%s/%d' % (prefix[int(prefix.len() / 2)], prefix._prefixlen + 1)),
|
||||||
]
|
]
|
||||||
if subprefix in prefixes[0]:
|
if subprefix in prefixes[0]:
|
||||||
return _remove_subprefix(prefixes[0], subprefix) + IPSet([prefixes[1]])
|
return _remove_subprefix(prefixes[0], subprefix) + IPSet([prefixes[1]])
|
||||||
|
@ -1657,9 +1654,7 @@ def _remove_subprefix(prefix, subprefix):
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import doctest
|
import doctest
|
||||||
|
|
||||||
failure, nbtest = doctest.testmod()
|
failure, nbtest = doctest.testmod()
|
||||||
if failure:
|
if failure:
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
|
@ -12,14 +12,13 @@ try:
|
||||||
class LdapAuthenticationBackend(ModelBackend):
|
class LdapAuthenticationBackend(ModelBackend):
|
||||||
|
|
||||||
def get_LDAP_user(self, username, password, filterString):
|
def get_LDAP_user(self, username, password, filterString):
|
||||||
print('get_LDAP_user')
|
print('get_LDAP_user {}'.format(username))
|
||||||
try:
|
try:
|
||||||
server = Server(settings.LDAP_URL, port=settings.LDAP_PORT,
|
server = Server(settings.LDAP_URL, port=settings.LDAP_PORT,
|
||||||
use_ssl=settings.USE_SSL,get_info=ALL)
|
use_ssl=settings.USE_SSL,get_info=ALL)
|
||||||
connection = Connection(server,
|
connection = Connection(server,
|
||||||
settings.LDAP_MASTER_DN,
|
settings.LDAP_MASTER_DN,
|
||||||
settings.LDAP_MASTER_PW, auto_bind=True)
|
settings.LDAP_MASTER_PW, auto_bind=True)
|
||||||
|
|
||||||
connection.search(settings.LDAP_ROOT_DN,
|
connection.search(settings.LDAP_ROOT_DN,
|
||||||
'(&({attr}={login})({filter}))'.format(
|
'(&({attr}={login})({filter}))'.format(
|
||||||
attr=settings.LDAP_USER_UID_PREFIX,
|
attr=settings.LDAP_USER_UID_PREFIX,
|
||||||
|
@ -31,11 +30,10 @@ try:
|
||||||
return None
|
return None
|
||||||
specificUser = connection.response[0]
|
specificUser = connection.response[0]
|
||||||
userDn = str(specificUser.get('raw_dn'),'utf-8')
|
userDn = str(specificUser.get('raw_dn'),'utf-8')
|
||||||
with Connection(server,
|
with Connection(server, userDn, password) as con:
|
||||||
userDn,
|
|
||||||
password) as con:
|
|
||||||
return username
|
return username
|
||||||
except:
|
except Exception as e:
|
||||||
|
print("LDAP Exception: {}".format(e))
|
||||||
return None
|
return None
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -50,6 +48,7 @@ try:
|
||||||
if self.get_LDAP_user(username, password, settings.LDAP_SEARCH_GROUP_FILTER_ADMINS) is None:
|
if self.get_LDAP_user(username, password, settings.LDAP_SEARCH_GROUP_FILTER_ADMINS) is None:
|
||||||
if self.get_LDAP_user(username, password, settings.LDAP_SEARCH_GROUP_FILTER_STAFF) is None:
|
if self.get_LDAP_user(username, password, settings.LDAP_SEARCH_GROUP_FILTER_STAFF) is None:
|
||||||
if self.get_LDAP_user(username, password, settings.LDAP_SEARCH_GROUP_FILTER_USERS) is None:
|
if self.get_LDAP_user(username, password, settings.LDAP_SEARCH_GROUP_FILTER_USERS) is None:
|
||||||
|
print("User does not belong to any search group. Check LDAP_SEARCH_GROUP_FILTER in settings.")
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
isStaff = True
|
isStaff = True
|
||||||
|
@ -62,7 +61,7 @@ try:
|
||||||
attributes = UserAttributes.objects.get(user=user)
|
attributes = UserAttributes.objects.get(user=user)
|
||||||
# TODO VERIFY
|
# TODO VERIFY
|
||||||
except User.DoesNotExist:
|
except User.DoesNotExist:
|
||||||
print("authenticate-create new user")
|
print("authenticate-create new user: {}".format(username))
|
||||||
user = User(username=username)
|
user = User(username=username)
|
||||||
user.is_active = True
|
user.is_active = True
|
||||||
user.is_staff = isStaff
|
user.is_staff = isStaff
|
||||||
|
|
|
@ -268,6 +268,7 @@ LDAP_MASTER_PW = ''
|
||||||
LDAP_ROOT_DN = ''
|
LDAP_ROOT_DN = ''
|
||||||
## Queries to identify the users, i use groupOfUniqueNames on openldap
|
## Queries to identify the users, i use groupOfUniqueNames on openldap
|
||||||
|
|
||||||
|
### PLEASE BE SURE memberOf overlay is activated on slapd
|
||||||
## e.g. memberOf=cn=admins,cn=staff,cn=webvirtcloud,ou=groups,dc=kendar,dc=org
|
## e.g. memberOf=cn=admins,cn=staff,cn=webvirtcloud,ou=groups,dc=kendar,dc=org
|
||||||
LDAP_SEARCH_GROUP_FILTER_ADMINS = ''
|
LDAP_SEARCH_GROUP_FILTER_ADMINS = ''
|
||||||
## e.g. memberOf=cn=staff,cn=webvirtcloud,ou=groups,dc=kendar,dc=org
|
## e.g. memberOf=cn=staff,cn=webvirtcloud,ou=groups,dc=kendar,dc=org
|
||||||
|
|
Loading…
Reference in a new issue