Add namespace support for workbooks to client
Accept namespace parameter for workbook commands Depends-On: I2c66b3961915f0f35a9c468eb6dd0c0c70995234 Change-Id: I0a9da7673616e935b6653ed13ea041bb0c07afc8
This commit is contained in:
@@ -25,7 +25,22 @@ class Workbook(base.Resource):
|
|||||||
class WorkbookManager(base.ResourceManager):
|
class WorkbookManager(base.ResourceManager):
|
||||||
resource_class = Workbook
|
resource_class = Workbook
|
||||||
|
|
||||||
def create(self, definition, scope='private'):
|
def _get_workbooks_url(self, resource=None, namespace=None, scope=None):
|
||||||
|
path = '/workbooks'
|
||||||
|
|
||||||
|
if resource:
|
||||||
|
path += '/%s' % resource
|
||||||
|
|
||||||
|
if scope and namespace:
|
||||||
|
path += '?scope=%s&namespace=%s' % (scope, namespace)
|
||||||
|
elif scope:
|
||||||
|
path += '?scope=%s' % scope
|
||||||
|
elif namespace:
|
||||||
|
path += '?namespace=%s' % namespace
|
||||||
|
|
||||||
|
return path
|
||||||
|
|
||||||
|
def create(self, definition, namespace='', scope='private'):
|
||||||
self._ensure_not_empty(definition=definition)
|
self._ensure_not_empty(definition=definition)
|
||||||
|
|
||||||
# If the specified definition is actually a file, read in the
|
# If the specified definition is actually a file, read in the
|
||||||
@@ -34,7 +49,7 @@ class WorkbookManager(base.ResourceManager):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
resp = self.http_client.post(
|
resp = self.http_client.post(
|
||||||
'/workbooks?scope=%s' % scope,
|
self._get_workbooks_url(None, namespace, scope),
|
||||||
definition,
|
definition,
|
||||||
headers={'content-type': 'text/plain'}
|
headers={'content-type': 'text/plain'}
|
||||||
)
|
)
|
||||||
@@ -46,7 +61,7 @@ class WorkbookManager(base.ResourceManager):
|
|||||||
|
|
||||||
return self.resource_class(self, base.extract_json(resp, None))
|
return self.resource_class(self, base.extract_json(resp, None))
|
||||||
|
|
||||||
def update(self, definition, scope='private'):
|
def update(self, definition, namespace='', scope='private'):
|
||||||
self._ensure_not_empty(definition=definition)
|
self._ensure_not_empty(definition=definition)
|
||||||
|
|
||||||
# If the specified definition is actually a file, read in the
|
# If the specified definition is actually a file, read in the
|
||||||
@@ -55,7 +70,7 @@ class WorkbookManager(base.ResourceManager):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
resp = self.http_client.put(
|
resp = self.http_client.put(
|
||||||
'/workbooks?scope=%s' % scope,
|
self._get_workbooks_url(None, namespace, scope),
|
||||||
definition,
|
definition,
|
||||||
headers={'content-type': 'text/plain'}
|
headers={'content-type': 'text/plain'}
|
||||||
)
|
)
|
||||||
@@ -67,18 +82,23 @@ class WorkbookManager(base.ResourceManager):
|
|||||||
|
|
||||||
return self.resource_class(self, base.extract_json(resp, None))
|
return self.resource_class(self, base.extract_json(resp, None))
|
||||||
|
|
||||||
def list(self):
|
def list(self, namespace=''):
|
||||||
return self._list('/workbooks', response_key='workbooks')
|
return self._list(
|
||||||
|
self._get_workbooks_url(None, namespace),
|
||||||
|
response_key='workbooks'
|
||||||
|
)
|
||||||
|
|
||||||
def get(self, name):
|
def get(self, name, namespace=''):
|
||||||
self._ensure_not_empty(name=name)
|
self._ensure_not_empty(name=name)
|
||||||
|
|
||||||
return self._get('/workbooks/%s' % name)
|
return self._get(
|
||||||
|
self._get_workbooks_url(name, namespace)
|
||||||
|
)
|
||||||
|
|
||||||
def delete(self, name):
|
def delete(self, name, namespace=''):
|
||||||
self._ensure_not_empty(name=name)
|
self._ensure_not_empty(name=name)
|
||||||
|
|
||||||
self._delete('/workbooks/%s' % name)
|
self._delete(self._get_workbooks_url(name, namespace))
|
||||||
|
|
||||||
def validate(self, definition):
|
def validate(self, definition):
|
||||||
self._ensure_not_empty(definition=definition)
|
self._ensure_not_empty(definition=definition)
|
||||||
|
@@ -24,6 +24,7 @@ from mistralclient import utils
|
|||||||
def format(workbook=None):
|
def format(workbook=None):
|
||||||
columns = (
|
columns = (
|
||||||
'Name',
|
'Name',
|
||||||
|
'Namespace',
|
||||||
'Tags',
|
'Tags',
|
||||||
'Scope',
|
'Scope',
|
||||||
'Created at',
|
'Created at',
|
||||||
@@ -33,6 +34,7 @@ def format(workbook=None):
|
|||||||
if workbook:
|
if workbook:
|
||||||
data = (
|
data = (
|
||||||
workbook.name,
|
workbook.name,
|
||||||
|
workbook.namespace,
|
||||||
base.wrap(', '.join(workbook.tags or '')) or '<none>',
|
base.wrap(', '.join(workbook.tags or '')) or '<none>',
|
||||||
workbook.scope,
|
workbook.scope,
|
||||||
workbook.created_at,
|
workbook.created_at,
|
||||||
@@ -66,16 +68,23 @@ class Get(command.ShowOne):
|
|||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
parser = super(Get, self).get_parser(prog_name)
|
parser = super(Get, self).get_parser(prog_name)
|
||||||
|
|
||||||
|
parser.add_argument('workbook', help='Workbook name')
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'workbook',
|
'--namespace',
|
||||||
help='Workbook name'
|
nargs='?',
|
||||||
|
default='',
|
||||||
|
help="Namespace to get the workbook from."
|
||||||
)
|
)
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
mistral_client = self.app.client_manager.workflow_engine
|
mistral_client = self.app.client_manager.workflow_engine
|
||||||
workbook = mistral_client.workbooks.get(parsed_args.workbook)
|
workbook = mistral_client.workbooks.get(
|
||||||
|
parsed_args.workbook,
|
||||||
|
parsed_args.namespace
|
||||||
|
)
|
||||||
|
|
||||||
return format(workbook)
|
return format(workbook)
|
||||||
|
|
||||||
@@ -97,6 +106,13 @@ class Create(command.ShowOne):
|
|||||||
help='With this flag workbook will be marked as "public".'
|
help='With this flag workbook will be marked as "public".'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'--namespace',
|
||||||
|
nargs='?',
|
||||||
|
default='',
|
||||||
|
help="Namespace to create the workbook within."
|
||||||
|
)
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
@@ -105,6 +121,7 @@ class Create(command.ShowOne):
|
|||||||
mistral_client = self.app.client_manager.workflow_engine
|
mistral_client = self.app.client_manager.workflow_engine
|
||||||
workbook = mistral_client.workbooks.create(
|
workbook = mistral_client.workbooks.create(
|
||||||
parsed_args.definition.read(),
|
parsed_args.definition.read(),
|
||||||
|
namespace=parsed_args.namespace,
|
||||||
scope=scope
|
scope=scope
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -118,13 +135,20 @@ class Delete(command.Command):
|
|||||||
parser = super(Delete, self).get_parser(prog_name)
|
parser = super(Delete, self).get_parser(prog_name)
|
||||||
|
|
||||||
parser.add_argument('workbook', nargs='+', help='Name of workbook(s).')
|
parser.add_argument('workbook', nargs='+', help='Name of workbook(s).')
|
||||||
|
parser.add_argument(
|
||||||
|
'--namespace',
|
||||||
|
nargs='?',
|
||||||
|
default=None,
|
||||||
|
help="Namespace to delete the workbook(s) from."
|
||||||
|
)
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
mistral_client = self.app.client_manager.workflow_engine
|
mistral_client = self.app.client_manager.workflow_engine
|
||||||
utils.do_action_on_many(
|
utils.do_action_on_many(
|
||||||
lambda s: mistral_client.workbooks.delete(s),
|
lambda s: mistral_client.workbooks.delete(s,
|
||||||
|
parsed_args.namespace),
|
||||||
parsed_args.workbook,
|
parsed_args.workbook,
|
||||||
"Request to delete workbook %s has been accepted.",
|
"Request to delete workbook %s has been accepted.",
|
||||||
"Unable to delete the specified workbook(s)."
|
"Unable to delete the specified workbook(s)."
|
||||||
@@ -142,6 +166,12 @@ class Update(command.ShowOne):
|
|||||||
type=argparse.FileType('r'),
|
type=argparse.FileType('r'),
|
||||||
help='Workbook definition file'
|
help='Workbook definition file'
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--namespace',
|
||||||
|
nargs='?',
|
||||||
|
default=None,
|
||||||
|
help="Namespace to update the workbook in."
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--public',
|
'--public',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
@@ -156,6 +186,7 @@ class Update(command.ShowOne):
|
|||||||
mistral_client = self.app.client_manager.workflow_engine
|
mistral_client = self.app.client_manager.workflow_engine
|
||||||
workbook = mistral_client.workbooks.update(
|
workbook = mistral_client.workbooks.update(
|
||||||
parsed_args.definition.read(),
|
parsed_args.definition.read(),
|
||||||
|
namespace=parsed_args.namespace,
|
||||||
scope=scope
|
scope=scope
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -111,12 +111,21 @@ class MistralClientTestBase(base.MistralCLIAuth, base.MistralCLIAltAuth):
|
|||||||
else:
|
else:
|
||||||
return self.mistral_alt_user(cmd, params)
|
return self.mistral_alt_user(cmd, params)
|
||||||
|
|
||||||
def workbook_create(self, wb_def, admin=True, scope='private'):
|
def workbook_create(self, wb_def, namespace='', admin=True,
|
||||||
|
scope='private'):
|
||||||
|
|
||||||
params = '{0}'.format(wb_def)
|
params = '{0}'.format(wb_def)
|
||||||
|
|
||||||
|
namespace_params = ''
|
||||||
|
|
||||||
|
if namespace:
|
||||||
|
namespace_params += ' --namespace {}'.format(namespace)
|
||||||
|
|
||||||
if scope == 'public':
|
if scope == 'public':
|
||||||
params += ' --public'
|
params += ' --public'
|
||||||
|
|
||||||
|
params += namespace_params
|
||||||
|
|
||||||
wb = self.mistral_cli(
|
wb = self.mistral_cli(
|
||||||
admin,
|
admin,
|
||||||
'workbook-create',
|
'workbook-create',
|
||||||
@@ -125,11 +134,13 @@ class MistralClientTestBase(base.MistralCLIAuth, base.MistralCLIAltAuth):
|
|||||||
|
|
||||||
wb_name = self.get_field_value(wb, "Name")
|
wb_name = self.get_field_value(wb, "Name")
|
||||||
|
|
||||||
|
wb_delete_params = wb_name + namespace_params
|
||||||
|
|
||||||
self.addCleanup(
|
self.addCleanup(
|
||||||
self.mistral_cli,
|
self.mistral_cli,
|
||||||
admin,
|
admin,
|
||||||
'workbook-delete',
|
'workbook-delete',
|
||||||
params=wb_name
|
params=wb_delete_params
|
||||||
)
|
)
|
||||||
|
|
||||||
self.addCleanup(
|
self.addCleanup(
|
||||||
|
@@ -22,6 +22,7 @@ from mistralclient.tests.unit import base
|
|||||||
|
|
||||||
WORKBOOK_DICT = {
|
WORKBOOK_DICT = {
|
||||||
'name': 'a',
|
'name': 'a',
|
||||||
|
'namespace': '',
|
||||||
'tags': ['a', 'b'],
|
'tags': ['a', 'b'],
|
||||||
'scope': 'private',
|
'scope': 'private',
|
||||||
'created_at': '1',
|
'created_at': '1',
|
||||||
@@ -55,7 +56,7 @@ class TestCLIWorkbooksV2(base.BaseCommandTest):
|
|||||||
|
|
||||||
result = self.call(workbook_cmd.Create, app_args=['wb.yaml'])
|
result = self.call(workbook_cmd.Create, app_args=['wb.yaml'])
|
||||||
|
|
||||||
self.assertEqual(('a', 'a, b', 'private', '1', '1'), result[1])
|
self.assertEqual(('a', '', 'a, b', 'private', '1', '1'), result[1])
|
||||||
|
|
||||||
@mock.patch('argparse.open', create=True)
|
@mock.patch('argparse.open', create=True)
|
||||||
def test_create_public(self, mock_open):
|
def test_create_public(self, mock_open):
|
||||||
@@ -69,7 +70,7 @@ class TestCLIWorkbooksV2(base.BaseCommandTest):
|
|||||||
app_args=['wb.yaml', '--public']
|
app_args=['wb.yaml', '--public']
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(('a', 'a, b', 'public', '1', '1'), result[1])
|
self.assertEqual(('a', '', 'a, b', 'public', '1', '1'), result[1])
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'public',
|
'public',
|
||||||
@@ -82,7 +83,7 @@ class TestCLIWorkbooksV2(base.BaseCommandTest):
|
|||||||
|
|
||||||
result = self.call(workbook_cmd.Update, app_args=['definition'])
|
result = self.call(workbook_cmd.Update, app_args=['definition'])
|
||||||
|
|
||||||
self.assertEqual(('a', 'a, b', 'private', '1', '1'), result[1])
|
self.assertEqual(('a', '', 'a, b', 'private', '1', '1'), result[1])
|
||||||
|
|
||||||
@mock.patch('argparse.open', create=True)
|
@mock.patch('argparse.open', create=True)
|
||||||
def test_update_public(self, mock_open):
|
def test_update_public(self, mock_open):
|
||||||
@@ -96,7 +97,7 @@ class TestCLIWorkbooksV2(base.BaseCommandTest):
|
|||||||
app_args=['definition', '--public']
|
app_args=['definition', '--public']
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(('a', 'a, b', 'public', '1', '1'), result[1])
|
self.assertEqual(('a', '', 'a, b', 'public', '1', '1'), result[1])
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'public',
|
'public',
|
||||||
@@ -108,26 +109,26 @@ class TestCLIWorkbooksV2(base.BaseCommandTest):
|
|||||||
|
|
||||||
result = self.call(workbook_cmd.List)
|
result = self.call(workbook_cmd.List)
|
||||||
|
|
||||||
self.assertEqual([('a', 'a, b', 'private', '1', '1')], result[1])
|
self.assertEqual([('a', '', 'a, b', 'private', '1', '1')], result[1])
|
||||||
|
|
||||||
def test_get(self):
|
def test_get(self):
|
||||||
self.client.workbooks.get.return_value = WORKBOOK
|
self.client.workbooks.get.return_value = WORKBOOK
|
||||||
|
|
||||||
result = self.call(workbook_cmd.Get, app_args=['name'])
|
result = self.call(workbook_cmd.Get, app_args=['name'])
|
||||||
|
|
||||||
self.assertEqual(('a', 'a, b', 'private', '1', '1'), result[1])
|
self.assertEqual(('a', '', 'a, b', 'private', '1', '1'), result[1])
|
||||||
|
|
||||||
def test_delete(self):
|
def test_delete(self):
|
||||||
self.call(workbook_cmd.Delete, app_args=['name'])
|
self.call(workbook_cmd.Delete, app_args=['name'])
|
||||||
|
|
||||||
self.client.workbooks.delete.assert_called_once_with('name')
|
self.client.workbooks.delete.assert_called_once_with('name', None)
|
||||||
|
|
||||||
def test_delete_with_multi_names(self):
|
def test_delete_with_multi_names(self):
|
||||||
self.call(workbook_cmd.Delete, app_args=['name1', 'name2'])
|
self.call(workbook_cmd.Delete, app_args=['name1', 'name2'])
|
||||||
|
|
||||||
self.assertEqual(2, self.client.workbooks.delete.call_count)
|
self.assertEqual(2, self.client.workbooks.delete.call_count)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
[mock.call('name1'), mock.call('name2')],
|
[mock.call('name1', None), mock.call('name2', None)],
|
||||||
self.client.workbooks.delete.call_args_list
|
self.client.workbooks.delete.call_args_list
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Add namespace parameter to workbook commands. Namespace parameter allows
|
||||||
|
to create multiple workbooks with same name under different namespaces.
|
Reference in New Issue
Block a user