Fix overcloud admin authorize

overcloud admin authorize can no longer be used with
ephemeral Heat. This change allows us to use an existing
inventory file. It also allows for the use to provide a
group from the Inventory rather than running against all
of the nodes in the inventory.

Change-Id: I07902a84e16af94b250ecb621017cd5b7de40a9c
This commit is contained in:
Brendan Shephard 2021-10-17 09:47:47 +00:00
parent 35e3278f6c
commit a2b6a9addd
4 changed files with 111 additions and 36 deletions

View File

@ -0,0 +1,9 @@
---
features:
- |
The Admin Authorize command can now be targeted at
specific nodes using '--limit'. It can also take a
custom static-inventory using '--static-inventory'.
fixes:
- |
Fixes Admin Authorize to work with Ephemeral Heat.

View File

@ -13,32 +13,56 @@
import mock
from tripleoclient.tests.v1 import test_plugin
from tripleoclient import utils
from tripleoclient.v1 import overcloud_admin
from tripleoclient.workflows import deployment
@mock.patch.object(utils, 'get_stack', autospec=True)
@mock.patch.object(deployment, 'get_hosts_and_enable_ssh_admin', autospec=True)
class TestAdminAuthorize(test_plugin.TestPluginV1):
def setUp(self):
super(TestAdminAuthorize, self).setUp()
self.cmd = overcloud_admin.Authorize(self.app, None)
self.app.client_manager = mock.Mock()
def test_ok(self, mock_get_host_and_enable_ssh_admin, mock_get_stack):
arglist = []
parsed_args = self.check_parser(self.cmd, arglist, [])
mock_stack = mock.Mock()
mock_get_stack.return_value = mock_stack
@mock.patch('tripleoclient.utils.parse_ansible_inventory',
autospec=True)
@mock.patch('tripleoclient.utils.get_key')
@mock.patch('tripleoclient.utils.get_default_working_dir')
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
def test_admin_authorize(self,
mock_playbook,
mock_dir,
mock_key,
mock_inventory):
arglist = ['--limit', 'overcloud']
verifylist = [('limit_hosts', 'overcloud')]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
mock_dir.return_value = "/home/stack/overcloud-deploy"
ansible_dir = "{}/config-download/overcloud".format(
mock_dir.return_value
)
inventory = "{}/tripleo-ansible-inventory.yaml".format(
ansible_dir
)
mock_key.return_value = '/home/stack/.ssh/id_rsa_tripleo'
mock_inventory.return_value = ['overcloud-novacompute-0',
'overcloud-dellcompute-0',
'overcloud-controller-0']
self.cmd.take_action(parsed_args)
mock_get_host_and_enable_ssh_admin.assert_called_once_with(
mock_stack,
parsed_args.overcloud_ssh_network,
parsed_args.overcloud_ssh_user,
mock.ANY,
parsed_args.overcloud_ssh_port_timeout,
self.cmd.working_dir,
mock.ANY
mock_playbook.assert_called_once_with(
playbook='cli-enable-ssh-admin.yaml',
inventory=inventory,
workdir=ansible_dir,
key=parsed_args.overcloud_ssh_key,
playbook_dir='/usr/share/ansible/tripleo-playbooks',
ssh_user=parsed_args.overcloud_ssh_user,
extra_vars={
"ANSIBLE_PRIVATE_KEY_FILE": '/home/stack/.ssh/id_rsa_tripleo',
"ssh_servers": ['overcloud-novacompute-0',
'overcloud-dellcompute-0',
'overcloud-controller-0']
},
ansible_timeout=parsed_args.overcloud_ssh_port_timeout
)

View File

@ -49,6 +49,8 @@ import yaml
import ansible_runner
from ansible.parsing.dataloader import DataLoader
from ansible.inventory.manager import InventoryManager
from heatclient.common import event_utils
from heatclient.common import template_utils
from heatclient.common import utils as heat_utils
@ -3160,3 +3162,16 @@ def get_parameter_file(path):
LOG.warning('File %s was not found during export' %
path)
return file_data
def parse_ansible_inventory(inventory_file, group):
""" Retrieve a list of hosts from a defined ansible inventory file.
:param inventory: Ansible inventory file
:param group: The group to return hosts from, default will be 'all'
:return: list of hosts in the inventory matching the pattern
"""
inventory = InventoryManager(loader=DataLoader(),
sources=[inventory_file])
return(inventory.get_hosts(pattern=group))

View File

@ -13,6 +13,7 @@
# under the License.
#
import os
from oslo_config import cfg
from oslo_log import log as logging
@ -22,7 +23,7 @@ from osc_lib import utils
from tripleoclient import command
from tripleoclient import constants
from tripleoclient import utils as oooutils
from tripleoclient.workflows import deployment
from tripleoclient.constants import ANSIBLE_TRIPLEO_PLAYBOOKS
CONF = cfg.CONF
@ -70,11 +71,22 @@ class Authorize(command.Command):
default=constants.ENABLE_SSH_ADMIN_SSH_PORT_TIMEOUT
)
parser.add_argument(
'--working-dir',
'--static-inventory',
dest='static_inventory',
action='store',
help=_('The working directory for the deployment where all '
'input, output, and generated files will be stored.\n'
'Defaults to "$HOME/overcloud-deploy/<stack>"')
default=None,
help=_('Path to an existing ansible inventory to '
'use. If not specified, one will be '
'generated in '
'~/tripleo-ansible-inventory.yaml')
)
parser.add_argument(
'--limit',
dest='limit_hosts',
action='store',
default='all',
help=_('Define which hosts or group of hosts to '
'run the Admin Authorize tasks against.')
)
return parser
@ -83,21 +95,36 @@ class Authorize(command.Command):
logging.register_options(CONF)
logging.setup(CONF, '')
self.log.debug("take_action({})".format(parsed_args))
clients = self.app.client_manager
stack = oooutils.get_stack(clients.orchestration, parsed_args.stack)
ansible_dir = os.path.join(oooutils.get_default_working_dir(
parsed_args.stack
),
'config-download',
parsed_args.stack)
if not parsed_args.working_dir:
self.working_dir = oooutils.get_default_working_dir(
parsed_args.stack)
if not parsed_args.static_inventory:
inventory = os.path.join(ansible_dir,
'tripleo-ansible-inventory.yaml')
else:
self.working_dir = parsed_args.working_dir
inventory = parsed_args.static_inventory
deployment.get_hosts_and_enable_ssh_admin(
stack,
parsed_args.overcloud_ssh_network,
parsed_args.overcloud_ssh_user,
self.get_key_pair(parsed_args),
parsed_args.overcloud_ssh_port_timeout,
working_dir=self.working_dir,
verbosity=oooutils.playbook_verbosity(self=self)
key_file = oooutils.get_key(parsed_args.stack)
if not parsed_args.limit_hosts:
hosts = parsed_args.stack
else:
hosts = parsed_args.limit_hosts
oooutils.run_ansible_playbook(
playbook='cli-enable-ssh-admin.yaml',
inventory=inventory,
workdir=ansible_dir,
key=parsed_args.overcloud_ssh_key,
playbook_dir=ANSIBLE_TRIPLEO_PLAYBOOKS,
ssh_user=parsed_args.overcloud_ssh_user,
extra_vars={
"ANSIBLE_PRIVATE_KEY_FILE": key_file,
"ssh_servers": oooutils.parse_ansible_inventory(
inventory, hosts)
},
ansible_timeout=parsed_args.overcloud_ssh_port_timeout
)