Ejemplo n.º 1
0
 def test_canonical_records_ipv6(self, zones):
     n = NodeAddr('vm00', 'fe', 'whq', ip.IPAddress('2a02:248:101:63::5b'))
     n.inject_records(zones)
     zones.add_addr.assert_any_call('vm00.fe.whq',
                                    ip.IPAddress('2a02:248:101:63::5b'))
     zones.add_addr.assert_any_call('vm00.fe.whq.ipv6',
                                    ip.IPAddress('2a02:248:101:63::5b'))
Ejemplo n.º 2
0
    def test_render_forward(self):
        config = configobj.ConfigObj(
            pkg_resources.resource_stream(__name__,
                                          'fixtures/configure-zones.cfg'))
        z = ForwardZone('gocept.net', parent_zones=Zones(config))
        z.add_a('vm00', ip.IPAddress('212.122.41.136'))
        z.add_a('vm00', ip.IPAddress('2a02:248:101:63::5b'))
        z.add_cname('vm00.srv.whq', 'vm00')
        self.maxDiff = 1024
        self.assertEqual(
            z.render(2014021900), """\
; generated by configure-zones
$TTL 86400
$ORIGIN gocept.net.
@               86400   IN      SOA ns1.gocept.net. hostmaster.fcio.net. (
                                        2014021900 ; serial
                                        10800 ; refresh
                                        900 ; retry
                                        2419200 ; expire
                                        1800 ; neg ttl
                                )
                                NS      ns1.gocept.net.
                                NS      ns2.gocept.net.
$TTL 7200
vm00                            A       212.122.41.136
vm00                            AAAA    2a02:248:101:63::5b
vm00.srv.whq                    CNAME   vm00
""")
Ejemplo n.º 3
0
 def test_canonical_records_ipv4(self, zones):
     n = NodeAddr('vm00', 'fe', 'whq', ip.IPAddress('195.62.120.10'))
     n.inject_records(zones)
     zones.add_addr.assert_any_call('vm00.fe.whq',
                                    ip.IPAddress('195.62.120.10'))
     zones.add_addr.assert_any_call('vm00.fe.whq.ipv4',
                                    ip.IPAddress('195.62.120.10'))
Ejemplo n.º 4
0
 def test_default_reverse(self, zones):
     n = NodeAddr('vm00',
                  'srv',
                  'whq',
                  ip.IPAddress('212.122.42.136'),
                  canonical=True)
     n.inject_records(zones)
     zones.add_reverse.assert_called_with(ip.IPAddress('212.122.42.136'),
                                          'vm00')
Ejemplo n.º 5
0
 def test_custom_reverse(self, zones):
     n = NodeAddr('vm00',
                  'fe',
                  'whq',
                  ip.IPAddress('195.62.125.10'),
                  reverse='www.example.com.')
     n.inject_records(zones)
     zones.add_reverse.assert_called_with(ip.IPAddress('195.62.125.10'),
                                          'www.example.com.')
Ejemplo n.º 6
0
 def test_add_addr_creates_public_records(self):
     self.z.add_addr('vm00', ip.IPAddress('195.62.125.33'), ['vm00.ipv4'])
     self.assertIn(RR.A('vm00', ip.IPAddress('195.62.125.33')),
                   self.z.external_forward.records)
     self.assertIn(RR.A('vm00', ip.IPAddress('195.62.125.33')),
                   self.z.internal_forward.records)
     self.assertIn(RR.CNAME('vm00.ipv4', 'vm00'),
                   self.z.external_forward.records)
     self.assertIn(RR.CNAME('vm00.ipv4', 'vm00'),
                   self.z.internal_forward.records)
Ejemplo n.º 7
0
 def test_short_and_canonical_for_srv_ipv4(self, zones):
     n = NodeAddr('vm00',
                  'srv',
                  'whq',
                  ip.IPAddress('212.122.41.136'),
                  canonical=True)
     n.inject_records(zones)
     zones.add_addr.assert_any_call('vm00', ip.IPAddress('212.122.41.136'),
                                    ['vm00.srv.whq'])
     zones.add_addr.assert_any_call('vm00.ipv4',
                                    ip.IPAddress('212.122.41.136'),
                                    ['vm00.srv.whq.ipv4'])
