Ejemplo n.º 1
0
 def test_check_lease_changes_returns_tuple_if_lease_changed(self):
     ip = factory.getRandomIPAddress()
     leases = {ip: factory.getRandomMACAddress()}
     self.set_lease_state(datetime.utcnow() - timedelta(seconds=10),
                          leases.copy())
     leases[ip] = factory.getRandomMACAddress()
     leases_file = self.fake_leases_file(leases)
     self.assertEqual((get_write_time(leases_file), leases),
                      check_lease_changes())
Ejemplo n.º 2
0
 def test_gather_leases_combines_expired_and_current_leases(self):
     earlier = '1 2001/01/01 00:00:00'
     ip = factory.getRandomIPAddress()
     old_owner = factory.getRandomMACAddress()
     new_owner = factory.getRandomMACAddress()
     leases = [
         self.fake_parsed_lease(ip=ip, mac=old_owner, ends=earlier),
         self.fake_parsed_lease(ip=ip, mac=new_owner),
     ]
     self.assertEqual({ip: new_owner}, gather_leases(leases))
Ejemplo n.º 3
0
 def test_gather_leases_combines_expired_and_current_leases(self):
     earlier = '1 2001/01/01 00:00:00'
     ip = factory.getRandomIPAddress()
     old_owner = factory.getRandomMACAddress()
     new_owner = factory.getRandomMACAddress()
     leases = [
         self.fake_parsed_lease(ip=ip, mac=old_owner, ends=earlier),
         self.fake_parsed_lease(ip=ip, mac=new_owner),
         ]
     self.assertEqual({ip: new_owner}, gather_leases(leases))
Ejemplo n.º 4
0
 def test_gather_leases_ignores_ordering(self):
     earlier = '1 2001/01/01 00:00:00'
     ip = factory.getRandomIPAddress()
     old_owner = factory.getRandomMACAddress()
     new_owner = factory.getRandomMACAddress()
     leases = [
         self.fake_parsed_lease(ip=ip, mac=new_owner),
         self.fake_parsed_lease(ip=ip, mac=old_owner, ends=earlier),
     ]
     self.assertEqual({ip: new_owner}, gather_leases(leases))
Ejemplo n.º 5
0
 def test_check_lease_changes_returns_tuple_if_lease_changed(self):
     ip = factory.getRandomIPAddress()
     leases = {ip: factory.getRandomMACAddress()}
     self.set_lease_state(
         datetime.utcnow() - timedelta(seconds=10), leases.copy())
     leases[ip] = factory.getRandomMACAddress()
     leases_file = self.fake_leases_file(leases)
     self.assertEqual(
         (get_write_time(leases_file), leases),
         check_lease_changes())
Ejemplo n.º 6
0
 def test_gather_leases_ignores_ordering(self):
     earlier = '1 2001/01/01 00:00:00'
     ip = factory.getRandomIPAddress()
     old_owner = factory.getRandomMACAddress()
     new_owner = factory.getRandomMACAddress()
     leases = [
         self.fake_parsed_lease(ip=ip, mac=new_owner),
         self.fake_parsed_lease(ip=ip, mac=old_owner, ends=earlier),
         ]
     self.assertEqual({ip: new_owner}, gather_leases(leases))
Ejemplo n.º 7
0
 def test_parse_leases_takes_latest_lease_for_address(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'old_owner': factory.getRandomMACAddress(),
         'new_owner': factory.getRandomMACAddress(),
     }
     leases = parse_leases(dedent("""\
         lease %(ip)s {
             hardware ethernet %(old_owner)s;
         }
         lease %(ip)s {
             hardware ethernet %(new_owner)s;
         }
         """ % params))
     self.assertEqual({params['ip']: params['new_owner']}, leases)
