def test_ipv6_unicode(): # Fully qualified assert unicode(IPv6("::/0")) == u"::/0" assert unicode(IPv6("2001:db8::/32")) == u"2001:db8::/32" assert unicode(IPv6("::ffff:192.168.0.1")) == u"::ffff:192.168.0.1/128" # Address only assert unicode(IPv6("::")) == u"::/128"
def test_ipv6_sub(): # prefix - number returns prefix assert repr(IPv6("100::5") - 3) == "<IPv6 100::2/128>" assert repr(IPv6("100::5") - 5) == "<IPv6 100::/128>" assert repr(IPv6("100::5") - 6) == "<IPv6 ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128>" # prefix - prefix returns distance assert IPv6("100::7") - IPv6("100::5") == 2
def test_ipv6_str(): # Fully qualified assert str(IPv6("::/0")), "::/0" assert str(IPv6("2001:db8::/32")) == "2001:db8::/32" assert str(IPv6("::ffff:192.168.0.1")) == "::ffff:192.168.0.1/128" # Address only assert str(IPv6("::")) == "::/128"
def test_ipv6_iter_free(): assert [repr(x) for x in IPv6("2001:db8::/32").iter_free([])] == ["<IPv6 2001:db8::/32>"] assert [repr(x) for x in IPv6("2001:db8::/32").iter_free(["2001:db8::/34"])] == [ "<IPv6 2001:db8:4000::/34>", "<IPv6 2001:db8:8000::/33>" ] assert [repr(x) for x in IPv6("2001:db8::/32").iter_free(["2001:db8:4000::/34"])] == [ "<IPv6 2001:db8::/34>", "<IPv6 2001:db8:8000::/33>" ]
def test_ipv6_hash(): p0 = IPv6("::1") p1 = IPv6("::2") s = {p0} assert p0 in s assert p1 not in s ss = {p0: 1} assert ss[p0] == 1 with pytest.raises(KeyError): ss[p1]
def test_ipv6_hash(): p0 = IPv6("::1") p1 = IPv6("::2") s = {p0} assert p0 in s assert p1 not in s ss = {p0: 1} assert ss[p0] == 1 with pytest.raises(KeyError): ss[p1] # pylint: disable=pointless-statement
def test_ipv6_comparison(p1, p2, c, eq, ne, lt, le, gt, ge): p1 = IPv6(p1) p2 = IPv6(p2) assert ((p1 > p2) - (p1 < p2)) == c assert (p1 == p2) is eq assert (p1 != p2) is ne assert (p1 < p2) is lt assert (p1 > p2) is gt assert (p1 <= p2) is le assert (p1 >= p2) is ge
def test_ipv6_comparison(ipv6_comparison): p1, p2, c, eq, ne, lt, le, gt, ge = ipv6_comparison p1 = IPv6(p1) p2 = IPv6(p2) assert cmp(p1, p2) is c assert (p1 == p2) is eq assert (p1 != p2) is ne assert (p1 < p2) is lt assert (p1 > p2) is gt assert (p1 <= p2) is le assert (p1 >= p2) is ge
def test_ipv6_iter_address(): assert [repr(x) for x in IPv6("2001:db8::").iter_address(count=5)] == [ "<IPv6 2001:db8::/128>", "<IPv6 2001:db8::1/128>", "<IPv6 2001:db8::2/128>", "<IPv6 2001:db8::3/128>", "<IPv6 2001:db8::4/128>" ] assert [repr(x) for x in IPv6("2001:db8::ffff").iter_address(count=5)] == [ "<IPv6 2001:db8::ffff/128>", "<IPv6 2001:db8::1:0/128>", "<IPv6 2001:db8::1:1/128>", "<IPv6 2001:db8::1:2/128>", "<IPv6 2001:db8::1:3/128>" ] assert [repr(x) for x in IPv6("2001:db8::ffff").iter_address(until="2001:db8::1:3")] == [ "<IPv6 2001:db8::ffff/128>", "<IPv6 2001:db8::1:0/128>", "<IPv6 2001:db8::1:1/128>", "<IPv6 2001:db8::1:2/128>", "<IPv6 2001:db8::1:3/128>" ]
def test_prefixdb_ipv6(p1, p2, p3, p4, p5, p6, p7, p8, p9): db = PrefixDB() db[IPv6(p1)] = p2 db[IPv6(p3)] = p4 db[IPv6(p5)] = p6 db[IPv6(p7)] = p8 assert db[IPv6(p1)] == p2 assert db[IPv6(p3)] == p4 assert db[IPv6(p5)] == p6 assert db[IPv6(p7)] == p8 with pytest.raises(KeyError): db[IPv6(p9)]
def test_prefixdb_ipv6(): db = PrefixDB() db[IPv6("2001:db8:100::/48")] = 1 db[IPv6("2001:db8:200::/48")] = 2 db[IPv6("2001:db8:300::/48")] = 3 db[IPv6("2001:db8:400::/48")] = 4 assert db[IPv6("2001:db8:100::/48")] == 1 assert db[IPv6("2001:db8:200::/48")] == 2 assert db[IPv6("2001:db8:300::/48")] == 3 assert db[IPv6("2001:db8:400::/48")] == 4 with pytest.raises(KeyError): db[IPv6("::/128")]
def get_zone(cls, name): """ Resolve name to zone object :return: """ def get_closest(n): """ Return closest matching zone """ while n: try: return DNSZone.objects.get(name=n) except DNSZone.DoesNotExist: pass n = ".".join(n.split(".")[1:]) return None if not name: return None if is_ipv4(name): # IPv4 zone n = name.split(".") n.reverse() return get_closest("%s.in-addr.arpa" % (".".join(n[1:]))) elif is_ipv6(name): # IPv6 zone d = IPv6(name).digits d.reverse() c = ".".join(d) return (get_closest("%s.ip6.arpa" % c) or get_closest("%s.ip6.int" % c)) else: return get_closest(name)
def clean(self, value): if value is None and self.default is not None: return self.default v = super(IPv6Parameter, self).clean(value) if not is_ipv6(v): self.raise_error(value) return IPv6(v).normalized.address
def execute(self): r = [] ns = { "isapi": "http://www.isapi.org/ver20/XMLSchema", "std-cgi": "http://www.std-cgi.com/ver20/XMLSchema", "hikvision": "http://www.hikvision.com/ver20/XMLSchema", } v = self.http.get("/ISAPI/System/Network/interfaces", use_basic=True) v = v.replace("\n", "") if "std-cgi" in v: ns["ns"] = ns["std-cgi"] elif "www.hikvision.com" in v: ns["ns"] = ns["hikvision"] else: ns["ns"] = ns["isapi"] root = ElementTree.fromstring(v) # mac = self.scripts.get_chassis_id()[0]["first_chassis_mac"] for o in root: o_id = o.find("{%s}id" % ns["ns"]).text name = "eth%s" % o_id iface = {"name": name, "type": "physical", "admin_status": True, "oper_status": True} sub = {"name": name, "admin_status": True, "oper_status": True, "enabled_afi": []} try: v = self.http.get("/ISAPI/System/Network/interfaces/%s/Link" % o_id, use_basic=True) v = v.replace("\n", "") v = ElementTree.fromstring(v) mac = v.find("{%s}MACAddress" % ns["ns"]).text except HTTPError: mac = self.scripts.get_chassis_id()[0]["first_chassis_mac"] if mac: sub["mac"] = mac iface["mac"] = mac ip = o.find("{%s}IPAddress" % ns["ns"]) # for ip in ip_addresses: afi = ip.find("{%s}ipVersion" % ns["ns"]).text if afi == "v4": if "IPv4" not in sub["enabled_afi"]: sub["enabled_afi"] += ["IPv4"] ip_address = "%s/%s" % ( ip.find("{%s}ipAddress" % ns["ns"]).text, IPv4.netmask_to_len(ip.find("{%s}subnetMask" % ns["ns"]).text), ) if "ipv4_addresses" in sub: sub["ipv4_addresses"] += [ip_address] else: sub["ipv4_addresses"] = [ip_address] if afi == "v6": if "IPv6" not in sub["enabled_afi"]: sub["enabled_afi"] += ["IPv6"] ip_address = IPv6( ip.find("{%s}ipAddress" % ns["ns"]).text, netmask=ip.find("ns:subnetMask", ns).text, ).prefix iface["subinterfaces"] = [sub] r += [iface] return [{"interfaces": r}]
def test_ipv6_area_spot(): assert [ repr(x) for x in IPv6("2001:db8::/32").area_spot(["2001:db8::1", "2001:db8::a"], dist=2) ] == [ "<IPv6 2001:db8::/128>", "<IPv6 2001:db8::1/128>", "<IPv6 2001:db8::2/128>", "<IPv6 2001:db8::3/128>", "<IPv6 2001:db8::8/128>", "<IPv6 2001:db8::9/128>", "<IPv6 2001:db8::a/128>", "<IPv6 2001:db8::b/128>", "<IPv6 2001:db8::c/128>" ]
def execute(self): conf_interfaces = {} interfaces = [] v = self.cli("show running-config interface", cached=True) for match in self.rx_conf_iface.finditer(v): conf_interfaces[match.group("iface")] = match.group("cfg") v = self.cli("show interface", cached=True) for match in self.rx_iface.finditer(v): ifname = match.group("iface") iface = { "name": ifname, "type": self.profile.get_interface_type(ifname), "oper_status": match.group("oper") == "up", "admin_status": match.group("admin") == "up", "subinterfaces": [{ "name": ifname, "oper_status": match.group("oper") == "up", "admin_status": match.group("admin") == "up", "enabled_afi": [] }] } if match.group("mac"): iface["mac"] = match.group("mac") iface["subinterfaces"][0]["mac"] = match.group("mac") if match.group("mtu"): iface["subinterfaces"][0]["mtu"] = int(match.group("mtu")) if match.group("ip_addr"): ip = match.group("ip_addr") netmask = str(IPv4.netmask_to_len(match.group("ip_mask"))) ip = ip + '/' + netmask ip_list = [ip] iface["subinterfaces"][0]["ipv4_addresses"] = ip_list iface["subinterfaces"][0]["enabled_afi"] += ["IPv4"] if match.group("ipv6_addr"): ip = match.group("ipv6_addr") netmask = match.group("ipv6_mask") ip = IPv6(ip, netmask=match.group("ipv6_mask")).prefix ip_list = [ip] iface["subinterfaces"][0]["ipv6_addresses"] = ip_list iface["subinterfaces"][0]["enabled_afi"] += ["IPv6"] else: iface["subinterfaces"][0]["enabled_afi"] += ["BRIDGE"] if match.group("pvid"): iface["subinterfaces"][0]["untagged_vlan"] = \ int(match.group("pvid")) if conf_interfaces.get(ifname): cfg = conf_interfaces[ifname] for match in self.rx_trunk.finditer(cfg): if iface["subinterfaces"][0].get("tagged_vlans"): iface["subinterfaces"][0]["tagged_vlans"] += \ [int(match.group("vlan_id"))] else: iface["subinterfaces"][0]["tagged_vlans"] = \ [int(match.group("vlan_id"))] interfaces += [iface] return [{"interfaces": interfaces}]
def iter_ipam_ptr6(cls, zone): """ Yield IPv6 PTR records from IPAM :return: (name, type, content, ttl, prio) :return: """ origin_length = (len(zone.name) - 8 + 1) // 2 for a in Address.objects.filter(afi="6").extra( where=["address << %s"], params=[zone.reverse_prefix]): yield RR(zone=zone.name, name=IPv6(a.address).ptr(origin_length), ttl=zone.profile.zone_ttl, type="PTR", rdata=a.fqdn + ".")
def _get_reverse_for_ipv6_address(cls, address): """ Get reverze zone holding IPv6 address :param address: Address (as a string) :return: DNSZone instance or None """ # @todo: Impelement properly parts = [str(x) for x in reversed(IPv6(address).iter_bits())][1:] while parts: for suffix in (".ip6.int", ".ip6.arpa"): name = "%s.%s" % (".".join(parts), suffix) zone = DNSZone.get_by_name(name) if zone: return zone parts.pop(0) # Remove first par return None
def reverse_prefix(self): """ Appropriative prefix for reverse zone :return: IPv4 or IPv6 prefix :rtype: String """ if self.type == ZONE_REVERSE_IPV4: # Get IPv4 prefix covering reverse zone n = self.name.lower() if n.endswith(".in-addr.arpa"): r = n[:-13].split(".") r.reverse() length = 4 - len(r) r += ["0"] * length ml = 32 - 8 * length return ".".join(r) + "/%d" % ml elif self.type == ZONE_REVERSE_IPV6: # Get IPv6 prefix covering reverse zone n = self.name.lower() if n.endswith(".ip6.int"): n = n[:-8] elif n.endswith(".ip6.arpa"): n = n[:-9] else: raise Exception("Invalid IPv6 zone suffix") p = n.split(".") p.reverse() length = len(p) if length % 4: p += [u"0"] * (4 - length % 4) r = "" for i, c in enumerate(p): if i and i % 4 == 0: r += ":" r += c if len(p) != 32: r += "::" prefix = r + "/%d" % (length * 4) return IPv6(prefix).normalized.prefix
def test_ipv6_first(): assert repr(IPv6("2001:db8::10/32").first) == "<IPv6 2001:db8::/32>"
def test_ipv6_from_bits(): assert repr(IPv6.from_bits([1, 1, 1, 1, 1, 1, 1, 1])) == "<IPv6 ff00::/8>" assert repr(IPv6.from_bits([1, 1, 1, 1, 1, 1, 1, 1, 1])) == "<IPv6 ff80::/9>"
def execute_cli(self): # TODO # Get portchannes portchannel_members = {} # member -> (portchannel, type) # with self.cached(): # for pc in self.scripts.get_portchannel(): # i = pc["interface"] # t = pc["type"] == "L" # for m in pc["members"]: # portchannel_members[m] = (i, t) interfaces = [] # Try SNMP first """ # SNMP working but without IP if self.has_snmp(): try: # Get mac mac = self.scripts.get_chassis_id() # Get switchports for swp in self.scripts.get_switchport(): iface = swp["interface"] if iface[0] == "T": return 1 # IF-MIB::ifAdminStatus if len(iface.split('/')) < 3: if_OID = iface.split('/')[1] else: if_OID = iface.split('/')[2] s = self.snmp.get("1.3.6.1.2.1.2.2.1.7.%d" % int(if_OID)) admin = int(s) == 1 name = swp["interface"] iface = { "name": name, "type": "aggregated" if len(swp["members"]) > 0 else "physical", "admin_status": admin, "oper_status": swp["status"], "mac": mac, "subinterfaces": [{ "name": name, "admin_status": admin, "oper_status": swp["status"], "is_bridge": True, "mac": mac, #"snmp_ifindex": self.scripts.get_ifindex(interface=name) }] } if swp["tagged"]: iface["subinterfaces"][0]["tagged_vlans"] = swp["tagged"] try: iface["subinterfaces"][0]["untagged_vlan"] = swp["untagged"] except KeyError: pass if swp["description"]: iface["description"] = swp["description"] if name in portchannel_members: iface["aggregated_interface"] = portchannel_members[name][0] iface["is_lacp"] = portchannel_members[name][1] interfaces += [iface] return [{"interfaces": interfaces}] except self.snmp.TimeOutError: pass # Fallback to CLI """ # Fallback to CLI # Get port-to-vlan mappings switchports = {} # interface -> (untagged, tagged) for swp in self.scripts.get_switchport(): switchports[swp["interface"]] = ( swp["untagged"] if "untagged" in swp else None, swp["tagged"], swp["description"], ) interfaces = [] # Get L3 interfaces try: enabled_afi = [] ip_int = self.cli("show ip interface") # QWS-3xxx match = self.rx_mac.search(ip_int) mac = match.group("mac") # TODO Get router interfaces self.get_ospfint() self.get_ripint() self.get_bgpint() for match in self.rx_sh_svi.finditer(ip_int): description = match.group("description") if not description: description = "Outband managment" ifname = match.group("interface") ip1 = match.group("ip1") ip2 = match.group("ip2") if ":" in ip1: ip_interfaces = "ipv6_addresses" enabled_afi += ["IPv6"] ip1 = IPv6(ip1, netmask=match.group("mask1")).prefix if ip2: ip2 = IPv6(ip2, netmask=match.group("mask2")).prefix ip_list = [ip1, ip2] else: ip_list = [ip1] else: ip_interfaces = "ipv4_addresses" enabled_afi += ["IPv4"] ip1 = IPv4(ip1, netmask=match.group("mask1")).prefix if ip2: ip2 = IPv4(ip2, netmask=match.group("mask2")).prefix ip_list = [ip1, ip2] else: ip_list = [ip1] vlan = match.group("vlan") a_stat = match.group("admin_status").lower() == "up" iface = { "name": ifname, "type": "SVI", "admin_status": a_stat, "oper_status": a_stat, "mac": mac, "description": description, "subinterfaces": [{ "name": ifname, "description": description, "admin_status": a_stat, "oper_status": a_stat, "enabled_afi": enabled_afi, ip_interfaces: ip_list, "mac": mac, "vlan_ids": self.expand_rangelist(vlan), }], } interfaces += [iface] except self.CLISyntaxError: enabled_afi = [] ip_int = self.cli("show ip") # QWS-2xxx match = self.rx_sh_mng.search(ip_int) ip = match.group("ip") if ":" in ip: ip_interfaces = "ipv6_addresses" enabled_afi += ["IPv6"] ip = IPv6(ip, netmask=match.group("mask")).prefix else: ip_interfaces = "ipv4_addresses" enabled_afi += ["IPv4"] ip = IPv4(ip, netmask=match.group("mask")).prefix ip_list = [ip] vlan = match.group("vlan") mac = match.group("mac") iface = { "name": "VLAN-" + vlan, "type": "management", "admin_status": True, "oper_status": True, "mac": mac, "description": "Managment", "subinterfaces": [{ "name": "VLAN-" + vlan, "description": "Managment", "admin_status": True, "oper_status": True, "enabled_afi": enabled_afi, ip_interfaces: ip_list, "mac": mac, "vlan_ids": self.expand_rangelist(vlan), }], } interfaces += [iface] # # Get L2 interfaces mac = self.scripts.get_chassis_id()[0]["first_chassis_mac"] status = self.cli("show interface") for match in self.rx_status.finditer(status): ifname = match.group("interface") a_stat = match.group("admin_status").lower() == "enabled" o_stat = match.group("oper_status").lower() == "up" iface = { "name": self.profile.convert_interface_name(ifname), "type": self.types[ifname[:1]], "admin_status": a_stat, "oper_status": o_stat, "mac": mac, "description": switchports[ifname][2], "subinterfaces": [{ "name": ifname, "description": switchports[ifname][2], "admin_status": a_stat, "oper_status": o_stat, "enabled_afi": ["BRIDGE"], "mac": mac, # "snmp_ifindex": self.scripts.get_ifindex(interface=name) }], } if switchports[ifname][1]: iface["subinterfaces"][0]["tagged_vlans"] = switchports[ ifname][1] if switchports[ifname][0]: iface["subinterfaces"][0]["untagged_vlan"] = switchports[ ifname][0] # iface["description"] = switchports[ifname][2] # Portchannel member if ifname in portchannel_members: ai, is_lacp = portchannel_members[ifname] iface["aggregated_interface"] = ai if is_lacp: iface["enabled_protocols"] = ["LACP"] interfaces += [iface] return [{"interfaces": interfaces}]
def test_ipv6_from_to_bits(ipv6_bits): p = IPv6(ipv6_bits) assert IPv6.from_bits(p.iter_bits()) == p
def test_ipv6_contains(): assert IPv6("2001:db8::/32").contains(IPv6("2001:db8::/32")) is True assert IPv6("2001:db8::/32").contains(IPv6("2001:db8::/64")) is True assert IPv6("2001:db8::/32").contains(IPv6("2001:db8::")) is True assert IPv6("2001:db8::/32").contains(IPv6("2001:db8:0:ffff:ffff:ffff:ffff:ffff")) is True assert IPv6("2001:db8::/32").contains(IPv6("2001:db8:ffff:ffff:ffff:ffff:ffff:ffff")) is True assert IPv6("2001:db8::/32").contains(IPv6("2001:db7:ffff:ffff:ffff:ffff:ffff:ffff")) is False assert IPv6("2001:db8::/32").contains(IPv6("2001:db9::")) is False
def test_ipv6_last(): assert repr(IPv6("2001:db8::10/32").last) == "<IPv6 2001:db8:ffff:ffff:ffff:ffff:ffff:ffff/32>"
def test_ipv6_rebase(ipv6_rebase): p, b, nb, r = ipv6_rebase assert IPv6(p).rebase(IPv6(b), IPv6(nb)) == IPv6(r)
def test_ipv6_digits(): assert IPv6("2001:db8::1").digits == [ "2", "0", "0", "1", "0", "d", "b", "8", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1" ]
def test_ipv6_ptr(): assert IPv6("2001:db8::1" ).ptr(0) == "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2" assert IPv6("2001:db8::1").ptr(8) == "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0"
def test_ipv6_set_mask(): assert repr(IPv6("2001:db8::20/48").set_mask()) == "<IPv6 2001:db8::20/128>" assert repr(IPv6("2001:db8::20/48").set_mask(64)) == "<IPv6 2001:db8::20/64>"
def test_ipv6_normalized(): assert repr(IPv6("0:00:0:0:0::1").normalized) == "<IPv6 ::1/128>" assert repr(IPv6("2001:db8:0:7:0:0:0:1").normalized) == "<IPv6 2001:db8:0:7::1/128>" assert repr(IPv6("::ffff:c0a8:1").normalized) == "<IPv6 ::ffff:192.168.0.1/128>"