Ejemplo n.º 8
0
 def test_short_and_canonical_for_srv_ipv6(self, zones):
     n = NodeAddr('vm00',
                  'srv',
                  'whq',
                  ip.IPAddress('2a02:248:101:63::5b'),
                  canonical=True)
     n.inject_records(zones)
     zones.add_addr.assert_any_call('vm00',
                                    ip.IPAddress('2a02:248:101:63::5b'),
                                    ['vm00.srv.whq'])
     zones.add_addr.assert_any_call('vm00.ipv6',
                                    ip.IPAddress('2a02:248:101:63::5b'),
                                    ['vm00.srv.whq.ipv6'])
Ejemplo n.º 9
0
def walk(directory):
    for node in sorted(directory.list_nodes()):
        shortname = node['name']
        location = node['parameters']['location']
        production = node['parameters']['production']

        # Choose the VLAN for the canonical name: SRV is preferable, but some
        # devices only have MGMT and then we use that.
        canonical_vlan = None
        vlans = set(node['parameters']['interfaces'])
        for v in ['srv', 'mgm']:
            if v in vlans:
                canonical_vlan = v
                break

        # sort everything to keep stable ordering
        for vlan, params in sorted(node['parameters']['interfaces'].items()):
            for addresses in sorted(params['networks'].values()):
                for addr in sorted(addresses):
                    reverse = node['parameters']['reverses'].get(addr)
                    yield NodeAddr(shortname,
                                   vlan,
                                   location,
                                   ip.IPAddress(addr),
                                   production,
                                   reverse,
                                   canonical=(vlan == canonical_vlan))
Ejemplo n.º 10
0
 def test_add_ptr_strips_prefix(self):
     z = ReverseZone('1.0.1.0.8.4.2.0.2.0.a.2.ip6.arpa',
                     ip.IPNetwork('2a02:238:101::/48'))
     z.add_ptr(ip.IPAddress('2a02:248:101:63::5b'), 'vm00')
     self.assertEqual(
         RR.PTR('b.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.6.0.0', 'vm00'),
         z.records[0])
Ejemplo n.º 11
0
    def validate(self, value):
        """ ensure valid ip address """
        super(IPAddressField, self).validate(value)

        try:
            ip.IPAddress(value)
        except (ip.AddrFormatError, ValueError):
            raise ValidationError(_('Invalid ip address'))
Ejemplo n.º 12
0
 def test_save_returns_true_if_changed(self, now):
     now.return_value = datetime.datetime(2014, 2, 17, tzinfo=pytz.utc)
     with open(self.filename, 'w') as f:
         f.write(self.z.render(2014021703))
     self.z.records.append(RR.A('vm01', ip.IPAddress('192.168.1.1')))
     self.assertTrue(self.z.save())
     with open(self.filename) as f:
         self.assertEqual(f.read(), self.z.render(2014021704))
Ejemplo n.º 13
0
 def inject_records(self, zones):
     """Implement naming policy."""
     for index, variant in enumerate(self.variants):
         if self.canonical:
             # e.g., vm00.{ipv4.,ipv6.,}gocept.net
             # with alias vm00.srv.whq.{ipv4.,ipv6.,}gocept.net
             default_name = join_dn(self.name, variant)
             zones.add_addr(
                 default_name, self.addr,
                 [join_dn(self.name, self.vlan, self.loc, variant)])
         else:
             # e.g., vm00.fe.whq.{ipv4.,ipv6.,}gocept.net
             default_name = join_dn(self.name, self.vlan, self.loc, variant)
             zones.add_addr(default_name, ip.IPAddress(self.addr))
         if index == 0:
             # the first variant determines the reverse address
             zones.add_reverse(self.addr, self.reverse or default_name)
Ejemplo n.º 14
0
 def test_forward_ipv6(self):
     z = ForwardZone('gocept.net')
     z.add_a('vm00.srv.whq', ip.IPAddress('2a02:248:101:63::5b'))
     self.assertIn(
         RR.AAAA('vm00.srv.whq', ip.IPAddress('2a02:248:101:63::5b')),
         z.records)
Ejemplo n.º 15
0
 def test_add_pre_strips_correct_prefix_for_cidr_zones(self):
     z = ReverseZone('128-25.41.122.212.in-addr.arpa',
                     prefix=ip.IPNetwork('212.122.41.128/25'),
                     strip_suffix='41.122.212.in-addr.arpa')
     z.add_ptr(ip.IPAddress('212.122.41.152'), 'rt.gocept.com.')
     self.assertEqual(RR.PTR('152', 'rt.gocept.com.'), z.records[0])
