diff --git a/teeth_agent/agent.py b/teeth_agent/agent.py new file mode 100644 index 000000000..4211b5001 --- /dev/null +++ b/teeth_agent/agent.py @@ -0,0 +1,81 @@ +""" +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. +""" + +from collections import OrderedDict +import time + +from pkg_resources import get_distribution +from teeth_rest.encoding import Serializable +from werkzeug.serving import run_simple + +from teeth_agent.api import TeethAgentAPIServer + + +class TeethAgentOperationModes(object): + DECOM = 'DECOM' + STANDBY = 'STANDBY' + + @classmethod + def validate_mode(cls, mode): + if not hasattr(cls, mode) or getattr(cls, mode) != mode: + raise RuntimeError('Invalid mode: {}'.format(mode)) + + +class TeethAgentStatus(Serializable): + def __init__(self, mode, started_at, version): + self.mode = mode + self.started_at = started_at + self.version = version + + def serialize(self, view): + """ + Turn the status into a dict. + """ + return OrderedDict([ + ('mode', self.mode), + ('started_at', self.started_at), + ('version', self.version), + ]) + + +class TeethAgent(object): + def __init__(self, listen_host, listen_port, mode): + TeethAgentOperationModes.validate_mode(mode) + self.listen_host = listen_host + self.listen_port = listen_port + self.started_at = None + self.mode = mode + self.api = TeethAgentAPIServer(self) + + def get_status(self): + """ + Retrieve a serializable status. + """ + return TeethAgentStatus( + mode=self.mode, + started_at=self.started_at, + version=get_distribution('teeth-agent').version + ) + + def run(self): + """ + Run the Teeth Agent. + """ + if self.started_at: + raise RuntimeError('Agent was already started') + + self.started_at = time.time() + run_simple(self.listen_host, self.listen_port, self.api) diff --git a/teeth_agent/api.py b/teeth_agent/api.py new file mode 100644 index 000000000..740ad58b3 --- /dev/null +++ b/teeth_agent/api.py @@ -0,0 +1,52 @@ +""" +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. +""" + +from teeth_rest.component import APIComponent, APIServer +from teeth_rest.responses import ( + ItemResponse +) + + +class TeethAgentAPI(APIComponent): + """ + The primary Teeth Agent API. + """ + + def __init__(self, agent): + super(TeethAgentAPI, self).__init__() + self.agent = agent + + def add_routes(self): + """ + Called during initialization. Override to map relative routes to methods. + """ + self.route('GET', '/status', self.get_agent_status) + + def get_agent_status(self, request): + """ + Get the status of the agent. + """ + return ItemResponse(self.agent.get_status()) + + +class TeethAgentAPIServer(APIServer): + """ + Server for the teeth agent API. + """ + + def __init__(self, agent): + super(TeethAgentAPIServer, self).__init__() + self.add_component('/v1.0', TeethAgentAPI(agent)) diff --git a/teeth_agent/cmd/agent.py b/teeth_agent/cmd/agent.py index 431293b09..359323391 100644 --- a/teeth_agent/cmd/agent.py +++ b/teeth_agent/cmd/agent.py @@ -14,6 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. """ +from teeth_agent.agent import TeethAgent + def run(): - pass + agent = TeethAgent('0.0.0.0', 9999, 'STANDBY') + agent.run()