def test_run_without_inspection_and_apiurl(self, mock_list_hardware, mock_wsgi, mock_dispatch, mock_inspector, mock_wait): # If both api_url and inspection_callback_url are not configured when # the agent starts, ensure that the inspection will be skipped and wsgi # server will work as usual. Also, make sure api_client and heartbeater # will not be initialized in this case. CONF.set_override('inspection_callback_url', None) self.agent = agent.IronicPythonAgent(None, agent.Host('203.0.113.1', 9990), agent.Host('192.0.2.1', 9999), 3, 10, 'eth0', 300, 1, False) self.assertFalse(hasattr(self.agent, 'api_client')) self.assertFalse(hasattr(self.agent, 'heartbeater')) def set_serve_api(): self.agent.serve_api = False wsgi_server = mock_wsgi.return_value wsgi_server.handle_request.side_effect = set_serve_api self.agent.run() listen_addr = agent.Host('192.0.2.1', 9999) mock_wsgi.assert_called_once_with( (listen_addr.hostname, listen_addr.port), simple_server.WSGIRequestHandler) self.assertTrue(wsgi_server.handle_request.called) self.assertFalse(mock_inspector.called) self.assertFalse(mock_wait.called) self.assertFalse(mock_dispatch.called)
def setUp(self): super(TestAgentStandalone, self).setUp() self.agent = agent.IronicPythonAgent( 'https://fake_api.example.' 'org:8081/', agent.Host(hostname='203.0.113.1', port=9990), agent.Host(hostname='192.0.2.1', port=9999), 3, 10, 'eth0', 300, 1, 'agent_ipmitool', True)
def test_ipv4_lookup(self, mock_get_ipv4, mock_list_net, mock_time_sleep, mock_poll, mock_read): homeless_agent = agent.IronicPythonAgent( 'https://fake_api.example.' 'org:8081/', (None, 9990), ('192.0.2.1', 9999), 3, 10, None, 300, 1, 'agent_ipmitool', False) mock_poll.return_value.poll.return_value = True mock_read.return_value = 'a' # Can't find network interfaces, and therefore can't find IP mock_list_net.return_value = [] mock_get_ipv4.return_value = None self.assertRaises(errors.LookupAgentInterfaceError, homeless_agent.set_agent_advertise_addr) # Can look up network interfaces, but not IP. Network interface not # set, because no interface yields an IP. mock_ifaces = [ hardware.NetworkInterface('eth0', '00:00:00:00:00:00'), hardware.NetworkInterface('eth1', '00:00:00:00:00:01') ] mock_list_net.return_value = mock_ifaces self.assertRaises(errors.LookupAgentIPError, homeless_agent.set_agent_advertise_addr) self.assertEqual(6, mock_get_ipv4.call_count) self.assertEqual(None, homeless_agent.network_interface) # First interface eth0 has no IP, second interface eth1 has an IP mock_get_ipv4.side_effect = [None, '1.1.1.1'] homeless_agent.heartbeater.run() self.assertEqual(('1.1.1.1', 9990), homeless_agent.advertise_address) self.assertEqual('eth1', homeless_agent.network_interface)
def test_run_without_inspection_and_apiurl(self, mock_list_hardware, mock_make_server, mock_dispatch, mock_inspector, mock_wait): # If both api_url and inspection_callback_url are not configured when # the agent starts, ensure that the inspection will be skipped and wsgi # server will work as usual. Also, make sure api_client and heartbeater # will not be initialized in this case. CONF.set_override('inspection_callback_url', None, enforce_type=True) self.agent = agent.IronicPythonAgent(None, agent.Host('203.0.113.1', 9990), agent.Host('192.0.2.1', 9999), 3, 10, 'eth0', 300, 1, False) self.assertFalse(hasattr(self.agent, 'api_client')) self.assertFalse(hasattr(self.agent, 'heartbeater')) wsgi_server = mock_make_server.return_value wsgi_server.start.side_effect = KeyboardInterrupt() self.agent.run() listen_addr = agent.Host('192.0.2.1', 9999) mock_make_server.assert_called_once_with( listen_addr.hostname, listen_addr.port, self.agent.api, server_class=simple_server.WSGIServer) wsgi_server.serve_forever.assert_called_once_with() self.assertFalse(mock_inspector.called) self.assertFalse(mock_wait.called) self.assertFalse(mock_dispatch.called)
def run(): """Entrypoint for IronicPythonAgent.""" # NOTE(dtantsur): this must happen very early of the files from # /etc/ironic-python-agent.d won't be loaded utils.copy_config_from_vmedia() log.register_options(CONF) CONF(args=sys.argv[1:]) # Debug option comes from oslo.log, allow overriding it via kernel cmdline ipa_debug = config.APARAMS.get('ipa-debug') if ipa_debug is not None: ipa_debug = strutils.bool_from_string(ipa_debug) CONF.set_override('debug', ipa_debug) log.setup(CONF, 'ironic-python-agent') # Used for TLS configuration sslutils.register_opts(CONF) logger = log.getLogger(__name__) logger.debug("Configuration:") CONF.log_opt_values(logger, log.DEBUG) utils.log_early_log_to_logger() agent.IronicPythonAgent( CONF.api_url, agent.Host(hostname=CONF.advertise_host, port=CONF.advertise_port), agent.Host(hostname=CONF.listen_host, port=CONF.listen_port), CONF.ip_lookup_attempts, CONF.ip_lookup_sleep, CONF.network_interface, CONF.lookup_timeout, CONF.lookup_interval, False, CONF.agent_token, CONF.hardware_initialization_delay, CONF.advertise_protocol).run()
def setUp(self): """Start the agent and wait for it to start""" super(FunctionalBase, self).setUp() mpl = multiprocessing.log_to_stderr() mpl.setLevel(logging.INFO) test_port = os.environ.get('TEST_PORT', '9999') # Build a basic standalone agent using the config option defaults. # 127.0.0.1:6835 is the fake Ironic client. self.agent = agent.IronicPythonAgent( 'http://127.0.0.1:6835', 'localhost', ('0.0.0.0', int(test_port)), 3, 10, None, 300, 1, 'agent_ipmitool', True) self.process = multiprocessing.Process( target=self.agent.run) self.process.start() self.addCleanup(self.process.terminate) # Wait for process to start, otherwise we have a race for tests tries = 0 max_tries = os.environ.get('IPA_WAIT_TIME', '2') while tries < int(max_tries): try: return requests.get('http://localhost:%s/v1/commands' % test_port) except requests.ConnectionError: time.sleep(.1) tries += 1 raise IOError('Agent did not start after %s seconds.' % max_tries)
def run(): CONF() log.setup('ironic-python-agent') agent.IronicPythonAgent( CONF.api_url, (CONF.advertise_host, CONF.advertise_port), (CONF.listen_host, CONF.listen_port), CONF.ip_lookup_attempts, CONF.ip_lookup_sleep, CONF.network_interface, CONF.lookup_timeout, CONF.lookup_interval, CONF.driver_name, CONF.standalone).run()
def run(): """Entrypoint for IronicPythonAgent.""" log.register_options(CONF) CONF(args=sys.argv[1:]) log.setup(CONF, 'ironic-python-agent') agent.IronicPythonAgent( CONF.api_url, (CONF.advertise_host, CONF.advertise_port), (CONF.listen_host, CONF.listen_port), CONF.ip_lookup_attempts, CONF.ip_lookup_sleep, CONF.network_interface, CONF.lookup_timeout, CONF.lookup_interval, CONF.driver_name, CONF.standalone).run()
def setUp(self): super(TestBaseAgent, self).setUp() self.encoder = encoding.RESTJSONEncoder(indent=4) self.agent = agent.IronicPythonAgent( 'https://fake_api.example.' 'org:8081/', ('203.0.113.1', 9990), ('192.0.2.1', 9999), 3, 10, 'eth0', 300, 1, 'agent_ipmitool', False) self.agent.ext_mgr = extension.ExtensionManager.\ make_test_instance([extension.Extension('fake', None, FakeExtension, FakeExtension())])
def setUp(self): super(TestAdvertiseAddress, self).setUp() self.agent = agent.IronicPythonAgent( api_url='https://fake_api.example.org:8081/', advertise_address=agent.Host(None, 9990), listen_address=agent.Host('0.0.0.0', 9999), ip_lookup_attempts=5, ip_lookup_sleep=10, network_interface=None, lookup_timeout=300, lookup_interval=1, standalone=False)
def test_url_from_mdns_explicitly(self, mock_get_managers, mock_wsgi, mock_wait, mock_dispatch, mock_mdns): CONF.set_override('inspection_callback_url', '') CONF.set_override('disk_wait_attempts', 0) mock_mdns.return_value = 'https://example.com', { # configuration via mdns 'ipa_disk_wait_attempts': '42', } wsgi_server = mock_wsgi.return_value self.agent = agent.IronicPythonAgent('mdns', agent.Host('203.0.113.1', 9990), agent.Host('192.0.2.1', 9999), 3, 10, 'eth0', 300, 1, False, None) def set_serve_api(): self.agent.serve_api = False wsgi_server.start.side_effect = set_serve_api self.agent.heartbeater = mock.Mock() self.agent.api_client.lookup_node = mock.Mock() self.agent.api_client.lookup_node.return_value = { 'node': { 'uuid': 'deadbeef-dabb-ad00-b105-f00d00bab10c' }, 'config': { 'heartbeat_timeout': 300 } } self.agent.run() mock_wsgi.assert_called_once_with(CONF, 'ironic-python-agent', app=self.agent.api, host=mock.ANY, port=9999, use_ssl=False) wsgi_server.start.assert_called_once_with() mock_wait.assert_called_once_with(mock.ANY) self.assertEqual([mock.call('list_hardware_info'), mock.call('wait_for_disks')], mock_dispatch.call_args_list) self.agent.heartbeater.start.assert_called_once_with() # changed via mdns self.assertEqual(42, CONF.disk_wait_attempts)
def setUp(self): super(TestBaseAgent, self).setUp() self.encoder = encoding.RESTJSONEncoder(indent=4) self.agent = agent.IronicPythonAgent( 'https://fake_api.example.' 'org:8081/', ('203.0.113.1', 9990), ('192.0.2.1', 9999), 3, 10, 'eth0', 300, 1, 'agent_ipmitool', False) self.agent.ext_mgr = extension.ExtensionManager.\ make_test_instance([extension.Extension('fake', None, FakeExtension, FakeExtension())]) self.sample_nw_iface = hardware.NetworkInterface( "eth9", "AA:BB:CC:DD:EE:FF", "1.2.3.4", True)
def run(): """Entrypoint for IronicPythonAgent.""" log.register_options(CONF) CONF(args=sys.argv[1:]) # Debug option comes from oslo.log, allow overriding it via kernel cmdline ipa_debug = config.APARAMS.get('ipa-debug') if ipa_debug is not None: ipa_debug = strutils.bool_from_string(ipa_debug) CONF.set_override('debug', ipa_debug) log.setup(CONF, 'ironic-python-agent') agent.IronicPythonAgent( CONF.api_url, (CONF.advertise_host, CONF.advertise_port), (CONF.listen_host, CONF.listen_port), CONF.ip_lookup_attempts, CONF.ip_lookup_sleep, CONF.network_interface, CONF.lookup_timeout, CONF.lookup_interval, CONF.driver_name, CONF.standalone, CONF.hardware_initialization_delay).run()
def test_run_with_inspection_without_apiurl(self, mock_list_hardware, mock_wsgi, mock_dispatch, mock_inspector, mock_wait, mock_mdns): mock_mdns.side_effect = lib_exc.ServiceLookupFailure() # If inspection_callback_url is configured and api_url is not when the # agent starts, ensure that the inspection will be called and wsgi # server will work as usual. Also, make sure api_client and heartbeater # will not be initialized in this case. CONF.set_override('inspection_callback_url', 'http://foo/bar') self.agent = agent.IronicPythonAgent(None, agent.Host('203.0.113.1', 9990), agent.Host('192.0.2.1', 9999), 3, 10, 'eth0', 300, 1, False, None) self.assertFalse(hasattr(self.agent, 'api_client')) self.assertFalse(hasattr(self.agent, 'heartbeater')) def set_serve_api(): self.agent.serve_api = False wsgi_server = mock_wsgi.return_value wsgi_server.start.side_effect = set_serve_api self.agent.run() mock_wsgi.assert_called_once_with(CONF, 'ironic-python-agent', app=self.agent.api, host=mock.ANY, port=9999, use_ssl=False) wsgi_server.start.assert_called_once_with() mock_inspector.assert_called_once_with() self.assertTrue(mock_wait.called) self.assertFalse(mock_dispatch.called)
def test_url_from_mdns_by_default(self, mock_load_managers, mock_wsgi, mock_wait, mock_dispatch, mock_mdns): CONF.set_override('inspection_callback_url', '') mock_mdns.return_value = 'https://example.com', {} wsgi_server = mock_wsgi.return_value self.agent = agent.IronicPythonAgent(None, agent.Host('203.0.113.1', 9990), agent.Host('192.0.2.1', 9999), 3, 10, 'eth0', 300, 1, False) def set_serve_api(): self.agent.serve_api = False wsgi_server.handle_request.side_effect = set_serve_api self.agent.heartbeater = mock.Mock() self.agent.api_client.lookup_node = mock.Mock() self.agent.api_client.lookup_node.return_value = { 'node': { 'uuid': 'deadbeef-dabb-ad00-b105-f00d00bab10c' }, 'config': { 'heartbeat_timeout': 300 } } self.agent.run() listen_addr = agent.Host('192.0.2.1', 9999) mock_wsgi.assert_called_once_with( (listen_addr.hostname, listen_addr.port), simple_server.WSGIRequestHandler) wsgi_server.set_app.assert_called_once_with(self.agent.api) self.assertTrue(wsgi_server.handle_request.called) mock_wait.assert_called_once_with(mock.ANY) self.assertEqual( [mock.call('list_hardware_info'), mock.call('wait_for_disks')], mock_dispatch.call_args_list) self.agent.heartbeater.start.assert_called_once_with()
def setUp(self): """Start the agent and wait for it to start""" super(FunctionalBase, self).setUp() mpl = multiprocessing.log_to_stderr() mpl.setLevel(logging.INFO) self.test_port = os.environ.get('TEST_PORT', '9999') # Build a basic standalone agent using the config option defaults. # 127.0.0.1:6835 is the fake Ironic client. self.agent = agent.IronicPythonAgent( api_url='http://127.0.0.1:6835', advertise_address=agent.Host('localhost', 9999), listen_address=agent.Host(netutils.get_wildcard_address(), int(self.test_port)), ip_lookup_attempts=3, ip_lookup_sleep=10, network_interface=None, lookup_timeout=300, lookup_interval=1, standalone=True, agent_token=None) self.process = multiprocessing.Process(target=self.agent.run) self.process.start() self.addCleanup(self.process.terminate) # Wait for process to start, otherwise we have a race for tests sleep_time = 0.1 tries = 0 max_tries = int(os.environ.get('IPA_WAIT_TRIES', '100')) while tries < max_tries: try: return self.request('get', 'commands') except requests.ConnectionError: time.sleep(sleep_time) tries += 1 raise IOError('Agent did not start after %s seconds.' % (max_tries * sleep_time))