Ejemplo n.º 8
0
 def test_parse_leases_parses_lease(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     leases = parse_leases(dedent("""\
         lease %(ip)s {
             starts 5 2010/01/01 00:00:01;
             ends never;
             tstp 6 2010/01/02 05:00:00;
             tsfp 6 2010/01/02 05:00:00;
             atsfp 6 2010/01/02 05:00:00;
             cltt 1 2010/01/02 05:00:00;
             binding state free;
             next binding state free;
             rewind binding state free;
             hardware ethernet %(mac)s;
             uid "\001\000\234\002\242\2020";
             set vendorclass = "PXEClient:Arch:00000:UNDI:002001";
             client-hostname foo;
             abandoned;
             option agent.circuit-id thing;
             option agent.remote-id thing;
             ddns-text foo;
             ddns-fwd-name foo;
             ddns-client-fqdn foo;
             ddns-rev-name foo;
             vendor-class-identifier foo;
             bootp;
             reserved;
         }
         """ % params))
     self.assertEqual({params['ip']: params['mac']}, leases)
Ejemplo n.º 9
0
 def test_parse_leases_parses_lease(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     leases = parse_leases(
         dedent("""\
         lease %(ip)s {
             starts 5 2010/01/01 00:00:01;
             ends never;
             tstp 6 2010/01/02 05:00:00;
             tsfp 6 2010/01/02 05:00:00;
             atsfp 6 2010/01/02 05:00:00;
             cltt 1 2010/01/02 05:00:00;
             binding state free;
             next binding state free;
             rewind binding state free;
             hardware ethernet %(mac)s;
             uid "\001\000\234\002\242\2020";
             set vendorclass = "PXEClient:Arch:00000:UNDI:002001";
             client-hostname foo;
             abandoned;
             option agent.circuit-id thing;
             option agent.remote-id thing;
             ddns-text foo;
             ddns-fwd-name foo;
             ddns-client-fqdn foo;
             ddns-rev-name foo;
             vendor-class-identifier foo;
             bootp;
             reserved;
         }
         """ % params))
     self.assertEqual({params['ip']: params['mac']}, leases)
Ejemplo n.º 10
0
 def test_parse_leases_takes_latest_lease_for_address(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'old_owner': factory.getRandomMACAddress(),
         'new_owner': factory.getRandomMACAddress(),
     }
     leases = parse_leases(
         dedent("""\
         lease %(ip)s {
             hardware ethernet %(old_owner)s;
         }
         lease %(ip)s {
             hardware ethernet %(new_owner)s;
         }
         """ % params))
     self.assertEqual({params['ip']: params['new_owner']}, leases)
Ejemplo n.º 11
0
    def test_get_reader_config_file(self):
        # For paths matching re_config_file, TFTPBackend.get_reader() returns
        # a Deferred that will yield a BytesReader.
        cluster_uuid = factory.getRandomUUID()
        self.patch(tftp_module,
                   'get_cluster_uuid').return_value = (cluster_uuid)
        mac = factory.getRandomMACAddress("-")
        config_path = compose_config_path(mac)
        backend = TFTPBackend(self.make_dir(), b"http://example.com/")
        # python-tx-tftp sets up call context so that backends can discover
        # more about the environment in which they're running.
        call_context = {
            "local": (factory.getRandomIPAddress(), factory.getRandomPort()),
            "remote": (factory.getRandomIPAddress(), factory.getRandomPort()),
        }

        @partial(self.patch, backend, "get_config_reader")
        def get_config_reader(params):
            params_json = json.dumps(params)
            params_json_reader = BytesReader(params_json)
            return succeed(params_json_reader)

        reader = yield context.call(call_context, backend.get_reader,
                                    config_path)
        output = reader.read(10000)
        # The addresses provided by python-tx-tftp in the call context are
        # passed over the wire as address:port strings.
        expected_params = {
            "mac": mac,
            "local": call_context["local"][0],  # address only.
            "remote": call_context["remote"][0],  # address only.
            "cluster_uuid": cluster_uuid,
        }
        observed_params = json.loads(output)
        self.assertEqual(expected_params, observed_params)
Ejemplo n.º 12
0
    def test_get_config_reader_returns_rendered_params(self):
        # get_config_reader() takes a dict() of parameters and returns an
        # `IReader` of a PXE configuration, rendered by `render_pxe_config`.
        backend = TFTPBackend(self.make_dir(), b"http://example.com/")
        # Fake configuration parameters, as discovered from the file path.
        fake_params = {"mac": factory.getRandomMACAddress(b"-")}
        # Fake kernel configuration parameters, as returned from the API call.
        fake_kernel_params = make_kernel_parameters()

        # Stub get_page to return the fake API configuration parameters.
        fake_get_page_result = json.dumps(fake_kernel_params._asdict())
        get_page_patch = self.patch(backend, "get_page")
        get_page_patch.return_value = succeed(fake_get_page_result)

        # Stub render_pxe_config to return the render parameters.
        fake_render_result = factory.make_name("render")
        render_patch = self.patch(backend, "render_pxe_config")
        render_patch.return_value = fake_render_result

        # Get the rendered configuration, which will actually be a JSON dump
        # of the render-time parameters.
        reader = yield backend.get_config_reader(fake_params)
        self.addCleanup(reader.finish)
        self.assertIsInstance(reader, BytesReader)
        output = reader.read(10000)

        # The kernel parameters were fetched using `backend.get_page`.
        backend.get_page.assert_called_once()

        # The result has been rendered by `backend.render_pxe_config`.
        self.assertEqual(fake_render_result.encode("utf-8"), output)
        backend.render_pxe_config.assert_called_once_with(
            kernel_params=fake_kernel_params, **fake_params)
Ejemplo n.º 13
0
    def test_create_calls_omshell_correctly(self):
        server_address = factory.getRandomString()
        shared_key = factory.getRandomString()
        ip_address = factory.getRandomIPAddress()
        mac_address = factory.getRandomMACAddress()
        shell = Omshell(server_address, shared_key)

        # Instead of calling a real omshell, we'll just record the
        # parameters passed to Popen.
        recorder = FakeMethod(result=(0, "hardware-type"))
        shell._run = recorder

        shell.create(ip_address, mac_address)

        expected_script = dedent("""\
            server {server}
            key omapi_key {key}
            connect
            new host
            set ip-address = {ip}
            set hardware-address = {mac}
            set hardware-type = 1
            set name = "{ip}"
            create
            """)
        expected_script = expected_script.format(server=server_address,
                                                 key=shared_key,
                                                 ip=ip_address,
                                                 mac=mac_address)

        # Check that the 'stdin' arg contains the correct set of
        # commands.
        self.assertEqual([1, (expected_script, )],
                         [recorder.call_count,
                          recorder.extract_args()[0]])
Ejemplo n.º 14
0
    def test_create_calls_omshell_correctly(self):
        server_address = factory.getRandomString()
        shared_key = factory.getRandomString()
        ip_address = factory.getRandomIPAddress()
        mac_address = factory.getRandomMACAddress()
        shell = Omshell(server_address, shared_key)

        # Instead of calling a real omshell, we'll just record the
        # parameters passed to Popen.
        recorder = FakeMethod(result=(0, "hardware-type"))
        shell._run = recorder

        shell.create(ip_address, mac_address)

        expected_args = (dedent("""\
            server {server}
            key omapi_key {key}
            connect
            new host
            set ip-address = {ip}
            set hardware-address = {mac}
            set hardware-type = 1
            set name = "{ip}"
            create
            """).format(
                server=server_address,
                key=shared_key,
                ip=ip_address,
                mac=mac_address),)

        # Check that the 'stdin' arg contains the correct set of
        # commands.
        self.assertEqual(
            [1, expected_args],
            [recorder.call_count, recorder.extract_args()[0]])
Ejemplo n.º 15
0
    def test_get_config_reader_returns_rendered_params(self):
        # get_config_reader() takes a dict() of parameters and returns an
        # `IReader` of a PXE configuration, rendered by `render_pxe_config`.
        backend = TFTPBackend(self.make_dir(), b"http://example.com/")
        # Fake configuration parameters, as discovered from the file path.
        fake_params = {"mac": factory.getRandomMACAddress("-")}
        # Fake kernel configuration parameters, as returned from the API call.
        fake_kernel_params = make_kernel_parameters()

        # Stub get_page to return the fake API configuration parameters.
        fake_get_page_result = json.dumps(fake_kernel_params._asdict())
        get_page_patch = self.patch(backend, "get_page")
        get_page_patch.return_value = succeed(fake_get_page_result)

        # Stub render_pxe_config to return the render parameters.
        fake_render_result = factory.make_name("render")
        render_patch = self.patch(backend, "render_pxe_config")
        render_patch.return_value = fake_render_result

        # Get the rendered configuration, which will actually be a JSON dump
        # of the render-time parameters.
        reader = yield backend.get_config_reader(fake_params)
        self.addCleanup(reader.finish)
        self.assertIsInstance(reader, BytesReader)
        output = reader.read(10000)

        # The kernel parameters were fetched using `backend.get_page`.
        backend.get_page.assert_called_once()

        # The result has been rendered by `backend.render_pxe_config`.
        self.assertEqual(fake_render_result.encode("utf-8"), output)
        backend.render_pxe_config.assert_called_once_with(
            kernel_params=fake_kernel_params, **fake_params)
Ejemplo n.º 16
0
 def test_create_succeeds_when_host_map_already_exists(self):
     # To omshell, creating the same host map twice is an error.  But
     # Omshell.create swallows the error and makes it look like
     # success.
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
         'hostname': factory.make_name('hostname')
     }
     shell = Omshell(factory.make_name('server'), factory.make_name('key'))
     # This is the kind of error output we get if a host map has
     # already been created.
     error_output = dedent("""\
         obj: host
         ip-address = %(ip)s
         hardware-address = %(mac)s
         name = "%(hostname)s"
         >
         can't open object: I/O error
         obj: host
         ip-address = %(ip)s
         hardware-address = %(mac)s
         name = "%(hostname)s"
         """) % params
     shell._run = Mock(return_value=(0, error_output))
     shell.create(params['ip'], params['mac'])
     # The test is that we get here without error.
     pass
Ejemplo n.º 17
0
 def test_create_succeeds_when_host_map_already_exists(self):
     # To omshell, creating the same host map twice is an error.  But
     # Omshell.create swallows the error and makes it look like
     # success.
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
         'hostname': factory.make_name('hostname')
     }
     shell = Omshell(factory.make_name('server'), factory.make_name('key'))
     # This is the kind of error output we get if a host map has
     # already been created.
     error_output = dedent("""\
         obj: host
         ip-address = %(ip)s
         hardware-address = %(mac)s
         name = "%(hostname)s"
         >
         can't open object: I/O error
         obj: host
         ip-address = %(ip)s
         hardware-address = %(mac)s
         name = "%(hostname)s"
         """) % params
     shell._run = Mock(return_value=(0, error_output))
     shell.create(params['ip'], params['mac'])
     # The test is that we get here without error.
     pass
