From ea8cbaa077ffa96fa0e0bd528fb8098ac4274a98 Mon Sep 17 00:00:00 2001 From: Steven Dake Date: Wed, 19 Nov 2014 10:53:45 -0700 Subject: [PATCH] Add initial conductor API and service Add an initial conductor API and service. This service allows operation on the four object types -> bays, pods, services, and containers and allows the ability to list, read, write, or delete those objects in the database. The implementation of the list/read/write/delete is incomplete and should come in a follow-up patch. Change-Id: I60e9070e4b5aeaeddba67233b99dd0e3a3cffe22 --- magnum/cmd/conductor.py | 46 ++++++++++++++ magnum/conductor/__init__.py | 0 magnum/conductor/api.py | 88 +++++++++++++++++++++++++++ magnum/conductor/config.py | 33 ++++++++++ magnum/conductor/handlers/__init__.py | 0 magnum/conductor/handlers/default.py | 82 +++++++++++++++++++++++++ setup.cfg | 1 + 7 files changed, 250 insertions(+) create mode 100644 magnum/cmd/conductor.py create mode 100644 magnum/conductor/__init__.py create mode 100644 magnum/conductor/api.py create mode 100644 magnum/conductor/config.py create mode 100644 magnum/conductor/handlers/__init__.py create mode 100644 magnum/conductor/handlers/default.py diff --git a/magnum/cmd/conductor.py b/magnum/cmd/conductor.py new file mode 100644 index 0000000000..ae17aec041 --- /dev/null +++ b/magnum/cmd/conductor.py @@ -0,0 +1,46 @@ +# Copyright 2014 - Rackspace Hosting +# +# 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. + +"""Starter script for the Magnum Conductor service.""" + +import logging as std_logging +import os +import sys + +from oslo.config import cfg + +from magnum.common.rpc import service +from magnum.conductor.handlers import default as default_handler +from magnum.openstack.common._i18n import _ +from magnum.openstack.common import log as logging + +LOG = logging.getLogger(__name__) + + +def main(): + cfg.CONF(sys.argv[1:], project='magnum') + logging.setup('magnum') + + LOG.info(_('Starting server in PID %s') % os.getpid()) + LOG.debug("Configuration:") + cfg.CONF.log_opt_values(LOG, std_logging.DEBUG) + + cfg.CONF.import_opt('topic', 'magnum.conductor.config', group='conductor') + cfg.CONF.import_opt('host', 'magnum.conductor.config', group='conductor') + endpoints = [ + default_handler.Handler(), + ] + server = service.Service(cfg.CONF.conductor.topic, + cfg.CONF.conductor.host, endpoints) + server.serve() diff --git a/magnum/conductor/__init__.py b/magnum/conductor/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/magnum/conductor/api.py b/magnum/conductor/api.py new file mode 100644 index 0000000000..96a4409554 --- /dev/null +++ b/magnum/conductor/api.py @@ -0,0 +1,88 @@ +# 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. + +"""API for interfacing with Magnum Conductor.""" + +from oslo.config import cfg + +from magnum.common.rpc import service + + +# The Conductor API class serves as a AMQP client for communicating +# on a topic exchange specific to the conductor. This allows all database +# access to execute. + +class API(service.API): + def __init__(self, transport=None, context=None): + cfg.CONF.import_opt('topic', 'magnum.conductor.config', + group='conductor') + super(API, self).__init__(transport, context, + topic=cfg.CONF.conductor.topic) + + # Get objects from database + + def bay_get(self, uuid): + return self._call('bay_get', uuid=uuid) + + def service_get(self, uuid): + return self._call('service_get', uuid=uuid) + + def pod_get(self, uuid): + return self._call('pod_get', uuid=uuid) + + def container_get(self, uuid): + return self._call('container_get', uuid=uuid) + + # Put objects into database + + def bay_put(self, uuid=None, contents=None): + self._cast('bay_get', uuid=uuid, contents=contents) + + def service_put(self, uuid=None, contents=None): + self._cast('service_get', uuid=uuid, contents=contents) + + def pod_put(self, uuid=None, contents=None): + self._cast('pod_get', uuid=uuid, contents=contents) + + def container_put(self, uuid=None, contents=None): + self._cast('container_get', uuid=uuid, contents=contents) + + # Delete objects from database + + def bay_delete(self, uuid): + self._cast('bay_delete', uuid=uuid) + + def service_delete(self, uuid): + self._cast('service_delete', uuid=uuid) + + def pod_delete(self, uuid): + self._cast('pod_delete', uuid=uuid) + + def container_delete(self, uuid): + self._cast('container_delete', uuid=uuid) + + # List objects from database + # + # TODO(sdake) - this could probably use some filters and + # pagination for scalability + + def bay_list(self): + return self._call('bay_list') + + def service_list(self): + return self._call('service_list') + + def pod_list(self): + return self._call('pod_list') + + def container_list(self): + return self._call('container_list') diff --git a/magnum/conductor/config.py b/magnum/conductor/config.py new file mode 100644 index 0000000000..01177f3ef4 --- /dev/null +++ b/magnum/conductor/config.py @@ -0,0 +1,33 @@ +# Copyright 2014 - Rackspace Hosting +# +# 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. + +"""Config options for Magnum Conductor service.""" + + +from oslo.config import cfg + +SERVICE_OPTS = [ + cfg.StrOpt('topic', + default='magnum-conductor', + help='The queue to add conductor tasks to'), + cfg.StrOpt('host', + default='localhost', + help='The location of the conductor rpc queue'), +] + +opt_group = cfg.OptGroup( + name='conductor', + title='Options for the magnum-conductor service') +cfg.CONF.register_group(opt_group) +cfg.CONF.register_opts(SERVICE_OPTS, opt_group) diff --git a/magnum/conductor/handlers/__init__.py b/magnum/conductor/handlers/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/magnum/conductor/handlers/default.py b/magnum/conductor/handlers/default.py new file mode 100644 index 0000000000..4b0ba783f2 --- /dev/null +++ b/magnum/conductor/handlers/default.py @@ -0,0 +1,82 @@ +# 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. + +"""Magnum Conductor default handler.""" + +from magnum.openstack.common import log as logging + +LOG = logging.getLogger(__name__) + + +# These are the database operations - They are executed by the conductor +# service. API calls via AMQP trigger the handlers to be called. + +class Handler(object): + def __init__(self): + super(Handler, self).__init__() + # Open DB here I suspect + + def bay_get(uuid): + LOG.debug("bay_get %s" % uuid) + # return bay information dict + + def service_get(uuid): + LOG.debug("service_get %s" % uuid) + # return service information dict + + def pod_get(uuid): + LOG.debug("pod_get %s" % uuid) + # return pod information dict + + def container_get(uuid): + LOG.debug("container_get %s" % uuid) + # return container information dict + + def bay_put(uuid, contents): + LOG.debug("bay_put %s contents=%s" % (uuid, contents)) + + def service_put(uuid, contents): + LOG.debug("service_put %s contents=%s" % (uuid, contents)) + + def pod_put(uuid, contents): + LOG.debug("pod_put %s contents=%s" % (uuid, contents)) + + def container_put(uuid, contents): + LOG.debug("container_put %s contents=%s" % (uuid, contents)) + + def bay_delete(uuid): + LOG.debug("bay_delete %s" % uuid) + + def service_delete(uuid): + LOG.debug("bay_delete %s" % uuid) + + def pod_delete(uuid): + LOG.debug("pod_delete %s" % uuid) + + def container_delete(uuid): + LOG.debug("cotainer_delete %s" % uuid) + + def bay_list(): + LOG.debug("bay_list") + # return bay list dict + + def service_list(): + LOG.debug("service_list") + # return service list dict + + def pod_list(): + LOG.debug("pod_list") + # return pod list dict + + def container_list(): + LOG.debug("container_list") + # return container list dict diff --git a/setup.cfg b/setup.cfg index c6491cf017..5f7873276d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -46,6 +46,7 @@ output_file = magnum/locale/magnum.pot [entry_points] console_scripts = magnum-api = magnum.cmd.api:main + magnum-conductor = magnum.cmd.conductor:main [wheel] universal = 1