Ejemplo n.º 16
0
 def import_interfaces(self):
     self.verbose('retrieving interfaces from old mysql DB...')
     self.old_interfaces = list(OldInterface.objects.all())
     self.message('retrieved %d interfaces' % len(self.old_interfaces))
     
     saved_interfaces = []
     saved_vaps = []
     saved_ipv4 = []
     saved_ipv6 = []
     
     for old_interface in self.old_interfaces:
         interface_dict = {
             "id": old_interface.id,
             "device_id": int(old_interface.device_id),
             "mac": old_interface.mac_address,
             "name": old_interface.cname[0:10],
             "added": old_interface.added,
             "updated": old_interface.updated,
             "data": {}
         }
         vap = None
         ipv4 = None
         ipv6 = None
         
         # determine interface type and specific fields
         if old_interface.type == 'eth':
             interface_dict['standard'] = 'fast'
             interface_dict['duplex'] = 'full'
             InterfaceModel = Ethernet
         elif old_interface.type == 'wifi':
             interface_dict['mode'] = old_interface.wireless_mode
             interface_dict['channel'] = old_interface.wireless_channel
             InterfaceModel = Wireless
             # determine ssid
             if old_interface.essid or old_interface.bssid:
                 vap = Vap(**{
                     "interface_id": old_interface.id,
                     "essid": old_interface.essid,
                     "bssid": old_interface.essid
                 })
             if old_interface.essid:
                 interface_dict['data']['essid'] = old_interface.essid
             if old_interface.bssid:
                 interface_dict['data']['bssid'] = old_interface.bssid
         elif old_interface.type == 'bridge':
             InterfaceModel = Bridge
         elif old_interface.type == 'vpn':
             InterfaceModel = Tunnel
         else:
             interface_dict['type'] = INTERFACE_TYPES.get('virtual')
             interface_dict['data']['old_nodeshot_interface_type'] = old_interface.get_type_display()
             InterfaceModel = Interface
         
         interface = InterfaceModel(**interface_dict)
         
         if old_interface.ipv4_address:
             old_interface.ipv4_address = old_interface.ipv4_address.strip()  # stupid django bug
             ipv4 = Ip(**{
                 "interface_id": old_interface.id,
                 "address": old_interface.ipv4_address
             })
             # ensure ipv4 is valid            
             try:
                 ip.IPAddress(old_interface.ipv4_address)
             except (ip.AddrFormatError, ValueError):
                 self.message('Invalid IPv4 address %s' % (old_interface.ipv4_address))
                 ipv4 = None
         
         if old_interface.ipv6_address:
             old_interface.ipv6_address = old_interface.ipv6_address.strip()  # stupid django bug
             ipv6 = Ip(**{
                 "interface_id": old_interface.id,
                 "address": old_interface.ipv6_address
             })
             # ensure ipv6 is valid            
             try:
                 ip.IPAddress(old_interface.ipv6_address)
             except (ip.AddrFormatError, ValueError):
                 self.message('Invalid IPv6 address %s' % (old_interface.ipv6_address))
                 ipv6 = None
         
         try:
             interface.full_clean()
             interface.save(auto_update=False)
             saved_interfaces.append(interface)
             self.verbose('Saved interface %s' % interface.name)
         except Exception as e:
             self.message('Could not save interface %s, got exception: %s' % (interface.mac, e))
             continue
         
         if vap:
             try:
                 vap.full_clean()
                 vap.save()
                 saved_vaps.append(vap)
                 self.verbose('Saved vap %s' % vap.essid or vap.bssid)
             except Exception as e:
                 self.message('Could not save vap %s, got exception: %s' % (vap.essid or vap.bssid, e))
         
         if ipv4:
             try:
                 ipv4.full_clean()
                 ipv4.save()
                 saved_ipv4.append(ipv4)
                 self.verbose('Saved ipv4 %s' % ipv4.address)
             except Exception as e:
                 self.message('Could not save ipv4 %s, got exception: %s' % (ipv4.address, e))
         
         if ipv6:
             try:
                 ipv6.full_clean()
                 ipv6.save()
                 saved_ipv6.append(ipv6)
                 self.verbose('Saved ipv6 %s' % ipv6.address)
             except Exception as e:
                 self.message('Could not save ipv6 %s, got exception: %s' % (ipv6.address, e))
         
     self.message('saved %d interfaces into local DB' % len(saved_interfaces))
     self.message('saved %d vaps into local DB' % len(saved_vaps))
     self.message('saved %d ipv4 addresses into local DB' % len(saved_ipv4))
     self.message('saved %d ipv6 addresses into local DB' % len(saved_ipv6))
     self.saved_interfaces = saved_interfaces
     self.saved_vaps = saved_vaps
     self.saved_ipv4 = saved_ipv4
     self.saved_ipv6 = saved_ipv6