Ejemplo n.º 18
0
    def test_init_sets_transaction_ID(self):
        transaction_id = make_transaction_ID()
        self.patch(detect_module,
                   'make_transaction_ID').return_value = (transaction_id)

        discover = DHCPDiscoverPacket(factory.getRandomMACAddress())

        self.assertEqual(transaction_id, discover.transaction_ID)
Ejemplo n.º 19
0
 def test_combine_entries_accepts_reassigned_host(self):
     ip = factory.getRandomIPAddress()
     mac = factory.getRandomMACAddress()
     entries = [
         self.fake_parsed_host(ip=ip),
         self.fake_parsed_rubout(ip=ip),
         self.fake_parsed_host(ip=ip, mac=mac),
     ]
     self.assertEqual({ip: mac}, combine_entries(entries))
Ejemplo n.º 20
0
 def test_combine_entries_accepts_expired_lease_followed_by_host(self):
     ip = factory.getRandomIPAddress()
     mac = factory.getRandomMACAddress()
     earlier = '1 2001/01/01 00:00:00'
     entries = [
         self.fake_parsed_lease(ip=ip, ends=earlier),
         self.fake_parsed_host(ip=ip, mac=mac),
     ]
     self.assertEqual({ip: mac}, combine_entries(entries))
Ejemplo n.º 21
0
 def test_combine_entries_accepts_reassigned_host(self):
     ip = factory.getRandomIPAddress()
     mac = factory.getRandomMACAddress()
     entries = [
         self.fake_parsed_host(ip=ip),
         self.fake_parsed_rubout(ip=ip),
         self.fake_parsed_host(ip=ip, mac=mac),
         ]
     self.assertEqual({ip: mac}, combine_entries(entries))
