def test_look_for_cnames_ptrs(self): name = "sucks1" a_dom,_ = Domain.objects.get_or_create( name = name, delegated=False ) a_dom.save() name = "adsfme1" c_dom,_ = Domain.objects.get_or_create( name = name, delegated=False ) c_dom.save() cn, _ = CNAME.objects.get_or_create(domain=c_dom, label="nddo", data="really.teebow.sucks1") cn.full_clean() cn.save() ptr = PTR(ip_str="128.193.2.1", name="seriously.teebow.sucks1", ip_type='4') ptr.full_clean() ptr.save() name = "teebow.sucks1" b_dom,_ = Domain.objects.get_or_create( name = name, delegated=False ) b_dom.save() cn = CNAME.objects.get(pk=cn.pk) ptr = PTR.objects.get(pk=ptr.pk) self.assertTrue( cn.data_domain == b_dom ) self.assertTrue( ptr.data_domain == b_dom )
def test_integration5_ip(self): root_domain = create_fake_zone("wee5.wee.mozilla.com", "") create_fake_zone("10.in-addr.arpa", "") res, error = self.search("10.in-addr.arpa OR " "wee5.wee.mozilla.com") self.assertFalse(error) self.assertEqual(len(res['SOA']), 2) self.assertEqual(len(res['NS']), 2) self.assertEqual(len(res['DOMAIN']), 2) ptr = PTR(name="host1.wee2.wee.mozilla.com", ip_str="10.0.0.1", ip_type="4") ptr.save() addr = AddressRecord(label="host1", domain=root_domain, ip_str="10.0.0.1", ip_type="4") addr.save() res, error = self.search(ptr.ip_str) self.assertFalse(error) self.assertEqual(len(res['PTR']), 1) self.assertEqual(len(res['A']), 1) res, error = self.search("10.0.0.2") self.assertFalse(error) self.assertEqual(len(res['PTR']), 0) self.assertEqual(len(res['A']), 0)
def do_generic_add(self, ip_str, fqdn, ip_type, domain=None): ret = PTR(name=fqdn, ip_str=ip_str, ip_type=ip_type) ret.full_clean() ret.save() self.assertTrue(ret.details()) self.assertTrue(ret.get_detail_url()) self.assertTrue(ret.get_update_url()) self.assertTrue(ret.get_delete_url()) ip = Ip(ip_str=ip_str, ip_type=ip_type) ip.clean_ip() ptr = PTR.objects.filter(name=fqdn, ip_upper=ip.ip_upper, ip_lower=ip.ip_lower) ptr.__repr__() self.assertTrue(ptr) ip_str = ip_str.lower() self.assertEqual(ptr[0].ip_str, ip_str) if domain: if ptr[0].name == "": self.assertEqual(fqdn, domain.name) else: self.assertEqual(fqdn, ptr[0].name + "." + domain.name) else: self.assertEqual(fqdn, ptr[0].name) return ret
def test_bad_nameserver_soa_state_case_3_2(self): # This is Case 3 ... with ptrs root_domain = create_fake_zone("32.in-addr.arpa", suffix="") for ns in root_domain.nameserver_set.all(): ns.delete() soa = ns.domain.soa ns.domain.soa = None root_domain.soa = None # Shit's getting cached ns.domain.save() soa.delete() # At his point we should have a domain pointed at no SOA record with no # records attached to it. It also has no child domains. # Add a record to the domain. ptr = PTR(name="asdf", ip_str="32.1.1.1", ip_type="4") ptr.save() s = SOA(primary="asdf.asdf", contact="asdf.asdf", description="asdf") s.save() root_domain.soa = s self.assertRaises(ValidationError, root_domain.save)
def gen_domain( self, domain, dname, records, rdomain ): if domain == 0 or dname == "root": print "Root domain, skipping" return else: print "Generating %s" % (dname) #if not re.search( "^10" ,self.ip_from_domainname(dname) ): # return self.gen_NS( domain, dname, rdomain ) records_to_remove = [] search_string = "^"+self.ip_from_domainname(dname).replace('.','\.')+"\." for record in records: longip, name = record ip = long2ip(longip) # TODO compile this if re.search( search_string, ip ): #self.printer.print_PTR( ip, name ) possible = PTR.objects.filter( ip_str = ip, name=name, ip_type='4' ) if possible: ptr = possible[0] else: ptr = PTR( ip_str = ip, name=name, ip_type='4' ) ptr.full_clean() ptr.save() records_to_remove.append( record ) for record in records_to_remove: records.remove(record) self.gen_ORIGIN( domain, dname, 999 )
def test_private_view_case_1_ptr(self): ptr = PTR(name="asf", ip_str="10.0.0.1", ip_type="4") ptr.clean() ptr.save() # Object has to exist before views can be assigned. ptr.views.add(self.private) ptr.save()
def test_dirty_ptr(self): self.rsoa.dirty = False self.rdom.dirty = False c = PTR(name="asfd", ip_str="123.123.123.123", ip_type="4") c.full_clean() c.save() self.rdom = ReverseDomain.objects.get(pk=self.rdom.pk) self.assertTrue(self.rdom.dirty) self.assertFalse(self.rsoa.dirty)
def do_generic_remove(self, ip, fqdn, ip_type): ptr = PTR(ip_str=ip, name=fqdn, ip_type=ip_type) ptr.full_clean() ptr.save() ptr.delete() ip = Ip(ip_str=ip, ip_type=ip_type) ip.clean_ip() ptr = PTR.objects.filter(name=fqdn, ip_upper=ip.ip_upper, ip_lower=ip.ip_lower) self.assertFalse(ptr)
def test_ptr_exists(self): label = "testyfoo" data = "wat" dom, _ = Domain.objects.get_or_create(name="cd") dom, _ = Domain.objects.get_or_create(name="what.cd") rec = PTR(ip_str="10.193.1.1", ip_type='4', name='testyfoo.what.cd') rec.full_clean() rec.save() cn = CNAME(label=label, domain=dom, target=data) self.assertRaises(ValidationError, cn.full_clean)
def test_bad_nameserver_soa_state_case_2_2(self): # This is Case 2 ... with ptrs root_domain = create_fake_zone("22.in-addr.arpa", suffix="") self.assertEqual(root_domain.nameserver_set.count(), 1) ns = root_domain.nameserver_set.all()[0] # At his point we should have a domain at the root of a zone with one # ns record associated to the domain. ptr = PTR(name="asdf", ip_str="22.1.1.1", ip_type="4") ptr.save() self.assertRaises(ValidationError, ns.delete)
def gen_AR(self): """ Generates the Address Record and PTR objects related to this zone's domain. .. note:: Some AddressRecords may need to be added to the pointer table in MAINTAIN for successful migration, for example, cob-dc81 and cob-dc82.bus.oregonstate.edu .. note:: AddressRecords/PTRs with the same ip as a StaticInterface can't coexist, so if a StaticInterface with the same ip exists, it has priority. :AddressRecord uniqueness: label, domain, ip_str, ip_type :PTR uniqueness: name, ip_str, ip_type """ name = self.domain.name cursor.execute("SELECT ip, hostname, type, enabled " "FROM pointer " "WHERE hostname LIKE '%%.%s';" % name) for ip, hostname, ptr_type, enabled in cursor.fetchall(): hostname = hostname.lower() label, dname = hostname.split(".", 1) if dname != name: continue if StaticInterface.objects.filter(ip_str=long2ip(ip)).exists(): continue if ptr_type == "forward": arec, _ = AddressRecord.objects.get_or_create( label=label, domain=self.domain, ip_str=long2ip(ip), ip_type="4" ) if enabled: arec.views.add(public) elif ptr_type == "reverse": if not PTR.objects.filter(name=name, ip_str=long2ip(ip)).exists(): ptr = PTR(name=name, ip_str=long2ip(ip), ip_type="4") # PTRs need to be cleaned independently of saving # (no get_or_create) ptr.full_clean() ptr.save() if enabled: ptr.views.add(public)
def test2_bad_add_for_a_ptr(self): # PTR and A exist, then try add intr mac = "11:22:33:44:55:66" label = "9988fdfood" domain = self.c ip_str = "10.0.0.1" kwargs = {'mac': mac, 'label': label, 'domain': domain, 'ip_str': ip_str} ip_type = '4' a = AddressRecord(label=label, domain=domain, ip_str=ip_str, ip_type=ip_type) a.clean() a.save() ptr = PTR(ip_str=ip_str, ip_type=ip_type, name=a.fqdn) ptr.clean() ptr.save() self.assertRaises(ValidationError, self.do_add, **kwargs)
def test_remove_domain_with_child_objects(self): """Removing a domain should remove CNAMES and PTR records that have data in that domain.""" name = "sucks" a_dom, _ = Domain.objects.get_or_create(name=name, delegated=False) a_dom.save() name = "teebow.sucks" b_dom, _ = Domain.objects.get_or_create(name=name, delegated=False) b_dom.save() name = "adsfme" c_dom, _ = Domain.objects.get_or_create(name=name, delegated=False) c_dom.save() cn, _ = CNAME.objects.get_or_create(domain=c_dom, label="nddo", target="really.teebow.sucks") cn.full_clean() cn.save() ptr = PTR( ip_str="128.193.2.1", name="seriously.teebow.sucks", ip_type='4') ptr.full_clean() ptr.save() self.assertTrue(cn.target_domain == b_dom) self.assertTrue(ptr.data_domain == b_dom) b_dom, _ = Domain.objects.get_or_create( name="teebow.sucks", delegated=False) b_dom.delete() try: cn = CNAME.objects.get(pk=cn.pk) except: self.fail("CNAME was deleted.") self.assertTrue(cn.target_domain == a_dom) try: ptr = PTR.objects.get(pk=ptr.pk) except: self.fail("PTR was deleted") self.assertTrue(ptr.data_domain == a_dom)
def test_bad_nameserver_soa_state_case_2_3(self): # This is Case 2 ... with ptrs root_domain = create_fake_zone("10.23.in-addr.arpa", suffix="") self.assertEqual(root_domain.nameserver_set.count(), 1) ns = root_domain.nameserver_set.all()[0] # At his point we should have a domain at the root of a zone with one # ns record associated to the domain. # Let's create a child domain and add a record there, then try to # delete the NS record cdomain = Domain(name="test." + root_domain.name) cdomain.soa = root_domain.soa cdomain.save() ptr = PTR(name="asdf", ip_str="23.10.1.1", ip_type="4") ptr.save() self.assertRaises(ValidationError, ns.delete)
def test_integration2(self): root_domain = create_fake_zone("wee2.wee.mozilla.com", "") res, error = self.search("wee2.wee.mozilla.com") self.assertFalse(error) self.assertEqual(len(res['SOA']), 1) self.assertEqual(len(res['NS']), 1) self.assertEqual(len(res['DOMAIN']), 1) create_fake_zone("1.1.ip6.arpa", "") res, error = self.search("1.1.ip6.arpa") self.assertFalse(error) self.assertEqual(len(res['SOA']), 1) self.assertEqual(len(res['NS']), 1) self.assertEqual(len(res['DOMAIN']), 1) ptr = PTR(name="host1.wee2.wee.mozilla.com", ip_str="1111::", ip_type="6") ptr.save() addr = AddressRecord(label="host1", domain=root_domain, ip_str="11::", ip_type="6") addr.save() res, error = self.search("host1.wee2.wee.mozilla.com") self.assertFalse(error) self.assertEqual(len(res['A']), 1) self.assertEqual(len(res['PTR']), 1) res, error = self.search("host1.wee2.wee.mozilla.com type=:A") self.assertFalse(error) self.assertEqual(len(res['A']), 1) self.assertEqual(len(res['PTR']), 0) res, error = self.search("host1.wee2.wee.mozilla.com type=:PTR") self.assertFalse(error) self.assertEqual(len(res['A']), 0) self.assertEqual(len(res['PTR']), 1) res, error = self.search("host1.wee2.wee.mozilla.com type=:A " "type=:PTR") self.assertFalse(error) self.assertEqual(len(res['A']), 0) self.assertEqual(len(res['PTR']), 0)
def test_bad_nameserver_soa_state_case_3_3(self): # This is Case 3 ... with ptrs root_domain = create_fake_zone("33.in-addr.arpa", suffix="") for ns in root_domain.nameserver_set.all(): ns.delete() # At his point we should have a domain pointed at an SOA record with no # records attached to it (esspecially no ns recods). It also has no # child domains. # Try case 3 but add a record to a child domain of root_domain cdomain = Domain(name="10.33.in-addr.arpa") cdomain.save() # Add a record to the domain. ptr = PTR(name="asdf", ip_str="33.10.1.1", ip_type="4") ptr.save() # Now try to add the domain to the zone that has no NS records at it's # root cdomain.soa = root_domain.soa self.assertRaises(ValidationError, cdomain.save)
def test_integration4_ip_range(self): create_fake_zone("wee3.wee.mozilla.com", "") create_fake_zone("1.2.ip6.arpa", "") res, error = self.search("1.2.ip6.arpa") self.assertFalse(error) self.assertEqual(len(res['SOA']), 1) self.assertEqual(len(res['NS']), 1) self.assertEqual(len(res['DOMAIN']), 1) ptr = PTR(name="host1.wee2.wee.mozilla.com", ip_str="2111:0::", ip_type="6") ptr.save() res, error = self.search(ptr.ip_str) self.assertFalse(error) self.assertEqual(len(res['PTR']), 1) self.assertEqual(len(res['A']), 0) res, error = self.search("2111:0:0::") self.assertFalse(error) self.assertEqual(len(res['PTR']), 0) self.assertEqual(len(res['A']), 0)
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', '') elif name.endswith('.ipv6.arpa'): ip_type = '6' ip_str = name.replace('.ipv6.arpa', '') raise NotImplemented("Ipv6 migration isn't done yet.") else: print "We so f****d. Lol" pdb.set_trace() continue ip_str = '.'.join(list(reversed(ip_str.split('.')))) 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_str=ip_str, ip_type='4') if ptr: ptr = ptr[0] else: ptr = PTR(name=fqdn, ip_str=ip_str, ip_type='4') ptr.full_clean() ptr.save() if views: for view in views: ptr.views.add(view)
def test_private_view_case_2_ptr(self): ptr = PTR(name="asf", ip_str="10.0.0.2", ip_type="4") ptr.clean() ptr.save() # Object has to exist before views can be assigned. ptr.views.add(self.public) self.assertFalse(ptr.views.filter(name="public")) ptr = PTR(name="asf", ip_str="172.16.0.1", ip_type="4") ptr.clean() ptr.save() # Object has to exist before views can be assigned. ptr.views.add(self.public) self.assertFalse(ptr.views.filter(name="public")) ptr = PTR(name="asf", ip_str="192.168.2.3", ip_type="4") ptr.clean() ptr.save() # Object has to exist before views can be assigned. ptr.views.add(self.public) self.assertFalse(ptr.views.filter(name="public"))
r, _ = ReverseDomain.objects.get_or_create(name='128.193') r.soa = s r.save() # ReverseNameserver rns, _ = ReverseNameserver.objects.get_or_create( reverse_domain= r, server = random_label()+"."+random_label()+"."+random_label() ) r1, _ = ReverseDomain.objects.get_or_create(name='128.193.15') r1.soa = s1 r1.save() # ReverseNameserver rns, _ = ReverseNameserver.objects.get_or_create( reverse_domain= r1, server = random_label()+"."+random_label()+"."+random_label() ) for i in range(0, 100): try: ptr= PTR( name = random_label(), ip_str= random_ipv4('128.193'), ip_type = '4') except: continue ptr.full_clean() ptr.save() for i in range(0, 100): try: ptr = PTR( name = random_label(), ip_str= random_ipv4('128.193.15'), ip_type = '4') except: continue ptr.full_clean() ptr.save()
def populate_reverse_dns(rev_svn_zones): arpa = create_domain(name='arpa') i_arpa = create_domain(name='in-addr.arpa') i6_arpa = create_domain(name='ipv6.arpa') for site, data in rev_svn_zones.iteritems(): site_path, more_data = data zone, records = more_data print "-" * 15 + " " + site for (name, ttl, rdata) in zone.iterate_rdatas('SOA'): print str(name) + " SOA " + str(rdata) exists = SOA.objects.filter(minimum=rdata.minimum, contact=rdata.rname.to_text( ).strip('.'), primary=rdata.mname.to_text( ).strip('.'), comment="SOA for {0}.in-addr.arpa".format(site)) if exists: soa = exists[0] else: soa = SOA(serial=rdata.serial, minimum=rdata.minimum, contact=rdata.rname.to_text().strip('.'), primary=rdata.mname.to_text().strip('.'), comment="SOA for {0}.in-addr.arpa".format(site)) soa.clean() soa.save() name = name.to_text().replace('.IN-ADDR.ARPA.', '') domain_split = list(reversed(name.split('.'))) for i in range(len(domain_split)): domain_name = domain_split[:i + 1] rev_name = ip_to_domain_name( '.'.join(domain_name), ip_type='4') base_domain, created = Domain.objects.get_or_create( name=rev_name) base_domain.soa = soa base_domain.save() for (name, ttl, rdata) in zone.iterate_rdatas('NS'): name = name.to_text().strip('.') name = name.replace('.IN-ADDR.ARPA', '') name = name.replace('.in-addr.arpa', '') print str(name) + " NS " + str(rdata) domain_name = '.'.join(list(reversed(name.split('.')))) domain = ensure_rev_domain(domain_name) ns, _ = Nameserver.objects.get_or_create(domain=domain, server=rdata.target.to_text().strip('.')) for (name, ttl, rdata) in zone.iterate_rdatas('PTR'): ip_str = name.to_text().strip('.') ip_str = ip_str.replace('.IN-ADDR.ARPA', '') ip_str = ip_str.replace('.in-addr.arpa', '') ip_str = '.'.join(list(reversed(ip_str.split('.')))) fqdn = rdata.target.to_text().strip('.') if fqdn.startswith('unused'): print "Skipping " + ip_str + " " + fqdn continue if ip_str == '10.2.171.IN': log("Skipping 10.2.171.IN", WARNING) continue print str(name) + " PTR " + str(fqdn) ptr = PTR.objects.filter(name=fqdn, ip_str=ip_str, ip_type='4') if ptr: continue else: ptr = PTR(name=fqdn, ip_str=ip_str, ip_type='4') ptr.full_clean() ptr.save() """
def add_ptr_ipv6(self, ip): ptr = PTR(name = random_label(), ip_str = ip, ip_type='6') ptr.full_clean() ptr.save() return ptr
def add_ptr_ipv4(self, ip): ptr = PTR(name=random_label(), ip_str=ip, ip_type='4') ptr.full_clean() ptr.save() return ptr
def populate_reverse_dns(rev_svn_zones, views=None): arpa = create_domain(name='arpa') i_arpa = create_domain(name='in-addr.arpa') i6_arpa = create_domain(name='ipv6.arpa') for site, data in rev_svn_zones.iteritems(): site_path, more_data = data zone, records = more_data print "-" * 15 + " " + site for (name, ttl, rdata) in zone.iterate_rdatas('SOA'): print str(name) + " SOA " + str(rdata) exists = SOA.objects.filter(minimum=rdata.minimum, contact=rdata.rname.to_text( ).strip('.'), primary=rdata.mname.to_text( ).strip('.'), comment="SOA for {0}.in-addr.arpa".format( '.'.join(reversed(site.split('.'))))) if exists: soa = exists[0] else: soa = SOA(serial=rdata.serial, minimum=rdata.minimum, contact=rdata.rname.to_text().strip('.'), primary=rdata.mname.to_text().strip('.'), comment="SOA for {0}.in-addr.arpa".format( '.'.join(reversed(site.split('.'))))) soa.clean() soa.save() name = name.to_text().replace('.IN-ADDR.ARPA.', '') domain_split = list(reversed(name.split('.'))) for i in range(len(domain_split)): domain_name = domain_split[:i + 1] rev_name = ip_to_domain_name( '.'.join(domain_name), ip_type='4') base_domain, created = Domain.objects.get_or_create( name=rev_name) #null_all_soas(base_domain) base_domain.soa = soa base_domain.save() #set_all_soas(base_domain, soa) for (name, ttl, rdata) in zone.iterate_rdatas('NS'): name = name.to_text().strip('.') name = name.replace('.IN-ADDR.ARPA', '') name = name.replace('.in-addr.arpa', '') print str(name) + " NS " + str(rdata) domain_name = '.'.join(list(reversed(name.split('.')))) domain = ensure_rev_domain(domain_name) ns, _ = Nameserver.objects.get_or_create(domain=domain, server=rdata.target.to_text().strip('.')) if views: for view in views: ns.views.add(view) ns.save() for (name, ttl, rdata) in zone.iterate_rdatas('PTR'): ip_str = name.to_text().strip('.') ip_str = ip_str.replace('.IN-ADDR.ARPA', '') ip_str = ip_str.replace('.in-addr.arpa', '') ip_str = '.'.join(list(reversed(ip_str.split('.')))) fqdn = rdata.target.to_text().strip('.') if fqdn.startswith('unused'): print "Skipping " + ip_str + " " + fqdn continue if ip_str == '10.2.171.IN': log("Skipping 10.2.171.IN", WARNING) continue print str(name) + " PTR " + str(fqdn) ptr = PTR.objects.filter(name=fqdn, ip_str=ip_str, ip_type='4') if ptr: ptr = ptr[0] else: try: ptr = PTR(name=fqdn, ip_str=ip_str, ip_type='4') ptr.full_clean() ptr.save() if views: for view in views: ptr.views.add(view) ptr.save() except Exception, e: pdb.set_trace() if views: for view in views: ptr.views.add(view)
def gen_AR(self): """ Generates the Address Record and PTR objects related to this zone's domain. .. note:: Some AddressRecords may need to be added to the pointer table in MAINTAIN for successful migration, for example, cob-dc81 and cob-dc82.bus.oregonstate.edu .. note:: AddressRecords/PTRs with the same ip as a StaticInterface can't coexist, so if a StaticInterface with the same ip exists, it has priority. :AddressRecord uniqueness: label, domain, ip_str, ip_type :PTR uniqueness: name, ip_str, ip_type """ name = self.domain.name cursor.execute("SELECT ip, hostname, type, zone.name, enabled " "FROM pointer JOIN zone ON pointer.zone = zone.id " "WHERE hostname LIKE '%%.%s';" % name) for ip, hostname, ptr_type, zone, enabled, in cursor.fetchall(): hostname = hostname.lower() label, dname = hostname.split('.', 1) if dname != name: continue dup_stats = StaticInterface.objects.filter(ip_str=long2ip(ip)) if dup_stats.exists(): if ptr_type == 'reverse': print "Ignoring PTR %s; Static intr exists." % long2ip(ip) continue elif dup_stats.filter(fqdn=hostname).exists(): print "Ignoring AR %s; Static intr exists." % hostname continue else: pass ctnr = self.ctnr_from_zone_name(zone, 'AR/PTR') if ctnr is None: continue if ptr_type == 'forward': if AddressRecord.objects.filter( fqdn=hostname, ip_str=long2ip(ip)).exists(): continue try: arec, _ = range_usage_get_create( AddressRecord, label=label, domain=self.domain, ip_str=long2ip(ip), ip_type='4', ctnr=ctnr) except ValidationError, e: print "Could not migrate AR %s: %s" % (hostname, e) continue if enabled: arec.views.add(public) arec.views.add(private) elif ptr_type == 'reverse': if not PTR.objects.filter(ip_str=long2ip(ip)).exists(): ptr = PTR(fqdn=hostname, ip_str=long2ip(ip), ip_type='4', ctnr=ctnr) # PTRs need to be cleaned independently of saving # (no get_or_create) try: ptr.full_clean() except ValidationError, e: print "Could not migrate PTR %s: %s" % (ptr.ip_str, e) continue ptr.save(update_range_usage=False) if enabled: ptr.views.add(public) ptr.views.add(private)
def do_add_ptr(self, label, domain, ip_str, ip_type='4'): ptr = PTR(name=label + '.' + domain.name, ip_str=ip_str, ip_type=ip_type) ptr.clean() ptr.save() return ptr
def test_private_view_case_3_ptr(self): ptr = PTR(name="asf3", ip_str="10.0.0.2", ip_type="4") ptr.clean() ptr.save() ptr.views.add(self.private) ptr.save() # Object has to exist before views can be assigned. ptr.views.add(self.public) self.assertFalse(ptr.views.filter(name="public")) ptr = PTR(name="asf3", ip_str="172.16.0.1", ip_type="4") ptr.clean() ptr.save() ptr.views.add(self.private) ptr.save() # Object has to exist before views can be assigned. ptr.views.add(self.public) self.assertFalse(ptr.views.filter(name="public")) ptr = PTR(name="asf3", ip_str="192.168.2.3", ip_type="4") ptr.clean() ptr.save() ptr.views.add(self.private) ptr.save() # Object has to exist before views can be assigned. ptr.views.add(self.public) self.assertFalse(ptr.views.filter(name="public"))