Add package list to openstack CLI

usage: openstack package list [-h] [-f {csv,json,table,value,yaml}]
                              [-c COLUMN] [--max-width <integer>] [--noindent]
                              [--quote {all,minimal,none,nonnumeric}]
                              [--limit LIMIT] [--marker MARKER]
                              [--include-disabled] [--owned]
                              [--search <SEARCH_KEYS>] [--name <PACKAGE_NAME>]
                              [--fqn <PACKAGE_FULLY_QUALIFIED_NAME>]
                              [--type <PACKAGE_TYPE>]
                              [--category <PACKAGE_CATEGORY>]
                              [--class_name <PACKAGE_CLASS_NAME>]
                              [--tag <PACKAGE_TAG>]

List available packages.

Partially implements: blueprint openstack-client-plugin-support

Change-Id: I92ba1c4d3a4e73d2f1e5928964d478305d8d126e
This commit is contained in:
zhurong 2016-09-27 12:53:18 +08:00 committed by Kirill Zaitsev
parent 59443dc77d
commit 4bc630f9ad
4 changed files with 228 additions and 0 deletions

View File

@ -12,15 +12,18 @@
"""Application-catalog v1 package action implementation"""
import itertools
import os
import shutil
import tempfile
import zipfile
from muranoclient.openstack.common.apiclient import exceptions
from muranoclient.v1.package_creator import hot_package
from muranoclient.v1.package_creator import mpl_package
from osc_lib.command import command
from osc_lib import exceptions as exc
from osc_lib import utils
from oslo_log import log as logging
LOG = logging.getLogger(__name__)
@ -136,3 +139,136 @@ class CreatePackage(command.Command):
finally:
if directory_path:
shutil.rmtree(directory_path)
class ListPackages(command.Lister):
"""List available packages."""
def get_parser(self, prog_name):
parser = super(ListPackages, self).get_parser(prog_name)
parser.add_argument(
"--limit",
type=int,
default=0,
help='Show limited number of packages'
)
parser.add_argument(
"--marker",
default='',
help='Show packages starting from package with id excluding it'
)
parser.add_argument(
"--include-disabled",
default=False,
action="store_true"
)
parser.add_argument(
"--owned",
default=False,
action="store_true"
)
parser.add_argument(
'--search',
metavar='<SEARCH_KEYS>',
dest='search',
required=False,
help='Show packages, that match search keys fuzzily'
)
parser.add_argument(
'--name',
metavar='<PACKAGE_NAME>',
dest='name',
required=False,
help='Show packages, whose name match parameter exactly'
)
parser.add_argument(
'--fqn',
metavar="<PACKAGE_FULLY_QUALIFIED_NAME>",
dest='fqn',
required=False,
help='Show packages, '
'whose fully qualified name match parameter exactly'
)
parser.add_argument(
'--type',
metavar='<PACKAGE_TYPE>',
dest='type',
required=False,
help='Show packages, whose type match parameter exactly'
)
parser.add_argument(
'--category',
metavar='<PACKAGE_CATEGORY>',
dest='category',
required=False,
help='Show packages, whose categories include parameter'
)
parser.add_argument(
'--class_name',
metavar='<PACKAGE_CLASS_NAME>',
dest='class_name',
required=False,
help='Show packages, whose class name match parameter exactly'
)
parser.add_argument(
'--tag',
metavar='<PACKAGE_TAG>',
dest='tag',
required=False,
help='Show packages, whose tags include parameter'
)
return parser
def take_action(self, parsed_args):
LOG.debug("take_action({0})".format(parsed_args))
client = self.app.client_manager.application_catalog
filter_args = {
"include_disabled": getattr(parsed_args,
'include_disabled', False),
"owned": getattr(parsed_args, 'owned', False),
}
if parsed_args:
if parsed_args.limit < 0:
raise exceptions.CommandError(
'--limit parameter must be non-negative')
if parsed_args.limit != 0:
filter_args['limit'] = parsed_args.limit
if parsed_args.marker:
filter_args['marker'] = parsed_args.marker
if parsed_args.search:
filter_args['search'] = parsed_args.search
if parsed_args.name:
filter_args['name'] = parsed_args.name
if parsed_args.fqn:
filter_args['fqn'] = parsed_args.fqn
if parsed_args.type:
filter_args['type'] = parsed_args.type
if parsed_args.category:
filter_args['category'] = parsed_args.category
if parsed_args.class_name:
filter_args['class_name'] = parsed_args.class_name
if parsed_args.tag:
filter_args['tag'] = parsed_args.tag
data = client.packages.filter(**filter_args)
columns = ('id', 'name', 'fully_qualified_name', 'author', 'active',
'is public', 'type', 'version')
column_headers = [c.capitalize() for c in columns]
if not parsed_args or parsed_args.limit == 0:
return (
column_headers,
list(utils.get_item_properties(
s,
columns,
) for s in data)
)
else:
return (
column_headers,
list(utils.get_item_properties(
s,
columns,
) for s in itertools.islice(data, parsed_args.limit))
)