Ejemplo n.º 17
0
 def test_add_addr_creates_no_public_records(self):
     self.z.add_addr('vm00', ip.IPAddress('172.22.48.20'), ['vm00.ipv4'])
     self.assertNotIn(RR.A('vm00', ip.IPAddress('172.22.48.20')),
                      self.z.external_forward.records)
     self.assertNotIn(RR.CNAME('vm00.ipv4', 'vm00'),
                      self.z.external_forward.records)
Ejemplo n.º 18
0
 def test_add_reverse_to_correct_zone(self):
     self.z.add_reverse(ip.IPAddress('2a02:248:101:63::5b'), 'vm00.ipv6')
     self.assertEqual(
         'vm00.ipv6.gocept.net.', self.z.reverse_zones[ip.IPNetwork(
             '2a02:248:101::/48')].records[0].value)
Ejemplo n.º 19
0
 def test_cannot_mix_a_and_cname(self):
     z = ForwardZone('gocept.net')
     z.add_a('vm00', ip.IPAddress('2a02:248:101:63::5b'))
     with self.assertRaises(MixedRecordTypesException):
         z.add_cname('vm00', 'other')
Ejemplo n.º 20
0
 def test_add_reverse_does_not_fail_when_address_does_not_fit_any_zone(
         self):
     # We used to fail here but decided to not fail as that will
     # (kinda silently) block DNS updates that people expect to see quickly.
     self.z.add_reverse(ip.IPAddress('192.0.1.2'), 'vm00')
Ejemplo n.º 21
0
 def test_forward_ipv4(self):
     z = ForwardZone('gocept.net')
     z.add_a('vm00.fe.whq', ip.IPAddress('195.62.125.10'))
     self.assertIn(RR.A('vm00.fe.whq', ip.IPAddress('195.62.125.10')),
                   z.records)
