Add 'fuel2 plugins list' command support
* Add ability to get list of all plugins using
new CLI, e.g.:
'fuel2 plugins list'.
* Allow to show additional information about
openstack releases that plugins support
Change-Id: I1253fe0443ab33a212bed86535e4ff326270b30e
Partial-Bug: 1562466
Related-Bug: 1499742
This commit is contained in:
committed by
Roman Prykhodchenko
parent
fd6e2dc601
commit
34b745f54a
@@ -13,12 +13,29 @@
|
||||
# under the License.
|
||||
|
||||
from fuelclient.commands import base
|
||||
from fuelclient.common import data_utils
|
||||
|
||||
|
||||
class PluginsMixIn(object):
|
||||
entity_name = 'plugins'
|
||||
|
||||
|
||||
class PluginsList(PluginsMixIn, base.BaseListCommand):
|
||||
"""Show list of all available plugins."""
|
||||
|
||||
columns = ('id',
|
||||
'name',
|
||||
'version',
|
||||
'package_version',
|
||||
'releases')
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
data = self.client.get_all()
|
||||
data = data_utils.get_display_data_multi(self.columns, data)
|
||||
|
||||
return self.columns, data
|
||||
|
||||
|
||||
class PluginsSync(PluginsMixIn, base.BaseCommand):
|
||||
"""Synchronise plugins on file system with plugins in API service."""
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import mock
|
||||
|
||||
from fuelclient.tests.unit.v2.cli import test_engine
|
||||
from fuelclient.tests.utils import fake_plugin
|
||||
|
||||
|
||||
class TestPluginsCommand(test_engine.BaseCLITest):
|
||||
@@ -25,6 +26,17 @@ class TestPluginsCommand(test_engine.BaseCLITest):
|
||||
def setUp(self):
|
||||
super(TestPluginsCommand, self).setUp()
|
||||
|
||||
get_fake_plugins = fake_plugin.get_fake_plugins
|
||||
|
||||
self.m_client.get_modified.return_value = get_fake_plugins(10)
|
||||
|
||||
def test_plugin_list(self):
|
||||
args = 'plugins list'
|
||||
self.exec_command(args)
|
||||
|
||||
self.m_get_client.assert_called_once_with('plugins', mock.ANY)
|
||||
self.m_client.get_all.assert_called_once_with()
|
||||
|
||||
def test_plugins_sync_all(self):
|
||||
args = 'plugins sync'
|
||||
self.exec_command(args)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import fuelclient
|
||||
from fuelclient.tests.unit.v2.lib import test_api
|
||||
from fuelclient.tests import utils
|
||||
|
||||
|
||||
class TestPluginsFacade(test_api.BaseLibTest):
|
||||
@@ -24,8 +25,17 @@ class TestPluginsFacade(test_api.BaseLibTest):
|
||||
super(TestPluginsFacade, self).setUp()
|
||||
|
||||
self.version = 'v1'
|
||||
self.res_uri = '/api/{version}/plugins/'.format(version=self.version)
|
||||
|
||||
self.fake_plugins = utils.get_fake_plugins(10)
|
||||
|
||||
self.client = fuelclient.get_client('plugins', self.version)
|
||||
|
||||
def test_plugins_list(self):
|
||||
matcher = self.m_request.get(self.res_uri, json=self.fake_plugins)
|
||||
self.client.get_all()
|
||||
self.assertTrue(self.res_uri, matcher.called)
|
||||
|
||||
def test_sync_plugins(self):
|
||||
expected_uri = '/api/{version}/plugins/sync/'.format(
|
||||
version=self.version
|
||||
|
||||
@@ -36,6 +36,8 @@ from fuelclient.tests.utils.fake_node_group import get_fake_node_group
|
||||
from fuelclient.tests.utils.fake_node_group import get_fake_node_groups
|
||||
from fuelclient.tests.utils.fake_openstack_config \
|
||||
import get_fake_openstack_config
|
||||
from fuelclient.tests.utils.fake_plugin import get_fake_plugin
|
||||
from fuelclient.tests.utils.fake_plugin import get_fake_plugins
|
||||
|
||||
|
||||
__all__ = (get_fake_deployment_history,
|
||||
@@ -53,4 +55,6 @@ __all__ = (get_fake_deployment_history,
|
||||
random_string,
|
||||
get_fake_node_group,
|
||||
get_fake_node_groups,
|
||||
get_fake_openstack_config)
|
||||
get_fake_openstack_config,
|
||||
get_fake_plugin,
|
||||
get_fake_plugins)
|
||||
|
||||
49
fuelclient/tests/utils/fake_plugin.py
Normal file
49
fuelclient/tests/utils/fake_plugin.py
Normal file
@@ -0,0 +1,49 @@
|
||||
# -*- coding:utf8 -*-
|
||||
#
|
||||
# Copyright 2016 Mirantis, 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.
|
||||
|
||||
import six
|
||||
from six import moves as six_moves
|
||||
|
||||
|
||||
def get_fake_plugin(**kwargs):
|
||||
"""Creates a fake plugin
|
||||
|
||||
Returns the serialized and parametrized representation of a dumped Fuel
|
||||
Plugin. Represents the average amount of data.
|
||||
|
||||
"""
|
||||
plugin = {'id': 1,
|
||||
'name': 'plugin_name',
|
||||
'title': 'plugin_title',
|
||||
'version': '1.0.0',
|
||||
'description': 'plugin_description',
|
||||
'authors': ['author1', 'author2'],
|
||||
'package_version': '3.0.0',
|
||||
'releases': [{'os': 'ubuntu',
|
||||
'version': 'liberty-8.0'},
|
||||
{'os': 'ubuntu',
|
||||
'version': 'mitaka-9.0'}],
|
||||
'is_hotpluggable': True}
|
||||
for k, v in six.iteritems(kwargs):
|
||||
if k in plugin:
|
||||
plugin[k] = v
|
||||
return plugin
|
||||
|
||||
|
||||
def get_fake_plugins(plugins_number, **kwargs):
|
||||
"""Creates fake plugins list."""
|
||||
return [get_fake_plugin(plugin_id=i, **kwargs)
|
||||
for i in six_moves.range(1, plugins_number + 1)]
|
||||
@@ -12,6 +12,9 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import collections
|
||||
import six
|
||||
|
||||
from fuelclient import objects
|
||||
from fuelclient.v1 import base_v1
|
||||
|
||||
@@ -20,6 +23,27 @@ class PluginsClient(base_v1.BaseV1Client):
|
||||
|
||||
_entity_wrapper = objects.Plugins
|
||||
|
||||
def get_all(self):
|
||||
"""Get plugins data and re-format 'releases' info to display
|
||||
supported 'os', 'version' in a user-friendly way, e.g.:
|
||||
ubuntu (liberty-8.0, liberty-9.0, mitaka-9.0)
|
||||
centos (liberty-8.0), ubuntu (liberty-8.0)
|
||||
|
||||
:returns: list of plugins
|
||||
:rtype: list
|
||||
"""
|
||||
# Replace original nested 'releases' dictionary (from plugins meta
|
||||
# dictionary) to a new user-friendly form with releases info, i.e.
|
||||
# 'os', 'version' that specific plugin supports
|
||||
plugins = self._entity_wrapper.get_all_data()
|
||||
for plugin in plugins:
|
||||
releases = collections.defaultdict(list)
|
||||
for key in plugin['releases']:
|
||||
releases[key['os']].append(key['version'])
|
||||
plugin['releases'] = ', '.join('{} ({})'.format(k, ', '.join(v))
|
||||
for k, v in six.iteritems(releases))
|
||||
return plugins
|
||||
|
||||
def sync(self, ids):
|
||||
"""Synchronise plugins on file system with plugins in API service.
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ fuelclient =
|
||||
node_show=fuelclient.commands.node:NodeShow
|
||||
node_update=fuelclient.commands.node:NodeUpdate
|
||||
node_ansible-inventory=fuelclient.commands.node:NodeAnsibleInventory
|
||||
plugins_list=fuelclient.commands.plugins:PluginsList
|
||||
plugins_sync=fuelclient.commands.plugins:PluginsSync
|
||||
task_list=fuelclient.commands.task:TaskList
|
||||
task_show=fuelclient.commands.task:TaskShow
|
||||
|
||||
Reference in New Issue
Block a user