overcloud plan deployment status

Add a new command to tripleoclient:
openstack overcloud plan deployment status

The command shows the top level deployment status based on a plan name
and makes use of the
tripleo.plan_management.v1.get_plan_deployment_status workflow.

Change-Id: I600fe9b83b69aee64d8ca44e405d0c5e7a20a273
Depends-On: Ia8e3ecadfb97c0827c396cd418c32d3daa2e299b
(cherry picked from commit 0220592660)
This commit is contained in:
James Slagle 2018-04-25 15:00:21 -04:00 committed by Sergii Golovatiuk
parent 4c10f387fa
commit 10b14b061f
7 changed files with 125 additions and 0 deletions

View File

@ -0,0 +1,4 @@
---
features:
- A new command, openstack overcloud status, is added to show
the status of a deployment plan when using config-download.

View File

@ -66,6 +66,7 @@ openstack.tripleoclient.v1 =
overcloud_delete = tripleoclient.v1.overcloud_delete:DeleteOvercloud
overcloud_credentials = tripleoclient.v1.overcloud_credentials:OvercloudCredentials
overcloud_deploy = tripleoclient.v1.overcloud_deploy:DeployOvercloud
overcloud_status = tripleoclient.v1.overcloud_deploy:GetDeploymentStatus
overcloud_image_build = tripleoclient.v1.overcloud_image:BuildOvercloudImage
overcloud_image_upload = tripleoclient.v1.overcloud_image:UploadOvercloudImage
overcloud_node_configure = tripleoclient.v1.overcloud_node:ConfigureNode

View File

@ -22,6 +22,7 @@ import yaml
from heatclient import exc as hc_exc
import mock
from osc_lib import exceptions as oscexc
from osc_lib.tests import utils
from swiftclient.exceptions import ClientException as ObjectClientException
from tripleoclient import constants
@ -1902,3 +1903,45 @@ class TestArgumentValidation(fakes.TestDeployOvercloud):
def test_validate_env_dir_ignore_default_not_existing(self):
full_path = os.path.expanduser(constants.DEFAULT_ENV_DIRECTORY)
self.assertIsNone(self.validate([full_path]))
class TestGetDeploymentStatus(utils.TestCommand):
def setUp(self):
super(TestGetDeploymentStatus, self).setUp()
self.cmd = overcloud_deploy.GetDeploymentStatus(self.app, None)
self.app.client_manager = mock.Mock()
self.clients = self.app.client_manager
@mock.patch(
'tripleoclient.workflows.deployment.get_deployment_status',
autospec=True)
def test_get_deployment_status(self, mock_get_deployment_status):
parsed_args = self.check_parser(self.cmd, [], [])
self.cmd.app.stdout = six.StringIO()
status = {
'workflow_status': {
'payload': {
'execution': {
'created_at': 'yesterday',
'updated_at': 'today'
},
'plan_name': 'testplan',
'deployment_status': 'SUCCESS'
}
}
}
mock_get_deployment_status.return_value = status
self.cmd.take_action(parsed_args)
expected = (
'+-----------+-----------+---------+-------------------+\n'
'| Plan Name | Created | Updated | Deployment Status |\n'
'+-----------+-----------+---------+-------------------+\n'
'| testplan | yesterday | today | SUCCESS |\n'
'+-----------+-----------+---------+-------------------+\n')
self.assertEqual(expected, self.cmd.app.stdout.getvalue())

View File

@ -18,6 +18,20 @@ from tripleoclient import exceptions
from tripleoclient.v1 import overcloud_plan
class TestStringCapture(object):
def __init__(self):
self.capture_string = ''
def write(self, msg):
self.capture_string = self.capture_string + msg
def getvalue(self):
return self.capture_string
def flush(self):
return
class TestOvercloudPlanList(utils.TestCommand):
def setUp(self):

View File

@ -18,6 +18,7 @@ import argparse
import logging
import os
import os.path
from prettytable import PrettyTable
import re
import shutil
import six
@ -1027,3 +1028,36 @@ class DeployOvercloud(command.Command):
print("Overcloud Horizon Dashboard URL: {0}".format(horizon_url))
print("Overcloud rc file: {0}".format(rcpath))
print("Overcloud Deployed")
class GetDeploymentStatus(command.Command):
"""Check status of a deployment plan"""
log = logging.getLogger(__name__ + ".GetDeploymentStatus")
def get_parser(self, prog_name):
parser = super(GetDeploymentStatus, self).get_parser(prog_name)
parser.add_argument('--plan', '--stack',
help=_('Name of the stack/plan. '
'(default: overcloud)'),
default='overcloud')
return parser
def take_action(self, parsed_args):
self.log.debug("take_action(%s)" % parsed_args)
plan = parsed_args.plan
status = deployment.get_deployment_status(
self.app.client_manager,
plan=plan
)
payload = status['workflow_status']['payload']
execution = payload['execution']
table = PrettyTable(
['Plan Name', 'Created', 'Updated', 'Deployment Status'])
table.add_row([payload['plan_name'],
execution['created_at'],
execution['updated_at'],
payload['deployment_status']])
print(table, file=self.app.stdout)

View File

@ -10,6 +10,8 @@
# License for the specific language governing permissions and limitations
# under the License.
from __future__ import print_function
import json
import logging
import os.path

View File

@ -30,6 +30,9 @@ from tripleoclient import utils
from tripleoclient.workflows import base
_WORKFLOW_TIMEOUT = 360 # 6 * 60 seconds
def deploy(clients, **workflow_input):
workflow_client = clients.workflow_engine
@ -267,3 +270,27 @@ def get_horizon_url(clients, **workflow_input):
assert payload['status'] == "SUCCESS"
return payload['horizon_url']
def get_deployment_status(clients, **workflow_input):
workflow_client = clients.workflow_engine
tripleoclients = clients.tripleoclient
execution = base.start_workflow(
workflow_client,
'tripleo.deployment.v1.get_deployment_status',
workflow_input=workflow_input
)
with tripleoclients.messaging_websocket() as ws:
for payload in base.wait_for_messages(workflow_client, ws, execution,
_WORKFLOW_TIMEOUT):
if 'message' in payload:
print(payload['message'])
if payload['status'] == 'SUCCESS':
return payload['deployment_status']
else:
raise exceptions.WorkflowServiceError(
'Exception getting deployment status: {}'.format(
payload.get('message', '')))