Ejemplo n.º 22
0
 def test_combine_entries_accepts_expired_lease_followed_by_host(self):
     ip = factory.getRandomIPAddress()
     mac = factory.getRandomMACAddress()
     earlier = '1 2001/01/01 00:00:00'
     entries = [
         self.fake_parsed_lease(ip=ip, ends=earlier),
         self.fake_parsed_host(ip=ip, mac=mac),
         ]
     self.assertEqual({ip: mac}, combine_entries(entries))
Ejemplo n.º 23
0
 def test_gather_hosts_follows_reassigned_host(self):
     ip = factory.getRandomIPAddress()
     new_owner = factory.getRandomMACAddress()
     hosts = [
         self.fake_parsed_host(ip=ip),
         self.fake_parsed_rubout(ip=ip),
         self.fake_parsed_host(ip=ip, mac=new_owner),
         ]
     self.assertEqual({ip: new_owner}, gather_hosts(hosts))
Ejemplo n.º 24
0
 def test_gather_hosts_follows_reassigned_host(self):
     ip = factory.getRandomIPAddress()
     new_owner = factory.getRandomMACAddress()
     hosts = [
         self.fake_parsed_host(ip=ip),
         self.fake_parsed_rubout(ip=ip),
         self.fake_parsed_host(ip=ip, mac=new_owner),
     ]
     self.assertEqual({ip: new_owner}, gather_hosts(hosts))
