From 15c63e8b46e7a3cf6f6ebd32d56a8fc75add97d0 Mon Sep 17 00:00:00 2001 From: Russell Haering <russell.haering@rackspace.com> Date: Sat, 21 Dec 2013 17:22:09 -0800 Subject: [PATCH] begin hacking on command execution --- teeth_agent/base.py | 7 ++++++- teeth_agent/errors.py | 36 ++++++++++++++++++++++++++++++++++++ teeth_agent/standby.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 teeth_agent/errors.py diff --git a/teeth_agent/base.py b/teeth_agent/base.py index c9c82a564..2df99446b 100644 --- a/teeth_agent/base.py +++ b/teeth_agent/base.py @@ -22,6 +22,7 @@ from teeth_rest import encoding from werkzeug import serving from teeth_agent import api +from teeth_agent import errors class TeethAgentStatus(encoding.Serializable): @@ -46,6 +47,7 @@ class BaseTeethAgent(object): self.started_at = None self.mode = mode self.api = api.TeethAgentAPIServer(self) + self.command_map = {} def get_status(self): """Retrieve a serializable status.""" @@ -57,7 +59,10 @@ class BaseTeethAgent(object): def execute_command(self, command_name, **kwargs): """Execute an agent command.""" - pass + if command_name not in self.command_map: + raise errors.InvalidCommandError(command_name) + + self.comand_map[command_name](**kwargs) def run(self): """Run the Teeth Agent.""" diff --git a/teeth_agent/errors.py b/teeth_agent/errors.py new file mode 100644 index 000000000..3dd4b8fe5 --- /dev/null +++ b/teeth_agent/errors.py @@ -0,0 +1,36 @@ +""" +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 import errors + + +class InvalidCommandError(errors.InvalidContentError): + """Error which is raised when an unknown command is issued.""" + + messsage = 'Unknown command' + + def __init__(self, command_name): + details = 'Command \'{}\' is unknown.'.format(command_name) + super(InvalidCommandError, self).__init__(details) + + +class InvalidCommandParamsError(errors.InvalidContentError): + """Error which is raised when command parameters are invalid.""" + + message = 'Invalid command parameters' + + def __init__(self, details): + super(InvalidCommandParamsError, self).__init__(details) diff --git a/teeth_agent/standby.py b/teeth_agent/standby.py index 70539fb02..504c6d7a4 100644 --- a/teeth_agent/standby.py +++ b/teeth_agent/standby.py @@ -15,8 +15,37 @@ limitations under the License. """ from teeth_agent import base +from teeth_agent import errors class StandbyAgent(base.BaseTeethAgent): def __init__(self, listen_host, listen_port): super(StandbyAgent, self).__init__(listen_host, listen_port, 'STANDBY') + + self.command_map = { + 'standby.cache_images': self.cache_images, + } + + def _validate_image_info(self, image_info): + for field in ['id', 'urls', 'hashes']: + if field not in image_info: + msg = 'Image is missing \'{}\' field.'.format(field) + raise errors.InvalidCommandParamsError(msg) + + if type(image_info['urls']) != list: + raise errors.InvalidCommandParamsError( + 'Image \'urls\' must be a list.') + + if type(image_info['hashes']) != dict: + raise errors.InvalidCommandParamsError( + 'Image \'hashes\' must be a dictionary.') + + def cache_images(self, image_infos): + if type(image_infos) != list: + raise errors.InvalidCommandParamsError( + '\'image_infos\' parameter must be a list.') + + for image_info in image_infos: + self._validate_image_info(image_info) + + # TODO(russellhaering): Actually cache images