View File

@ -19,8 +19,11 @@ from testtools import matchers
from muranoclient.osc.v1 import package as osc_pkg
from muranoclient.tests.unit.osc.v1 import fakes
from muranoclient.v1 import packages
import mock
from osc_lib import exceptions as exc
from osc_lib import utils
FIXTURE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__),
'fixture_data'))
@ -101,3 +104,88 @@ class TestCreatePackage(TestPackage):
matchers.MatchesRegex(stdout,
"Application package "
"is available at {0}".format(RESULT_PACKAGE))
class TestPackageList(TestPackage):
columns = ['Id', 'Name', 'Fully_qualified_name', 'Author', 'Active',
'Is public', 'Type', 'Version']
data = {
'class_definitions': ['com.example.apache.ApacheHttpServer'],
'updated': '2016-09-20T06:23:45.000000',
'description': 'Test description.\n',
'created': '2016-09-20T06:23:15.000000',
'author': 'Mirantis, Inc',
'enabled': True,
'owner_id': 'a203405ea871484a940850d6c0b8dfd9',
'tags': ['Server', 'WebServer', 'Apache', 'HTTP', 'HTML'],
'is_public': False,
'fully_qualified_name': 'com.example.apache.ApacheHttpServer',
'type': 'Application',
'id': '46860070-5f8a-4936-96e8-d7b89e5187d7',
'categories': [],
'name': 'Apache HTTP Server'
}
def setUp(self):
super(TestPackageList, self).setUp()
self.cmd = osc_pkg.ListPackages(self.app, None)
self.package_mock.filter.return_value = \
[packages.Package(None, self.data)]
utils.get_dict_properties = mock.MagicMock(return_value='')
def test_stack_list_defaults(self):
arglist = []
parsed_args = self.check_parser(self.cmd, arglist, [])
columns, data = self.cmd.take_action(parsed_args)
self.package_mock.filter.assert_called_with(
include_disabled=False,
owned=False)
self.assertEqual(self.columns, columns)
def test_stack_list_with_limit(self):
arglist = ['--limit', '10']
parsed_args = self.check_parser(self.cmd, arglist, [])
columns, data = self.cmd.take_action(parsed_args)
self.package_mock.filter.assert_called_with(
include_disabled=False,
limit=10,
owned=False)
def test_stack_list_with_marker(self):
arglist = ['--marker', '12345']
parsed_args = self.check_parser(self.cmd, arglist, [])
columns, data = self.cmd.take_action(parsed_args)
self.package_mock.filter.assert_called_with(
include_disabled=False,
marker='12345',
owned=False)
def test_stack_list_with_name(self):
arglist = ['--name', 'mysql']
parsed_args = self.check_parser(self.cmd, arglist, [])
columns, data = self.cmd.take_action(parsed_args)
self.package_mock.filter.assert_called_with(
include_disabled=False,
name='mysql',
owned=False)
def test_stack_list_with_fqn(self):
arglist = ['--fqn', 'mysql']
parsed_args = self.check_parser(self.cmd, arglist, [])
columns, data = self.cmd.take_action(parsed_args)
self.package_mock.filter.assert_called_with(
include_disabled=False,
fqn='mysql',
owned=False)

View File

@ -0,0 +1,3 @@
---
features:
- New OSC command ``package list``.

View File

@ -52,6 +52,7 @@ openstack.application_catalog.v1 =
deployment_list = muranoclient.osc.v1.deployment:ListDeployment
package_create = muranoclient.osc.v1.package:CreatePackage
package_list = muranoclient.osc.v1.package:ListPackages
static-action_call = muranoclient.osc.v1.action:StaticActionCall
class-schema = muranoclient.osc.v1.schema:ShowSchema