def test2_ipv6_to_longs2(self): ip_upper_str = "aFFF:FaFF:FFaF:FFFa" ip_lower_str = "0000:0000:0000:0000" ip_upper, ip_lower = ipv6_to_longs(ip_upper_str + ":" + ip_lower_str) self.assertEqual(hex(ip_upper).lower(), "0x%sl" % (ip_upper_str.lower() .replace(':', ''))) self.assertEqual(hex(ip_lower).lower(), "0x0l")
def redirect_to_range_from_ip(request): ip_str = request.GET.get('ip_str') ip_type = request.GET.get('ip_type') if not (ip_str and ip_type): return HttpResponse(json.dumps({'failure': "Slob"})) if ip_type == '4': try: ip_upper, ip_lower = 0, int(ipaddr.IPv4Address(ip_str)) except ipaddr.AddressValueError: return HttpResponse( json.dumps({'success': False, 'message': "Failure to " "recognize{0} as an IPv4 " "Address.".format(ip_str)})) else: try: ip_upper, ip_lower = ipv6_to_longs(ip_str) except ValidationError: return HttpResponse(json.dumps({'success': False, 'message': 'Invalid IP'})) range_ = Range.objects.filter(start_upper__lte=ip_upper, start_lower__lte=ip_lower, end_upper__gte=ip_upper, end_lower__gte=ip_lower) if not len(range_) == 1: return HttpResponse(json.dumps({'failure': "Failture to find range"})) else: return HttpResponse(json.dumps( {'success': True, 'redirect_url': range_[0].get_absolute_url()}))
def _do_generic_update_test(self, record, new_name, new_ip, ip_type): if new_ip: if ip_type == '4': ip_upper, ip_lower = 0, ipaddr.IPv4Address(new_ip).__int__() else: ip_upper, ip_lower = ipv6_to_longs(new_ip) else: ip_upper, ip_lower = record.ip_upper, record.ip_lower if new_name is not None and new_ip is not None: aret = AddressRecord.objects.filter( label=new_name, ip_upper=ip_upper, ip_lower=ip_lower, ip_type=ip_type)[0] elif new_name is not None: # Just new_name aret = AddressRecord.objects.filter( label=new_name, ip_upper=ip_upper, ip_lower=ip_lower, ip_type=ip_type)[0] else: # Just new_ip aret = AddressRecord.objects.filter( label=new_name, ip_upper=ip_upper, ip_lower=ip_lower, ip_type=ip_type)[0] if new_name: self.assertEqual(aret.label, new_name) if new_ip: if ip_type == '4': self.assertEqual( aret.ip_str, ipaddr.IPv4Address(new_ip).__str__()) else: self.assertEqual( aret.ip_str, ipaddr.IPv6Address(new_ip).__str__())
def _do_generic_update_test(self, record, new_name, new_ip, ip_type): if new_ip: if ip_type == '4': ip_upper, ip_lower = 0, ipaddr.IPv4Address(new_ip).__int__() else: ip_upper, ip_lower = ipv6_to_longs(new_ip) else: ip_upper, ip_lower = record.ip_upper, record.ip_lower if new_name is not None and new_ip is not None: aret = AddressRecord.objects.filter(label=new_name, ip_upper=ip_upper, ip_lower=ip_lower, ip_type=ip_type)[0] elif new_name is not None: # Just new_name aret = AddressRecord.objects.filter(label=new_name, ip_upper=ip_upper, ip_lower=ip_lower, ip_type=ip_type)[0] else: # Just new_ip aret = AddressRecord.objects.filter(label=new_name, ip_upper=ip_upper, ip_lower=ip_lower, ip_type=ip_type)[0] if new_name: self.assertEqual(aret.label, new_name) if new_ip: if ip_type == '4': self.assertEqual(aret.ip_str, ipaddr.IPv4Address(new_ip).__str__()) else: self.assertEqual(aret.ip_str, ipaddr.IPv6Address(new_ip).__str__())
def migrate_AAAA(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('AAAA'): name = name.to_text().strip('.') print str(name) + " AAAA " + str(rdata) exists_domain = Domain.objects.filter(name=name) if exists_domain: label = '' domain = exists_domain[0] else: label = name.split('.')[0] if label.startswith('unused'): continue domain_name = '.'.join(name.split('.')[1:]) domain = ensure_domain(domain_name, force=True) ip_upper, ip_lower = ipv6_to_longs(rdata.to_text()) if AddressRecord.objects.filter(label=label, domain=domain, ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6').exists(): a = AddressRecord.objects.get( label=label, domain=domain, ip_type='6', ip_upper=ip_upper, ip_lower=ip_lower ) else: a = AddressRecord( label=label, domain=domain, ip_str=rdata.to_text(), ip_type='6', description=rdata.comment, ttl=ttl ) a.clean() a.save() for view in views: a.views.add(view) a.save()
def clean(self): self.update_network() # Look at all ranges that claim to be in this subnet, are they actually # in the subnet? for range_ in self.range_set.all(): """ I was writing checks to make sure that subnets wouldn't orphan ranges. IPv6 needs support. """ fail = False # Check the start addresses. if range_.start_upper < self.ip_upper: fail = True elif range_.start_upper > self.ip_upper and range_.start_lower < self.ip_lower: fail = True elif range_.start_upper == self.ip_upper and range_.start_lower < self.ip_lower: fail = True if self.ip_type == "4": brdcst_upper, brdcst_lower = 0, int(self.network.broadcast) else: brdcst_upper, brdcst_lower = ipv6_to_longs(str(self.network.broadcast)) # Check the end addresses. if range_.end_upper > brdcst_upper: fail = True elif range_.end_upper < brdcst_upper and range_.end_lower > brdcst_lower: fail = True elif range_.end_upper == brdcst_upper and range_.end_lower > brdcst_lower: fail = True if fail: raise ValidationError( "Resizing this subnet to the requested " "network prefix would orphan existing " "ranges." )
def test_add_remove_reverse_ipv6_domains(self): osu_block = "2620:105:F000" rd0 = boot_strap_ipv6_reverse_domain("2.6.2.0.0.1.0.5.f.0.0.0") ip1 = self.add_ptr_ipv6(osu_block + ":8000::1") self.assertEqual(ip1.reverse_domain, rd0) ip2 = self.add_ptr_ipv6(osu_block + ":8000::2") self.assertEqual(ip2.reverse_domain, rd0) ip3 = self.add_ptr_ipv6(osu_block + ":8000::3") self.assertEqual(ip3.reverse_domain, rd0) self.add_ptr_ipv6(osu_block + ":8000::4") rd1 = self.create_domain(name="2.6.2.0.0.1.0.5.f.0.0.0.8", ip_type='6') rd1.save() ip_upper, ip_lower = ipv6_to_longs(osu_block + ":8000::1") ptr1 = PTR.objects.filter(ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6')[0] self.assertEqual(ptr1.reverse_domain, rd1) ip_upper, ip_lower = ipv6_to_longs(osu_block + ":8000::2") ptr2 = PTR.objects.filter(ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6')[0] self.assertEqual(ptr2.reverse_domain, rd1) ip_upper, ip_lower = ipv6_to_longs(osu_block + ":8000::3") ptr3 = PTR.objects.filter(ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6')[0] self.assertEqual(ptr3.reverse_domain, rd1) ip_upper, ip_lower = ipv6_to_longs(osu_block + ":8000::4") ptr4 = PTR.objects.filter(ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6')[0] self.assertEqual(ptr4.reverse_domain, rd1) rd1.delete() ip_upper, ip_lower = ipv6_to_longs(osu_block + ":8000::1") ptr1 = PTR.objects.filter(ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6')[0] self.assertEqual(ptr1.reverse_domain, rd0) ip_upper, ip_lower = ipv6_to_longs(osu_block + ":8000::2") ptr2 = PTR.objects.filter(ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6')[0] self.assertEqual(ptr2.reverse_domain, rd0) ip_upper, ip_lower = ipv6_to_longs(osu_block + ":8000::3") ptr3 = PTR.objects.filter(ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6')[0] self.assertEqual(ptr3.reverse_domain, rd0) ip_upper, ip_lower = ipv6_to_longs(osu_block + ":8000::4") ptr4 = PTR.objects.filter(ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6')[0] self.assertEqual(ptr4.reverse_domain, rd0)
def test_ipv6_str(self): boot_strap_ipv6_reverse_domain('1.2.3.4') ip_str = '1234:1234:1243:1243:1243::' new_ip = Ip(ip_str=ip_str, ip_type='6') new_ip.clean_ip() ip_upper, ip_lower = ipv6_to_longs(ip_str) self.assertEqual(new_ip.ip_upper, ip_upper) self.assertEqual(new_ip.ip_lower, ip_lower) ip_str = '1234:432:3:0:3414:22::' new_ip = Ip(ip_str=ip_str, ip_type='6') new_ip.clean_ip() ip_upper, ip_lower = ipv6_to_longs(ip_str) self.assertEqual(new_ip.ip_upper, ip_upper) self.assertEqual(new_ip.ip_lower, ip_lower)
def test_large_ipv6(self): boot_strap_ipv6_reverse_domain('f') ip_str = 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' ip = ipaddr.IPv6Address(ip_str) ip_upper, ip_lower = ipv6_to_longs(ip_str) self.assertEqual(ip.__int__(), (2 ** 64) * ip_upper + ip_lower) new_ip = Ip(ip_str=ip_str, ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6') new_ip.clean_ip() self.assertEqual(ip_str, new_ip.ip_str) self.assertEqual(ip.__int__(), new_ip.__int__())
def test2_create_ipv6(self): network = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" prefixlen = "24" kwargs = {'network': network, 'prefixlen': prefixlen, 'ip_type': '6'} s = self.do_basic_add(**kwargs) str(s) s.__repr__() self.assertTrue(s) ip_upper, ip_lower = ipv6_to_longs(network) self.assertEqual(s.ip_upper, ip_upper) self.assertEqual(s.ip_lower, ip_lower)
def test_add_remove_reverse_ipv6_domains(self): osu_block = "2620:105:F000" rd0 = boot_strap_ipv6_reverse_domain("2.6.2.0.0.1.0.5.f.0.0.0") ip1 = self.add_ptr_ipv6(osu_block + ":8000::1") self.assertEqual(ip1.reverse_domain, rd0) ip2 = self.add_ptr_ipv6(osu_block + ":8000::2") self.assertEqual(ip2.reverse_domain, rd0) ip3 = self.add_ptr_ipv6(osu_block + ":8000::3") self.assertEqual(ip3.reverse_domain, rd0) self.add_ptr_ipv6(osu_block + ":8000::4") rd1 = self.create_domain(name="2.6.2.0.0.1.0.5.f.0.0.0.8", ip_type='6') rd1.save() ip_upper, ip_lower = ipv6_to_longs(osu_block + ":8000::1") ptr1 = PTR.objects.filter( ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6')[0] self.assertEqual(ptr1.reverse_domain, rd1) ip_upper, ip_lower = ipv6_to_longs(osu_block + ":8000::2") ptr2 = PTR.objects.filter( ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6')[0] self.assertEqual(ptr2.reverse_domain, rd1) ip_upper, ip_lower = ipv6_to_longs(osu_block + ":8000::3") ptr3 = PTR.objects.filter( ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6')[0] self.assertEqual(ptr3.reverse_domain, rd1) ip_upper, ip_lower = ipv6_to_longs(osu_block + ":8000::4") ptr4 = PTR.objects.filter( ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6')[0] self.assertEqual(ptr4.reverse_domain, rd1) rd1.delete() ip_upper, ip_lower = ipv6_to_longs(osu_block + ":8000::1") ptr1 = PTR.objects.filter( ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6')[0] self.assertEqual(ptr1.reverse_domain, rd0) ip_upper, ip_lower = ipv6_to_longs(osu_block + ":8000::2") ptr2 = PTR.objects.filter( ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6')[0] self.assertEqual(ptr2.reverse_domain, rd0) ip_upper, ip_lower = ipv6_to_longs(osu_block + ":8000::3") ptr3 = PTR.objects.filter( ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6')[0] self.assertEqual(ptr3.reverse_domain, rd0) ip_upper, ip_lower = ipv6_to_longs(osu_block + ":8000::4") ptr4 = PTR.objects.filter( ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6')[0] self.assertEqual(ptr4.reverse_domain, rd0)
def migrate_PTR(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('PTR'): fqdn = rdata.target.to_text().strip('.') if fqdn.find('unused') != -1: print "Skipping " + name.to_text() + " " + fqdn continue # 4.3.2.1.IN-ADDR.ARPA. --> 1.2.3.4 name = name.to_text().lower().strip('.') if name.endswith('.in-addr.arpa'): ip_type = '4' ip_str = name.replace('.in-addr.arpa', '') ip_str = '.'.join(list(reversed(ip_str.split('.')))) ip_upper, ip_lower = 0, ipaddr.IPv4Address(ip_str) elif name.endswith('.ip6.arpa'): ip_type = '6' ip_str = name.replace('.ip6.arpa', '') chunks = [ ''.join(ip_str.split('.')[i:i + 4]) for i in xrange(0, len(ip_str.split('.')), 4) ] ip_str = ':'.join(chunks)[::-1] ip_upper, ip_lower = ipv6_to_longs(ip_str) else: print "We so f****d. Lol" pdb.set_trace() continue if ip_str == '10.2.171.IN': print "Skipping " + ip_str + " " + fqdn continue print str(name) + " PTR " + str(fqdn) ptr = PTR.objects.filter(name=fqdn, ip_upper=ip_upper, ip_lower=ip_lower, ip_type=ip_type) if ptr: ptr = ptr[0] else: ptr = PTR(name=fqdn, ip_str=ip_str, ip_type=ip_type, description=rdata.comment) ptr.full_clean() ptr.save() if views: for view in views: ptr.views.add(view) ptr.save()
def migrate_PTR(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('PTR'): fqdn = rdata.target.to_text().strip('.') if fqdn.find('unused') != -1: print "Skipping "+name.to_text()+" "+fqdn continue # 4.3.2.1.IN-ADDR.ARPA. --> 1.2.3.4 name = name.to_text().lower().strip('.') if name.endswith('.in-addr.arpa'): ip_type = '4' ip_str = name.replace('.in-addr.arpa','') ip_str = '.'.join(list(reversed(ip_str.split('.')))) ip_upper, ip_lower = 0, ipaddr.IPv4Address(ip_str) elif name.endswith('.ip6.arpa'): ip_type = '6' ip_str = name.replace('.ip6.arpa','') chunks = [''.join(ip_str.split('.')[i:i+4]) for i in xrange(0, len(ip_str.split('.')), 4)] ip_str = ':'.join(chunks)[::-1] ip_upper, ip_lower = ipv6_to_longs(ip_str) else: print "We so f****d. Lol" pdb.set_trace() continue if ip_str == '10.2.171.IN': print "Skipping "+ip_str+" "+fqdn continue print str(name) + " PTR " + str(fqdn) ptr = PTR.objects.filter(name=fqdn, ip_upper=ip_upper, ip_lower=ip_lower, ip_type=ip_type) if ptr: ptr = ptr[0] else: ptr = PTR( name=fqdn, ip_str=ip_str, ip_type=ip_type, description=rdata.comment ) ptr.full_clean() ptr.save() if views: for view in views: ptr.views.add(view) ptr.save()
def redirect_to_range_from_ip(request): ip_str = request.GET.get('ip_str') ip_type = request.GET.get('ip_type') if not (ip_str and ip_type): return HttpResponse(json.dumps({'failure': "Slob"})) if ip_type == '4': try: ip_upper, ip_lower = 0, int(ipaddr.IPv4Address(ip_str)) except ipaddr.AddressValueError: return HttpResponse( json.dumps({ 'success': False, 'message': "Failure to " "recognize{0} as an IPv4 " "Address.".format(ip_str) })) else: try: ip_upper, ip_lower = ipv6_to_longs(ip_str) except ValidationError: return HttpResponse( json.dumps({ 'success': False, 'message': 'Invalid IP' })) range_ = Range.objects.filter(start_upper__lte=ip_upper, start_lower__lte=ip_lower, end_upper__gte=ip_upper, end_lower__gte=ip_lower) if not len(range_) == 1: return HttpResponse(json.dumps({'failure': "Failture to find range"})) else: return HttpResponse( json.dumps({ 'success': True, 'redirect_url': range_[0].get_absolute_url() }))
def clean(self): self.update_network() # Look at all ranges that claim to be in this subnet, are they actually # in the subnet? for range_ in self.range_set.all(): """ I was writing checks to make sure that subnets wouldn't orphan ranges. IPv6 needs support. """ fail = False # Check the start addresses. if range_.start_upper < self.ip_upper: fail = True elif (range_.start_upper > self.ip_upper and range_.start_lower < self.ip_lower): fail = True elif (range_.start_upper == self.ip_upper and range_.start_lower < self.ip_lower): fail = True if self.ip_type == '4': brdcst_upper, brdcst_lower = 0, int(self.network.broadcast) else: brdcst_upper, brdcst_lower = ipv6_to_longs(str( self.network.broadcast)) # Check the end addresses. if range_.end_upper > brdcst_upper: fail = True elif (range_.end_upper < brdcst_upper and range_.end_lower > brdcst_lower): fail = True elif (range_.end_upper == brdcst_upper and range_.end_lower > brdcst_lower): fail = True if fail: raise ValidationError("Resizing this subnet to the requested " "network prefix would orphan existing " "ranges.")
def migrate_AAAA(zone, root_domain, soa, views): for (name, ttl, rdata) in zone.iterate_rdatas('AAAA'): name = name.to_text().strip('.') print str(name) + " AAAA " + str(rdata) exists_domain = Domain.objects.filter(name=name) if exists_domain: label = '' domain = exists_domain[0] else: label = name.split('.')[0] if label.startswith('unused'): continue domain_name = '.'.join(name.split('.')[1:]) domain = ensure_domain(domain_name, force=True) ip_upper, ip_lower = ipv6_to_longs(rdata.to_text()) if AddressRecord.objects.filter(label=label, domain=domain, ip_upper=ip_upper, ip_lower=ip_lower, ip_type='6').exists(): a = AddressRecord.objects.get(label=label, domain=domain, ip_type='6', ip_upper=ip_upper, ip_lower=ip_lower) else: a = AddressRecord(label=label, domain=domain, ip_str=rdata.to_text(), ip_type='6', description=rdata.comment, ttl=ttl) a.clean() a.save() for view in views: a.views.add(view) a.save()
def test_ipv6_to_longs(self): ip = ipaddr.IPv6Address('2001:0db8:85a3:0000:0000:8a2e:0370:733') ret = ipv6_to_longs(ip.__str__()) self.assertEqual(ret, (2306139570357600256, 151930230802227))
def test1_ipv6_to_longs(self): ip_str = "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF" ip_upper, ip_lower = ipv6_to_longs(ip_str) self.assertEqual(hex(ip_upper).lower(), "0xffffffffffffffffl") self.assertEqual(hex(ip_lower).lower(), "0xffffffffffffffffl")
def test_ipv6_to_longs(self): ip = ipaddr.IPv6Address("2001:0db8:85a3:0000:0000:8a2e:0370:733") ret = ipv6_to_longs(ip.__str__()) self.assertEqual(ret, (2306139570357600256, 151930230802227))
def search_ip(request): if request.method == "POST": form = IpSearchForm(request.POST) try: if form.is_valid(): ip_type = form.cleaned_data['ip_type'] search_ip = form.cleaned_data['search_ip'] try: if ip_type == '4': network = ipaddr.IPv4Network(search_ip) if ip_type == '6': network = ipaddr.IPv6Network(search_ip) except ipaddr.AddressValueError, e: form._errors['__all__'] = ErrorList( ["Bad IPv{0} Address {1}".format(ip_type, search_ip)]) return render(request, 'core/core_form.html', { 'form': form }) try: network = Network.objects.get(network_str=search_ip) search_ip = network found_exact = True except ObjectDoesNotExist: found_exact = False network = Network(ip_type, network_str=search_ip, ip_type=ip_type) parent = calc_parent(network) eldars, sub_networks = calc_networks(network) if ip_type == '6': sip_upper, sip_lower = ipv6_to_longs(network.network.ip) eip_upper, eip_lower = ipv6_to_longs( network.network.broadcast) else: sip_upper, sip_lower = 0, int(network.network.ip) eip_upper, eip_lower = 0, int(network.network.broadcast) addrs_count = AddressRecord.objects.filter( ip_upper__gte=sip_upper, ip_lower__gte=sip_lower, ip_upper__lte=eip_upper, ip_lower__lte=eip_lower).count() if addrs_count > 100: addrs = None # This is too much else: addrs = AddressRecord.objects.filter( ip_upper__gte=sip_upper, ip_lower__gte=sip_lower, ip_upper__lte=eip_upper, ip_lower__lte=eip_lower) ptrs_count = PTR.objects.filter( ip_upper__gte=sip_upper, ip_lower__gte=sip_lower, ip_upper__lte=eip_upper, ip_lower__lte=eip_lower).count() if ptrs_count > 100: ptrs = None # This is too much else: ptrs = PTR.objects.filter( ip_upper__gte=sip_upper, ip_lower__gte=sip_lower, ip_upper__lte=eip_upper, ip_lower__lte=eip_lower) return render(request, 'core/core_results.html', { 'search_ip': search_ip, 'found_exact': found_exact, 'addrs': addrs, 'addrs_count': addrs_count, 'ptrs_count': ptrs_count, 'ptrs': ptrs, 'parent': parent, 'eldars': eldars, 'sub_networks': sub_networks, }) except ValidationError, e: form._errors['__all__'] = ErrorList(e.messages) return render(request, 'core/core_form.html', { 'form': form })
def create_ipv4_interface(label, vlan_str, site_str, system, mac, domain_suffix, network_str=None): """This is an api for creating an interface. :param label: The label of the interface. :type lavel: str :param vlan_str: The name of the vlan the interface should be put into. :type vlan_str: str :param site_str: The Datacenter (and possibly the Buisness Unit) the vlan is in. :type site_str: str :param system: The system the interface belongs to. :type system: :class:`System` :param mac: The mac address of the new interface. :type mac: str :param domain_suffix: The suffix of the domain. This is usually 'mozilla.com'. :type domain_suffix: str :param network_str: This is an optional paramter. If you get a :class:`MultipleObjectsReturned` error when trying to find a network, you can specify which network to use by passing the network's name using this kwarg. E.g. ``network="10.22.9.0/24"`` :type network_str: str This function returns two values. The first value is the :class:`StaticInterface` instance. If the interface was succesfully created the second return value is meaningless. If there were errors while creating the interface the first value is None and the second return value is an ErrorDict containing errors that should be displayed to the user. Always check the first return value for being a NoneType. Using this function requires that certain objects exist in the database. *Understanding these objects before using this function is a good thing*. :: <label> (.<BU>) .<DC> . <domain_suffix> 1. This function starts by looking for a site in the site table that has a site path (i.e. `<BU>.<DC>` like 'relenge.scl3' or just 'scl3') equal to the 'site_str' paramter. If you get errors from this step (i.e. There is a 'site' key in the errors dictionary), create the site you are trying to use in the Web UI. 2. The function then looks in the site found in Step 1 for a :class:`Vlan` instance with a name equal to the 'vlan_str' parameter. If you get errors from this step (i.e. There is a 'vlan' key in the errors dictionary), create the vlan you are trying to use in the Web UI. 3. Using the :class:`Site` and :class:`Vlan` instance found in Step 1 & 2 and the `domain_suffix` paramter, the function constructs the following string.:: <vlan>.<site>.<domain_suffix> As an example, imaging we were using:: site = relenge.scl3 vlan = db domain_suffix = mozilla.com The constructed string would be:: db.relenge.scl3.mozilla.com The function will now use this constructed string as the domain name for creating the interface's A/PTR records. For this reason *a domain with the constructed name _must_ be in the database*. If you get errors from this step (i.e. There is a 'domain' key in the errors dictionary), create the domain you are trying to use in the Web UI. 4. The function then looks at the networks associated with that vlan found in Step 2 and chooses the networks that are associated to the site found in Step 1. If you get errors from this step (i.e. There is a 'network' key in the errors dictionary), create the network you are trying to use in the Web UI and associate it with the vlan *and* site you are trying to use. 5. The function then looks for ranges within the networks found in Step 4. If the function finds more than one range it does not make a choice for you and returns an error. If the function finds only one range it looks for a free IP in that range while returning an error if no free IP is found. 6. Using the 'label', 'system', 'mac', and IP address found in Step 4, a new StaticInterface is created. If there are errors while creating the Interface those errors are returned. If there are no errors while creating the Interface the Interface is returned. """ errors = ErrorDict() if not label: errors['label'] = ErrorList(["Please supply a label."]) return None, errors if not system: errors['system'] = ErrorList( "Please supply a system.".format(site_str)) return None, errors site = None for s in Site.objects.all(): if '.'.join(s.get_site_path().split('.')) == site_str: site = s break if not site: errors['site'] = ErrorList( ["Site {0} does not exist".format(site_str)]) return None, errors try: vlan = Vlan.objects.get(name=vlan_str) except ObjectDoesNotExist: errors['vlan'] = ErrorList(["Vlan {0} does not exist.".format( vlan_str)]) return None, errors tmp_site_str = '.'.join(s.get_site_path().split('.')) domain_name = vlan.name + "." + tmp_site_str + "." + domain_suffix try: domain = Domain.objects.get(name=domain_name) except ObjectDoesNotExist: errors['domain'] = ErrorList(["Could not find domain " "{0}".format(domain_name)]) return None, errors if not network_str: try: network = vlan.network_set.get(site=site) except MultipleObjectsReturned: networks = vlan.network_set.filter(site=site) errors['network'] = ErrorList(["There were too many networks " "associated with vlan {0} in {1}. " "Manually specify which network " "to use. Your choces are " "{2}".format(vlan, site, ", ".join([n.network_str for n in networks]))]) return None, errors except ObjectDoesNotExist: errors['network'] = "No network for vlan {0} in {1}.".format( vlan, site) return None, errors else: try: # Guess which type of network it is. try: if network_str.find(':') > -1: ip_type = '6' tmp_network = ipaddr.IPv6Network(network_str) ip_upper, ip_lower = ipv6_to_longs(network_str) else: ip_type = '4' tmp_network = ipaddr.IPv4Network(network_str) ip_upper, ip_lower = 0, int(tmp_network) except ipaddr.AddressValueError: errors['network'] = ErrorList(["The network {0} is not a " "valid IPv{1} network.". format(network_str, ip_type)]) return None, errors # Now try to find a network that matches the query. Error out if we # can't find one and recommend the user create it. network = Network.objects.get(ip_type=ip_type, ip_upper=ip_upper, ip_lower=ip_lower, prefixlen=tmp_network.prefixlen) except ObjectDoesNotExist: errors['network'] = ErrorList(["The network {0} was not found. " "Consider creating it in the web " "UI.".format(network_str)]) return None, errors if not network.range_set.all().exists(): errors['range'] = ErrorList(["No range for network {0} in vlan {1} in " "site {0}. Create it via the web UI too " "many networks associated with vlan " "{0} in {1}".format(network, vlan, site)]) return None, errors if network.range_set.all().count() > 1: errors['ip'] = ErrorList(["Too many ranges. In the face of ambiguity, " "*this script* has refused the temptation to" " guess which range you want to put the " "interface in."]) return None, errors range_ = network.range_set.all()[0] return _create_ipv4_intr_from_range(label, domain.name, system, mac, range_.start_lower, range_.end_lower)