Add initial commit for integration with Openstackclient
This patch adds support of Sahara CLI to Openstackclient by setting entry points and implementing interface functions. Also it adds Plugins functionality and unit tests to cover it. Co-Authored-By: Sergey Reshetnyak <sreshetniak@mirantis.com> Partially implements: blueprint cli-as-openstackclient-plugin Change-Id: If5c33f8446d64385a71e02a0ae7bf23d7b40f862
This commit is contained in:
parent
afff5823f7
commit
f0a3abeecf
@ -5,10 +5,12 @@
|
||||
pbr<2.0,>=1.3
|
||||
|
||||
Babel>=1.3
|
||||
cliff>=1.14.0 # Apache-2.0
|
||||
netaddr>=0.7.12
|
||||
oslo.i18n>=1.5.0 # Apache-2.0
|
||||
oslo.utils>=1.9.0 # Apache-2.0
|
||||
python-keystoneclient>=1.6.0
|
||||
python-openstackclient>=1.5.0
|
||||
requests>=2.5.2
|
||||
six>=1.9.0
|
||||
PrettyTable<0.8,>=0.7
|
||||
|
0
saharaclient/osc/__init__.py
Normal file
0
saharaclient/osc/__init__.py
Normal file
57
saharaclient/osc/plugin.py
Normal file
57
saharaclient/osc/plugin.py
Normal file
@ -0,0 +1,57 @@
|
||||
# Copyright (c) 2015 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.
|
||||
|
||||
from openstackclient.common import utils
|
||||
from oslo_log import log as logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_DATA_PROCESSING_API_VERSION = "1.1"
|
||||
API_VERSION_OPTION = "os_data_processing_api_version"
|
||||
API_NAME = "data_processing"
|
||||
API_VERSIONS = {
|
||||
"1.1": "saharaclient.api.client.Client"
|
||||
}
|
||||
|
||||
|
||||
def make_client(instance):
|
||||
data_processing_client = utils.get_client_class(
|
||||
API_NAME,
|
||||
instance._api_version[API_NAME],
|
||||
API_VERSIONS)
|
||||
LOG.debug('Instantiating data-processing client: %s',
|
||||
data_processing_client)
|
||||
|
||||
client = data_processing_client(
|
||||
session=instance.session,
|
||||
region_name=instance._region_name,
|
||||
cacert=instance._cacert,
|
||||
insecure=instance._insecure
|
||||
)
|
||||
return client
|
||||
|
||||
|
||||
def build_option_parser(parser):
|
||||
"""Hook to add global options."""
|
||||
parser.add_argument(
|
||||
"--os-data-processing-api-version",
|
||||
metavar="<data-processing-api-version>",
|
||||
default=utils.env(
|
||||
'OS_DATA_PROCESSING_API_VERSION',
|
||||
default=DEFAULT_DATA_PROCESSING_API_VERSION),
|
||||
help=("Data processing API version, default=" +
|
||||
DEFAULT_DATA_PROCESSING_API_VERSION +
|
||||
' (Env: OS_DATA_PROCESSING_API_VERSION)'))
|
||||
return parser
|
0
saharaclient/osc/v1/__init__.py
Normal file
0
saharaclient/osc/v1/__init__.py
Normal file
135
saharaclient/osc/v1/plugins.py
Normal file
135
saharaclient/osc/v1/plugins.py
Normal file
@ -0,0 +1,135 @@
|
||||
# Copyright (c) 2015 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.
|
||||
|
||||
from os import path
|
||||
|
||||
from cliff import command
|
||||
from cliff import lister
|
||||
from cliff import show
|
||||
from openstackclient.common import utils
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
|
||||
class ListPlugins(lister.Lister):
|
||||
"""Lists plugins"""
|
||||
|
||||
log = logging.getLogger(__name__ + ".ListPlugins")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListPlugins, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--long',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='List additional fields in output',
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)" % parsed_args)
|
||||
client = self.app.client_manager.data_processing
|
||||
data = client.plugins.list()
|
||||
|
||||
if parsed_args.long:
|
||||
columns = ('name', 'title', 'versions', 'description')
|
||||
column_headers = [c.capitalize() for c in columns]
|
||||
|
||||
else:
|
||||
columns = ('name', 'versions')
|
||||
column_headers = [c.capitalize() for c in columns]
|
||||
|
||||
return (
|
||||
column_headers,
|
||||
(utils.get_item_properties(
|
||||
s,
|
||||
columns,
|
||||
formatters={
|
||||
'versions': utils.format_list
|
||||
},
|
||||
) for s in data)
|
||||
)
|
||||
|
||||
|
||||
class ShowPlugin(show.ShowOne):
|
||||
"""Display plugin details"""
|
||||
|
||||
log = logging.getLogger(__name__ + ".ShowPlugin")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowPlugin, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
"plugin",
|
||||
metavar="<plugin>",
|
||||
help="Name of the plugin to display",
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)" % parsed_args)
|
||||
client = self.app.client_manager.data_processing
|
||||
|
||||
data = client.plugins.get(parsed_args.plugin).to_dict()
|
||||
data['versions'] = utils.format_list(data['versions'])
|
||||
|
||||
return self.dict2columns(data)
|
||||
|
||||
|
||||
class GetPluginConfigs(command.Command):
|
||||
"""Get plugin configs"""
|
||||
|
||||
log = logging.getLogger(__name__ + ".GetPluginConfigs")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(GetPluginConfigs, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
"plugin",
|
||||
metavar="<plugin>",
|
||||
help="Name of the plugin to provide config information about",
|
||||
)
|
||||
parser.add_argument(
|
||||
"version",
|
||||
metavar="<version>",
|
||||
help="Version of the plugin to provide config information about",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--file',
|
||||
metavar="<file>",
|
||||
help='Destination file (defaults to plugin name)',
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)" % parsed_args)
|
||||
client = self.app.client_manager.data_processing
|
||||
|
||||
if not parsed_args.file:
|
||||
parsed_args.file = parsed_args.plugin
|
||||
|
||||
data = client.plugins.get_version_details(
|
||||
parsed_args.plugin, parsed_args.version).to_dict()
|
||||
|
||||
if path.exists(parsed_args.file):
|
||||
self.log.error('File "%s" already exists. Chose another one with '
|
||||
'--file argument.' % parsed_args.file)
|
||||
else:
|
||||
with open(parsed_args.file, 'w') as f:
|
||||
jsonutils.dump(data, f, indent=4)
|
||||
self.log.info(
|
||||
'"%(plugin)s" plugin configs was saved in "%(file)s"'
|
||||
'file' % {'plugin': parsed_args.plugin,
|
||||
'file': parsed_args.file})
|
43
saharaclient/osc/v1/utils.py
Normal file
43
saharaclient/osc/v1/utils.py
Normal file
@ -0,0 +1,43 @@
|
||||
# Copyright (c) 2015 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.
|
||||
|
||||
from openstackclient.common import exceptions
|
||||
from openstackclient.common import utils
|
||||
|
||||
|
||||
def get_resource(manager, name_or_id):
|
||||
resource = utils.find_resource(manager, name_or_id)
|
||||
if isinstance(resource, list):
|
||||
if not resource:
|
||||
msg = "No %s with a name or ID of '%s' exists." % \
|
||||
(manager.resource_class.__name__.lower(), name_or_id)
|
||||
raise exceptions.CommandError(msg)
|
||||
if len(resource) > 1:
|
||||
msg = "More than one %s exists with the name '%s'." % \
|
||||
(manager.resource_class.__name__.lower(), name_or_id)
|
||||
raise exceptions.CommandError(msg)
|
||||
return resource[0]
|
||||
|
||||
else:
|
||||
return resource
|
||||
|
||||
|
||||
def prepare_data(data, fields):
|
||||
new_data = {}
|
||||
for f in fields:
|
||||
if f in data:
|
||||
new_data[f.replace('_', ' ').capitalize()] = data[f]
|
||||
|
||||
return new_data
|
0
saharaclient/tests/unit/osc/__init__.py
Normal file
0
saharaclient/tests/unit/osc/__init__.py
Normal file
38
saharaclient/tests/unit/osc/test_plugin.py
Normal file
38
saharaclient/tests/unit/osc/test_plugin.py
Normal file
@ -0,0 +1,38 @@
|
||||
# Copyright (c) 2015 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 mock
|
||||
|
||||
from saharaclient.osc import plugin
|
||||
from saharaclient.tests.unit import base
|
||||
|
||||
|
||||
class TestDataProcessingPlugin(base.BaseTestCase):
|
||||
|
||||
@mock.patch("saharaclient.api.client.Client")
|
||||
def test_make_client(self, p_client):
|
||||
|
||||
instance = mock.Mock()
|
||||
instance._api_version = {"data_processing": '1.1'}
|
||||
instance.session = 'session'
|
||||
instance._region_name = 'region_name'
|
||||
instance._cacert = 'cacert'
|
||||
instance._insecure = 'insecure'
|
||||
|
||||
plugin.make_client(instance)
|
||||
p_client.assert_called_with(session='session',
|
||||
region_name='region_name',
|
||||
cacert='cacert',
|
||||
insecure='insecure')
|
0
saharaclient/tests/unit/osc/v1/__init__.py
Normal file
0
saharaclient/tests/unit/osc/v1/__init__.py
Normal file
26
saharaclient/tests/unit/osc/v1/fakes.py
Normal file
26
saharaclient/tests/unit/osc/v1/fakes.py
Normal file
@ -0,0 +1,26 @@
|
||||
# Copyright (c) 2015 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 mock
|
||||
from openstackclient.tests import utils
|
||||
|
||||
|
||||
class TestDataProcessing(utils.TestCommand):
|
||||
|
||||
def setUp(self):
|
||||
super(TestDataProcessing, self).setUp()
|
||||
|
||||
self.app.client_manager.data_processing = mock.Mock()
|
160
saharaclient/tests/unit/osc/v1/test_plugins.py
Normal file
160
saharaclient/tests/unit/osc/v1/test_plugins.py
Normal file
@ -0,0 +1,160 @@
|
||||
# Copyright (c) 2015 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 mock
|
||||
|
||||
from saharaclient.api import plugins as api_plugins
|
||||
from saharaclient.osc.v1 import plugins as osc_plugins
|
||||
from saharaclient.tests.unit.osc.v1 import fakes
|
||||
|
||||
|
||||
PLUGIN_INFO = {'name': 'fake',
|
||||
'title': 'Fake Plugin',
|
||||
'versions': ['0.1', '0.2'],
|
||||
'description': 'Plugin for tests'}
|
||||
|
||||
|
||||
class TestPlugins(fakes.TestDataProcessing):
|
||||
def setUp(self):
|
||||
super(TestPlugins, self).setUp()
|
||||
self.plugins_mock = self.app.client_manager.data_processing.plugins
|
||||
self.plugins_mock.reset_mock()
|
||||
|
||||
|
||||
class TestListPlugins(TestPlugins):
|
||||
def setUp(self):
|
||||
super(TestListPlugins, self).setUp()
|
||||
self.plugins_mock.list.return_value = [api_plugins.Plugin(
|
||||
None, PLUGIN_INFO)]
|
||||
|
||||
# Command to test
|
||||
self.cmd = osc_plugins.ListPlugins(self.app, None)
|
||||
|
||||
def test_plugins_list_no_options(self):
|
||||
arglist = []
|
||||
verifylist = []
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
# Check that columns are correct
|
||||
expected_columns = ['Name', 'Versions']
|
||||
self.assertEqual(expected_columns, columns)
|
||||
|
||||
# Check that data is correct
|
||||
expected_data = [('fake', '0.1, 0.2')]
|
||||
self.assertEqual(expected_data, list(data))
|
||||
|
||||
def test_plugins_list_long(self):
|
||||
arglist = ['--long']
|
||||
verifylist = [('long', True)]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
# Check that columns are correct
|
||||
expected_columns = ['Name', 'Title', 'Versions', 'Description']
|
||||
self.assertEqual(expected_columns, columns)
|
||||
|
||||
# Check that data is correct
|
||||
expected_data = [('fake', 'Fake Plugin', '0.1, 0.2',
|
||||
'Plugin for tests')]
|
||||
self.assertEqual(expected_data, list(data))
|
||||
|
||||
|
||||
class TestShowPlugin(TestPlugins):
|
||||
def setUp(self):
|
||||
super(TestShowPlugin, self).setUp()
|
||||
self.plugins_mock.get.return_value = api_plugins.Plugin(
|
||||
None, PLUGIN_INFO)
|
||||
|
||||
# Command to test
|
||||
self.cmd = osc_plugins.ShowPlugin(self.app, None)
|
||||
|
||||
def test_plugin_show(self):
|
||||
arglist = ['fake']
|
||||
verifylist = []
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
# Check that correct arguments was passed
|
||||
self.plugins_mock.get.assert_called_once_with('fake')
|
||||
|
||||
# Check that columns are correct
|
||||
expected_columns = ('description', 'name', 'title', 'versions')
|
||||
self.assertEqual(expected_columns, columns)
|
||||
|
||||
# Check that data is correct
|
||||
expected_data = ('Plugin for tests', 'fake', 'Fake Plugin', '0.1, 0.2')
|
||||
self.assertEqual(expected_data, data)
|
||||
|
||||
|
||||
class TestGetPluginConfigs(TestPlugins):
|
||||
def setUp(self):
|
||||
super(TestGetPluginConfigs, self).setUp()
|
||||
self.plugins_mock.get_version_details.return_value = (
|
||||
api_plugins.Plugin(None, PLUGIN_INFO))
|
||||
|
||||
# Command to test
|
||||
self.cmd = osc_plugins.GetPluginConfigs(self.app, None)
|
||||
|
||||
@mock.patch('oslo_serialization.jsonutils.dump')
|
||||
def test_get_plugin_configs_default_file(self, p_dump):
|
||||
m_open = mock.mock_open()
|
||||
with mock.patch('six.moves.builtins.open', m_open, create=True):
|
||||
arglist = ['fake', '0.1']
|
||||
verifylist = [('plugin', 'fake'), ('version', '0.1')]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
# Check that correct arguments was passed
|
||||
self.plugins_mock.get_version_details.assert_called_once_with(
|
||||
'fake', '0.1')
|
||||
|
||||
args_to_dump = p_dump.call_args[0]
|
||||
# Check that the right data will be saved
|
||||
|
||||
self.assertEqual(PLUGIN_INFO, args_to_dump[0])
|
||||
# Check that data will be saved to the right file
|
||||
self.assertEqual('fake', m_open.call_args[0][0])
|
||||
|
||||
@mock.patch('oslo_serialization.jsonutils.dump')
|
||||
def test_get_plugin_configs_specified_file(self, p_dump):
|
||||
m_open = mock.mock_open()
|
||||
with mock.patch('six.moves.builtins.open', m_open):
|
||||
arglist = ['fake', '0.1', '--file', 'testfile']
|
||||
verifylist = [('plugin', 'fake'), ('version', '0.1'),
|
||||
('file', 'testfile')]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
# Check that correct arguments was passed
|
||||
self.plugins_mock.get_version_details.assert_called_once_with(
|
||||
'fake', '0.1')
|
||||
|
||||
args_to_dump = p_dump.call_args[0]
|
||||
# Check that the right data will be saved
|
||||
|
||||
self.assertEqual(PLUGIN_INFO, args_to_dump[0])
|
||||
# Check that data will be saved to the right file
|
||||
self.assertEqual('testfile', m_open.call_args[0][0])
|
76
saharaclient/tests/unit/osc/v1/test_utils.py
Normal file
76
saharaclient/tests/unit/osc/v1/test_utils.py
Normal file
@ -0,0 +1,76 @@
|
||||
# Copyright (c) 2015 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.
|
||||
|
||||
from openstackclient.common import exceptions
|
||||
|
||||
from saharaclient.osc.v1 import utils
|
||||
from saharaclient.tests.unit import base
|
||||
|
||||
|
||||
class TestUtils(base.BaseTestCase):
|
||||
def test_prepare_data(self):
|
||||
data = {'id': '123', 'name_of_res': 'name', 'description': 'descr'}
|
||||
|
||||
fields = ['id', 'name_of_res', 'description']
|
||||
expected_data = {'Description': 'descr', 'Id': '123',
|
||||
'Name of res': 'name'}
|
||||
self.assertEqual(expected_data, utils.prepare_data(data, fields))
|
||||
|
||||
fields = ['id', 'name_of_res']
|
||||
expected_data = {'Id': '123', 'Name of res': 'name'}
|
||||
self.assertEqual(expected_data, utils.prepare_data(data, fields))
|
||||
|
||||
fields = ['name_of_res']
|
||||
expected_data = {'Name of res': 'name'}
|
||||
self.assertEqual(expected_data, utils.prepare_data(data, fields))
|
||||
|
||||
def test_get_resource_id(self):
|
||||
class TestResource(object):
|
||||
def __init__(self, id):
|
||||
self.id = id
|
||||
|
||||
class TestManager(object):
|
||||
|
||||
resource_class = TestResource
|
||||
|
||||
def get(self, id):
|
||||
if id == 'id':
|
||||
return TestResource('from_id')
|
||||
else:
|
||||
raise
|
||||
|
||||
def find(self, name):
|
||||
if name == 'name':
|
||||
return [TestResource('from_name')]
|
||||
if name == 'null':
|
||||
return []
|
||||
if name == 'mult':
|
||||
return [TestResource('1'), TestResource('2')]
|
||||
|
||||
# check case when resource id is passed
|
||||
self.assertEqual('from_id', utils.get_resource(
|
||||
TestManager(), 'id').id)
|
||||
|
||||
# check case when resource name is passed
|
||||
self.assertEqual('from_name', utils.get_resource(
|
||||
TestManager(), 'name').id)
|
||||
|
||||
# check that error is raised when resource doesn't exists
|
||||
self.assertRaises(exceptions.CommandError, utils.get_resource,
|
||||
TestManager(), 'null')
|
||||
|
||||
# check that error is raised when multiple resources choice
|
||||
self.assertRaises(exceptions.CommandError, utils.get_resource,
|
||||
TestManager(), 'mult')
|
10
setup.cfg
10
setup.cfg
@ -25,13 +25,21 @@ classifier =
|
||||
setup-hooks = pbr.hooks.setup_hook
|
||||
|
||||
[files]
|
||||
packages =
|
||||
packages =
|
||||
saharaclient
|
||||
|
||||
[entry_points]
|
||||
console_scripts =
|
||||
sahara = saharaclient.shell:main
|
||||
|
||||
openstack.cli.extension =
|
||||
data_processing = saharaclient.osc.plugin
|
||||
|
||||
openstack.data_processing.v1 =
|
||||
dataprocessing_plugin_list = saharaclient.osc.v1.plugins:ListPlugins
|
||||
dataprocessing_plugin_show = saharaclient.osc.v1.plugins:ShowPlugin
|
||||
dataprocessing_plugin_configs_get = saharaclient.osc.v1.plugins:GetPluginConfigs
|
||||
|
||||
[build_sphinx]
|
||||
all_files = 1
|
||||
build-dir = doc/build
|
||||
|
Loading…
Reference in New Issue
Block a user