Provide consistent options and return latest execution entries
This patchset updates the *-list commands to have consistent definitions of the sort_keys/sort_dirs/limit/filter/marker options. It also modified the execution-list, action-execution-list and task-list commands to return the MOST RECENT entries by default, when no other sort_key, sort_dir or marker options are provided, rather than the oldest entries. There is a new --oldest option for these three commands to allow the user to access the oldest entries instead of the newest. A release note has also been created. Change-Id: I002edd1b10ab281072cfa7501cfa763073a7781c
This commit is contained in:

committed by
Bob.Haddleton

parent
7a1c8cc240
commit
d53da3629f
@@ -14,9 +14,12 @@
|
|||||||
|
|
||||||
import copy
|
import copy
|
||||||
import json
|
import json
|
||||||
|
import six
|
||||||
|
|
||||||
from keystoneauth1 import exceptions
|
from keystoneauth1 import exceptions
|
||||||
|
|
||||||
|
urlparse = six.moves.urllib.parse
|
||||||
|
|
||||||
|
|
||||||
class Resource(object):
|
class Resource(object):
|
||||||
resource_name = 'Something'
|
resource_name = 'Something'
|
||||||
@@ -71,7 +74,41 @@ class ResourceManager(object):
|
|||||||
self.http_client = http_client
|
self.http_client = http_client
|
||||||
|
|
||||||
def find(self, **kwargs):
|
def find(self, **kwargs):
|
||||||
return [i for i in self.list() if _check_items(i, kwargs.items())]
|
return [i for i in self._list() if _check_items(i, kwargs.items())]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _build_query_params(marker=None, limit=None, sort_keys=None,
|
||||||
|
sort_dirs=None, fields=None, filters=None,
|
||||||
|
scope=None, namespace=None):
|
||||||
|
qparams = {}
|
||||||
|
|
||||||
|
if marker:
|
||||||
|
qparams['marker'] = marker
|
||||||
|
|
||||||
|
if limit and limit > 0:
|
||||||
|
qparams['limit'] = limit
|
||||||
|
|
||||||
|
if sort_keys:
|
||||||
|
qparams['sort_keys'] = sort_keys
|
||||||
|
|
||||||
|
if sort_dirs:
|
||||||
|
qparams['sort_dirs'] = sort_dirs
|
||||||
|
|
||||||
|
if fields:
|
||||||
|
qparams['fields'] = ",".join(fields)
|
||||||
|
|
||||||
|
if filters:
|
||||||
|
for name, val in filters.items():
|
||||||
|
qparams[name] = val
|
||||||
|
|
||||||
|
if scope:
|
||||||
|
qparams['scope'] = scope
|
||||||
|
|
||||||
|
if namespace:
|
||||||
|
qparams['namespace'] = namespace
|
||||||
|
|
||||||
|
return ("?%s" % urlparse.urlencode(list(qparams.items()))
|
||||||
|
if qparams else "")
|
||||||
|
|
||||||
def _ensure_not_empty(self, **kwargs):
|
def _ensure_not_empty(self, **kwargs):
|
||||||
for name, value in kwargs.items():
|
for name, value in kwargs.items():
|
||||||
|
@@ -13,12 +13,9 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import six
|
|
||||||
|
|
||||||
from mistralclient.api import base
|
from mistralclient.api import base
|
||||||
|
|
||||||
urlparse = six.moves.urllib.parse
|
|
||||||
|
|
||||||
|
|
||||||
class ActionExecution(base.Resource):
|
class ActionExecution(base.Resource):
|
||||||
resource_name = 'ActionExecution'
|
resource_name = 'ActionExecution'
|
||||||
@@ -62,7 +59,8 @@ class ActionExecutionManager(base.ResourceManager):
|
|||||||
|
|
||||||
return self._update('/action_executions/%s' % id, data)
|
return self._update('/action_executions/%s' % id, data)
|
||||||
|
|
||||||
def list(self, task_execution_id=None, limit=None):
|
def list(self, task_execution_id=None, limit=None, marker='', fields=None,
|
||||||
|
sort_keys='', sort_dirs='', **filters):
|
||||||
url = '/action_executions'
|
url = '/action_executions'
|
||||||
|
|
||||||
if task_execution_id:
|
if task_execution_id:
|
||||||
@@ -70,13 +68,14 @@ class ActionExecutionManager(base.ResourceManager):
|
|||||||
|
|
||||||
url += "%s"
|
url += "%s"
|
||||||
|
|
||||||
qparams = {}
|
query_string = self._build_query_params(
|
||||||
|
marker=marker,
|
||||||
if limit and limit > 0:
|
limit=limit,
|
||||||
qparams['limit'] = limit
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
query_string = ("?%s" % urlparse.urlencode(list(qparams.items()))
|
fields=fields,
|
||||||
if qparams else "")
|
filters=filters
|
||||||
|
)
|
||||||
|
|
||||||
return self._list(url % query_string, response_key='action_executions')
|
return self._list(url % query_string, response_key='action_executions')
|
||||||
|
|
||||||
|
@@ -12,14 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from keystoneauth1 import exceptions
|
from keystoneauth1 import exceptions
|
||||||
from mistralclient.api import base
|
from mistralclient.api import base
|
||||||
from mistralclient import utils
|
from mistralclient import utils
|
||||||
|
|
||||||
urlparse = six.moves.urllib.parse
|
|
||||||
|
|
||||||
|
|
||||||
class Action(base.Resource):
|
class Action(base.Resource):
|
||||||
resource_name = 'Action'
|
resource_name = 'Action'
|
||||||
@@ -75,26 +71,16 @@ class ActionManager(base.ResourceManager):
|
|||||||
for resource_data in base.extract_json(resp, 'actions')]
|
for resource_data in base.extract_json(resp, 'actions')]
|
||||||
|
|
||||||
def list(self, marker='', limit=None, sort_keys='', sort_dirs='',
|
def list(self, marker='', limit=None, sort_keys='', sort_dirs='',
|
||||||
**filters):
|
fields='', **filters):
|
||||||
qparams = {}
|
|
||||||
|
|
||||||
if marker:
|
query_string = self._build_query_params(
|
||||||
qparams['marker'] = marker
|
marker=marker,
|
||||||
|
limit=limit,
|
||||||
if limit and limit > 0:
|
sort_keys=sort_keys,
|
||||||
qparams['limit'] = limit
|
sort_dirs=sort_dirs,
|
||||||
|
fields=fields,
|
||||||
if sort_keys:
|
filters=filters
|
||||||
qparams['sort_keys'] = sort_keys
|
)
|
||||||
|
|
||||||
if sort_dirs:
|
|
||||||
qparams['sort_dirs'] = sort_dirs
|
|
||||||
|
|
||||||
for name, val in filters.items():
|
|
||||||
qparams[name] = val
|
|
||||||
|
|
||||||
query_string = ("?%s" % urlparse.urlencode(list(qparams.items()))
|
|
||||||
if qparams else "")
|
|
||||||
|
|
||||||
return self._list(
|
return self._list(
|
||||||
'/actions%s' % query_string,
|
'/actions%s' % query_string,
|
||||||
|
@@ -54,8 +54,19 @@ class CronTriggerManager(base.ResourceManager):
|
|||||||
|
|
||||||
return self._create('/cron_triggers', data)
|
return self._create('/cron_triggers', data)
|
||||||
|
|
||||||
def list(self):
|
def list(self, marker='', limit=None, sort_keys='', fields='',
|
||||||
return self._list('/cron_triggers', response_key='cron_triggers')
|
sort_dirs='', **filters):
|
||||||
|
query_string = self._build_query_params(
|
||||||
|
marker=marker,
|
||||||
|
limit=limit,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
fields=fields,
|
||||||
|
filters=filters
|
||||||
|
)
|
||||||
|
|
||||||
|
return self._list('/cron_triggers%s' % query_string,
|
||||||
|
response_key='cron_triggers')
|
||||||
|
|
||||||
def get(self, name):
|
def get(self, name):
|
||||||
self._ensure_not_empty(name=name)
|
self._ensure_not_empty(name=name)
|
||||||
|
@@ -13,7 +13,6 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from mistralclient.api import base
|
from mistralclient.api import base
|
||||||
@@ -71,8 +70,19 @@ class EnvironmentManager(base.ResourceManager):
|
|||||||
|
|
||||||
return self._update('/environments', kwargs)
|
return self._update('/environments', kwargs)
|
||||||
|
|
||||||
def list(self):
|
def list(self, marker='', limit=None, sort_keys='', sort_dirs='',
|
||||||
return self._list('/environments', response_key='environments')
|
fields='', **filters):
|
||||||
|
query_string = self._build_query_params(
|
||||||
|
marker=marker,
|
||||||
|
limit=limit,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
fields=fields,
|
||||||
|
filters=filters
|
||||||
|
)
|
||||||
|
|
||||||
|
return self._list('/environments%s' % query_string,
|
||||||
|
response_key='environments')
|
||||||
|
|
||||||
def get(self, name):
|
def get(self, name):
|
||||||
self._ensure_not_empty(name=name)
|
self._ensure_not_empty(name=name)
|
||||||
|
@@ -47,8 +47,19 @@ class EventTriggerManager(base.ResourceManager):
|
|||||||
|
|
||||||
return self._create('/event_triggers', data)
|
return self._create('/event_triggers', data)
|
||||||
|
|
||||||
def list(self):
|
def list(self, marker='', limit=None, sort_keys='', sort_dirs='',
|
||||||
return self._list('/event_triggers', response_key='event_triggers')
|
fields='', **filters):
|
||||||
|
query_string = self._build_query_params(
|
||||||
|
marker=marker,
|
||||||
|
limit=limit,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
fields=fields,
|
||||||
|
filters=filters
|
||||||
|
)
|
||||||
|
|
||||||
|
return self._list('/event_triggers%s' % query_string,
|
||||||
|
response_key='event_triggers')
|
||||||
|
|
||||||
def get(self, id):
|
def get(self, id):
|
||||||
self._ensure_not_empty(id=id)
|
self._ensure_not_empty(id=id)
|
||||||
|
@@ -14,16 +14,13 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from oslo_utils import uuidutils
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
|
from oslo_utils import uuidutils
|
||||||
|
|
||||||
from mistralclient.api import base
|
from mistralclient.api import base
|
||||||
|
|
||||||
|
|
||||||
urlparse = six.moves.urllib.parse
|
|
||||||
|
|
||||||
|
|
||||||
class Execution(base.Resource):
|
class Execution(base.Resource):
|
||||||
resource_name = 'Execution'
|
resource_name = 'Execution'
|
||||||
|
|
||||||
@@ -79,29 +76,18 @@ class ExecutionManager(base.ResourceManager):
|
|||||||
return self._update('/executions/%s' % id, data)
|
return self._update('/executions/%s' % id, data)
|
||||||
|
|
||||||
def list(self, task=None, marker='', limit=None, sort_keys='',
|
def list(self, task=None, marker='', limit=None, sort_keys='',
|
||||||
sort_dirs='', **filters):
|
sort_dirs='', fields='', **filters):
|
||||||
qparams = {}
|
|
||||||
|
|
||||||
if task:
|
if task:
|
||||||
qparams['task_execution_id'] = task
|
filters['task_execution_id'] = task
|
||||||
|
|
||||||
if marker:
|
query_string = self._build_query_params(
|
||||||
qparams['marker'] = marker
|
marker=marker,
|
||||||
|
limit=limit,
|
||||||
if limit and limit > 0:
|
sort_keys=sort_keys,
|
||||||
qparams['limit'] = limit
|
sort_dirs=sort_dirs,
|
||||||
|
fields=fields,
|
||||||
if sort_keys:
|
filters=filters
|
||||||
qparams['sort_keys'] = sort_keys
|
)
|
||||||
|
|
||||||
if sort_dirs:
|
|
||||||
qparams['sort_dirs'] = sort_dirs
|
|
||||||
|
|
||||||
for name, val in filters.items():
|
|
||||||
qparams[name] = val
|
|
||||||
|
|
||||||
query_string = ("?%s" % urlparse.urlencode(list(qparams.items()))
|
|
||||||
if qparams else "")
|
|
||||||
|
|
||||||
return self._list(
|
return self._list(
|
||||||
'/executions%s' % query_string,
|
'/executions%s' % query_string,
|
||||||
@@ -116,11 +102,9 @@ class ExecutionManager(base.ResourceManager):
|
|||||||
def delete(self, id, force=None):
|
def delete(self, id, force=None):
|
||||||
self._ensure_not_empty(id=id)
|
self._ensure_not_empty(id=id)
|
||||||
qparams = {}
|
qparams = {}
|
||||||
|
|
||||||
if force:
|
if force:
|
||||||
qparams['force'] = True
|
qparams['force'] = True
|
||||||
|
|
||||||
query_string = ("?%s" % urlparse.urlencode(list(qparams.items()))
|
query_string = self._build_query_params(filters=qparams)
|
||||||
if qparams else "")
|
|
||||||
|
|
||||||
self._delete('/executions/%s%s' % (id, query_string))
|
self._delete('/executions/%s%s' % (id, query_string))
|
||||||
|
@@ -14,12 +14,9 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import six
|
|
||||||
|
|
||||||
from mistralclient.api import base
|
from mistralclient.api import base
|
||||||
|
|
||||||
urlparse = six.moves.urllib.parse
|
|
||||||
|
|
||||||
|
|
||||||
class Task(base.Resource):
|
class Task(base.Resource):
|
||||||
resource_name = 'Task'
|
resource_name = 'Task'
|
||||||
@@ -29,7 +26,7 @@ class TaskManager(base.ResourceManager):
|
|||||||
resource_class = Task
|
resource_class = Task
|
||||||
|
|
||||||
def list(self, workflow_execution_id=None, marker='', limit=None,
|
def list(self, workflow_execution_id=None, marker='', limit=None,
|
||||||
sort_keys='', sort_dirs='', fields=[], **filters):
|
sort_keys='', sort_dirs='', fields=None, **filters):
|
||||||
url = '/tasks'
|
url = '/tasks'
|
||||||
|
|
||||||
if workflow_execution_id:
|
if workflow_execution_id:
|
||||||
@@ -37,28 +34,14 @@ class TaskManager(base.ResourceManager):
|
|||||||
|
|
||||||
url += '%s'
|
url += '%s'
|
||||||
|
|
||||||
qparams = {}
|
query_string = self._build_query_params(
|
||||||
|
marker=marker,
|
||||||
if marker:
|
limit=limit,
|
||||||
qparams['marker'] = marker
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
if limit and limit > 0:
|
fields=fields,
|
||||||
qparams['limit'] = limit
|
filters=filters
|
||||||
|
)
|
||||||
if sort_keys:
|
|
||||||
qparams['sort_keys'] = sort_keys
|
|
||||||
|
|
||||||
if sort_dirs:
|
|
||||||
qparams['sort_dirs'] = sort_dirs
|
|
||||||
|
|
||||||
if fields:
|
|
||||||
qparams['fields'] = ",".join(fields)
|
|
||||||
|
|
||||||
for name, val in filters.items():
|
|
||||||
qparams[name] = val
|
|
||||||
|
|
||||||
query_string = ("?%s" % urlparse.urlencode(list(qparams.items()))
|
|
||||||
if qparams else "")
|
|
||||||
|
|
||||||
return self._list(url % query_string, response_key='tasks')
|
return self._list(url % query_string, response_key='tasks')
|
||||||
|
|
||||||
|
@@ -82,12 +82,20 @@ 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, namespace=''):
|
def list(self, namespace='', marker='', limit=None, sort_keys='',
|
||||||
return self._list(
|
sort_dirs='', fields='', **filters):
|
||||||
self._get_workbooks_url(None, namespace),
|
query_string = self._build_query_params(
|
||||||
response_key='workbooks'
|
marker=marker,
|
||||||
|
limit=limit,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
filters=filters,
|
||||||
|
namespace=namespace
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return self._list('/workbooks{}'.format(query_string),
|
||||||
|
response_key='workbooks')
|
||||||
|
|
||||||
def get(self, name, namespace=''):
|
def get(self, name, namespace=''):
|
||||||
self._ensure_not_empty(name=name)
|
self._ensure_not_empty(name=name)
|
||||||
|
|
||||||
|
@@ -13,16 +13,11 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from keystoneauth1 import exceptions
|
from keystoneauth1 import exceptions
|
||||||
from mistralclient.api import base
|
from mistralclient.api import base
|
||||||
from mistralclient import utils
|
from mistralclient import utils
|
||||||
|
|
||||||
|
|
||||||
urlparse = six.moves.urllib.parse
|
|
||||||
|
|
||||||
|
|
||||||
class Workflow(base.Resource):
|
class Workflow(base.Resource):
|
||||||
resource_name = 'Workflow'
|
resource_name = 'Workflow'
|
||||||
|
|
||||||
@@ -80,29 +75,18 @@ class WorkflowManager(base.ResourceManager):
|
|||||||
for resource_data in base.extract_json(resp, 'workflows')]
|
for resource_data in base.extract_json(resp, 'workflows')]
|
||||||
|
|
||||||
def list(self, namespace='', marker='', limit=None, sort_keys='',
|
def list(self, namespace='', marker='', limit=None, sort_keys='',
|
||||||
sort_dirs='', **filters):
|
sort_dirs='', fields='', **filters):
|
||||||
qparams = {}
|
|
||||||
|
|
||||||
if namespace:
|
if namespace:
|
||||||
qparams['namespace'] = namespace
|
filters['namespace'] = namespace
|
||||||
|
|
||||||
if marker:
|
query_string = self._build_query_params(
|
||||||
qparams['marker'] = marker
|
marker=marker,
|
||||||
|
limit=limit,
|
||||||
if limit and limit > 0:
|
sort_keys=sort_keys,
|
||||||
qparams['limit'] = limit
|
sort_dirs=sort_dirs,
|
||||||
|
fields=fields,
|
||||||
if sort_keys:
|
filters=filters
|
||||||
qparams['sort_keys'] = sort_keys
|
)
|
||||||
|
|
||||||
if sort_dirs:
|
|
||||||
qparams['sort_dirs'] = sort_dirs
|
|
||||||
|
|
||||||
for name, val in filters.items():
|
|
||||||
qparams[name] = val
|
|
||||||
|
|
||||||
query_string = ("?%s" % urlparse.urlencode(list(qparams.items()))
|
|
||||||
if qparams else "")
|
|
||||||
|
|
||||||
return self._list(
|
return self._list(
|
||||||
'/workflows%s' % query_string,
|
'/workflows%s' % query_string,
|
||||||
|
@@ -25,64 +25,46 @@ from mistralclient import utils
|
|||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def format_list(action_ex=None):
|
class ActionExecutionFormatter(base.MistralFormatter):
|
||||||
columns = (
|
COLUMNS = [
|
||||||
'ID',
|
('id', 'ID'),
|
||||||
'Name',
|
('name', 'Name'),
|
||||||
'Workflow name',
|
('workflow_name', 'Workflow name'),
|
||||||
'Workflow namespace',
|
('workflow_namespace', 'Workflow namespace'),
|
||||||
'Task name',
|
('task_name', 'Task name'),
|
||||||
'Task ID',
|
('task_execution_id', 'Task ID'),
|
||||||
'State',
|
('state', 'State'),
|
||||||
'Accepted',
|
('state_info', 'State info'),
|
||||||
'Created at',
|
('accepted', 'Accepted'),
|
||||||
'Updated at'
|
('created_at', 'Created at'),
|
||||||
)
|
('updated_at', 'Updated at'),
|
||||||
|
]
|
||||||
|
|
||||||
if action_ex:
|
LIST_COLUMN_FIELD_NAMES = [c[0] for c in COLUMNS if c[0] != 'state_info']
|
||||||
data = (
|
LIST_COLUMN_HEADING_NAMES = [c[1] for c in COLUMNS if c[0] != 'state_info']
|
||||||
action_ex.id,
|
|
||||||
action_ex.name,
|
@staticmethod
|
||||||
action_ex.workflow_name,
|
def format(action_ex=None, lister=False):
|
||||||
action_ex.workflow_namespace,
|
if lister:
|
||||||
action_ex.task_name if hasattr(action_ex, 'task_name') else None,
|
columns = ActionExecutionFormatter.LIST_COLUMN_HEADING_NAMES
|
||||||
action_ex.task_execution_id,
|
|
||||||
action_ex.state,
|
|
||||||
action_ex.accepted,
|
|
||||||
action_ex.created_at,
|
|
||||||
action_ex.updated_at or '<none>'
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
data = (tuple('' for _ in range(len(columns))),)
|
columns = ActionExecutionFormatter.headings()
|
||||||
|
|
||||||
return columns, data
|
|
||||||
|
|
||||||
|
|
||||||
def format(action_ex=None):
|
|
||||||
columns = (
|
|
||||||
'ID',
|
|
||||||
'Name',
|
|
||||||
'Workflow name',
|
|
||||||
'Workflow namespace',
|
|
||||||
'Task name',
|
|
||||||
'Task ID',
|
|
||||||
'State',
|
|
||||||
'State info',
|
|
||||||
'Accepted',
|
|
||||||
'Created at',
|
|
||||||
'Updated at',
|
|
||||||
)
|
|
||||||
|
|
||||||
if action_ex:
|
if action_ex:
|
||||||
|
if hasattr(action_ex, 'task_name'):
|
||||||
|
task_name = action_ex.task_name
|
||||||
|
else:
|
||||||
|
task_name = None
|
||||||
data = (
|
data = (
|
||||||
action_ex.id,
|
action_ex.id,
|
||||||
action_ex.name,
|
action_ex.name,
|
||||||
action_ex.workflow_name,
|
action_ex.workflow_name,
|
||||||
action_ex.workflow_namespace,
|
action_ex.workflow_namespace,
|
||||||
action_ex.task_name if hasattr(action_ex, 'task_name') else None,
|
task_name,
|
||||||
action_ex.task_execution_id,
|
action_ex.task_execution_id,
|
||||||
action_ex.state,
|
action_ex.state,)
|
||||||
action_ex.state_info,
|
if not lister:
|
||||||
|
data += (action_ex.state_info,)
|
||||||
|
data += (
|
||||||
action_ex.accepted,
|
action_ex.accepted,
|
||||||
action_ex.created_at,
|
action_ex.created_at,
|
||||||
action_ex.updated_at or '<none>'
|
action_ex.updated_at or '<none>'
|
||||||
@@ -166,18 +148,18 @@ class Create(command.ShowOne):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if not parsed_args.run_sync and parsed_args.save_result:
|
if not parsed_args.run_sync and parsed_args.save_result:
|
||||||
return format(action_ex)
|
return ActionExecutionFormatter.format(action_ex)
|
||||||
else:
|
else:
|
||||||
self.app.stdout.write("%s\n" % action_ex.output)
|
self.app.stdout.write("%s\n" % action_ex.output)
|
||||||
|
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
|
|
||||||
class List(base.MistralLister):
|
class List(base.MistralExecutionLister):
|
||||||
"""List all Action executions."""
|
"""List all Action executions."""
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return format_list
|
return ActionExecutionFormatter.format_list
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
parser = super(List, self).get_parser(prog_name)
|
parser = super(List, self).get_parser(prog_name)
|
||||||
@@ -187,33 +169,21 @@ class List(base.MistralLister):
|
|||||||
nargs='?',
|
nargs='?',
|
||||||
help='Task execution ID.'
|
help='Task execution ID.'
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
|
||||||
'--limit',
|
|
||||||
type=int,
|
|
||||||
help='Maximum number of action-executions to return in a single '
|
|
||||||
'result. limit is set to %s by default. Use --limit -1 to '
|
|
||||||
'fetch the full result set.' % base.DEFAULT_LIMIT,
|
|
||||||
nargs='?'
|
|
||||||
)
|
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
if parsed_args.limit is None:
|
|
||||||
parsed_args.limit = base.DEFAULT_LIMIT
|
|
||||||
|
|
||||||
LOG.info(
|
|
||||||
"limit is set to %s by default. Set "
|
|
||||||
"the limit explicitly using \'--limit\', if required. "
|
|
||||||
"Use \'--limit\' -1 to fetch the full result set.",
|
|
||||||
base.DEFAULT_LIMIT
|
|
||||||
)
|
|
||||||
|
|
||||||
mistral_client = self.app.client_manager.workflow_engine
|
mistral_client = self.app.client_manager.workflow_engine
|
||||||
|
|
||||||
return mistral_client.action_executions.list(
|
return mistral_client.action_executions.list(
|
||||||
parsed_args.task_execution_id,
|
parsed_args.task_execution_id,
|
||||||
|
marker=parsed_args.marker,
|
||||||
limit=parsed_args.limit,
|
limit=parsed_args.limit,
|
||||||
|
sort_keys=parsed_args.sort_keys,
|
||||||
|
sort_dirs=parsed_args.sort_dirs,
|
||||||
|
# TODO(bobh) - Uncomment when the fix for bug 1800322 merges
|
||||||
|
# fields=ActionExecutionFormatter.LIST_COLUMN_FIELD_NAMES,
|
||||||
|
**base.get_filters(parsed_args)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -234,7 +204,7 @@ class Get(command.ShowOne):
|
|||||||
parsed_args.action_execution
|
parsed_args.action_execution
|
||||||
)
|
)
|
||||||
|
|
||||||
return format(execution)
|
return ActionExecutionFormatter.format(execution)
|
||||||
|
|
||||||
|
|
||||||
class Update(command.ShowOne):
|
class Update(command.ShowOne):
|
||||||
@@ -270,7 +240,7 @@ class Update(command.ShowOne):
|
|||||||
output
|
output
|
||||||
)
|
)
|
||||||
|
|
||||||
return format(execution)
|
return ActionExecutionFormatter.format(execution)
|
||||||
|
|
||||||
|
|
||||||
class GetOutput(command.Command):
|
class GetOutput(command.Command):
|
||||||
|
@@ -22,25 +22,23 @@ from mistralclient.commands.v2 import base
|
|||||||
from mistralclient import utils
|
from mistralclient import utils
|
||||||
|
|
||||||
|
|
||||||
def format_list(action=None):
|
class ActionFormatter(base.MistralFormatter):
|
||||||
return format(action, lister=True)
|
COLUMNS = [
|
||||||
|
('id', 'ID'),
|
||||||
|
('name', 'Name'),
|
||||||
|
('is_system', 'Is system'),
|
||||||
|
('input', 'Input'),
|
||||||
|
('description', 'Description'),
|
||||||
|
('tags', 'Tags'),
|
||||||
|
('created_at', 'Created at'),
|
||||||
|
('updated_at', 'Updated at')
|
||||||
|
]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
def format(action=None, lister=False):
|
def format(action=None, lister=False):
|
||||||
columns = (
|
|
||||||
'ID',
|
|
||||||
'Name',
|
|
||||||
'Is system',
|
|
||||||
'Input',
|
|
||||||
'Description',
|
|
||||||
'Tags',
|
|
||||||
'Created at',
|
|
||||||
'Updated at'
|
|
||||||
)
|
|
||||||
|
|
||||||
if action:
|
if action:
|
||||||
tags = getattr(action, 'tags', None) or []
|
tags = getattr(action, 'tags', None) or []
|
||||||
input = action.input if not lister else base.cut(action.input)
|
input_ = action.input if not lister else base.cut(action.input)
|
||||||
desc = (action.description if not lister
|
desc = (action.description if not lister
|
||||||
else base.cut(action.description))
|
else base.cut(action.description))
|
||||||
|
|
||||||
@@ -48,44 +46,42 @@ def format(action=None, lister=False):
|
|||||||
action.id,
|
action.id,
|
||||||
action.name,
|
action.name,
|
||||||
action.is_system,
|
action.is_system,
|
||||||
input,
|
input_,
|
||||||
desc,
|
desc,
|
||||||
base.wrap(', '.join(tags)) or '<none>',
|
base.wrap(', '.join(tags)) or '<none>',
|
||||||
action.created_at,
|
action.created_at,
|
||||||
)
|
)
|
||||||
|
|
||||||
if hasattr(action, 'updated_at'):
|
if hasattr(action, 'updated_at'):
|
||||||
data += (action.updated_at,)
|
data += (action.updated_at,)
|
||||||
else:
|
else:
|
||||||
data += (None,)
|
data += (None,)
|
||||||
else:
|
|
||||||
data = (tuple('' for _ in range(len(columns))),)
|
|
||||||
|
|
||||||
return columns, data
|
else:
|
||||||
|
data = (tuple('' for _ in range(len(ActionFormatter.COLUMNS))),)
|
||||||
|
|
||||||
|
return ActionFormatter.headings(), data
|
||||||
|
|
||||||
|
|
||||||
class List(base.MistralLister):
|
class List(base.MistralLister):
|
||||||
"""List all actions."""
|
"""List all actions."""
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return format_list
|
return ActionFormatter.format_list
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
parser = super(List, self).get_parser(prog_name)
|
parser = super(List, self).get_parser(prog_name)
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--filter',
|
|
||||||
dest='filters',
|
|
||||||
action='append',
|
|
||||||
help='Filters. Can be repeated.'
|
|
||||||
)
|
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
mistral_client = self.app.client_manager.workflow_engine
|
mistral_client = self.app.client_manager.workflow_engine
|
||||||
|
|
||||||
return mistral_client.actions.list(
|
return mistral_client.actions.list(
|
||||||
|
marker=parsed_args.marker,
|
||||||
|
limit=parsed_args.limit,
|
||||||
|
sort_keys=parsed_args.sort_keys,
|
||||||
|
sort_dirs=parsed_args.sort_dirs,
|
||||||
|
fields=ActionFormatter.fields(),
|
||||||
**base.get_filters(parsed_args)
|
**base.get_filters(parsed_args)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -104,7 +100,7 @@ class Get(command.ShowOne):
|
|||||||
mistral_client = self.app.client_manager.workflow_engine
|
mistral_client = self.app.client_manager.workflow_engine
|
||||||
action = mistral_client.actions.get(parsed_args.action)
|
action = mistral_client.actions.get(parsed_args.action)
|
||||||
|
|
||||||
return format(action)
|
return ActionFormatter.format(action)
|
||||||
|
|
||||||
|
|
||||||
class Create(base.MistralLister):
|
class Create(base.MistralLister):
|
||||||
@@ -131,7 +127,7 @@ class Create(base.MistralLister):
|
|||||||
raise RuntimeError("Provide action definition file.")
|
raise RuntimeError("Provide action definition file.")
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return format_list
|
return ActionFormatter.format_list
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
scope = 'public' if parsed_args.public else 'private'
|
scope = 'public' if parsed_args.public else 'private'
|
||||||
@@ -190,7 +186,7 @@ class Update(base.MistralLister):
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return format_list
|
return ActionFormatter.format_list
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
scope = 'public' if parsed_args.public else 'private'
|
scope = 'public' if parsed_args.public else 'private'
|
||||||
@@ -223,8 +219,8 @@ class GetDefinition(command.Command):
|
|||||||
|
|
||||||
class Validate(command.ShowOne):
|
class Validate(command.ShowOne):
|
||||||
"""Validate action."""
|
"""Validate action."""
|
||||||
|
@staticmethod
|
||||||
def _format(self, result=None):
|
def _format(result=None):
|
||||||
columns = ('Valid', 'Error')
|
columns = ('Valid', 'Error')
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
|
@@ -24,12 +24,75 @@ import six
|
|||||||
DEFAULT_LIMIT = 100
|
DEFAULT_LIMIT = 100
|
||||||
|
|
||||||
|
|
||||||
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
|
class MistralFormatter(object):
|
||||||
|
COLUMNS = []
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def fields(cls):
|
||||||
|
return [c[0] for c in cls.COLUMNS]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def headings(cls):
|
||||||
|
return [c[1] for c in cls.COLUMNS]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def format_list(cls, instance=None):
|
||||||
|
return cls.format(instance, lister=True)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def format(instance=None, lister=False):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
@six.add_metaclass(abc.ABCMeta)
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
class MistralLister(command.Lister):
|
class MistralLister(command.Lister):
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def get_parser(self, parsed_args):
|
||||||
|
parser = super(MistralLister, self).get_parser(parsed_args)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'--marker',
|
||||||
|
type=str,
|
||||||
|
help='The last execution uuid of the previous page, displays list '
|
||||||
|
'of executions after "marker".',
|
||||||
|
default='',
|
||||||
|
nargs='?'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--limit',
|
||||||
|
type=int,
|
||||||
|
help='Maximum number of entries to return in a single result. ',
|
||||||
|
nargs='?'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--sort_keys',
|
||||||
|
help='Comma-separated list of sort keys to sort results by. '
|
||||||
|
'Default: created_at. '
|
||||||
|
'Example: mistral execution-list --sort_keys=id,description',
|
||||||
|
default='created_at',
|
||||||
|
nargs='?'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--sort_dirs',
|
||||||
|
help='Comma-separated list of sort directions. Default: asc. '
|
||||||
|
'Example: mistral execution-list --sort_keys=id,description '
|
||||||
|
'--sort_dirs=asc,desc',
|
||||||
|
default='asc',
|
||||||
|
nargs='?'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--filter',
|
||||||
|
dest='filters',
|
||||||
|
action='append',
|
||||||
|
help='Filters. Can be repeated.'
|
||||||
|
)
|
||||||
|
|
||||||
|
return parser
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
"""Gets a list of API resources (e.g. using client)."""
|
"""Gets a list of API resources (e.g. using client)."""
|
||||||
@@ -56,6 +119,48 @@ class MistralLister(command.Lister):
|
|||||||
return f()
|
return f()
|
||||||
|
|
||||||
|
|
||||||
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
|
class MistralExecutionLister(MistralLister):
|
||||||
|
def get_parser(self, parsed_args):
|
||||||
|
parser = super(MistralExecutionLister, self).get_parser(parsed_args)
|
||||||
|
parser.set_defaults(limit=DEFAULT_LIMIT)
|
||||||
|
parser.add_argument(
|
||||||
|
'--oldest',
|
||||||
|
help='Display the executions starting from the oldest entries '
|
||||||
|
'instead of the newest',
|
||||||
|
default=False,
|
||||||
|
action='store_true'
|
||||||
|
)
|
||||||
|
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
self._validate_parsed_args(parsed_args)
|
||||||
|
|
||||||
|
f = self._get_format_function()
|
||||||
|
|
||||||
|
reverse_results = False
|
||||||
|
if (parsed_args.marker == '' and parsed_args.sort_dirs == 'asc' and
|
||||||
|
parsed_args.sort_keys == 'created_at' and
|
||||||
|
not parsed_args.oldest):
|
||||||
|
reverse_results = True
|
||||||
|
parsed_args.sort_dirs = 'desc'
|
||||||
|
|
||||||
|
ret = self._get_resources(parsed_args)
|
||||||
|
if not isinstance(ret, list):
|
||||||
|
ret = [ret]
|
||||||
|
|
||||||
|
if reverse_results:
|
||||||
|
ret.reverse()
|
||||||
|
|
||||||
|
data = [f(r)[1] for r in ret]
|
||||||
|
|
||||||
|
if data:
|
||||||
|
return f()[0], data
|
||||||
|
else:
|
||||||
|
return f()
|
||||||
|
|
||||||
|
|
||||||
def cut(string, length=25):
|
def cut(string, length=25):
|
||||||
if string and len(string) > length:
|
if string and len(string) > length:
|
||||||
return "%s..." % string[:length]
|
return "%s..." % string[:length]
|
||||||
|
@@ -22,24 +22,22 @@ from mistralclient.commands.v2 import base
|
|||||||
from mistralclient import utils
|
from mistralclient import utils
|
||||||
|
|
||||||
|
|
||||||
def format_list(trigger=None):
|
class CronTriggerFormatter(base.MistralFormatter):
|
||||||
return format(trigger, lister=True)
|
COLUMNS = [
|
||||||
|
('name', 'Name'),
|
||||||
|
('workflow_name', 'Workflow'),
|
||||||
def format(trigger=None, lister=False):
|
('workflow_params', 'Params'),
|
||||||
columns = (
|
('pattern', 'Pattern'),
|
||||||
'Name',
|
|
||||||
'Workflow',
|
|
||||||
'Params',
|
|
||||||
'Pattern',
|
|
||||||
# TODO(rakhmerov): Uncomment when passwords are handled properly.
|
# TODO(rakhmerov): Uncomment when passwords are handled properly.
|
||||||
# TODO(rakhmerov): Add 'Workflow input' column.
|
# TODO(rakhmerov): Add 'Workflow input' column.
|
||||||
'Next execution time',
|
('next_execution_time', 'Next execution time'),
|
||||||
'Remaining executions',
|
('remaining_executions', 'Remaining executions'),
|
||||||
'Created at',
|
('created_at', 'Created at'),
|
||||||
'Updated at'
|
('updated_at', 'Updated at')
|
||||||
)
|
]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def format(trigger=None, lister=False):
|
||||||
if trigger:
|
if trigger:
|
||||||
# TODO(rakhmerov): Add following here:
|
# TODO(rakhmerov): Add following here:
|
||||||
# TODO(rakhmerov): wf_input = trigger.workflow_input if not lister
|
# TODO(rakhmerov): wf_input = trigger.workflow_input if not lister
|
||||||
@@ -50,7 +48,8 @@ def format(trigger=None, lister=False):
|
|||||||
trigger.workflow_name,
|
trigger.workflow_name,
|
||||||
trigger.workflow_params,
|
trigger.workflow_params,
|
||||||
trigger.pattern,
|
trigger.pattern,
|
||||||
# TODO(rakhmerov): Uncomment when passwords are handled properly.
|
# TODO(rakhmerov): Uncomment when passwords are handled
|
||||||
|
# properly.
|
||||||
# TODo(rakhmerov): Add 'wf_input' here.
|
# TODo(rakhmerov): Add 'wf_input' here.
|
||||||
trigger.next_execution_time,
|
trigger.next_execution_time,
|
||||||
trigger.remaining_executions,
|
trigger.remaining_executions,
|
||||||
@@ -62,20 +61,28 @@ def format(trigger=None, lister=False):
|
|||||||
else:
|
else:
|
||||||
data += (None,)
|
data += (None,)
|
||||||
else:
|
else:
|
||||||
data = (tuple('' for _ in range(len(columns))),)
|
data = (tuple('' for _ in
|
||||||
|
range(len(CronTriggerFormatter.COLUMNS))),)
|
||||||
|
|
||||||
return columns, data
|
return CronTriggerFormatter.headings(), data
|
||||||
|
|
||||||
|
|
||||||
class List(base.MistralLister):
|
class List(base.MistralLister):
|
||||||
"""List all cron triggers."""
|
"""List all cron triggers."""
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return format_list
|
return CronTriggerFormatter.format_list
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
mistral_client = self.app.client_manager.workflow_engine
|
mistral_client = self.app.client_manager.workflow_engine
|
||||||
return mistral_client.cron_triggers.list()
|
return mistral_client.cron_triggers.list(
|
||||||
|
marker=parsed_args.marker,
|
||||||
|
limit=parsed_args.limit,
|
||||||
|
sort_keys=parsed_args.sort_keys,
|
||||||
|
sort_dirs=parsed_args.sort_dirs,
|
||||||
|
fields=CronTriggerFormatter.fields(),
|
||||||
|
**base.get_filters(parsed_args)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Get(command.ShowOne):
|
class Get(command.ShowOne):
|
||||||
@@ -91,7 +98,7 @@ class Get(command.ShowOne):
|
|||||||
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
|
||||||
|
|
||||||
return format(mistral_client.cron_triggers.get(
|
return CronTriggerFormatter.format(mistral_client.cron_triggers.get(
|
||||||
parsed_args.cron_trigger
|
parsed_args.cron_trigger
|
||||||
))
|
))
|
||||||
|
|
||||||
@@ -189,7 +196,7 @@ class Create(command.ShowOne):
|
|||||||
parsed_args.count
|
parsed_args.count
|
||||||
)
|
)
|
||||||
|
|
||||||
return format(trigger)
|
return CronTriggerFormatter.format(trigger)
|
||||||
|
|
||||||
|
|
||||||
class Delete(command.Command):
|
class Delete(command.Command):
|
||||||
|
@@ -21,63 +21,41 @@ from mistralclient.commands.v2 import base
|
|||||||
from mistralclient import utils
|
from mistralclient import utils
|
||||||
|
|
||||||
|
|
||||||
def format_list(environment=None):
|
class EnvironmentFormatter(base.MistralFormatter):
|
||||||
columns = (
|
COLUMNS = [
|
||||||
'Name',
|
('name', 'Name'),
|
||||||
'Description',
|
('description', 'Description'),
|
||||||
'Scope',
|
('variables', 'Variables'),
|
||||||
'Created at',
|
('scope', 'Scope'),
|
||||||
'Updated at'
|
('created_at', 'Created at'),
|
||||||
)
|
('updated_at', 'Updated at'),
|
||||||
|
]
|
||||||
|
LIST_COLUMN_FIELD_NAMES = [c[0] for c in COLUMNS if c[0] != 'variables']
|
||||||
|
LIST_COLUMN_HEADING_NAMES = [c[1] for c in COLUMNS if c[0] != 'variables']
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def format(environment=None, lister=False):
|
||||||
|
if lister:
|
||||||
|
columns = EnvironmentFormatter.LIST_COLUMN_HEADING_NAMES
|
||||||
|
else:
|
||||||
|
columns = EnvironmentFormatter.headings()
|
||||||
|
|
||||||
if environment:
|
if environment:
|
||||||
data = (
|
data = (
|
||||||
environment.name,
|
environment.name,)
|
||||||
environment.description,
|
|
||||||
environment.scope,
|
|
||||||
environment.created_at,
|
|
||||||
)
|
|
||||||
|
|
||||||
if hasattr(environment, 'updated_at'):
|
|
||||||
data += (environment.updated_at or '<none>',)
|
|
||||||
else:
|
|
||||||
data += (None,)
|
|
||||||
|
|
||||||
else:
|
|
||||||
data = (tuple('<none>' for _ in range(len(columns))),)
|
|
||||||
|
|
||||||
return columns, data
|
|
||||||
|
|
||||||
|
|
||||||
def format(environment=None):
|
|
||||||
columns = (
|
|
||||||
'Name',
|
|
||||||
'Description',
|
|
||||||
'Variables',
|
|
||||||
'Scope',
|
|
||||||
'Created at',
|
|
||||||
'Updated at'
|
|
||||||
)
|
|
||||||
|
|
||||||
if environment:
|
|
||||||
data = (environment.name,)
|
|
||||||
|
|
||||||
if hasattr(environment, 'description'):
|
if hasattr(environment, 'description'):
|
||||||
data += (environment.description or '<none>',)
|
data += (environment.description or '<none>',)
|
||||||
else:
|
else:
|
||||||
data += (None,)
|
data += (None,)
|
||||||
|
if not lister:
|
||||||
|
data += (json.dumps(environment.variables, indent=4),)
|
||||||
data += (
|
data += (
|
||||||
json.dumps(environment.variables, indent=4),
|
|
||||||
environment.scope,
|
environment.scope,
|
||||||
environment.created_at,
|
environment.created_at,)
|
||||||
)
|
|
||||||
|
|
||||||
if hasattr(environment, 'updated_at'):
|
if hasattr(environment, 'updated_at'):
|
||||||
data += (environment.updated_at or '<none>',)
|
data += (environment.updated_at or '<none>',)
|
||||||
else:
|
else:
|
||||||
data += (None,)
|
data += (None,)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
data = (tuple('' for _ in range(len(columns))),)
|
data = (tuple('' for _ in range(len(columns))),)
|
||||||
|
|
||||||
@@ -88,11 +66,18 @@ class List(base.MistralLister):
|
|||||||
"""List all environments."""
|
"""List all environments."""
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return format_list
|
return EnvironmentFormatter.format_list
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
mistral_client = self.app.client_manager.workflow_engine
|
mistral_client = self.app.client_manager.workflow_engine
|
||||||
return mistral_client.environments.list()
|
return mistral_client.environments.list(
|
||||||
|
marker=parsed_args.marker,
|
||||||
|
limit=parsed_args.limit,
|
||||||
|
sort_keys=parsed_args.sort_keys,
|
||||||
|
sort_dirs=parsed_args.sort_dirs,
|
||||||
|
fields=EnvironmentFormatter.fields(),
|
||||||
|
**base.get_filters(parsed_args)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Get(command.ShowOne):
|
class Get(command.ShowOne):
|
||||||
@@ -132,7 +117,7 @@ class Get(command.ShowOne):
|
|||||||
|
|
||||||
return columns, data
|
return columns, data
|
||||||
|
|
||||||
return format(environment)
|
return EnvironmentFormatter.format(environment)
|
||||||
|
|
||||||
|
|
||||||
class Create(command.ShowOne):
|
class Create(command.ShowOne):
|
||||||
@@ -155,7 +140,7 @@ class Create(command.ShowOne):
|
|||||||
mistral_client = self.app.client_manager.workflow_engine
|
mistral_client = self.app.client_manager.workflow_engine
|
||||||
environment = mistral_client.environments.create(**data)
|
environment = mistral_client.environments.create(**data)
|
||||||
|
|
||||||
return format(environment)
|
return EnvironmentFormatter.format(environment)
|
||||||
|
|
||||||
|
|
||||||
class Delete(command.Command):
|
class Delete(command.Command):
|
||||||
@@ -203,4 +188,4 @@ class Update(command.ShowOne):
|
|||||||
mistral_client = self.app.client_manager.workflow_engine
|
mistral_client = self.app.client_manager.workflow_engine
|
||||||
environment = mistral_client.environments.update(**data)
|
environment = mistral_client.environments.update(**data)
|
||||||
|
|
||||||
return format(environment)
|
return EnvironmentFormatter.format(environment)
|
||||||
|
@@ -19,23 +19,21 @@ from mistralclient.commands.v2 import base
|
|||||||
from mistralclient import utils
|
from mistralclient import utils
|
||||||
|
|
||||||
|
|
||||||
def format_list(trigger=None):
|
class EventTriggerFormatter(base.MistralFormatter):
|
||||||
return format(trigger, lister=True)
|
COLUMNS = [
|
||||||
|
('id', 'ID'),
|
||||||
|
('name', 'Name'),
|
||||||
|
('workflow_id', 'Workflow ID'),
|
||||||
|
('workflow_params', 'Params'),
|
||||||
|
('exchange', 'Exchange'),
|
||||||
|
('topic', 'Topic'),
|
||||||
|
('event', 'Event'),
|
||||||
|
('created_at', 'Created at'),
|
||||||
|
('updated_at', 'Updated at')
|
||||||
|
]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
def format(trigger=None, lister=False):
|
def format(trigger=None, lister=False):
|
||||||
columns = (
|
|
||||||
'ID',
|
|
||||||
'Name',
|
|
||||||
'Workflow ID',
|
|
||||||
'Params',
|
|
||||||
'Exchange',
|
|
||||||
'Topic',
|
|
||||||
'Event',
|
|
||||||
'Created at',
|
|
||||||
'Updated at'
|
|
||||||
)
|
|
||||||
|
|
||||||
if trigger:
|
if trigger:
|
||||||
data = (
|
data = (
|
||||||
trigger.id,
|
trigger.id,
|
||||||
@@ -53,20 +51,28 @@ def format(trigger=None, lister=False):
|
|||||||
else:
|
else:
|
||||||
data += (None,)
|
data += (None,)
|
||||||
else:
|
else:
|
||||||
data = (tuple('' for _ in range(len(columns))),)
|
data = (tuple('' for _ in
|
||||||
|
range(len(EventTriggerFormatter.COLUMNS))),)
|
||||||
|
|
||||||
return columns, data
|
return EventTriggerFormatter.headings(), data
|
||||||
|
|
||||||
|
|
||||||
class List(base.MistralLister):
|
class List(base.MistralLister):
|
||||||
"""List all event triggers."""
|
"""List all event triggers."""
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return format_list
|
return EventTriggerFormatter.format_list
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
mistral_client = self.app.client_manager.workflow_engine
|
mistral_client = self.app.client_manager.workflow_engine
|
||||||
return mistral_client.event_triggers.list()
|
return mistral_client.event_triggers.list(
|
||||||
|
marker=parsed_args.marker,
|
||||||
|
limit=parsed_args.limit,
|
||||||
|
sort_keys=parsed_args.sort_keys,
|
||||||
|
sort_dirs=parsed_args.sort_dirs,
|
||||||
|
fields=EventTriggerFormatter.fields(),
|
||||||
|
**base.get_filters(parsed_args)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Get(command.ShowOne):
|
class Get(command.ShowOne):
|
||||||
@@ -82,9 +88,8 @@ class Get(command.ShowOne):
|
|||||||
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
|
||||||
|
|
||||||
return format(mistral_client.event_triggers.get(
|
return EventTriggerFormatter.format(mistral_client.event_triggers.get(
|
||||||
parsed_args.event_trigger
|
parsed_args.event_trigger))
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
class Create(command.ShowOne):
|
class Create(command.ShowOne):
|
||||||
@@ -140,7 +145,7 @@ class Create(command.ShowOne):
|
|||||||
wf_params,
|
wf_params,
|
||||||
)
|
)
|
||||||
|
|
||||||
return format(trigger)
|
return EventTriggerFormatter.format(trigger)
|
||||||
|
|
||||||
|
|
||||||
class Delete(command.Command):
|
class Delete(command.Command):
|
||||||
|
@@ -29,24 +29,23 @@ from mistralclient import utils
|
|||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def format_list(execution=None):
|
class ExecutionFormatter(base.MistralFormatter):
|
||||||
return format(execution, lister=True)
|
COLUMNS = [
|
||||||
|
('id', 'ID'),
|
||||||
|
('workflow_id', 'Workflow ID'),
|
||||||
|
('workflow_name', 'Workflow name'),
|
||||||
|
('workflow_namespace', 'Workflow namespace'),
|
||||||
|
('description', 'Description'),
|
||||||
|
('task_execution_id', 'Task Execution ID'),
|
||||||
|
('root_execution_id', 'Root Execution ID'),
|
||||||
|
('state', 'State'),
|
||||||
|
('state_info', 'State info'),
|
||||||
|
('created_at', 'Created at'),
|
||||||
|
('updated_at', 'Updated at'),
|
||||||
|
]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
def format(execution=None, lister=False):
|
def format(execution=None, lister=False):
|
||||||
columns = (
|
|
||||||
'ID',
|
|
||||||
'Workflow ID',
|
|
||||||
'Workflow name',
|
|
||||||
'Workflow namespace',
|
|
||||||
'Description',
|
|
||||||
'Task Execution ID',
|
|
||||||
'Root Execution ID',
|
|
||||||
'State',
|
|
||||||
'State info',
|
|
||||||
'Created at',
|
|
||||||
'Updated at'
|
|
||||||
)
|
|
||||||
# TODO(nmakhotkin) Add parent task id when it's implemented in API.
|
# TODO(nmakhotkin) Add parent task id when it's implemented in API.
|
||||||
|
|
||||||
if execution:
|
if execution:
|
||||||
@@ -67,16 +66,17 @@ def format(execution=None, lister=False):
|
|||||||
execution.updated_at or '<none>'
|
execution.updated_at or '<none>'
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
data = (tuple('' for _ in range(len(columns))),)
|
data = (tuple('' for _ in
|
||||||
|
range(len(ExecutionFormatter.COLUMNS))),)
|
||||||
|
|
||||||
return columns, data
|
return ExecutionFormatter.headings(), data
|
||||||
|
|
||||||
|
|
||||||
class List(base.MistralLister):
|
class List(base.MistralExecutionLister):
|
||||||
"""List all executions."""
|
"""List all executions."""
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return format_list
|
return ExecutionFormatter.format_list
|
||||||
|
|
||||||
def get_parser(self, parsed_args):
|
def get_parser(self, parsed_args):
|
||||||
parser = super(List, self).get_parser(parsed_args)
|
parser = super(List, self).get_parser(parsed_args)
|
||||||
@@ -86,58 +86,10 @@ class List(base.MistralLister):
|
|||||||
help="Parent task execution ID associated with workflow "
|
help="Parent task execution ID associated with workflow "
|
||||||
"execution list.",
|
"execution list.",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
|
||||||
'--marker',
|
|
||||||
type=str,
|
|
||||||
help='The last execution uuid of the previous page, displays list '
|
|
||||||
'of executions after "marker".',
|
|
||||||
default='',
|
|
||||||
nargs='?'
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'--limit',
|
|
||||||
type=int,
|
|
||||||
help='Maximum number of executions to return in a single result. '
|
|
||||||
'limit is set to %s by default. Use --limit -1 to fetch the '
|
|
||||||
'full result set.' % base.DEFAULT_LIMIT,
|
|
||||||
nargs='?'
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'--sort_keys',
|
|
||||||
help='Comma-separated list of sort keys to sort results by. '
|
|
||||||
'Default: created_at. '
|
|
||||||
'Example: mistral execution-list --sort_keys=id,description',
|
|
||||||
default='created_at',
|
|
||||||
nargs='?'
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'--sort_dirs',
|
|
||||||
help='Comma-separated list of sort directions. Default: asc. '
|
|
||||||
'Example: mistral execution-list --sort_keys=id,description '
|
|
||||||
'--sort_dirs=asc,desc',
|
|
||||||
default='asc',
|
|
||||||
nargs='?'
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'--filter',
|
|
||||||
dest='filters',
|
|
||||||
action='append',
|
|
||||||
help='Filters. Can be repeated.'
|
|
||||||
)
|
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
if parsed_args.limit is None:
|
|
||||||
parsed_args.limit = base.DEFAULT_LIMIT
|
|
||||||
|
|
||||||
LOG.info(
|
|
||||||
"limit is set to %s by default. Set "
|
|
||||||
"the limit explicitly using \'--limit\', if required. "
|
|
||||||
"Use \'--limit\' -1 to fetch the full result set.",
|
|
||||||
base.DEFAULT_LIMIT
|
|
||||||
)
|
|
||||||
|
|
||||||
mistral_client = self.app.client_manager.workflow_engine
|
mistral_client = self.app.client_manager.workflow_engine
|
||||||
|
|
||||||
return mistral_client.executions.list(
|
return mistral_client.executions.list(
|
||||||
@@ -146,6 +98,7 @@ class List(base.MistralLister):
|
|||||||
limit=parsed_args.limit,
|
limit=parsed_args.limit,
|
||||||
sort_keys=parsed_args.sort_keys,
|
sort_keys=parsed_args.sort_keys,
|
||||||
sort_dirs=parsed_args.sort_dirs,
|
sort_dirs=parsed_args.sort_dirs,
|
||||||
|
fields=ExecutionFormatter.fields(),
|
||||||
**base.get_filters(parsed_args)
|
**base.get_filters(parsed_args)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -164,7 +117,7 @@ class Get(command.ShowOne):
|
|||||||
mistral_client = self.app.client_manager.workflow_engine
|
mistral_client = self.app.client_manager.workflow_engine
|
||||||
execution = mistral_client.executions.get(parsed_args.execution)
|
execution = mistral_client.executions.get(parsed_args.execution)
|
||||||
|
|
||||||
return format(execution)
|
return ExecutionFormatter.format(execution)
|
||||||
|
|
||||||
|
|
||||||
class Create(command.ShowOne):
|
class Create(command.ShowOne):
|
||||||
@@ -235,7 +188,7 @@ class Create(command.ShowOne):
|
|||||||
**params
|
**params
|
||||||
)
|
)
|
||||||
|
|
||||||
return format(execution)
|
return ExecutionFormatter.format(execution)
|
||||||
|
|
||||||
|
|
||||||
class Delete(command.Command):
|
class Delete(command.Command):
|
||||||
@@ -322,7 +275,7 @@ class Update(command.ShowOne):
|
|||||||
env=env
|
env=env
|
||||||
)
|
)
|
||||||
|
|
||||||
return format(execution)
|
return ExecutionFormatter.format(execution)
|
||||||
|
|
||||||
|
|
||||||
class GetInput(command.Command):
|
class GetInput(command.Command):
|
||||||
|
@@ -19,21 +19,19 @@ from mistralclient.commands.v2 import base
|
|||||||
from mistralclient import exceptions
|
from mistralclient import exceptions
|
||||||
|
|
||||||
|
|
||||||
def format_list(member=None):
|
class MemberFormatter(base.MistralFormatter):
|
||||||
return format(member, lister=True)
|
COLUMNS = [
|
||||||
|
('resource_id', 'Resource ID'),
|
||||||
|
('resource_type', 'Resource Type'),
|
||||||
|
('project_id', 'Resource Owner'),
|
||||||
|
('member_id', 'Member ID'),
|
||||||
|
('status', 'Status'),
|
||||||
|
('created_at', 'Created at'),
|
||||||
|
('updated_at', 'Updated at')
|
||||||
|
]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
def format(member=None, lister=False):
|
def format(member=None, lister=False):
|
||||||
columns = (
|
|
||||||
'Resource ID',
|
|
||||||
'Resource Type',
|
|
||||||
'Resource Owner',
|
|
||||||
'Member ID',
|
|
||||||
'Status',
|
|
||||||
'Created at',
|
|
||||||
'Updated at'
|
|
||||||
)
|
|
||||||
|
|
||||||
if member:
|
if member:
|
||||||
data = (
|
data = (
|
||||||
member.resource_id,
|
member.resource_id,
|
||||||
@@ -49,16 +47,16 @@ def format(member=None, lister=False):
|
|||||||
else:
|
else:
|
||||||
data += (None,)
|
data += (None,)
|
||||||
else:
|
else:
|
||||||
data = (tuple('' for _ in range(len(columns))),)
|
data = (tuple('' for _ in range(len(MemberFormatter.COLUMNS))),)
|
||||||
|
|
||||||
return columns, data
|
return MemberFormatter.headings(), data
|
||||||
|
|
||||||
|
|
||||||
class List(base.MistralLister):
|
class List(base.MistralLister):
|
||||||
"""List all members."""
|
"""List all members."""
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return format_list
|
return MemberFormatter.format_list
|
||||||
|
|
||||||
def get_parser(self, parsed_args):
|
def get_parser(self, parsed_args):
|
||||||
parser = super(List, self).get_parser(parsed_args)
|
parser = super(List, self).get_parser(parsed_args)
|
||||||
@@ -114,7 +112,7 @@ class Get(command.ShowOne):
|
|||||||
parsed_args.member_id,
|
parsed_args.member_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
return format(member)
|
return MemberFormatter.format(member)
|
||||||
|
|
||||||
|
|
||||||
class Create(command.ShowOne):
|
class Create(command.ShowOne):
|
||||||
@@ -146,7 +144,7 @@ class Create(command.ShowOne):
|
|||||||
parsed_args.member_id,
|
parsed_args.member_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
return format(member)
|
return MemberFormatter.format(member)
|
||||||
|
|
||||||
|
|
||||||
class Delete(command.Command):
|
class Delete(command.Command):
|
||||||
@@ -232,4 +230,4 @@ class Update(command.ShowOne):
|
|||||||
status=parsed_args.status
|
status=parsed_args.status
|
||||||
)
|
)
|
||||||
|
|
||||||
return format(member)
|
return MemberFormatter.format(member)
|
||||||
|
@@ -27,7 +27,7 @@ from mistralclient import utils
|
|||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class TaskFormatter(object):
|
class TaskFormatter(base.MistralFormatter):
|
||||||
COLUMNS = [
|
COLUMNS = [
|
||||||
('id', 'ID'),
|
('id', 'ID'),
|
||||||
('name', 'Name'),
|
('name', 'Name'),
|
||||||
@@ -40,13 +40,6 @@ class TaskFormatter(object):
|
|||||||
('updated_at', 'Updated at'),
|
('updated_at', 'Updated at'),
|
||||||
]
|
]
|
||||||
|
|
||||||
COLUMN_FIELD_NAMES = list(zip(*COLUMNS))[0]
|
|
||||||
COLUMN_HEADING_NAMES = list(zip(*COLUMNS))[1]
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def format_list(task=None):
|
|
||||||
return TaskFormatter.format(task, lister=True)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def format(task=None, lister=False):
|
def format(task=None, lister=False):
|
||||||
if task:
|
if task:
|
||||||
@@ -67,10 +60,10 @@ class TaskFormatter(object):
|
|||||||
else:
|
else:
|
||||||
data = (tuple('' for _ in range(len(TaskFormatter.COLUMNS))),)
|
data = (tuple('' for _ in range(len(TaskFormatter.COLUMNS))),)
|
||||||
|
|
||||||
return TaskFormatter.COLUMN_HEADING_NAMES, data
|
return TaskFormatter.headings(), data
|
||||||
|
|
||||||
|
|
||||||
class List(base.MistralLister):
|
class List(base.MistralExecutionLister):
|
||||||
"""List all tasks."""
|
"""List all tasks."""
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
@@ -81,43 +74,21 @@ class List(base.MistralLister):
|
|||||||
nargs='?',
|
nargs='?',
|
||||||
help='Workflow execution ID associated with list of Tasks.'
|
help='Workflow execution ID associated with list of Tasks.'
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
|
||||||
'--filter',
|
|
||||||
dest='filters',
|
|
||||||
action='append',
|
|
||||||
help='Filters. Can be repeated.'
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'--limit',
|
|
||||||
type=int,
|
|
||||||
help='Maximum number of tasks to return in a single result. '
|
|
||||||
'limit is set to %s by default. Use --limit -1 to fetch the '
|
|
||||||
'full result set.' % base.DEFAULT_LIMIT,
|
|
||||||
nargs='?'
|
|
||||||
)
|
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return TaskFormatter.format_list
|
return TaskFormatter.format_list
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
if parsed_args.limit is None:
|
|
||||||
parsed_args.limit = base.DEFAULT_LIMIT
|
|
||||||
|
|
||||||
LOG.info(
|
|
||||||
"limit is set to %s by default. Set "
|
|
||||||
"the limit explicitly using \'--limit\', if required. "
|
|
||||||
"Use \'--limit\' -1 to fetch the full result set.",
|
|
||||||
base.DEFAULT_LIMIT
|
|
||||||
)
|
|
||||||
|
|
||||||
mistral_client = self.app.client_manager.workflow_engine
|
mistral_client = self.app.client_manager.workflow_engine
|
||||||
|
|
||||||
return mistral_client.tasks.list(
|
return mistral_client.tasks.list(
|
||||||
parsed_args.workflow_execution,
|
parsed_args.workflow_execution,
|
||||||
|
marker=parsed_args.marker,
|
||||||
limit=parsed_args.limit,
|
limit=parsed_args.limit,
|
||||||
fields=TaskFormatter.COLUMN_FIELD_NAMES,
|
sort_keys=parsed_args.sort_keys,
|
||||||
|
sort_dirs=parsed_args.sort_dirs,
|
||||||
|
fields=TaskFormatter.fields(),
|
||||||
**base.get_filters(parsed_args)
|
**base.get_filters(parsed_args)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -21,16 +21,18 @@ from mistralclient.commands.v2 import base
|
|||||||
from mistralclient import utils
|
from mistralclient import utils
|
||||||
|
|
||||||
|
|
||||||
def format(workbook=None):
|
class WorkbookFormatter(base.MistralFormatter):
|
||||||
columns = (
|
COLUMNS = [
|
||||||
'Name',
|
('name', 'Name'),
|
||||||
'Namespace',
|
('namespace', 'Namespace'),
|
||||||
'Tags',
|
('tags', 'Tags'),
|
||||||
'Scope',
|
('scope', 'Scope'),
|
||||||
'Created at',
|
('created_at', 'Created at'),
|
||||||
'Updated at'
|
('updated_at', 'Updated at')
|
||||||
)
|
]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def format(workbook=None, lister=False):
|
||||||
if workbook:
|
if workbook:
|
||||||
data = (
|
data = (
|
||||||
workbook.name,
|
workbook.name,
|
||||||
@@ -46,20 +48,27 @@ def format(workbook=None):
|
|||||||
data += (None,)
|
data += (None,)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
data = (tuple('' for _ in range(len(columns))),)
|
data = (tuple('' for _ in range(len(WorkbookFormatter.COLUMNS))),)
|
||||||
|
|
||||||
return columns, data
|
return WorkbookFormatter.headings(), data
|
||||||
|
|
||||||
|
|
||||||
class List(base.MistralLister):
|
class List(base.MistralLister):
|
||||||
"""List all workbooks."""
|
"""List all workbooks."""
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return format
|
return WorkbookFormatter.format
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
mistral_client = self.app.client_manager.workflow_engine
|
mistral_client = self.app.client_manager.workflow_engine
|
||||||
return mistral_client.workbooks.list()
|
return mistral_client.workbooks.list(
|
||||||
|
marker=parsed_args.marker,
|
||||||
|
limit=parsed_args.limit,
|
||||||
|
sort_keys=parsed_args.sort_keys,
|
||||||
|
sort_dirs=parsed_args.sort_dirs,
|
||||||
|
fields=WorkbookFormatter.fields(),
|
||||||
|
**base.get_filters(parsed_args)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Get(command.ShowOne):
|
class Get(command.ShowOne):
|
||||||
@@ -86,7 +95,7 @@ class Get(command.ShowOne):
|
|||||||
parsed_args.namespace
|
parsed_args.namespace
|
||||||
)
|
)
|
||||||
|
|
||||||
return format(workbook)
|
return WorkbookFormatter.format(workbook)
|
||||||
|
|
||||||
|
|
||||||
class Create(command.ShowOne):
|
class Create(command.ShowOne):
|
||||||
@@ -125,7 +134,7 @@ class Create(command.ShowOne):
|
|||||||
scope=scope
|
scope=scope
|
||||||
)
|
)
|
||||||
|
|
||||||
return format(workbook)
|
return WorkbookFormatter.format(workbook)
|
||||||
|
|
||||||
|
|
||||||
class Delete(command.Command):
|
class Delete(command.Command):
|
||||||
@@ -190,7 +199,7 @@ class Update(command.ShowOne):
|
|||||||
scope=scope
|
scope=scope
|
||||||
)
|
)
|
||||||
|
|
||||||
return format(workbook)
|
return WorkbookFormatter.format(workbook)
|
||||||
|
|
||||||
|
|
||||||
class GetDefinition(command.Command):
|
class GetDefinition(command.Command):
|
||||||
@@ -212,8 +221,8 @@ class GetDefinition(command.Command):
|
|||||||
|
|
||||||
class Validate(command.ShowOne):
|
class Validate(command.ShowOne):
|
||||||
"""Validate workbook."""
|
"""Validate workbook."""
|
||||||
|
@staticmethod
|
||||||
def _format(self, result=None):
|
def _format(result=None):
|
||||||
columns = ('Valid', 'Error')
|
columns = ('Valid', 'Error')
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
|
@@ -22,23 +22,21 @@ from mistralclient.commands.v2 import base
|
|||||||
from mistralclient import utils
|
from mistralclient import utils
|
||||||
|
|
||||||
|
|
||||||
def format_list(workflow=None):
|
class WorkflowFormatter(base.MistralFormatter):
|
||||||
return format(workflow, lister=True)
|
COLUMNS = [
|
||||||
|
('id', 'ID'),
|
||||||
|
('name', 'Name'),
|
||||||
|
('namespace', 'Namespace'),
|
||||||
|
('project_id', 'Project ID'),
|
||||||
|
('tags', 'Tags'),
|
||||||
|
('input', 'Input'),
|
||||||
|
('scope', 'Scope'),
|
||||||
|
('created_at', 'Created at'),
|
||||||
|
('updated_at', 'Updated at')
|
||||||
|
]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
def format(workflow=None, lister=False):
|
def format(workflow=None, lister=False):
|
||||||
columns = (
|
|
||||||
'ID',
|
|
||||||
'Name',
|
|
||||||
'Namespace',
|
|
||||||
'Project ID',
|
|
||||||
'Tags',
|
|
||||||
'Input',
|
|
||||||
'Scope',
|
|
||||||
'Created at',
|
|
||||||
'Updated at'
|
|
||||||
)
|
|
||||||
|
|
||||||
if workflow:
|
if workflow:
|
||||||
tags = getattr(workflow, 'tags', None) or []
|
tags = getattr(workflow, 'tags', None) or []
|
||||||
|
|
||||||
@@ -58,33 +56,31 @@ def format(workflow=None, lister=False):
|
|||||||
else:
|
else:
|
||||||
data += (None,)
|
data += (None,)
|
||||||
else:
|
else:
|
||||||
data = (tuple('' for _ in range(len(columns))),)
|
data = (tuple('' for _ in range(len(WorkflowFormatter.COLUMNS))),)
|
||||||
|
|
||||||
return columns, data
|
return WorkflowFormatter.headings(), data
|
||||||
|
|
||||||
|
|
||||||
class List(base.MistralLister):
|
class List(base.MistralLister):
|
||||||
"""List all workflows."""
|
"""List all workflows."""
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return format_list
|
return WorkflowFormatter.format_list
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
parser = super(List, self).get_parser(prog_name)
|
parser = super(List, self).get_parser(prog_name)
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--filter',
|
|
||||||
dest='filters',
|
|
||||||
action='append',
|
|
||||||
help='Filters. Can be repeated.'
|
|
||||||
)
|
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
mistral_client = self.app.client_manager.workflow_engine
|
mistral_client = self.app.client_manager.workflow_engine
|
||||||
|
|
||||||
return mistral_client.workflows.list(
|
return mistral_client.workflows.list(
|
||||||
|
marker=parsed_args.marker,
|
||||||
|
limit=parsed_args.limit,
|
||||||
|
sort_keys=parsed_args.sort_keys,
|
||||||
|
sort_dirs=parsed_args.sort_dirs,
|
||||||
|
fields=WorkflowFormatter.fields(),
|
||||||
**base.get_filters(parsed_args)
|
**base.get_filters(parsed_args)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -113,7 +109,7 @@ class Get(show.ShowOne):
|
|||||||
parsed_args.namespace
|
parsed_args.namespace
|
||||||
)
|
)
|
||||||
|
|
||||||
return format(wf)
|
return WorkflowFormatter.format(wf)
|
||||||
|
|
||||||
|
|
||||||
class Create(base.MistralLister):
|
class Create(base.MistralLister):
|
||||||
@@ -142,7 +138,7 @@ class Create(base.MistralLister):
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return format_list
|
return WorkflowFormatter.format_list
|
||||||
|
|
||||||
def _validate_parsed_args(self, parsed_args):
|
def _validate_parsed_args(self, parsed_args):
|
||||||
if not parsed_args.definition:
|
if not parsed_args.definition:
|
||||||
@@ -223,7 +219,7 @@ class Update(base.MistralLister):
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return format_list
|
return WorkflowFormatter.format_list
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
scope = 'public' if parsed_args.public else 'private'
|
scope = 'public' if parsed_args.public else 'private'
|
||||||
@@ -267,8 +263,8 @@ class GetDefinition(command.Command):
|
|||||||
|
|
||||||
class Validate(show.ShowOne):
|
class Validate(show.ShowOne):
|
||||||
"""Validate workflow."""
|
"""Validate workflow."""
|
||||||
|
@staticmethod
|
||||||
def _format(self, result=None):
|
def _format(result=None):
|
||||||
columns = ('Valid', 'Error')
|
columns = ('Valid', 'Error')
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
|
@@ -225,7 +225,7 @@ class TestCLIExecutionsV2(base.BaseCommandTest):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_list(self):
|
def test_list(self):
|
||||||
self.client.executions.list.return_value = [EXEC, SUB_WF_EXEC]
|
self.client.executions.list.return_value = [SUB_WF_EXEC, EXEC]
|
||||||
|
|
||||||
result = self.call(execution_cmd.List)
|
result = self.call(execution_cmd.List)
|
||||||
|
|
||||||
@@ -239,28 +239,46 @@ class TestCLIExecutionsV2(base.BaseCommandTest):
|
|||||||
|
|
||||||
self.call(execution_cmd.List)
|
self.call(execution_cmd.List)
|
||||||
self.client.executions.list.assert_called_once_with(
|
self.client.executions.list.assert_called_once_with(
|
||||||
|
fields=execution_cmd.ExecutionFormatter.fields(),
|
||||||
limit=100,
|
limit=100,
|
||||||
marker='',
|
marker='',
|
||||||
sort_dirs='asc',
|
sort_dirs='desc',
|
||||||
sort_keys='created_at',
|
sort_keys='created_at',
|
||||||
task=None
|
task=None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.call(
|
||||||
|
execution_cmd.List,
|
||||||
|
app_args=[
|
||||||
|
'--oldest'
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.client.executions.list.assert_called_with(
|
||||||
|
fields=execution_cmd.ExecutionFormatter.fields(),
|
||||||
|
limit=100,
|
||||||
|
marker='',
|
||||||
|
sort_keys='created_at',
|
||||||
|
sort_dirs='asc',
|
||||||
|
task=None
|
||||||
|
)
|
||||||
|
|
||||||
self.call(
|
self.call(
|
||||||
execution_cmd.List,
|
execution_cmd.List,
|
||||||
app_args=[
|
app_args=[
|
||||||
'--limit', '5',
|
'--limit', '5',
|
||||||
'--sort_dirs', 'id, Workflow',
|
'--sort_keys', 'id, Workflow',
|
||||||
'--sort_keys', 'desc',
|
'--sort_dirs', 'desc',
|
||||||
'--marker', 'abc'
|
'--marker', 'abc'
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
self.client.executions.list.assert_called_with(
|
self.client.executions.list.assert_called_with(
|
||||||
|
fields=execution_cmd.ExecutionFormatter.fields(),
|
||||||
limit=5,
|
limit=5,
|
||||||
marker='abc',
|
marker='abc',
|
||||||
sort_dirs='id, Workflow',
|
sort_keys='id, Workflow',
|
||||||
sort_keys='desc',
|
sort_dirs='desc',
|
||||||
task=None
|
task=None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -61,7 +61,7 @@ class TestCLITasksV2(base.BaseCommandTest):
|
|||||||
self.assertEqual([EXPECTED_TASK_RESULT], result[1])
|
self.assertEqual([EXPECTED_TASK_RESULT], result[1])
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.client.tasks.list.call_args[1]["fields"],
|
self.client.tasks.list.call_args[1]["fields"],
|
||||||
task_cmd.TaskFormatter.COLUMN_FIELD_NAMES
|
task_cmd.TaskFormatter.fields()
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_list_with_workflow_execution(self):
|
def test_list_with_workflow_execution(self):
|
||||||
|
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
critical:
|
||||||
|
- |
|
||||||
|
The default behavior of the action-execution-list, execution-list and
|
||||||
|
task-list commands has been changed. Instead of returning the oldest
|
||||||
|
N records (default 100 or --limit specified value) by default,
|
||||||
|
they now return the most recent N records, when no other sort_dir,
|
||||||
|
sort_key or marker values are provided. If the user specifies --oldest
|
||||||
|
or any of the --marker, --sort_key or --sort_dir options, the new
|
||||||
|
behavior is disabled and the commands will work according to the
|
||||||
|
user-supplied options.
|
Reference in New Issue
Block a user