Files
python-tripleoclient/tripleoclient/tests/v1/overcloud_node/test_overcloud_node.py
Bogdan Dobrelya 9c602da452 Fix misused deployment vs connection timeouts
Fix misused ansible connection timeout and deployment timeout passed in
config download and ansible runner utility.

Allow ansible runner utility to be given a job_timeout as well.

Also fix the misuse of timeout parameters in related worklows. Add
--overcloud-ssh-port-timeout and use it to configure ansible connection
timeout for the DeleteNode interace of the involved
workflows. Then use the timeout parameter as real timeout instead of
mistakingly passing it as a connection timeout.

Add new unit test for ansible timeout in config_download. Add missing
coverage for the existing timeout-related params in other unit tests.

Closes-Bug: #1868063
Co-authored-by: Kevin Carter <kevin@cloudnull.com>
Change-Id: I2a4d151bcb83074af5bcf7d1b8c68d81d3c0400d
Signed-off-by: Bogdan Dobrelya <bdobreli@redhat.com>
2020-04-07 09:12:37 +02:00

751 lines
28 KiB
Python

# Copyright 2015 Red Hat, 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.
#
import collections
import copy
import fixtures
import json
import mock
import os
import sys
import tempfile
from osc_lib import exceptions as oscexc
from osc_lib.tests import utils as test_utils
import yaml
from tripleoclient import exceptions
from tripleoclient import plugin
from tripleoclient.tests import fakes as ooofakes
from tripleoclient.tests.v1.overcloud_node import fakes
from tripleoclient.v1 import overcloud_node
from tripleoclient.v2 import overcloud_node as overcloud_node_v2
class TestDeleteNode(fakes.TestDeleteNode):
def setUp(self):
super(TestDeleteNode, self).setUp()
# Get the command object to test
self.cmd = overcloud_node.DeleteNode(self.app, None)
self.cmd.app_args = mock.Mock(verbose_level=1)
self.app.client_manager.workflow_engine = mock.Mock()
self.tripleoclient = mock.Mock()
self.websocket = mock.Mock()
self.websocket.__enter__ = lambda s: self.websocket
self.websocket.__exit__ = lambda s, *exc: None
self.tripleoclient.messaging_websocket.return_value = self.websocket
self.workflow = self.app.client_manager.workflow_engine
self.stack_name = self.app.client_manager.orchestration.stacks.get
stack = self.stack_name.return_value = mock.Mock(
stack_name="overcloud"
)
stack.output_show.return_value = {'output': {'output_value': []}}
execution = mock.Mock()
execution.id = "IDID"
self.workflow.executions.create.return_value = execution
delete_node = mock.patch(
'tripleo_common.actions.scale.ScaleDownAction.run',
autospec=True
)
delete_node.start()
delete_node.return_value = None
self.addCleanup(delete_node.stop)
wait_stack = mock.patch(
'tripleoclient.utils.wait_for_stack_ready',
autospec=True
)
wait_stack.start()
wait_stack.return_value = None
self.addCleanup(wait_stack.stop)
self.app.client_manager.compute.servers.get.return_value = None
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
def test_node_delete(self, mock_playbook):
argslist = ['instance1', 'instance2', '--templates',
'--stack', 'overcast', '--timeout', '90', '--yes']
verifylist = [
('stack', 'overcast'),
('nodes', ['instance1', 'instance2'])
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.cmd.take_action(parsed_args)
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=False)
def test_node_delete_no_confirm(self, confirm_mock):
argslist = ['instance1', 'instance2', '--templates',
'--stack', 'overcast', '--timeout', '90']
verifylist = [
('stack', 'overcast'),
('nodes', ['instance1', 'instance2'])
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.assertRaises(oscexc.CommandError,
self.cmd.take_action,
parsed_args)
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True,
side_effect=exceptions.InvalidConfiguration)
def test_node_wrong_stack(self, mock_playbook):
argslist = ['instance1', '--templates',
'--stack', 'overcast', '--yes']
verifylist = [
('stack', 'overcast'),
('nodes', ['instance1', ])
]
self.stack_name.return_value = None
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.assertRaises(exceptions.InvalidConfiguration,
self.cmd.take_action,
parsed_args)
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
def test_node_delete_without_stack(self, mock_playbook):
arglist = ['instance1', '--yes']
verifylist = [
('stack', 'overcloud'),
('nodes', ['instance1']),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
@mock.patch('tripleoclient.utils.tempfile')
def test_node_delete_baremetal_deployment(self,
mock_tempfile,
mock_playbook):
bm_yaml = [{
'name': 'Compute',
'count': 5,
'instances': [{
'name': 'baremetal-2',
'hostname': 'overcast-compute-0',
'provisioned': False
}],
}, {
'name': 'Controller',
'count': 2,
'instances': [{
'name': 'baremetal-1',
'hostname': 'overcast-controller-1',
'provisioned': False
}]
}]
tmp = tempfile.mkdtemp()
mock_tempfile.mkdtemp.side_effect = [
tmp,
tempfile.mkdtemp(),
tempfile.mkdtemp(),
tempfile.mkdtemp()
]
unprovision_confirm = os.path.join(tmp, 'unprovision_confirm.json')
with open(unprovision_confirm, 'w') as confirm:
confirm.write(json.dumps([
{
'hostname': 'overcast-controller-1',
'name': 'baremetal-1',
'id': 'aaaa'
}, {
'hostname': 'overcast-compute-0',
'name': 'baremetal-2',
'id': 'bbbb'
}
]))
with tempfile.NamedTemporaryFile(mode='w') as inp:
yaml.dump(bm_yaml, inp, encoding='utf-8')
inp.flush()
argslist = ['--baremetal-deployment', inp.name, '--templates',
'--stack', 'overcast', '--overcloud-ssh-port-timeout',
'42', '--timeout', '90', '--yes']
verifylist = [
('stack', 'overcast'),
('overcloud_ssh_port_timeout', 42),
('baremetal_deployment', inp.name)
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.cmd.take_action(parsed_args)
# Verify
mock_playbook.assert_has_calls([
mock.call(
playbook='cli-overcloud-node-unprovision.yaml',
inventory='localhost,',
verbosity=mock.ANY,
workdir=mock.ANY,
playbook_dir='/usr/share/ansible/tripleo-playbooks',
extra_vars={
'stack_name': 'overcast',
'baremetal_deployment': [{
'count': 5,
'instances': [{
'hostname': 'overcast-compute-0',
'name': 'baremetal-2',
'provisioned': False
}],
'name': 'Compute'
}, {
'count': 2,
'instances': [{
'hostname': 'overcast-controller-1',
'name': 'baremetal-1',
'provisioned': False
}], 'name': 'Controller'
}],
'prompt': True,
'unprovision_confirm': unprovision_confirm,
},
),
mock.call(
playbook='cli-grant-local-access.yaml',
inventory='localhost,',
workdir=mock.ANY,
playbook_dir='/usr/share/ansible/tripleo-playbooks',
verbosity=mock.ANY,
extra_vars={
'access_path': '/var/lib/mistral',
'execution_user': mock.ANY},
),
mock.call(
playbook=mock.ANY,
inventory=mock.ANY,
workdir=mock.ANY,
playbook_dir=mock.ANY,
skip_tags='opendev-validation',
ansible_cfg=None,
verbosity=mock.ANY,
ssh_user='tripleo-admin',
key=mock.ANY,
limit_hosts='overcast-controller-1:overcast-compute-0',
ansible_timeout=42,
reproduce_command=True,
extra_env_variables={'ANSIBLE_BECOME': True},
extra_vars=None,
tags=None,
timeout=90
),
mock.call(
inventory='localhost,',
playbook='cli-overcloud-node-unprovision.yaml',
verbosity=mock.ANY,
workdir=mock.ANY,
playbook_dir='/usr/share/ansible/tripleo-playbooks',
extra_vars={
'stack_name': 'overcast',
'baremetal_deployment': [{
'count': 5,
'instances': [{
'hostname': 'overcast-compute-0',
'name': 'baremetal-2',
'provisioned': False
}], 'name': 'Compute'
}, {
'count': 2,
'instances': [{
'hostname': 'overcast-controller-1',
'name': 'baremetal-1',
'provisioned': False
}],
'name': 'Controller'
}],
'prompt': False
},
)
])
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
@mock.patch('tripleoclient.utils.tempfile')
def test_nodes_to_delete(self, mock_tempfile, mock_playbook):
bm_yaml = [{
'name': 'Compute',
'count': 5,
'instances': [{
'name': 'baremetal-2',
'hostname': 'overcast-compute-0',
'provisioned': False
}],
}, {
'name': 'Controller',
'count': 2,
'instances': [{
'name': 'baremetal-1',
'hostname': 'overcast-controller-1',
'provisioned': False
}]
}]
tmp = tempfile.mkdtemp()
mock_tempfile.mkdtemp.return_value = tmp
unprovision_confirm = os.path.join(tmp, 'unprovision_confirm.json')
with open(unprovision_confirm, 'w') as confirm:
confirm.write(json.dumps([
{
'hostname': 'compute-0',
'name': 'baremetal-1',
'id': 'aaaa'
}, {
'hostname': 'controller-0',
'name': 'baremetal-2',
'id': 'bbbb'
}
]))
argslist = ['--baremetal-deployment', '/foo/bm_deploy.yaml']
verifylist = [
('baremetal_deployment', '/foo/bm_deploy.yaml')
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
nodes_text, nodes = self.cmd._nodes_to_delete(parsed_args, bm_yaml)
expected = '''+--------------+-------------+------+
| hostname | name | id |
+--------------+-------------+------+
| compute-0 | baremetal-1 | aaaa |
| controller-0 | baremetal-2 | bbbb |
+--------------+-------------+------+
'''
self.assertEqual(expected, nodes_text)
self.assertEqual(['compute-0', 'controller-0'], nodes)
class TestProvideNode(fakes.TestOvercloudNode):
def setUp(self):
super(TestProvideNode, self).setUp()
# Get the command object to test
self.cmd = overcloud_node.ProvideNode(self.app, None)
def test_provide_all_manageable_nodes(self):
parsed_args = self.check_parser(self.cmd,
['--all-manageable'],
[('all_manageable', True)])
self.cmd.take_action(parsed_args)
def test_provide_one_node(self):
node_id = 'node_uuid1'
parsed_args = self.check_parser(self.cmd,
[node_id],
[('node_uuids', [node_id])])
self.cmd.take_action(parsed_args)
def test_provide_multiple_nodes(self):
node_id1 = 'node_uuid1'
node_id2 = 'node_uuid2'
argslist = [node_id1, node_id2]
verifylist = [('node_uuids', [node_id1, node_id2])]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.cmd.take_action(parsed_args)
class TestCleanNode(fakes.TestOvercloudNode):
def setUp(self):
super(TestCleanNode, self).setUp()
self.workflow = self.app.client_manager.workflow_engine
execution = mock.Mock()
execution.id = "IDID"
self.workflow.executions.create.return_value = execution
client = self.app.client_manager.tripleoclient
self.websocket = client.messaging_websocket()
# Get the command object to test
self.cmd = overcloud_node.CleanNode(self.app, None)
def _check_clean_all_manageable(self, parsed_args, provide=False):
self.cmd.take_action(parsed_args)
def _check_clean_nodes(self, parsed_args, nodes, provide=False):
self.cmd.take_action(parsed_args)
def test_clean_all_manageable_nodes_without_provide(self):
parsed_args = self.check_parser(self.cmd,
['--all-manageable'],
[('all_manageable', True)])
self._check_clean_all_manageable(parsed_args, provide=False)
def test_clean_all_manageable_nodes_with_provide(self):
parsed_args = self.check_parser(self.cmd,
['--all-manageable', '--provide'],
[('all_manageable', True),
('provide', True)])
self._check_clean_all_manageable(parsed_args, provide=True)
def test_clean_nodes_without_provide(self):
nodes = ['node_uuid1', 'node_uuid2']
parsed_args = self.check_parser(self.cmd,
nodes,
[('node_uuids', nodes)])
self._check_clean_nodes(parsed_args, nodes, provide=False)
def test_clean_nodes_with_provide(self):
nodes = ['node_uuid1', 'node_uuid2']
argslist = nodes + ['--provide']
parsed_args = self.check_parser(self.cmd,
argslist,
[('node_uuids', nodes),
('provide', True)])
self._check_clean_nodes(parsed_args, nodes, provide=True)
class TestImportNodeMultiArch(fakes.TestOvercloudNode):
def setUp(self):
super(TestImportNodeMultiArch, self).setUp()
self.nodes_list = [{
"pm_user": "stack",
"pm_addr": "192.168.122.1",
"pm_password": "KEY1",
"pm_type": "pxe_ssh",
"mac": [
"00:0b:d0:69:7e:59"
],
}, {
"pm_user": "stack",
"pm_addr": "192.168.122.2",
"pm_password": "KEY2",
"pm_type": "pxe_ssh",
"arch": "x86_64",
"mac": [
"00:0b:d0:69:7e:58"
]
}, {
"pm_user": "stack",
"pm_addr": "192.168.122.3",
"pm_password": "KEY3",
"pm_type": "pxe_ssh",
"arch": "x86_64",
"platform": "SNB",
"mac": [
"00:0b:d0:69:7e:58"
]
}]
self.json_file = tempfile.NamedTemporaryFile(
mode='w', delete=False, suffix='.json')
json.dump(self.nodes_list, self.json_file)
self.json_file.close()
self.addCleanup(os.unlink, self.json_file.name)
self.workflow = self.app.client_manager.workflow_engine
execution = mock.Mock()
execution.id = "IDID"
self.workflow.executions.create.return_value = execution
client = self.app.client_manager.tripleoclient
self.websocket = client.messaging_websocket()
# Get the command object to test
self.cmd = overcloud_node_v2.ImportNode(self.app, None)
image = collections.namedtuple('image', ['id', 'name'])
self.app.client_manager.image = mock.Mock()
self.app.client_manager.image.images.list.return_value = [
image(id=3, name='overcloud-full'),
image(id=6, name='x86_64-overcloud-full'),
image(id=9, name='SNB-x86_64-overcloud-full'),
]
self.http_boot = '/var/lib/ironic/httpboot'
self.mock_playbook = mock.patch(
"tripleoclient.utils.run_ansible_playbook", spec=True)
self.mock_run_ansible_playbook = self.mock_playbook.start()
self.addCleanup(self.mock_playbook.stop)
existing = ['agent', 'x86_64/agent', 'SNB-x86_64/agent']
existing = {os.path.join(self.http_boot, name + ext)
for name in existing for ext in ('.kernel', '.ramdisk')}
self.useFixture(fixtures.MockPatch(
'os.path.exists', autospec=True,
side_effect=lambda path: path in existing))
def _check_workflow_call(self, parsed_args, introspect=False,
provide=False, local=None, no_deploy_image=False):
self.websocket.wait_for_messages.return_value = [{
"status": "SUCCESS",
"message": "Success",
"registered_nodes": [{
"uuid": "MOCK_NODE_UUID"
}],
"execution_id": "IDID"
}]
file_return_nodes = [
{
'uuid': 'MOCK_NODE_UUID'
}
]
mock_open = mock.mock_open(read_data=json.dumps(file_return_nodes))
# TODO(cloudnull): Remove this when py27 is dropped
if sys.version_info >= (3, 0):
mock_open_path = 'builtins.open'
else:
mock_open_path = 'tripleoclient.v1.overcloud_node.open'
with mock.patch(mock_open_path, mock_open):
self.cmd.take_action(parsed_args)
nodes_list = copy.deepcopy(self.nodes_list)
if not no_deploy_image:
nodes_list[0]['kernel_id'] = (
'file://%s/agent.kernel' % self.http_boot)
nodes_list[0]['ramdisk_id'] = (
'file://%s/agent.ramdisk' % self.http_boot)
nodes_list[1]['kernel_id'] = (
'file://%s/x86_64/agent.kernel' % self.http_boot)
nodes_list[1]['ramdisk_id'] = (
'file://%s/x86_64/agent.ramdisk' % self.http_boot)
nodes_list[2]['kernel_id'] = (
'file://%s/SNB-x86_64/agent.kernel' % self.http_boot)
nodes_list[2]['ramdisk_id'] = (
'file://%s/SNB-x86_64/agent.ramdisk' % self.http_boot)
if introspect:
self.mock_run_ansible_playbook.assert_called_with(
extra_vars={
'node_uuids': ['MOCK_NODE_UUID']},
inventory='localhost,',
playbook='cli-overcloud-node-provide.yaml',
playbook_dir='/usr/share/ansible/tripleo-playbooks',
workdir=mock.ANY,
)
def test_import_only(self):
argslist = [self.json_file.name]
verifylist = [('introspect', False),
('provide', False)]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self._check_workflow_call(parsed_args)
def test_import_with_netboot(self):
arglist = [self.json_file.name, '--instance-boot-option', 'netboot']
verifylist = [('instance_boot_option', 'netboot')]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self._check_workflow_call(parsed_args, local=False)
def test_import_with_no_deployed_image(self):
arglist = [self.json_file.name, '--no-deploy-image']
verifylist = [('no_deploy_image', True)]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self._check_workflow_call(parsed_args, no_deploy_image=True)
class TestConfigureNode(fakes.TestOvercloudNode):
def setUp(self):
super(TestConfigureNode, self).setUp()
self.workflow = self.app.client_manager.workflow_engine
execution = mock.Mock()
execution.id = "IDID"
self.workflow.executions.create.return_value = execution
client = self.app.client_manager.tripleoclient
self.websocket = client.messaging_websocket()
self.websocket.wait_for_messages.return_value = iter([{
"status": "SUCCESS",
"message": "",
"execution_id": "IDID"
}])
# Get the command object to test
self.cmd = overcloud_node.ConfigureNode(self.app, None)
self.http_boot = '/var/lib/ironic/httpboot'
self.workflow_input = {
'kernel_name': 'file://%s/agent.kernel' % self.http_boot,
'ramdisk_name': 'file://%s/agent.ramdisk' % self.http_boot,
'instance_boot_option': None,
'root_device': None,
'root_device_minimum_size': 4,
'overwrite_root_device_hints': False
}
def test_configure_all_manageable_nodes(self):
parsed_args = self.check_parser(self.cmd,
['--all-manageable'],
[('all_manageable', True)])
self.cmd.take_action(parsed_args)
def test_configure_specified_nodes(self):
argslist = ['node_uuid1', 'node_uuid2']
verifylist = [('node_uuids', ['node_uuid1', 'node_uuid2'])]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.cmd.take_action(parsed_args)
def test_configure_no_node_or_flag_specified(self):
self.assertRaises(test_utils.ParserException,
self.check_parser,
self.cmd, [], [])
def test_configure_uuids_and_all_both_specified(self):
argslist = ['node_id1', 'node_id2', '--all-manageable']
verifylist = [('node_uuids', ['node_id1', 'node_id2']),
('all_manageable', True)]
self.assertRaises(test_utils.ParserException,
self.check_parser,
self.cmd, argslist, verifylist)
def test_configure_kernel_and_ram(self):
argslist = ['--all-manageable', '--deploy-ramdisk', 'test_ramdisk',
'--deploy-kernel', 'test_kernel']
verifylist = [('deploy_kernel', 'test_kernel'),
('deploy_ramdisk', 'test_ramdisk')]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.cmd.take_action(parsed_args)
def test_configure_instance_boot_option(self):
argslist = ['--all-manageable', '--instance-boot-option', 'netboot']
verifylist = [('instance_boot_option', 'netboot')]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.cmd.take_action(parsed_args)
def test_configure_root_device(self):
argslist = ['--all-manageable',
'--root-device', 'smallest',
'--root-device-minimum-size', '2',
'--overwrite-root-device-hints']
verifylist = [('root_device', 'smallest'),
('root_device_minimum_size', 2),
('overwrite_root_device_hints', True)]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.cmd.take_action(parsed_args)
def test_configure_specified_node_with_all_arguments(self):
argslist = ['node_id',
'--deploy-kernel', 'test_kernel',
'--deploy-ramdisk', 'test_ramdisk',
'--instance-boot-option', 'netboot',
'--root-device', 'smallest',
'--root-device-minimum-size', '2',
'--overwrite-root-device-hints']
verifylist = [('node_uuids', ['node_id']),
('deploy_kernel', 'test_kernel'),
('deploy_ramdisk', 'test_ramdisk'),
('instance_boot_option', 'netboot'),
('root_device', 'smallest'),
('root_device_minimum_size', 2),
('overwrite_root_device_hints', True)]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.cmd.take_action(parsed_args)
class TestDiscoverNode(fakes.TestOvercloudNode):
def setUp(self):
super(TestDiscoverNode, self).setUp()
self.workflow = self.app.client_manager.workflow_engine
execution = mock.Mock()
execution.id = "IDID"
self.workflow.executions.create.return_value = execution
client = self.app.client_manager.tripleoclient
client.create_mistral_context = plugin.ClientWrapper(
instance=ooofakes.FakeInstanceData
).create_mistral_context
self.websocket = client.messaging_websocket()
self.cmd = overcloud_node.DiscoverNode(self.app, None)
self.gcn = mock.patch(
'tripleo_common.actions.baremetal.GetCandidateNodes',
autospec=True
)
self.gcn.start()
self.addCleanup(self.gcn.stop)
self.websocket.wait_for_messages.return_value = [{
"status": "SUCCESS",
"message": "Success",
"registered_nodes": [{
"uuid": "MOCK_NODE_UUID"
}],
"execution_id": "IDID"
}]
self.http_boot = '/var/lib/ironic/httpboot'
def test_with_ip_range(self):
argslist = ['--range', '10.0.0.0/24',
'--credentials', 'admin:password']
verifylist = [('ip_addresses', '10.0.0.0/24'),
('credentials', ['admin:password'])]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.cmd.take_action(parsed_args)
def test_with_address_list(self):
argslist = ['--ip', '10.0.0.1', '--ip', '10.0.0.2',
'--credentials', 'admin:password']
verifylist = [('ip_addresses', ['10.0.0.1', '10.0.0.2']),
('credentials', ['admin:password'])]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.cmd.take_action(parsed_args)
def test_with_all_options(self):
argslist = ['--range', '10.0.0.0/24',
'--credentials', 'admin:password',
'--credentials', 'admin2:password2',
'--port', '623', '--port', '6230',
'--introspect', '--provide', '--run-validations',
'--no-deploy-image', '--instance-boot-option', 'netboot',
'--concurrency', '10']
verifylist = [('ip_addresses', '10.0.0.0/24'),
('credentials', ['admin:password', 'admin2:password2']),
('port', [623, 6230]),
('introspect', True),
('run_validations', True),
('concurrency', 10),
('provide', True),
('no_deploy_image', True),
('instance_boot_option', 'netboot')]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.cmd.take_action(parsed_args)