Ejemplo n.º 25
0
 def test_add_new_dhcp_host_map_failure(self):
     # Check that task failures are caught.  Nothing much happens in
     # the Task code right now though.
     mac = factory.getRandomMACAddress()
     ip = factory.getRandomIPAddress()
     server_address = factory.getRandomString()
     key = factory.getRandomString()
     self.patch(Omshell, '_run', FakeMethod(result=(0, "this_will_fail")))
     self.assertRaises(CalledProcessError, add_new_dhcp_host_map.delay,
                       {mac: ip}, server_address, key)
Ejemplo n.º 26
0
 def test_combine_entries_ignores_rubout_followed_by_expired_lease(self):
     ip = factory.getRandomIPAddress()
     mac = factory.getRandomMACAddress()
     earlier = '1 2001/01/01 00:00:00'
     entries = [
         self.fake_parsed_host(ip=ip),
         self.fake_parsed_rubout(ip=ip),
         self.fake_parsed_lease(ip=ip, mac=mac, ends=earlier),
         ]
     self.assertEqual({}, combine_entries(entries))
Ejemplo n.º 27
0
 def test_combine_entries_ignores_rubout_followed_by_expired_lease(self):
     ip = factory.getRandomIPAddress()
     mac = factory.getRandomMACAddress()
     earlier = '1 2001/01/01 00:00:00'
     entries = [
         self.fake_parsed_host(ip=ip),
         self.fake_parsed_rubout(ip=ip),
         self.fake_parsed_lease(ip=ip, mac=mac, ends=earlier),
     ]
     self.assertEqual({}, combine_entries(entries))
Ejemplo n.º 28
0
    def get_example_path_and_components():
        """Return a plausible path and its components.

        The path is intended to match `re_config_file`, and the components are
        the expected groups from a match.
        """
        components = {"mac": factory.getRandomMACAddress(b"-"),
                      "arch": None,
                      "subarch": None}
        config_path = compose_config_path(components["mac"])
        return config_path, components
Ejemplo n.º 29
0
 def test_add_new_dhcp_host_map_failure(self):
     # Check that task failures are caught.  Nothing much happens in
     # the Task code right now though.
     mac = factory.getRandomMACAddress()
     ip = factory.getRandomIPAddress()
     server_address = factory.getRandomString()
     key = factory.getRandomString()
     self.patch(Omshell, '_run', FakeMethod(result=(0, "this_will_fail")))
     self.assertRaises(
         CalledProcessError, add_new_dhcp_host_map.delay,
         {mac: ip}, server_address, key)
Ejemplo n.º 30
0
 def fake_parsed_lease(self, ip=None, mac=None, ends=None,
                       entry_type='lease'):
     """Fake a lease as produced by the parser."""
     if ip is None:
         ip = factory.getRandomIPAddress()
     if mac is None:
         mac = factory.getRandomMACAddress()
     Hardware = namedtuple('Hardware', ['mac'])
     Lease = namedtuple(
         'Lease', ['lease_or_host', 'ip', 'hardware', 'ends'])
     return Lease(entry_type, ip, Hardware(mac), ends)
