Using advertise_address, using valid uuid/macs
This commit is contained in:
parent
56a0ed37a4
commit
d0323f3ec1
teeth_agent
@ -90,7 +90,10 @@ class TeethAgentHeartbeater(threading.Thread):
|
||||
|
||||
def do_heartbeat(self):
|
||||
try:
|
||||
deadline = self.api.heartbeat(uuid=self.agent.get_node_uuid())
|
||||
deadline = self.api.heartbeat(
|
||||
uuid=self.agent.get_node_uuid(),
|
||||
advertise_address=self.agent.advertise_address
|
||||
)
|
||||
self.error_delay = self.initial_delay
|
||||
self.log.info('heartbeat successful')
|
||||
except Exception:
|
||||
@ -109,10 +112,11 @@ class TeethAgentHeartbeater(threading.Thread):
|
||||
|
||||
|
||||
class TeethAgent(object):
|
||||
def __init__(self, api_url, listen_address):
|
||||
def __init__(self, api_url, advertise_address, listen_address):
|
||||
self.api_url = api_url
|
||||
self.api_client = overlord_agent_api.APIClient(self.api_url)
|
||||
self.listen_address = listen_address
|
||||
self.advertise_address = advertise_address
|
||||
self.mode_implementation = None
|
||||
self.version = pkg_resources.get_distribution('teeth-agent').version
|
||||
self.api = app.VersionSelectorApplication(self)
|
||||
@ -142,6 +146,8 @@ class TeethAgent(object):
|
||||
return self.hardware.get_primary_mac_address()
|
||||
|
||||
def get_node_uuid(self):
|
||||
if 'uuid' not in self.node:
|
||||
errors.HeartbeatError('Tried to heartbeat without node UUID.')
|
||||
return self.node['uuid']
|
||||
|
||||
def list_command_results(self):
|
||||
@ -234,5 +240,12 @@ def _load_mode_implementation(mode_name):
|
||||
return mgr.driver
|
||||
|
||||
|
||||
def build_agent(api_url, listen_host, listen_port):
|
||||
return TeethAgent(api_url, (listen_host, listen_port))
|
||||
def build_agent(api_url,
|
||||
advertise_host,
|
||||
advertise_port,
|
||||
listen_host,
|
||||
listen_port):
|
||||
|
||||
return TeethAgent(api_url=api_url,
|
||||
advertise_address=(advertise_host, advertise_port),
|
||||
listen_address=(listen_host, listen_port))
|
||||
|
@ -37,8 +37,22 @@ def run():
|
||||
default=9999,
|
||||
type=int,
|
||||
help='The port to listen on')
|
||||
|
||||
parser.add_argument('--advertise-host',
|
||||
default='0.0.0.0',
|
||||
type=str,
|
||||
help=('The port to tell Ironic to reply and send '
|
||||
'commands to. This is different than '
|
||||
'listen-host because Docker will have a '
|
||||
'different internal IP than the host IP that '
|
||||
'Ironic will be communicating with.'))
|
||||
parser.add_argument('--advertise-port',
|
||||
default=9999,
|
||||
type=int,
|
||||
help=('The port to tell Ironic to reply and send '
|
||||
'commands to.'))
|
||||
args = parser.parse_args()
|
||||
agent.build_agent(args.api_url,
|
||||
args.listen_host,
|
||||
args.listen_port).run()
|
||||
agent.build_agent(api_url=args.api_url,
|
||||
advertise_host=args.advertise_host,
|
||||
advertise_port=args.advertise_port,
|
||||
listen_host=args.listen_host,
|
||||
listen_port=args.listen_port).run()
|
||||
|
@ -46,13 +46,13 @@ class APIClient(object):
|
||||
headers=request_headers,
|
||||
data=data)
|
||||
|
||||
def heartbeat(self, uuid, listen_address):
|
||||
def heartbeat(self, uuid, advertise_address):
|
||||
path = '/{api_version}/nodes/{uuid}/vendor_passthru/heartbeat'.format(
|
||||
api_version=self.api_version,
|
||||
uuid=uuid
|
||||
)
|
||||
data = {
|
||||
'agent_url': self._get_agent_url(listen_address)
|
||||
'agent_url': self._get_agent_url(advertise_address)
|
||||
}
|
||||
try:
|
||||
response = self._request('POST', path, data=data)
|
||||
@ -74,6 +74,8 @@ class APIClient(object):
|
||||
path = '/{api_version}/drivers/teeth/lookup'.format(
|
||||
api_version=self.api_version
|
||||
)
|
||||
# This hardware won't be saved on the node currently, because of how
|
||||
# driver_vendor_passthru is implemented (no node saving).
|
||||
data = {
|
||||
'hardware': hardware_info,
|
||||
}
|
||||
@ -98,5 +100,6 @@ class APIClient(object):
|
||||
'{0}'.format(content))
|
||||
return content['node']
|
||||
|
||||
def _get_agent_url(self, listen_address):
|
||||
return "http://{0}:{1}".format(listen_address[0], listen_address[1])
|
||||
def _get_agent_url(self, advertise_address):
|
||||
return 'http://{0}:{1}'.format(advertise_address[0],
|
||||
advertise_address[1])
|
||||
|
@ -120,7 +120,8 @@ class TestBaseAgent(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.encoder = encoding.RESTJSONEncoder(indent=4)
|
||||
self.agent = agent.TeethAgent('https://fake_api.example.org:8081/',
|
||||
('localhost', 9999))
|
||||
('31.41.59.26', 9990),
|
||||
('42.42.42.42', 9999))
|
||||
|
||||
def assertEqualEncoded(self, a, b):
|
||||
# Evidently JSONEncoder.default() can't handle None (??) so we have to
|
||||
@ -164,7 +165,7 @@ class TestBaseAgent(unittest.TestCase):
|
||||
self.agent.api_client.lookup_node = mock.Mock()
|
||||
self.agent.run()
|
||||
|
||||
listen_addr = ('localhost', 9999)
|
||||
listen_addr = ('42.42.42.42', 9999)
|
||||
wsgi_server_cls.assert_called_once_with(
|
||||
listen_addr[0],
|
||||
listen_addr[1],
|
||||
|
@ -32,9 +32,9 @@ class TestBaseTeethAgent(unittest.TestCase):
|
||||
self.api_client = overlord_agent_api.APIClient(API_URL)
|
||||
self.hardware_info = [
|
||||
hardware.HardwareInfo(hardware.HardwareType.MAC_ADDRESS,
|
||||
'a:b:c:d'),
|
||||
'aa:bb:cc:dd:ee:ff'),
|
||||
hardware.HardwareInfo(hardware.HardwareType.MAC_ADDRESS,
|
||||
'0:1:2:3'),
|
||||
'ff:ee:dd:cc:bb:aa'),
|
||||
]
|
||||
|
||||
def test_successful_heartbeat(self):
|
||||
@ -47,16 +47,17 @@ class TestBaseTeethAgent(unittest.TestCase):
|
||||
self.api_client.session.request.return_value = response
|
||||
|
||||
heartbeat_before = self.api_client.heartbeat(
|
||||
uuid='fake-uuid',
|
||||
listen_address=('42.42.42.42', '9999')
|
||||
uuid='deadbeef-dabb-ad00-b105-f00d00bab10c',
|
||||
advertise_address=('42.42.42.42', '9999')
|
||||
)
|
||||
|
||||
self.assertEqual(heartbeat_before, expected_heartbeat_before)
|
||||
|
||||
heartbeat_path = 'v1/nodes/deadbeef-dabb-ad00-b105-f00d00bab10c/' \
|
||||
'vendor_passthru/heartbeat'
|
||||
request_args = self.api_client.session.request.call_args[0]
|
||||
self.assertEqual(request_args[0], 'POST')
|
||||
self.assertEqual(request_args[1], API_URL + 'v1/nodes/fake-uuid/vendor'
|
||||
'_passthru/heartbeat')
|
||||
self.assertEqual(request_args[1], API_URL + heartbeat_path)
|
||||
|
||||
def test_heartbeat_requests_exception(self):
|
||||
self.api_client.session.request = mock.Mock()
|
||||
@ -64,8 +65,8 @@ class TestBaseTeethAgent(unittest.TestCase):
|
||||
|
||||
self.assertRaises(errors.HeartbeatError,
|
||||
self.api_client.heartbeat,
|
||||
uuid='fake-uuid',
|
||||
listen_address=('42.42.42.42', '9999'))
|
||||
uuid='deadbeef-dabb-ad00-b105-f00d00bab10c',
|
||||
advertise_address=('42.42.42.42', '9999'))
|
||||
|
||||
def test_heartbeat_invalid_status_code(self):
|
||||
response = httmock.response(status_code=404)
|
||||
@ -74,8 +75,8 @@ class TestBaseTeethAgent(unittest.TestCase):
|
||||
|
||||
self.assertRaises(errors.HeartbeatError,
|
||||
self.api_client.heartbeat,
|
||||
uuid='fake-uuid',
|
||||
listen_address=('42.42.42.42', '9999'))
|
||||
uuid='deadbeef-dabb-ad00-b105-f00d00bab10c',
|
||||
advertise_address=('42.42.42.42', '9999'))
|
||||
|
||||
def test_heartbeat_missing_heartbeat_before_header(self):
|
||||
response = httmock.response(status_code=204)
|
||||
@ -84,8 +85,8 @@ class TestBaseTeethAgent(unittest.TestCase):
|
||||
|
||||
self.assertRaises(errors.HeartbeatError,
|
||||
self.api_client.heartbeat,
|
||||
uuid='fake-uuid',
|
||||
listen_address=('42.42.42.42', '9999'))
|
||||
uuid='deadbeef-dabb-ad00-b105-f00d00bab10c',
|
||||
advertise_address=('42.42.42.42', '9999'))
|
||||
|
||||
def test_heartbeat_invalid_heartbeat_before_header(self):
|
||||
response = httmock.response(status_code=204, headers={
|
||||
@ -96,13 +97,13 @@ class TestBaseTeethAgent(unittest.TestCase):
|
||||
|
||||
self.assertRaises(errors.HeartbeatError,
|
||||
self.api_client.heartbeat,
|
||||
uuid='fake-uuid',
|
||||
listen_address=('42.42.42.42', '9999'))
|
||||
uuid='deadbeef-dabb-ad00-b105-f00d00bab10c',
|
||||
advertise_address=('42.42.42.42', '9999'))
|
||||
|
||||
def test_lookup_node(self):
|
||||
response = httmock.response(status_code=200, content={
|
||||
'node': {
|
||||
'uuid': 'fake-uuid'
|
||||
'uuid': 'deadbeef-dabb-ad00-b105-f00d00bab10c'
|
||||
}
|
||||
})
|
||||
|
||||
@ -122,18 +123,18 @@ class TestBaseTeethAgent(unittest.TestCase):
|
||||
self.assertEqual(content['hardware'], [
|
||||
{
|
||||
'type': 'mac_address',
|
||||
'id': 'a:b:c:d',
|
||||
'id': 'aa:bb:cc:dd:ee:ff',
|
||||
},
|
||||
{
|
||||
'type': 'mac_address',
|
||||
'id': '0:1:2:3',
|
||||
'id': 'ff:ee:dd:cc:bb:aa',
|
||||
},
|
||||
])
|
||||
|
||||
def test_lookup_node_bad_response_code(self):
|
||||
response = httmock.response(status_code=400, content={
|
||||
'node': {
|
||||
'uuid': 'fake-uuid'
|
||||
'uuid': 'deadbeef-dabb-ad00-b105-f00d00bab10c'
|
||||
}
|
||||
})
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user