Move kolla prechecks action into kolla_actiom model

1. Prechecks action is one core action of kolla action command,
it should be in kolla_action rather than host, this PS to
move it from host model into kolla_action
2. Add prechecks action unit test with hosts and services flag

Change-Id: I8f636570a9756a004f186d806e4451a87f046f18
This commit is contained in:
gujin 2019-08-08 00:08:07 +08:00
parent d9d50149a1
commit 661f3f51d3
9 changed files with 156 additions and 78 deletions

View File

@ -60,6 +60,36 @@ class ControlPlaneApi(object):
ansible_job = action.deploy(hostnames, serial_flag, servicenames)
return Job(ansible_job)
@staticmethod
def prechecks(verbose_level=1, hostnames=[], servicenames=[]):
# type: (int, List[str], List[str]) -> Job
"""Check pre-deployment configuration of hosts.
Check if host is ready for a new deployment. This will fail if
any of the hosts are not configured correctly or if they have
already been deployed to.
:param hostnames: host names
:type hostnames: list
:param verbose_level: the higher the number, the more verbose
:type verbose_level: integer
:param servicenames: services to prechecks.
:type servicenames: list of strings
:return: Job object
:rtype: Job
"""
check_arg(hostnames, u._('Host names'), list,
empty_ok=True, none_ok=True)
check_arg(verbose_level, u._('Verbose level'), int)
check_arg(servicenames, u._('Service names'), list,
empty_ok=True, none_ok=True)
hostnames = safe_decode(hostnames)
servicenames = safe_decode(servicenames)
action = KollaAction(verbose_level=verbose_level,
playbook_name='site.yml')
ansible_job = action.precheck(hostnames, servicenames)
return Job(ansible_job)
@staticmethod
def pull(verbose_level=1, hostnames=[], servicenames=[]):
"""Pull.

View File

@ -190,32 +190,6 @@ class HostApi(object):
include_data, remove_images)
return Job(ansible_job)
@staticmethod
def host_precheck(hostnames, verbose_level=1):
# type: (List[str], int) -> Job
"""Check pre-deployment configuration of hosts.
Check if host is ready for a new deployment. This will fail if
any of the hosts are not configured correctly or if they have
already been deployed to.
:param hostnames: host names
:type hostnames: list
:param verbose_level: the higher the number, the more verbose
:type verbose_level: integer
:return: Job object
:rtype: Job
"""
check_arg(hostnames, u._('Host names'), list)
check_arg(verbose_level, u._('Verbose level'), int)
hostnames = safe_decode(hostnames)
inventory = Inventory.load()
inventory.validate_hostnames(hostnames)
action = KollaAction(verbose_level=verbose_level,
playbook_name='site.yml')
ansible_job = action.precheck(hostnames)
return Job(ansible_job)
@staticmethod
def host_stop(hostnames, verbose_level=1):
# type: (List[str], int) -> Job

View File

@ -185,45 +185,37 @@ class HostList(Lister):
class HostCheck(Command):
"""Check configuration of host(s)."""
"""Check an ssh check of host(s)."""
def get_parser(self, prog_name):
parser = super(HostCheck, self).get_parser(prog_name)
parser.add_argument('hostname', metavar='<hostname | all>',
help=u._('Host name or "all"'))
parser.add_argument('--predeploy', action='store_true',
help=u._('Run pre-deploy host checks.'))
return parser
def take_action(self, parsed_args):
try:
hostname = parsed_args.hostname.strip()
hostnames = [hostname]
if hostname == 'all':
hostnames = _get_all_hostnames()
if parsed_args.predeploy:
# run pre-deploy checks
verbose_level = self.app.options.verbose_level
job = CLIENT.host_precheck(hostnames, verbose_level)
status = job.wait()
handers_action_result(job, status, verbose_level)
else:
# just do an ssh check
summary = CLIENT.host_ssh_check(hostnames)
all_ok = True
for hostname, info in summary.items():
status = u._('success')
msg = ''
if not info['success']:
status = u._('failed-')
msg = info['msg']
all_ok = False
LOG.info(u._('Host {host}: {sts} {msg}')
.format(host=hostname, sts=status, msg=msg))
hostnames = [hostname]
if not all_ok:
raise CommandError(u._('Host check failed.'))
# just do an ssh check
summary = CLIENT.host_ssh_check(hostnames)
all_ok = True
for hostname, info in summary.items():
status = u._('success')
msg = ''
if not info['success']:
status = u._('failed-')
msg = info['msg']
all_ok = False
LOG.info(u._('Host {host}: {sts} {msg}')
.format(host=hostname, sts=status, msg=msg))
if not all_ok:
raise CommandError(u._('Host check failed.'))
except ClientException as e:
raise CommandError(str(e))
except Exception as e:

View File

@ -99,6 +99,37 @@ class Deploy(Command):
raise Exception(traceback.format_exc())
class Prechecks(Command):
"""Do pre-deployment checks for hosts."""
def get_parser(self, prog_name):
parser = super(Prechecks, self).get_parser(prog_name)
parser.add_argument('--hosts', nargs='?',
metavar='<host_list>',
help=u._('Pull host list'))
parser.add_argument('--services', nargs='?',
metavar='<service_list>',
help=u._('Pull service list'))
return parser
def take_action(self, parsed_args):
hosts = []
services = []
try:
verbose_level = self.app.options.verbose_level
if parsed_args.hosts:
host_list = parsed_args.hosts.strip()
hosts = host_list.split(',')
if parsed_args.services:
service_list = parsed_args.services.strip()
services = service_list.split(',')
job = CLIENT.prechecks(verbose_level, hosts, services)
status = job.wait()
handers_action_result(job, status, verbose_level)
except Exception:
raise Exception(traceback.format_exc())
class Pull(Command):
"""Pull all images for containers (only pulls, no running container)."""
def get_parser(self, prog_name):

View File

@ -118,7 +118,7 @@ class KollaAction(object):
job = self.playbook.run()
return job
def precheck(self, hostnames):
def precheck(self, hostnames=[], servicenames=[]):
'''run check playbooks on a set of hosts'''
# check that password file has no empty password values
@ -135,7 +135,8 @@ class KollaAction(object):
# define 'hosts' to be all, but inventory filtering will subset
# that down to the hosts in playbook.hosts.
self.playbook.hosts = hostnames
self.playbook.extra_vars = 'kolla_action=precheck hosts=all'
self.playbook.services = servicenames
self.playbook.extra_vars = 'kolla_action=precheck'
self.playbook.print_output = True
job = self.playbook.run()
return job

View File

@ -122,7 +122,6 @@ class TestFunctional(KollaCliTest):
self.check_types(CLIENT.host_setup, [dict])
self.check_types(CLIENT.host_ssh_check, [list])
self.check_types(CLIENT.host_destroy, [list, str, int, bool])
self.check_types(CLIENT.host_precheck, [list, int])
def test_host_list_nonascii(self):
hostname = 'host_test1'

View File

@ -135,30 +135,6 @@ class TestUnit(KollaCliUnitTest):
mock_ssh_check.assert_called_once_with([hostname])
mock_log.assert_called_once_with('Host %s: failed- FAILED' % hostname)
@mock.patch('kolla_cli.common.ansible.job.AnsibleJob.get_status')
@mock.patch('kolla_cli.commands.host.ClientApi.host_precheck')
@mock.patch('kolla_cli.api.client.ClientApi.host_get_all')
@mock.patch('kolla_cli.shell.KollaCli._is_inventory_present',
return_value=True)
def test_host_precheck(self, _, mock_get_all, mock_precheck,
mock_get_status):
hostname = 'foo'
mock_get_all.return_value = [self.get_fake_host(hostname)]
# host check hostname --predeploy (success)
mock_precheck.return_value = self.get_fake_job()
mock_get_status.return_value = 0
ret = self.run_cli_command('host check %s --predeploy' % hostname)
self.assertEqual(ret, 0)
mock_precheck.assert_called_once_with([hostname], 1)
# host check hostname --predeploy (fail)
mock_precheck.reset_mock()
mock_get_status.return_value = 1
ret = self.run_cli_command('host check %s --predeploy' % hostname)
self.assertEqual(ret, 1)
mock_precheck.assert_called_once_with([hostname], 1)
@mock.patch('kolla_cli.commands.host.HostSetup._get_yml_data')
@mock.patch('getpass.getpass')
@mock.patch('kolla_cli.commands.host.ClientApi.host_ssh_check')

View File

@ -0,0 +1,74 @@
# Copyright (c) 2018 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import mock
from kolla_cli.tests.unit.common import KollaCliUnitTest
class TestUnit(KollaCliUnitTest):
@mock.patch('kolla_cli.api.control_plane.ControlPlaneApi.prechecks')
@mock.patch('kolla_cli.common.ansible.job.AnsibleJob.get_status')
@mock.patch('kolla_cli.shell.KollaCli._is_inventory_present',
return_value=True)
def test_prechecks(self, _, mock_get_status, mock_prechecks):
mock_get_status.return_value = 0
mock_prechecks.return_value = self.get_fake_job()
ret = self.run_cli_command('action prechecks')
self.assertEqual(ret, 0)
mock_prechecks.assert_called_once_with(1, [], [])
@mock.patch('kolla_cli.api.control_plane.ControlPlaneApi.prechecks')
@mock.patch('kolla_cli.common.ansible.job.AnsibleJob.get_status')
@mock.patch('kolla_cli.shell.KollaCli._is_inventory_present',
return_value=True)
def test_prechecks_with_hosts(self, _, mock_get_status, mock_prechecks):
mock_get_status.return_value = 0
mock_prechecks.return_value = self.get_fake_job()
hostnames = ['host1', 'host2']
ret = self.run_cli_command(
'action prechecks --hosts {hosts}'.format(
hosts=','.join(hostnames)))
self.assertEqual(ret, 0)
mock_prechecks.assert_called_once_with(1, hostnames, [])
@mock.patch('kolla_cli.api.control_plane.ControlPlaneApi.prechecks')
@mock.patch('kolla_cli.common.ansible.job.AnsibleJob.get_status')
@mock.patch('kolla_cli.shell.KollaCli._is_inventory_present',
return_value=True)
def test_prechecks_with_services(self, _, mock_get_status, mock_prechecks):
mock_get_status.return_value = 0
mock_prechecks.return_value = self.get_fake_job()
services = ['service1', 'service2']
ret = self.run_cli_command(
'action prechecks --service {services}'.format(
services=','.join(services)))
self.assertEqual(ret, 0)
mock_prechecks.assert_called_once_with(1, [], services)
@mock.patch('kolla_cli.api.control_plane.ControlPlaneApi.prechecks')
@mock.patch('kolla_cli.common.ansible.job.AnsibleJob.get_status')
@mock.patch('kolla_cli.shell.KollaCli._is_inventory_present',
return_value=True)
def test_prechecks_with_hosts_and_services(self, _, mock_get_status,
mock_prechecks):
mock_get_status.return_value = 0
mock_prechecks.return_value = self.get_fake_job()
hostnames = ['host1', 'host2']
services = ['service1', 'service2']
ret = self.run_cli_command(
'action prechecks --hosts {hosts} --service {services}'.format(
hosts=','.join(hostnames), services=','.join(services)))
self.assertEqual(ret, 0)
mock_prechecks.assert_called_once_with(1, hostnames, services)

View File

@ -32,6 +32,7 @@ kolla.cli =
action_check = kolla_cli.commands.kolla_action:Check
action_deploy = kolla_cli.commands.kolla_action:Deploy
action_genconfig = kolla_cli.commands.kolla_action:Genconfig
action_prechecks = kolla_cli.commands.kolla_action:Prechecks
action_postdeploy = kolla_cli.commands.kolla_action:PostDeploy
action_pull = kolla_cli.commands.kolla_action:Pull
action_reconfigure = kolla_cli.commands.kolla_action:Reconfigure