Support deployment history for fuel client v1
Add new commands for Fuel v1: fuel deployment-tasks --task-id 5 --statuses error --nodes 1,2 Add tests Change-Id: I5a9633058925491b939c3dfe8979dc43e4c7763c Implements: blueprint store-deployment-tasks-history
This commit is contained in:
@@ -18,6 +18,7 @@ All action classes must be added to action_tuple to be used by parser
|
||||
"""
|
||||
from fuelclient.cli.actions.deploy import DeployChangesAction
|
||||
from fuelclient.cli.actions.deploy import RedeployChangesAction
|
||||
from fuelclient.cli.actions.deployment_tasks import DeploymentTasksAction
|
||||
from fuelclient.cli.actions.environment import EnvironmentAction
|
||||
from fuelclient.cli.actions.fact import DeploymentAction
|
||||
from fuelclient.cli.actions.fact import ProvisioningAction
|
||||
@@ -48,6 +49,7 @@ from fuelclient.cli.actions.vip import VIPAction
|
||||
actions_tuple = (
|
||||
DeployChangesAction,
|
||||
DeploymentAction,
|
||||
DeploymentTasksAction,
|
||||
EnvironmentAction,
|
||||
FuelVersionAction,
|
||||
GraphAction,
|
||||
|
||||
71
fuelclient/cli/actions/deployment_tasks.py
Normal file
71
fuelclient/cli/actions/deployment_tasks.py
Normal file
@@ -0,0 +1,71 @@
|
||||
# Copyright 2016 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from fuelclient.cli.actions.base import Action
|
||||
import fuelclient.cli.arguments as Args
|
||||
from fuelclient.cli.arguments import group
|
||||
from fuelclient.cli.formatting import format_table
|
||||
from fuelclient.objects.deployment_history import DeploymentHistory
|
||||
|
||||
|
||||
class DeploymentTasksAction(Action):
|
||||
"""Show deployment tasks
|
||||
"""
|
||||
action_name = "deployment-tasks"
|
||||
acceptable_keys = ("deployment_graph_task_name", "node_id", "status",
|
||||
"time_start", "time_end")
|
||||
|
||||
def __init__(self):
|
||||
super(DeploymentTasksAction, self).__init__()
|
||||
self.args = [
|
||||
group(
|
||||
Args.get_list_arg("List all deployment tasks"),
|
||||
),
|
||||
Args.get_single_task_arg(required=True),
|
||||
Args.get_deployment_node_arg(
|
||||
"Node ids."
|
||||
),
|
||||
Args.get_status_arg(
|
||||
"Statuses: pending, error, ready, running, skipped"
|
||||
)
|
||||
]
|
||||
self.flag_func_map = (
|
||||
(None, self.list),
|
||||
)
|
||||
|
||||
def list(self, params):
|
||||
"""To display all deployment tasks:
|
||||
fuel deployment-tasks --task-id 5
|
||||
|
||||
To display deployment tasks with for some nodes:
|
||||
fuel deployment-tasks --task-id 5 --nodes 1,2
|
||||
|
||||
To display deployment tasks with for some statuses(pending, error,
|
||||
ready, running):
|
||||
fuel deployment-tasks --task-id 5 --statuses pending,running
|
||||
|
||||
To display deployment tasks with for some statuses(pending, error,
|
||||
ready, running) on some nodes:
|
||||
fuel deployment-tasks --task-id 5 --statuses error --nodes 1,2
|
||||
"""
|
||||
|
||||
d_tasks_data = DeploymentHistory.get_all_with_nodes_and_statuses(
|
||||
params.task,
|
||||
params.node,
|
||||
params.status
|
||||
)
|
||||
self.serializer.print_to_output(
|
||||
d_tasks_data,
|
||||
format_table(d_tasks_data, acceptable_keys=self.acceptable_keys)
|
||||
)
|
||||
@@ -25,6 +25,7 @@ substitutions = {
|
||||
# replace from: to
|
||||
"env": "environment",
|
||||
"nodes": "node",
|
||||
"statuses": "status",
|
||||
"net": "network",
|
||||
"rel": "release",
|
||||
"list": "--list",
|
||||
@@ -179,6 +180,15 @@ def get_env_arg(required=False):
|
||||
)
|
||||
|
||||
|
||||
def get_single_task_arg(required=False):
|
||||
return get_int_arg(
|
||||
"task",
|
||||
flags=("--task-id", "--tid"),
|
||||
help="task id",
|
||||
required=required
|
||||
)
|
||||
|
||||
|
||||
def get_new_password_arg(help_msg):
|
||||
return get_str_arg(
|
||||
"newpass",
|
||||
@@ -666,3 +676,25 @@ def get_upload_file_arg(help_msg):
|
||||
flags=("-u", "--upload",),
|
||||
help=help_msg
|
||||
)
|
||||
|
||||
|
||||
def get_status_arg(help_msg):
|
||||
default_kwargs = {
|
||||
"action": SetAction,
|
||||
"flags": ("--status",),
|
||||
"nargs": '+',
|
||||
"default": None,
|
||||
"help": help_msg
|
||||
}
|
||||
return get_arg("status", **default_kwargs)
|
||||
|
||||
|
||||
def get_deployment_node_arg(help_msg):
|
||||
default_kwargs = {
|
||||
"action": SetAction,
|
||||
"flags": ("--node-id",),
|
||||
"nargs": '+',
|
||||
"default": None,
|
||||
"help": help_msg
|
||||
}
|
||||
return get_arg("node", **default_kwargs)
|
||||
|
||||
@@ -17,6 +17,7 @@ functionality from nailgun objects.
|
||||
"""
|
||||
|
||||
from fuelclient.objects.base import BaseObject
|
||||
from fuelclient.objects.deployment_history import DeploymentHistory
|
||||
from fuelclient.objects.environment import Environment
|
||||
from fuelclient.objects.node import Node
|
||||
from fuelclient.objects.node import NodeCollection
|
||||
|
||||
34
fuelclient/objects/deployment_history.py
Normal file
34
fuelclient/objects/deployment_history.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# Copyright 2016 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from fuelclient.objects.base import BaseObject
|
||||
|
||||
|
||||
class DeploymentHistory(BaseObject):
|
||||
|
||||
class_api_path = "transactions/{transaction_id}/deployment_history/"\
|
||||
"?nodes={nodes}&statuses={statuses}"
|
||||
|
||||
@classmethod
|
||||
def get_all_with_nodes_and_statuses(cls, transaction_id,
|
||||
nodes=None, statuses=None):
|
||||
statuses = ",".join(str(s) for s in statuses) if statuses else ""
|
||||
nodes = ",".join(str(n) for n in nodes) if nodes else ""
|
||||
history = cls.connection.get_request(
|
||||
cls.class_api_path.format(
|
||||
transaction_id=transaction_id,
|
||||
nodes=nodes,
|
||||
statuses=statuses))
|
||||
|
||||
return history
|
||||
95
fuelclient/tests/unit/v1/test_deployment_history_action.py
Normal file
95
fuelclient/tests/unit/v1/test_deployment_history_action.py
Normal file
@@ -0,0 +1,95 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2016 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from mock import patch
|
||||
|
||||
from fuelclient.cli.actions import DeploymentTasksAction
|
||||
from fuelclient.cli.formatting import format_table
|
||||
from fuelclient.cli.serializers import Serializer
|
||||
from fuelclient.tests.unit.v1 import base
|
||||
|
||||
|
||||
HISTORY_API_OUTPUT = [
|
||||
{
|
||||
"status": "ready",
|
||||
"time_start": "2016-03-25T17:22:10.687135",
|
||||
"time_end": "2016-03-25T17:22:30.830701",
|
||||
"node_id": "1",
|
||||
"deployment_graph_task_name": "controller_remaining_tasks"
|
||||
},
|
||||
{
|
||||
"status": "skipped",
|
||||
"time_start": "2016-03-25T17:23:37.313212",
|
||||
"time_end": "2016-03-25T17:23:37.313234",
|
||||
"node_id": "2",
|
||||
"deployment_graph_task_name": "ironic-compute"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class TestDeploymentTasksAction(base.UnitTestCase):
|
||||
|
||||
def assert_print_table(self, print_mock, tasks):
|
||||
print_mock.assert_called_once_with(
|
||||
tasks, format_table(
|
||||
tasks,
|
||||
acceptable_keys=DeploymentTasksAction.acceptable_keys))
|
||||
|
||||
@patch.object(Serializer, 'print_to_output')
|
||||
def test_show_full_history(self, print_mock):
|
||||
self.m_history_api = self.m_request.get(
|
||||
'/api/v1/transactions/1/deployment_history/?nodes=&statuses=',
|
||||
json=HISTORY_API_OUTPUT)
|
||||
|
||||
self.execute(
|
||||
['fuel', 'deployment-tasks', '--tid', '1']
|
||||
)
|
||||
|
||||
self.assert_print_table(print_mock, HISTORY_API_OUTPUT)
|
||||
|
||||
def test_show_history_for_special_nodes(self):
|
||||
self.m_history_api = self.m_request.get(
|
||||
'/api/v1/transactions/1/deployment_history/?nodes=1,2&statuses=',
|
||||
json={})
|
||||
|
||||
self.execute(
|
||||
['fuel', 'deployment-tasks', '--tid', '1',
|
||||
'--node-id', '1,2']
|
||||
)
|
||||
|
||||
self.assertEqual(self.m_history_api.call_count, 1)
|
||||
|
||||
def test_show_history_with_special_statuses(self):
|
||||
self.m_history_api = self.m_request.get(
|
||||
'/api/v1/transactions/1/deployment_history/'
|
||||
'?nodes=&statuses=ready,skipped',
|
||||
json={})
|
||||
self.execute(
|
||||
['fuel', 'deployment-tasks', '--tid', '1',
|
||||
'--status', 'ready,skipped']
|
||||
)
|
||||
self.assertEqual(self.m_history_api.call_count, 1)
|
||||
|
||||
def test_show_history_with_special_statuses_for_special_nodes(self):
|
||||
self.m_history_api = self.m_request.get(
|
||||
'/api/v1/transactions/1/deployment_history/'
|
||||
'?nodes=1,2&statuses=ready,skipped',
|
||||
json={})
|
||||
self.execute(
|
||||
['fuel', 'deployment-tasks', '--tid', '1',
|
||||
'--status', 'ready,skipped', '--node', '1,2']
|
||||
)
|
||||
self.assertEqual(self.m_history_api.call_count, 1)
|
||||
Reference in New Issue
Block a user