From 209182d96d6fc1fb92bbd55e63105c79f6da090c Mon Sep 17 00:00:00 2001 From: Sudarshan Acharya Date: Wed, 11 Apr 2012 17:16:25 -0500 Subject: [PATCH 1/2] Started the mgmt framework. --- reddwarf/extensions/mgmt.py | 56 ++++++++++++++++++ reddwarf/extensions/mgmt/__init__.py | 16 +++++ reddwarf/extensions/mgmt/service.py | 88 ++++++++++++++++++++++++++++ reddwarf/extensions/mgmt/views.py | 63 ++++++++++++++++++++ 4 files changed, 223 insertions(+) create mode 100644 reddwarf/extensions/mgmt.py create mode 100644 reddwarf/extensions/mgmt/__init__.py create mode 100644 reddwarf/extensions/mgmt/service.py create mode 100644 reddwarf/extensions/mgmt/views.py diff --git a/reddwarf/extensions/mgmt.py b/reddwarf/extensions/mgmt.py new file mode 100644 index 0000000000..6379744219 --- /dev/null +++ b/reddwarf/extensions/mgmt.py @@ -0,0 +1,56 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# All Rights Reserved. +# +# 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 logging + +from reddwarf.common import extensions +from reddwarf.common import wsgi +from reddwarf.extensions.mgmt import service + + +LOG = logging.getLogger(__name__) + + +class Mgmt(extensions.ExtensionsDescriptor): + + def get_name(self): + return "Mgmt" + + def get_description(self): + return "MGMT services such as details diagnostics" + + def get_alias(self): + return "Mgmt" + + def get_namespace(self): + return "http://TBD" + + def get_updated(self): + return "2011-01-22T13:25:27-06:00" + + def get_resources(self): + resources = [] + serializer = wsgi.ReddwarfResponseSerializer( + body_serializers={'application/xml': + wsgi.ReddwarfXMLDictSerializer()}) + resource = extensions.ResourceExtension('{tenant_id}/mgmt/instances', + service.InstanceController(), + deserializer=wsgi.RequestDeserializer(), + serializer=serializer) + resources.append(resource) + + return resources \ No newline at end of file diff --git a/reddwarf/extensions/mgmt/__init__.py b/reddwarf/extensions/mgmt/__init__.py new file mode 100644 index 0000000000..d65c689a83 --- /dev/null +++ b/reddwarf/extensions/mgmt/__init__.py @@ -0,0 +1,16 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# All Rights Reserved. +# +# 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. diff --git a/reddwarf/extensions/mgmt/service.py b/reddwarf/extensions/mgmt/service.py new file mode 100644 index 0000000000..3e12e78d52 --- /dev/null +++ b/reddwarf/extensions/mgmt/service.py @@ -0,0 +1,88 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# All Rights Reserved. +# +# 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 logging +import webob.exc + +from reddwarf.common import exception, config +from reddwarf.common import wsgi +from reddwarf.instance import models as instance_models +from reddwarf.extensions.mgmt import views + +LOG = logging.getLogger(__name__) + + +class BaseController(wsgi.Controller): + """Base controller class.""" + + exclude_attr = [] + exception_map = { + webob.exc.HTTPUnprocessableEntity: [ + exception.UnprocessableEntity, + ], + webob.exc.HTTPBadRequest: [ + exception.BadRequest, + ], + webob.exc.HTTPNotFound: [ + exception.NotFound, + instance_models.ModelNotFoundError, + ], + webob.exc.HTTPConflict: [ + ], + } + + def __init__(self): + self.add_addresses = config.Config.get('add_addresses', False) + pass + + def _extract_required_params(self, params, model_name): + params = params or {} + model_params = params.get(model_name, {}) + return utils.stringify_keys(utils.exclude(model_params, + *self.exclude_attr)) + + +class InstanceController(BaseController): + """Controller for instance functionality""" + + def index(self, req, tenant_id, detailed=False): + """Return all instances.""" + LOG.info(_("req : '%s'\n\n") % req) + LOG.info(_("Indexing a database instance for tenant '%s'") % tenant_id) + # TODO(sacharya): Load all servers from nova? + context = req.environ[wsgi.CONTEXT_KEY] + servers = instance_models.Instances.load(context) + + view_cls = views.InstancesView + return wsgi.Result(view_cls(servers, + add_addresses=self.add_addresses).data(), 200) + + def show(self, req, tenant_id, id): + """Return a single instance.""" + LOG.info(_("req : '%s'\n\n") % req) + LOG.info(_("Showing a database instance for tenant '%s'") % tenant_id) + LOG.info(_("id : '%s'\n\n") % id) + + context = req.environ[wsgi.CONTEXT_KEY] + try: + server = instance_models.Instance.load(context=context, id=id) + except exception.ReddwarfError, e: + LOG.error(e) + return wsgi.Result(str(e), 404) + return wsgi.Result(views.InstanceView(server, + add_addresses=self.add_addresses).data(), 200) + diff --git a/reddwarf/extensions/mgmt/views.py b/reddwarf/extensions/mgmt/views.py new file mode 100644 index 0000000000..577b3deaf8 --- /dev/null +++ b/reddwarf/extensions/mgmt/views.py @@ -0,0 +1,63 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# All Rights Reserved. +# +# 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. + + +def get_ip_address(addresses): + if addresses is not None and \ + addresses.get('private') is not None and \ + len(addresses['private']) > 0: + return [addr.get('addr') for addr in addresses['private']] + + +class InstanceView(object): + + def __init__(self, instance, add_addresses=False): + self.instance = instance + self.add_addresses = add_addresses + + def data(self): + ip = get_ip_address(self.instance.addresses) + instance_dict = { + "tenant_id": self.instance.server.tenant_id, + "id": self.instance.id, + "name": self.instance.name, + "status": self.instance.status, + "links": self.instance.links, + "created": self.instance.created, + "flavor": self.instance.flavor, + "updated": self.instance.updated + } + if self.add_addresses and ip is not None and len(ip) > 0: + instance_dict['ip'] = ip + return {"instance": instance_dict} + +class InstancesView(InstanceView): + + def __init__(self, instances, add_addresses=False): + self.instances = instances + self.add_addresses = add_addresses + + def data(self): + data = [] + # These are model instances + for instance in self.instances: + data.append(self.data_for_instance(instance)) + return {'instances': data} + + def data_for_instance(self, instance): + return InstanceView(instance, + self.add_addresses).data()['instance'] From f5f1a152d6afe0e530ff2ccd78b15c8afb4c7b44 Mon Sep 17 00:00:00 2001 From: Sudarshan Acharya Date: Mon, 23 Apr 2012 12:11:44 -0500 Subject: [PATCH 2/2] Extending mgmt api from core instancce api. --- reddwarf/extensions/mgmt.py | 2 +- reddwarf/extensions/mgmt/service.py | 35 +++-------------------------- 2 files changed, 4 insertions(+), 33 deletions(-) diff --git a/reddwarf/extensions/mgmt.py b/reddwarf/extensions/mgmt.py index 6379744219..c16127ac86 100644 --- a/reddwarf/extensions/mgmt.py +++ b/reddwarf/extensions/mgmt.py @@ -48,7 +48,7 @@ class Mgmt(extensions.ExtensionsDescriptor): body_serializers={'application/xml': wsgi.ReddwarfXMLDictSerializer()}) resource = extensions.ResourceExtension('{tenant_id}/mgmt/instances', - service.InstanceController(), + service.MgmtInstanceController(), deserializer=wsgi.RequestDeserializer(), serializer=serializer) resources.append(resource) diff --git a/reddwarf/extensions/mgmt/service.py b/reddwarf/extensions/mgmt/service.py index 3e12e78d52..6adbdb2526 100644 --- a/reddwarf/extensions/mgmt/service.py +++ b/reddwarf/extensions/mgmt/service.py @@ -18,45 +18,16 @@ import logging import webob.exc -from reddwarf.common import exception, config +from reddwarf.common import exception from reddwarf.common import wsgi from reddwarf.instance import models as instance_models from reddwarf.extensions.mgmt import views +from reddwarf.instance.service import InstanceController LOG = logging.getLogger(__name__) -class BaseController(wsgi.Controller): - """Base controller class.""" - - exclude_attr = [] - exception_map = { - webob.exc.HTTPUnprocessableEntity: [ - exception.UnprocessableEntity, - ], - webob.exc.HTTPBadRequest: [ - exception.BadRequest, - ], - webob.exc.HTTPNotFound: [ - exception.NotFound, - instance_models.ModelNotFoundError, - ], - webob.exc.HTTPConflict: [ - ], - } - - def __init__(self): - self.add_addresses = config.Config.get('add_addresses', False) - pass - - def _extract_required_params(self, params, model_name): - params = params or {} - model_params = params.get(model_name, {}) - return utils.stringify_keys(utils.exclude(model_params, - *self.exclude_attr)) - - -class InstanceController(BaseController): +class MgmtInstanceController(InstanceController): """Controller for instance functionality""" def index(self, req, tenant_id, detailed=False):