From 47be5fc735d737add0d6f36103a99d9b42d4bd79 Mon Sep 17 00:00:00 2001 From: Sam Morrison Date: Tue, 3 Nov 2020 18:16:43 +1100 Subject: Revert "Remove flavor API" Story: 2008309 Task: 41201 This reverts commit 910519127d8fb9880863eb219df68a574d00df6a. Change-Id: I77b72a965153e9583d93dee1f3a77d01a57e4ca2 --- trove/cluster/views.py | 5 ++- trove/common/api.py | 13 +++++++ trove/flavor/service.py | 51 ++++++++++++++++++++++++++++ trove/instance/views.py | 5 +++ trove/tests/api/instances.py | 2 +- trove/tests/scenario/runners/test_runners.py | 2 +- 6 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 trove/flavor/service.py diff --git a/trove/cluster/views.py b/trove/cluster/views.py index 8c3b559a..174ac14f 100644 --- a/trove/cluster/views.py +++ b/trove/cluster/views.py @@ -102,7 +102,10 @@ class ClusterView(object): return None def _build_flavor_info(self, flavor_id): - return {"id": flavor_id} + return { + "id": flavor_id, + "links": create_links("flavors", self.req, flavor_id) + } class ClusterInstanceDetailView(InstanceDetailView): diff --git a/trove/common/api.py b/trove/common/api.py index dbef09d3..98b4e2d3 100644 --- a/trove/common/api.py +++ b/trove/common/api.py @@ -21,6 +21,7 @@ from trove.common import wsgi from trove.configuration.service import ConfigurationsController from trove.configuration.service import ParametersController from trove.datastore.service import DatastoreController +from trove.flavor.service import FlavorController from trove.instance.service import InstanceController from trove.limits.service import LimitsController from trove.module.service import ModuleController @@ -35,6 +36,7 @@ class API(wsgi.Router): self._instance_router(mapper) self._cluster_router(mapper) self._datastore_router(mapper) + self._flavor_router(mapper) self._versions_router(mapper) self._limits_router(mapper) self._backups_router(mapper) @@ -168,6 +170,17 @@ class API(wsgi.Router): action="delete", conditions={'method': ['DELETE']}) + def _flavor_router(self, mapper): + flavor_resource = FlavorController().create_resource() + mapper.connect("/{tenant_id}/flavors", + controller=flavor_resource, + action="index", + conditions={'method': ['GET']}) + mapper.connect("/{tenant_id}/flavors/{id}", + controller=flavor_resource, + action="show", + conditions={'method': ['GET']}) + def _limits_router(self, mapper): limits_resource = LimitsController().create_resource() mapper.connect("/{tenant_id}/limits", diff --git a/trove/flavor/service.py b/trove/flavor/service.py new file mode 100644 index 00000000..fe16644a --- /dev/null +++ b/trove/flavor/service.py @@ -0,0 +1,51 @@ +# Copyright 2010-2012 OpenStack Foundation +# 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. + +from trove.common import exception +from trove.common import policy +from trove.common import wsgi +from trove.flavor import models +from trove.flavor import views + + +class FlavorController(wsgi.Controller): + """Controller for flavor functionality.""" + + def show(self, req, tenant_id, id): + """Return a single flavor.""" + context = req.environ[wsgi.CONTEXT_KEY] + self._validate_flavor_id(id) + flavor = models.Flavor(context=context, flavor_id=id) + # Flavors do not bind to a particular tenant. + # Only authorize the current tenant. + policy.authorize_on_tenant(context, 'flavor:show') + # Pass in the request to build accurate links. + return wsgi.Result(views.FlavorView(flavor, req).data(), 200) + + def index(self, req, tenant_id): + """Return all flavors.""" + context = req.environ[wsgi.CONTEXT_KEY] + policy.authorize_on_tenant(context, 'flavor:index') + flavors = models.Flavors(context=context) + return wsgi.Result(views.FlavorsView(flavors, req).data(), 200) + + def _validate_flavor_id(self, id): + if isinstance(id, str): + return + try: + if int(id) != float(id): + raise exception.NotFound(uuid=id) + except ValueError: + raise exception.NotFound(uuid=id) diff --git a/trove/instance/views.py b/trove/instance/views.py index 8fbb2c13..3dbf7958 100644 --- a/trove/instance/views.py +++ b/trove/instance/views.py @@ -86,8 +86,13 @@ class InstanceView(object): def _build_flavor_info(self): return { "id": self.instance.flavor_id, + "links": self._build_flavor_links() } + def _build_flavor_links(self): + return create_links("flavors", self.req, + self.instance.flavor_id) + def _build_master_info(self): return { "id": self.instance.slave_of_id, diff --git a/trove/tests/api/instances.py b/trove/tests/api/instances.py index f0b4517a..c36b692e 100644 --- a/trove/tests/api/instances.py +++ b/trove/tests/api/instances.py @@ -195,7 +195,7 @@ class CheckInstance(AttrCheck): if 'flavor' not in self.instance: self.fail("'flavor' not found in instance.") else: - allowed_attrs = ['id'] + allowed_attrs = ['id', 'links'] self.contains_allowed_attrs( self.instance['flavor'], allowed_attrs, msg="Flavor") diff --git a/trove/tests/scenario/runners/test_runners.py b/trove/tests/scenario/runners/test_runners.py index 350eeaf1..5fb3660f 100644 --- a/trove/tests/scenario/runners/test_runners.py +++ b/trove/tests/scenario/runners/test_runners.py @@ -985,7 +985,7 @@ class CheckInstance(AttrCheck): if 'flavor' not in self.instance: self.fail("'flavor' not found in instance.") else: - allowed_attrs = ['id'] + allowed_attrs = ['id', 'links'] self.contains_allowed_attrs( self.instance['flavor'], allowed_attrs, msg="Flavor") -- cgit v1.2.1