Hierarchy levels API handled in the fuel2
Referecne to level values added to DB model and level marshalling. Fuel2 commands lvl show, lvl list added. Change-Id: I11fb465c00c411464d75229fc2f8bffdbb8dcc53 Closes-Bug: #1642326
This commit is contained in:
parent
ed1760d83e
commit
70158d0e1f
@ -68,6 +68,8 @@ tuning_box.cli =
|
||||
def_show = tuning_box.cli.resource_definitions:ShowResourceDefinition
|
||||
def_delete = tuning_box.cli.resource_definitions:DeleteResourceDefinition
|
||||
def_update = tuning_box.cli.resource_definitions:UpdateResourceDefinition
|
||||
lvl_list = tuning_box.cli.hierarchy_levels:ListHierarchyLevels
|
||||
lvl_show = tuning_box.cli.hierarchy_levels:ShowHierarchyLevel
|
||||
fuelclient =
|
||||
config_get = tuning_box.fuelclient:Get
|
||||
config_set = tuning_box.fuelclient:Set
|
||||
@ -89,6 +91,8 @@ fuelclient =
|
||||
config_def_show = tuning_box.fuelclient:ShowResourceDefinition
|
||||
config_def_delete = tuning_box.fuelclient:DeleteResourceDefinition
|
||||
config_def_update = tuning_box.fuelclient:UpdateResourceDefinition
|
||||
config_lvl_list = tuning_box.fuelclient:ListHierarchyLevels
|
||||
config_lvl_show = tuning_box.fuelclient:ShowHierarchyLevel
|
||||
console_scripts =
|
||||
tuningbox_db_upgrade = tuning_box.migration:upgrade
|
||||
tuningbox_db_downgrade = tuning_box.migration:downgrade
|
||||
|
@ -95,7 +95,7 @@ api.add_resource(
|
||||
api.add_resource(
|
||||
hierarchy_levels.EnvironmentHierarchyLevels,
|
||||
'/environments/<int:environment_id>/hierarchy_levels/'
|
||||
'<string:level>'
|
||||
'<id_or_name:id_or_name>'
|
||||
)
|
||||
|
||||
|
||||
|
@ -99,7 +99,7 @@ class BaseOneCommand(BaseCommand):
|
||||
parser.add_argument(
|
||||
'id',
|
||||
type=int,
|
||||
help='Id of the {0} to delete.'.format(self.entity_name))
|
||||
help='Id of the {0}'.format(self.entity_name))
|
||||
return parser
|
||||
|
||||
def get_url(self, parsed_args):
|
||||
|
71
tuning_box/cli/hierarchy_levels.py
Normal file
71
tuning_box/cli/hierarchy_levels.py
Normal file
@ -0,0 +1,71 @@
|
||||
# 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 cliff import lister
|
||||
from cliff import show
|
||||
from fuelclient.cli import error as fc_error
|
||||
from fuelclient.common import data_utils
|
||||
|
||||
from tuning_box.cli import base
|
||||
|
||||
|
||||
class HierarchyLevelsCommand(base.BaseCommand):
|
||||
columns = ('id', 'name', 'parent', 'values')
|
||||
|
||||
def get_parser(self, *args, **kwargs):
|
||||
parser = super(HierarchyLevelsCommand, self).get_parser(
|
||||
*args, **kwargs)
|
||||
parser.add_argument(
|
||||
'-e', '--env',
|
||||
type=int,
|
||||
required=True,
|
||||
help="ID of environment to get data from",
|
||||
)
|
||||
return parser
|
||||
|
||||
def get_base_url(self, parsed_args):
|
||||
return '/environments/{}/hierarchy_levels'.format(parsed_args.env)
|
||||
|
||||
|
||||
class ListHierarchyLevels(HierarchyLevelsCommand, lister.Lister):
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
result = self.get_client().get(self.get_base_url(parsed_args))
|
||||
try:
|
||||
data = data_utils.get_display_data_multi(self.columns, result)
|
||||
return self.columns, data
|
||||
except fc_error.BadDataException:
|
||||
return zip(*result.items())
|
||||
|
||||
|
||||
class ShowHierarchyLevel(HierarchyLevelsCommand, show.ShowOne):
|
||||
|
||||
def get_parser(self, *args, **kwargs):
|
||||
parser = super(ShowHierarchyLevel, self).get_parser(*args, **kwargs)
|
||||
parser.add_argument(
|
||||
'name',
|
||||
type=str,
|
||||
help='Hierarchy level name'
|
||||
)
|
||||
return parser
|
||||
|
||||
def get_url(self, parsed_args):
|
||||
base_url = self.get_base_url(parsed_args)
|
||||
return base_url + '/{0}'.format(parsed_args.name)
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
result = self.get_client().get(self.get_url(parsed_args))
|
||||
try:
|
||||
data = data_utils.get_display_data_single(self.columns, result)
|
||||
return self.columns, data
|
||||
except fc_error.BadDataException:
|
||||
return zip(*result.items())
|
@ -196,6 +196,8 @@ class EnvironmentHierarchyLevel(ModelMixin, db.Model):
|
||||
env_levels.append(env_levels[-1].child)
|
||||
return env_levels
|
||||
|
||||
values = db.relationship('EnvironmentHierarchyLevelValue')
|
||||
|
||||
|
||||
class EnvironmentHierarchyLevelValue(ModelMixin, db.Model):
|
||||
level_id = fk(EnvironmentHierarchyLevel, ondelete='CASCADE')
|
||||
|
@ -19,6 +19,7 @@ from tuning_box import cli
|
||||
from tuning_box.cli import base as cli_base
|
||||
from tuning_box.cli import components
|
||||
from tuning_box.cli import environments
|
||||
from tuning_box.cli import hierarchy_levels
|
||||
from tuning_box.cli import resource_definitions
|
||||
from tuning_box.cli import resources
|
||||
from tuning_box import client as tb_client
|
||||
@ -147,6 +148,20 @@ class UpdateResourceDefinition(
|
||||
pass
|
||||
|
||||
|
||||
class ListHierarchyLevels(
|
||||
FuelBaseCommand,
|
||||
hierarchy_levels.ListHierarchyLevels
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
class ShowHierarchyLevel(
|
||||
FuelBaseCommand,
|
||||
hierarchy_levels.ShowHierarchyLevel
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
class Config(command.Command):
|
||||
def get_parser(self, *args, **kwargs):
|
||||
parser = super(Config, self).get_parser(*args, **kwargs)
|
||||
|
@ -60,9 +60,11 @@ def get_environment_level_value(environment, levels):
|
||||
|
||||
|
||||
environment_hierarchy_level_fields = {
|
||||
'id': fields.Integer,
|
||||
'name': fields.String,
|
||||
'environment_id': fields.Integer,
|
||||
'parent': fields.String(attribute='parent.name')
|
||||
'parent': fields.String(attribute='parent.name'),
|
||||
'values': fields.List(fields.String(attribute='value'))
|
||||
}
|
||||
|
||||
|
||||
@ -81,22 +83,28 @@ class EnvironmentHierarchyLevels(flask_restful.Resource):
|
||||
flask_restful.marshal_with(environment_hierarchy_level_fields)
|
||||
]
|
||||
|
||||
def get(self, environment_id, level):
|
||||
level = db.find_or_404(db.EnvironmentHierarchyLevel,
|
||||
environment_id=environment_id,
|
||||
name=level)
|
||||
def _get_query_params(self, environment_id, id_or_name):
|
||||
params = {'environment_id': environment_id}
|
||||
if isinstance(id_or_name, int):
|
||||
params['id'] = id_or_name
|
||||
else:
|
||||
params['name'] = id_or_name
|
||||
return params
|
||||
|
||||
def get(self, environment_id, id_or_name):
|
||||
params = self._get_query_params(environment_id, id_or_name)
|
||||
level = db.find_or_404(db.EnvironmentHierarchyLevel, **params)
|
||||
return level
|
||||
|
||||
@db.with_transaction
|
||||
def _do_update(self, environment_id, level):
|
||||
level = db.find_or_404(db.EnvironmentHierarchyLevel,
|
||||
environment_id=environment_id,
|
||||
name=level)
|
||||
def _do_update(self, environment_id, id_or_name):
|
||||
params = self._get_query_params(environment_id, id_or_name)
|
||||
level = db.find_or_404(db.EnvironmentHierarchyLevel, **params)
|
||||
level.name = flask.request.json.get('name', level.name)
|
||||
|
||||
def put(self, environment_id, level):
|
||||
return self.patch(environment_id, level)
|
||||
def put(self, environment_id, id_or_name):
|
||||
return self.patch(environment_id, id_or_name)
|
||||
|
||||
def patch(self, environment_id, level):
|
||||
self._do_update(environment_id, level)
|
||||
def patch(self, environment_id, id_or_name):
|
||||
self._do_update(environment_id, id_or_name)
|
||||
return None, 204
|
||||
|
67
tuning_box/tests/cli/test_hierarchy_levels.py
Normal file
67
tuning_box/tests/cli/test_hierarchy_levels.py
Normal file
@ -0,0 +1,67 @@
|
||||
# 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 testscenarios
|
||||
|
||||
from tuning_box.tests.cli import _BaseCLITest
|
||||
|
||||
|
||||
class TestHierarchyLevels(testscenarios.WithScenarios, _BaseCLITest):
|
||||
|
||||
scenarios = [
|
||||
(s[0], dict(zip(('mock_url', 'args', 'expected_result'), s[1])))
|
||||
for s in [
|
||||
('json', ('/environments/9/hierarchy_levels',
|
||||
'lvl list -e 9 -f json', '[]')),
|
||||
('yaml', ('/environments/9/hierarchy_levels',
|
||||
'lvl list -e 9 -f yaml', '[]\n'))
|
||||
]
|
||||
]
|
||||
mock_url = None
|
||||
args = None
|
||||
expected_result = None
|
||||
|
||||
def test_get(self):
|
||||
self.req_mock.get(
|
||||
self.BASE_URL + self.mock_url,
|
||||
headers={'Content-Type': 'application/json'},
|
||||
json={},
|
||||
)
|
||||
self.cli.run(self.args.split())
|
||||
self.assertEqual(self.expected_result, self.cli.stdout.getvalue())
|
||||
|
||||
|
||||
class TestShowHierarchyLevel(testscenarios.WithScenarios, _BaseCLITest):
|
||||
|
||||
scenarios = [
|
||||
(s[0], dict(zip(('mock_url', 'args', 'expected_result'), s[1])))
|
||||
for s in [
|
||||
('json', ('/environments/9/hierarchy_levels/n',
|
||||
'lvl show -e 9 -f json -c id n',
|
||||
'{\n "id": 1\n}')),
|
||||
('yaml', ('/environments/9/hierarchy_levels/nn',
|
||||
'lvl show -e 9 -f yaml -c id nn',
|
||||
'id: 1\n'))
|
||||
]
|
||||
]
|
||||
mock_url = None
|
||||
args = None
|
||||
expected_result = None
|
||||
|
||||
def test_get(self):
|
||||
self.req_mock.get(
|
||||
self.BASE_URL + self.mock_url,
|
||||
headers={'Content-Type': 'application/json'},
|
||||
json={'id': 1},
|
||||
)
|
||||
self.cli.run(self.args.split())
|
||||
self.assertEqual(self.expected_result, self.cli.stdout.getvalue())
|
@ -47,6 +47,31 @@ class TestLevelsHierarchy(BaseTest):
|
||||
self.assertEqual(level.name, 'lvl1')
|
||||
self.assertIsNone(level.parent)
|
||||
|
||||
def test_get_environment_level_values(self):
|
||||
self._fixture()
|
||||
env_id = 9
|
||||
with self.app.app_context(), db.db.session.begin():
|
||||
# Creating level values
|
||||
hierarchy_levels.get_environment_level_value(
|
||||
db.Environment(id=env_id),
|
||||
[('lvl1', 'val11'), ('lvl2', 'val21')],
|
||||
)
|
||||
hierarchy_levels.get_environment_level_value(
|
||||
db.Environment(id=env_id),
|
||||
[('lvl1', 'val11'), ('lvl2', 'val22')],
|
||||
)
|
||||
hierarchy_levels.get_environment_level_value(
|
||||
db.Environment(id=env_id),
|
||||
[('lvl1', 'val12'), ('lvl2', 'val23')],
|
||||
)
|
||||
|
||||
res = self.client.get(self.collection_url.format(9))
|
||||
lvl1 = res.json[0]
|
||||
self.assertItemsEqual(['val11', 'val12'], lvl1['values'])
|
||||
|
||||
lvl2 = res.json[1]
|
||||
self.assertItemsEqual(['val21', 'val22', 'val23'], lvl2['values'])
|
||||
|
||||
def test_get_environment_level_value_bad_level(self):
|
||||
self._fixture()
|
||||
with self.app.app_context(), db.db.session.begin():
|
||||
@ -84,6 +109,11 @@ class TestLevelsHierarchy(BaseTest):
|
||||
self.assertEqual(200, res.status_code)
|
||||
self.assertEqual(level, res.json['name'])
|
||||
|
||||
res = self.client.get(self.object_url.format(environment_id,
|
||||
res.json['id']))
|
||||
self.assertEqual(200, res.status_code)
|
||||
self.assertEqual(level, res.json['name'])
|
||||
|
||||
def test_get_hierarchy_level_not_found(self):
|
||||
levels = ['lvl1', 'lvl2']
|
||||
for level in levels:
|
||||
|
Loading…
x
Reference in New Issue
Block a user