diff --git a/teeth_agent/errors.py b/teeth_agent/errors.py index c4ad93791..a28ba47d7 100644 --- a/teeth_agent/errors.py +++ b/teeth_agent/errors.py @@ -44,3 +44,13 @@ class InvalidCommandParamsError(errors.InvalidContentError): def __init__(self, details): super(InvalidCommandParamsError, self).__init__(details) + + +class HeartbeatError(errors.RESTError): + """Error raised when a heartbeat to the agent API fails.""" + + message = 'Error heartbeating to agent API.' + + def __init__(self, details): + super(HeartbeatError, self).__init__() + self.details = details diff --git a/teeth_agent/overlord_agent_api.py b/teeth_agent/overlord_agent_api.py new file mode 100644 index 000000000..82663afd2 --- /dev/null +++ b/teeth_agent/overlord_agent_api.py @@ -0,0 +1,66 @@ +""" +Copyright 2013 Rackspace, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +import requests + +from teeth_rest import encoding + +from teeth_agent import errors + + +class APIClient(object): + api_version = 'v1' + + def __init__(self, api_url): + self.api_url = api_url.rstrip('/') + self.session = requests.Session() + self.encoder = encoding.RESTJSONEncoder( + encoding.SerializationViews.PUBLIC) + + def _request(self, method, path, data=None): + request_url = '{api_url}{path}'.format(api_url=self.api_url, path=path) + + if data is not None: + data = self.encoder.encode(data) + + request_headers = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + } + + return self.session.put(request_url, + headers=request_headers, + data=data) + + def heartbeat(self, mac_addr, url, mode, version): + path = '/{api_version}/agents/{mac_addr}'.format( + api_version=self.api_version, + mac_addr=mac_addr) + + data = { + 'url': url, + 'mode': mode, + 'version': version, + } + + try: + response = self._request('PUT', path, data=data) + except Exception as e: + raise errors.HeartbeatError(str(e)) + + if response.status_code != requests.codes.NO_CONTENT: + msg = 'Invalid status code: {}'.format(response.status_code) + raise errors.HeartbeatError(msg)