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:
tivaliy
2016-03-27 14:55:59 +03:00
committed by Roman Prykhodchenko
parent fd6e2dc601
commit 34b745f54a
7 changed files with 118 additions and 1 deletions

View File

@@ -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."""

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View 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)]

View File

@@ -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.

View File

@@ -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