Ejemplo n.º 31
0
 def test_get_host_mac_returns_None_for_host(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     [parsed_host] = lease_parser.searchString(dedent("""\
         host %(ip)s {
             hardware ethernet %(mac)s;
         }
         """ % params))
     self.assertEqual(params['mac'], get_host_mac(parsed_host))
Ejemplo n.º 32
0
 def test_parse_leases_treats_missing_end_date_as_eternity(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     leases = parse_leases(dedent("""\
         lease %(ip)s {
             hardware ethernet %(mac)s;
         }
         """ % params))
     self.assertEqual({params['ip']: params['mac']}, leases)
Ejemplo n.º 33
0
 def test_get_host_mac_returns_None_for_rubout_even_with_mac(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     [parsed_host] = lease_parser.searchString(dedent("""\
         host %(ip)s {
             deleted;
             hardware ethernet %(mac)s;
         }
         """ % params))
     self.assertIsNone(get_host_mac(parsed_host))
Ejemplo n.º 34
0
 def test_parse_leases_ignores_expired_leases(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     leases = parse_leases(dedent("""\
         lease %(ip)s {
             hardware ethernet %(mac)s;
             ends 1 2001/01/01 00:00:00;
         }
         """ % params))
     self.assertEqual({}, leases)
Ejemplo n.º 35
0
 def test_parse_leases_treats_missing_end_date_as_eternity(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     leases = parse_leases(
         dedent("""\
         lease %(ip)s {
             hardware ethernet %(mac)s;
         }
         """ % params))
     self.assertEqual({params['ip']: params['mac']}, leases)
Ejemplo n.º 36
0
 def test_get_host_mac_returns_None_for_host(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     [parsed_host] = lease_parser.searchString(
         dedent("""\
         host %(ip)s {
             hardware ethernet %(mac)s;
         }
         """ % params))
     self.assertEqual(params['mac'], get_host_mac(parsed_host))
Ejemplo n.º 37
0
 def test_host_declaration_is_like_an_unexpired_lease(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     leases = parse_leases(dedent("""\
         host %(ip)s {
             hardware ethernet %(mac)s;
             fixed-address %(ip)s;
         }
         """ % params))
     self.assertEqual({params['ip']: params['mac']}, leases)
Ejemplo n.º 38
0
 def test_get_host_mac_returns_None_for_rubout_even_with_mac(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     [parsed_host] = lease_parser.searchString(
         dedent("""\
         host %(ip)s {
             deleted;
             hardware ethernet %(mac)s;
         }
         """ % params))
     self.assertIsNone(get_host_mac(parsed_host))
Ejemplo n.º 39
0
 def test_is_lease_and_is_host_recognize_host(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     [parsed_host] = lease_parser.searchString(dedent("""\
         host %(ip)s {
             hardware ethernet %(mac)s;
         }
         """ % params))
     self.assertEqual(
         (False, True),
         (is_lease(parsed_host), is_host(parsed_host)))
Ejemplo n.º 40
0
 def test_host_declaration_is_like_an_unexpired_lease(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     leases = parse_leases(
         dedent("""\
         host %(ip)s {
             hardware ethernet %(mac)s;
             fixed-address %(ip)s;
         }
         """ % params))
     self.assertEqual({params['ip']: params['mac']}, leases)
Ejemplo n.º 41
0
    def test_add_new_dhcp_host_map(self):
        # We don't want to actually run omshell in the task, so we stub
        # out the wrapper class's _run method and record what it would
        # do.
        mac = factory.getRandomMACAddress()
        ip = factory.getRandomIPAddress()
        server_address = factory.getRandomString()
        key = factory.getRandomString()
        recorder = FakeMethod(result=(0, "hardware-type"))
        self.patch(Omshell, '_run', recorder)
        add_new_dhcp_host_map.delay({ip: mac}, server_address, key)

        self.assertRecordedStdin(recorder, ip, mac, server_address, key)
Ejemplo n.º 42
0
 def test_is_lease_and_is_host_recognize_host(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     [parsed_host] = lease_parser.searchString(
         dedent("""\
         host %(ip)s {
             hardware ethernet %(mac)s;
         }
         """ % params))
     self.assertEqual((False, True),
                      (is_lease(parsed_host), is_host(parsed_host)))
Ejemplo n.º 43
0
    def test_add_new_dhcp_host_map(self):
        # We don't want to actually run omshell in the task, so we stub
        # out the wrapper class's _run method and record what it would
        # do.
        mac = factory.getRandomMACAddress()
        ip = factory.getRandomIPAddress()
        server_address = factory.getRandomString()
        key = factory.getRandomString()
        recorder = FakeMethod(result=(0, "hardware-type"))
        self.patch(Omshell, '_run', recorder)
        add_new_dhcp_host_map.delay({ip: mac}, server_address, key)

        self.assertRecordedStdin(recorder, ip, mac, server_address, key)
Ejemplo n.º 44
0
    def get_example_path_and_components():
        """Return a plausible path and its components.

        The path is intended to match `re_config_file`, and the components are
        the expected groups from a match.
        """
        components = {
            "mac": factory.getRandomMACAddress("-"),
            "arch": None,
            "subarch": None
        }
        config_path = compose_config_path(components["mac"])
        return config_path, components
Ejemplo n.º 45
0
 def test_parse_leases_ignores_expired_leases(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     leases = parse_leases(
         dedent("""\
         lease %(ip)s {
             hardware ethernet %(mac)s;
             ends 1 2001/01/01 00:00:00;
         }
         """ % params))
     self.assertEqual({}, leases)
Ejemplo n.º 46
0
 def test_parse_leases_parses_host(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     leases = parse_leases(dedent("""\
         host %(ip)s {
             dynamic;
             hardware ethernet %(mac)s;
             fixed-address %(ip)s;
         }
         """ % params))
     self.assertEqual({params['ip']: params['mac']}, leases)
Ejemplo n.º 47
0
 def fake_parsed_lease(self,
                       ip=None,
                       mac=None,
                       ends=None,
                       entry_type='lease'):
     """Fake a lease as produced by the parser."""
     if ip is None:
         ip = factory.getRandomIPAddress()
     if mac is None:
         mac = factory.getRandomMACAddress()
     Hardware = namedtuple('Hardware', ['mac'])
     Lease = namedtuple('Lease',
                        ['lease_or_host', 'ip', 'hardware', 'ends'])
     return Lease(entry_type, ip, Hardware(mac), ends)
Ejemplo n.º 48
0
 def test_parse_leases_ignores_comments(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     leases = parse_leases(dedent("""\
         # Top comment (ignored).
         lease %(ip)s { # End-of-line comment (ignored).
             # Comment in lease block (ignored).
             hardware ethernet %(mac)s;  # EOL comment in lease (ignored).
         } # Comment right after closing brace (ignored).
         # End comment (ignored).
         """ % params))
     self.assertEqual({params['ip']: params['mac']}, leases)
Ejemplo n.º 49
0
 def test_parse_leases_recognizes_host_deleted_statement_as_rubout(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     leases = parse_leases(dedent("""\
         host %(ip)s {
             dynamic;
             hardware ethernet %(mac)s;
             fixed-address %(ip)s;
             deleted;
         }
         """ % params))
     self.assertEqual({}, leases)
Ejemplo n.º 50
0
 def test_parse_leases_ignores_incomplete_lease_at_end(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
         'incomplete_ip': factory.getRandomIPAddress(),
     }
     leases = parse_leases(dedent("""\
         lease %(ip)s {
             hardware ethernet %(mac)s;
         }
         lease %(incomplete_ip)s {
             starts 5 2010/01/01 00:00:05;
         """ % params))
     self.assertEqual({params['ip']: params['mac']}, leases)
Ejemplo n.º 51
0
    def test__build(self):
        mac = factory.getRandomMACAddress()
        discover = DHCPDiscoverPacket(mac)
        discover._build()

        expected = (b'\x01\x01\x06\x00' + discover.transaction_ID +
                    b'\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00' +
                    b'\x00\x00\x00\x00\x00\x00\x00\x00' + discover.packed_mac +
                    b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +
                    b'\x00' * 67 + b'\x00' * 125 +
                    b'\x63\x82\x53\x63\x35\x01\x01\x3d\x06' +
                    discover.packed_mac + b'\x37\x03\x03\x01\x06\xff')

        self.assertEqual(expected, discover.packet)
Ejemplo n.º 52
0
 def test_parse_leases_parses_host(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     leases = parse_leases(
         dedent("""\
         host %(ip)s {
             dynamic;
             hardware ethernet %(mac)s;
             fixed-address %(ip)s;
         }
         """ % params))
     self.assertEqual({params['ip']: params['mac']}, leases)
Ejemplo n.º 53
0
 def test_parse_leases_recognizes_host_deleted_statement_as_rubout(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     leases = parse_leases(
         dedent("""\
         host %(ip)s {
             dynamic;
             hardware ethernet %(mac)s;
             fixed-address %(ip)s;
             deleted;
         }
         """ % params))
     self.assertEqual({}, leases)
Ejemplo n.º 54
0
 def test_parse_leases_ignores_comments(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     leases = parse_leases(
         dedent("""\
         # Top comment (ignored).
         lease %(ip)s { # End-of-line comment (ignored).
             # Comment in lease block (ignored).
             hardware ethernet %(mac)s;  # EOL comment in lease (ignored).
         } # Comment right after closing brace (ignored).
         # End comment (ignored).
         """ % params))
     self.assertEqual({params['ip']: params['mac']}, leases)
Ejemplo n.º 55
0
 def test_parse_leases_ignores_incomplete_lease_at_end(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
         'incomplete_ip': factory.getRandomIPAddress(),
     }
     leases = parse_leases(
         dedent("""\
         lease %(ip)s {
             hardware ethernet %(mac)s;
         }
         lease %(incomplete_ip)s {
             starts 5 2010/01/01 00:00:05;
         """ % params))
     self.assertEqual({params['ip']: params['mac']}, leases)
Ejemplo n.º 56
0
 def test_get_generator_url(self):
     # get_generator_url() merges the parameters obtained from the request
     # file path (arch, subarch, name) into the configured generator URL.
     mac = factory.getRandomMACAddress("-")
     dummy = factory.make_name("dummy").encode("ascii")
     backend_url = b"http://example.com/?" + urlencode({b"dummy": dummy})
     backend = TFTPBackend(self.make_dir(), backend_url)
     # params is an example of the parameters obtained from a request.
     params = {"mac": mac}
     generator_url = urlparse(backend.get_generator_url(params))
     self.assertEqual("example.com", generator_url.hostname)
     query = parse_qsl(generator_url.query)
     query_expected = [
         ("dummy", dummy),
         ("mac", mac),
     ]
     self.assertItemsEqual(query_expected, query)
Ejemplo n.º 57
0
 def test_get_generator_url(self):
     # get_generator_url() merges the parameters obtained from the request
     # file path (arch, subarch, name) into the configured generator URL.
     mac = factory.getRandomMACAddress(b"-")
     dummy = factory.make_name("dummy").encode("ascii")
     backend_url = b"http://example.com/?" + urlencode({b"dummy": dummy})
     backend = TFTPBackend(self.make_dir(), backend_url)
     # params is an example of the parameters obtained from a request.
     params = {"mac": mac}
     generator_url = urlparse(backend.get_generator_url(params))
     self.assertEqual("example.com", generator_url.hostname)
     query = parse_qsl(generator_url.query)
     query_expected = [
         ("dummy", dummy),
         ("mac", mac),
         ]
     self.assertItemsEqual(query_expected, query)
Ejemplo n.º 58
0
 def test_parse_leases_file_parses_leases(self):
     params = {
         'ip': factory.getRandomIPAddress(),
         'mac': factory.getRandomMACAddress(),
     }
     leases_file = self.write_leases_file("""\
         lease %(ip)s {
             starts 5 2010/01/01 00:00:01;
             ends never;
             tstp 6 2010/01/02 05:00:00;
             tsfp 6 2010/01/02 05:00:00;
             binding state free;
             hardware ethernet %(mac)s;
         }
         """ % params)
     self.assertEqual(
         (get_write_time(leases_file), {params['ip']: params['mac']}),
         parse_leases_file())
Ejemplo n.º 59
0
    def test_create_raises_when_omshell_fails(self):
        # If the call to omshell doesn't result in output containing the
        # magic string 'hardware-type' it means the set of commands
        # failed.

        server_address = factory.getRandomString()
        shared_key = factory.getRandomString()
        ip_address = factory.getRandomIPAddress()
        mac_address = factory.getRandomMACAddress()
        shell = Omshell(server_address, shared_key)

        # Fake a call that results in a failure with random output.
        random_output = factory.getRandomString()
        recorder = FakeMethod(result=(0, random_output))
        shell._run = recorder

        exc = self.assertRaises(
            CalledProcessError, shell.create, ip_address, mac_address)
        self.assertEqual(random_output, exc.output)
Ejemplo n.º 60
0
    def test_get_reader_config_file(self):
        # For paths matching re_config_file, TFTPBackend.get_reader() returns
        # a Deferred that will yield a BytesReader.
        cluster_uuid = factory.getRandomUUID()
        self.patch(tftp_module, 'get_cluster_uuid').return_value = (
            cluster_uuid)
        mac = factory.getRandomMACAddress(b"-")
        config_path = compose_config_path(mac)
        backend = TFTPBackend(self.make_dir(), b"http://example.com/")
        # python-tx-tftp sets up call context so that backends can discover
        # more about the environment in which they're running.
        call_context = {
            "local": (
                factory.getRandomIPAddress(),
                factory.getRandomPort()),
            "remote": (
                factory.getRandomIPAddress(),
                factory.getRandomPort()),
            }

        @partial(self.patch, backend, "get_config_reader")
        def get_config_reader(params):
            params_json = json.dumps(params)
            params_json_reader = BytesReader(params_json)
            return succeed(params_json_reader)

        reader = yield context.call(
            call_context, backend.get_reader, config_path)
        output = reader.read(10000)
        # The addresses provided by python-tx-tftp in the call context are
        # passed over the wire as address:port strings.
        expected_params = {
            "mac": mac,
            "local": call_context["local"][0],  # address only.
            "remote": call_context["remote"][0],  # address only.
            "cluster_uuid": cluster_uuid,
            }
        observed_params = json.loads(output)
        self.assertEqual(expected_params, observed_params)