Ejemplo n.º 22
0
    def import_interfaces(self):
        self.verbose('retrieving interfaces from old mysql DB...')
        self.old_interfaces = list(OldInterface.objects.all())
        self.message('retrieved %d interfaces' % len(self.old_interfaces))

        saved_interfaces = []
        saved_vaps = []
        saved_ipv4 = []
        saved_ipv6 = []

        for old_interface in self.old_interfaces:
            interface_dict = {
                "id": old_interface.id,
                "device_id": int(old_interface.device_id),
                "mac": old_interface.mac_address,
                "name": old_interface.cname[0:10],
                "added": old_interface.added,
                "updated": old_interface.updated,
                "data": {}
            }
            vap = None
            ipv4 = None
            ipv6 = None

            # determine interface type and specific fields
            if old_interface.type == 'eth':
                interface_dict['standard'] = 'fast'
                interface_dict['duplex'] = 'full'
                InterfaceModel = Ethernet
            elif old_interface.type == 'wifi':
                interface_dict['mode'] = old_interface.wireless_mode
                interface_dict['channel'] = old_interface.wireless_channel
                InterfaceModel = Wireless
                # determine ssid
                if old_interface.essid or old_interface.bssid:
                    vap = Vap(
                        **{
                            "interface_id": old_interface.id,
                            "essid": old_interface.essid,
                            "bssid": old_interface.bssid
                        })
                    # if vap already exists flag it for UPDATE instead of INSERT
                    try:
                        v = Vap.objects.get(
                            Q(interface_id=old_interface.id)
                            & (Q(essid=old_interface.essid)
                               | Q(bssid=old_interface.bssid)))
                        # trick to make django do an update query instead of an insert
                        # working on django 1.6
                        vap.id = v.id
                        vap._state.adding = False
                    except Vap.DoesNotExist:
                        pass
                if old_interface.essid:
                    interface_dict['data']['essid'] = old_interface.essid
                if old_interface.bssid:
                    interface_dict['data']['bssid'] = old_interface.bssid
            elif old_interface.type == 'bridge':
                InterfaceModel = Bridge
            elif old_interface.type == 'vpn':
                InterfaceModel = Tunnel
            else:
                interface_dict['type'] = INTERFACE_TYPES.get('virtual')
                interface_dict['data'][
                    'old_nodeshot_interface_type'] = old_interface.get_type_display(
                    )
                InterfaceModel = Interface

            interface = InterfaceModel(**interface_dict)
            # if interface already exists flag it for UPDATE instead of INSERT
            try:
                InterfaceModel.objects.get(pk=old_interface.id)
                interface._state.adding = False
            except InterfaceModel.DoesNotExist:
                pass

            if old_interface.ipv4_address:
                old_interface.ipv4_address = old_interface.ipv4_address.strip(
                )  # stupid django bug
                ipv4 = Ip(
                    **{
                        "interface_id": old_interface.id,
                        "address": old_interface.ipv4_address
                    })
                # if ip already exists flag it for UPDATE instead of INSERT
                try:
                    ipv4.id = Ip.objects.get(
                        address=old_interface.ipv4_address).id
                    ipv4._state.adding = False
                except Ip.DoesNotExist:
                    pass
                # ensure ipv4 is valid
                try:
                    ip.IPAddress(old_interface.ipv4_address)
                except (ip.AddrFormatError, ValueError):
                    self.message('Invalid IPv4 address %s' %
                                 (old_interface.ipv4_address))
                    ipv4 = None

            if old_interface.ipv6_address:
                old_interface.ipv6_address = old_interface.ipv6_address.strip(
                )  # stupid django bug
                ipv6 = Ip(
                    **{
                        "interface_id": old_interface.id,
                        "address": old_interface.ipv6_address
                    })
                # if ip already exists flag it for UPDATE instead of INSERT
                try:
                    ipv6.id = Ip.objects.get(
                        address=old_interface.ipv6_address).id
                    ipv6._state.adding = False
                except Ip.DoesNotExist:
                    pass
                # ensure ipv6 is valid
                try:
                    ip.IPAddress(old_interface.ipv6_address)
                except (ip.AddrFormatError, ValueError):
                    self.message('Invalid IPv6 address %s' %
                                 (old_interface.ipv6_address))
                    ipv6 = None

            try:
                interface.full_clean()
                interface.save(auto_update=False)
                saved_interfaces.append(interface)
                self.verbose('Saved interface %s' % interface.name)
            except Exception:
                tb = traceback.format_exc()
                self.message(
                    'Could not save interface %s, got exception:\n\n%s' %
                    (interface.mac, tb))
                continue

            if vap:
                try:
                    vap.full_clean()
                    vap.save()
                    saved_vaps.append(vap)
                    self.verbose('Saved vap %s' % vap.essid or vap.bssid)
                except Exception:
                    tb = traceback.format_exc()
                    self.message(
                        'Could not save vap %s, got exception:\n\n%s' %
                        (vap.essid or vap.bssid, tb))

            if ipv4:
                try:
                    ipv4.full_clean()
                    ipv4.save()
                    saved_ipv4.append(ipv4)
                    self.verbose('Saved ipv4 %s' % ipv4.address)
                except Exception:
                    tb = traceback.format_exc()
                    self.message(
                        'Could not save ipv4 %s, got exception:\n\n%s' %
                        (ipv4.address, tb))

            if ipv6:
                try:
                    ipv6.full_clean()
                    ipv6.save()
                    saved_ipv6.append(ipv6)
                    self.verbose('Saved ipv6 %s' % ipv6.address)
                except Exception:
                    tb = traceback.format_exc()
                    self.message(
                        'Could not save ipv6 %s, got exception:\n\n%s' %
                        (ipv6.address, tb))

        self.message('saved %d interfaces into local DB' %
                     len(saved_interfaces))
        self.message('saved %d vaps into local DB' % len(saved_vaps))
        self.message('saved %d ipv4 addresses into local DB' % len(saved_ipv4))
        self.message('saved %d ipv6 addresses into local DB' % len(saved_ipv6))
        self.saved_interfaces = saved_interfaces
        self.saved_vaps = saved_vaps
        self.saved_ipv4 = saved_ipv4
        self.saved_ipv6 = saved_ipv6
Ejemplo n.º 23
0
 def to_internal_value(self, value):
     try:
         return ip.IPAddress(value)
     except (ip.AddrFormatError, ValueError):
         raise ValidationError(_('Invalid ip address'))