Use correct default key file and normalize the usage

The provision command was defaulting to id_rsa.pub, however the deploy
command uses id_rsa_tripleo for initial setup.

When using the deploy command for provision as well, use the public
key, not the private id_rsa_tripleo.

This option was being processed in several different ways, this change
normalize it by creating a single function in the Command class, which
all inheriting methods will consume. Tests have been updated to
accomodate this change.

Related-Bug: #1863920
Change-Id: Ib4ee480a99c0388c526e4a90a8a1db7d1747276a
Signed-off-by: Kevin Carter <kecarter@redhat.com>
(cherry picked from commit af749d1a6a)
This commit is contained in:
Kevin Carter 2020-02-19 20:15:22 -06:00 committed by Steve Baker
parent 74060d33e4
commit b5bc064b0c
17 changed files with 174 additions and 26 deletions

View File

@ -36,6 +36,29 @@ class Command(command.Command):
self.log.exception("Exception occured while running the command")
raise
def get_key_pair(self, parsed_args):
"""Autodetect or return a user defined key file.
:param parsed_args: An argparse object.
:type parsed_args: Object
:returns: String
"""
if not parsed_args.overcloud_ssh_key:
key = utils.get_key(
stack=parsed_args.stack,
needs_pair=True
)
if not key:
raise oscexc.CommandError(
'No key pair found, set the ssh key using'
'the --overcloud-ssh-key switch.'
)
return key
else:
return parsed_args.overcloud_ssh_key
class Lister(Command, command.Lister):
pass

View File

@ -80,3 +80,60 @@ class FakeClientWrapper(object):
def messaging_websocket(self):
return self.ws
class FakeRunnerConfig(object):
env = dict() # noqa
def prepare(self):
pass
class FakeInstanceData(object):
cacert = '/file/system/path'
_region_name = 'region1'
@staticmethod
def get_endpoint_for_service_type(*args, **kwargs):
return 'http://things'
class auth_ref(object):
trust_id = 'yy'
project_id = 'ww'
class auth(object):
auth_url = 'http://url'
_project_name = 'projectname'
_username = 'username'
_user_id = 'zz'
@staticmethod
def get_token(*args, **kwargs):
return '12345abcde'
@staticmethod
def get_project_id(*args, **kwargs):
return 'xx'
class session(object):
class auth(object):
class auth_ref(object):
_data = {'token': {}}
class FakeObjectClient(object):
def __init__(self):
self._instance = mock.Mock()
self.put_object = mock.Mock()
def get_object(self, *args):
return [None, "fake"]
def get_container(self, *args):
return [None, [{"name": "fake"}]]
def fake_ansible_runner_run_return(rc=0):
return 'Test Status', rc

View File

@ -145,3 +145,7 @@ class TestDeployOvercloud(utils.TestCommand):
workflow.executions.create.return_value = execution
self.app.client_manager.workflow_engine = workflow
self.app.client_manager.tripleoclient = FakeClientWrapper()
get_key = mock.patch('tripleoclient.utils.get_key')
get_key.start()
get_key.return_value = 'keyfile-path'
self.addCleanup(get_key.stop)

View File

@ -1559,6 +1559,9 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
with open(ssh_key_path, 'w') as temp_file:
temp_file.write('sekrit')
with open('{}.pub'.format(ssh_key_path), 'w') as f:
f.write('sekrit')
arglist = [
'--baremetal-deployment', bm_deploy_path,
'--overcloud-ssh-key', ssh_key_path

View File

@ -52,6 +52,10 @@ class TestFFWDUpgradePrepare(utils.TestCommand):
execution.id = "IDID"
workflow.executions.create.return_value = execution
self.app.client_manager.workflow_engine = workflow
get_key = mock.patch('tripleoclient.utils.get_key')
get_key.start()
get_key.return_value = 'keyfile-path'
self.addCleanup(get_key.stop)
class TestFFWDUpgradeRun(utils.TestCommand):

View File

@ -99,7 +99,7 @@ class TestFFWDUpgradePrepare(fakes.TestFFWDUpgradePrepare):
mock_enable_ssh_admin.assert_called_once_with(
self.cmd.log, self.app.client_manager, mock_stack,
parsed_args.overcloud_ssh_network,
parsed_args.overcloud_ssh_user, parsed_args.overcloud_ssh_key,
parsed_args.overcloud_ssh_user, mock.ANY,
600, 600)
mock_overcloud_deploy.assert_called_once_with(parsed_args)

View File

@ -1329,6 +1329,8 @@ class TestProvisionNode(fakes.TestOvercloudNode):
inp.flush()
keyf.write(b'I am a key')
keyf.flush()
with open('{}.pub'.format(keyf.name), 'w') as f:
f.write('I am a key')
argslist = ['--output', outp.name,
'--overcloud-ssh-key', keyf.name,

View File

@ -52,6 +52,10 @@ class TestOvercloudUpgradePrepare(utils.TestCommand):
execution.id = "IDID"
workflow.executions.create.return_value = execution
self.app.client_manager.workflow_engine = workflow
get_key = mock.patch('tripleoclient.utils.get_key')
get_key.start()
get_key.return_value = 'keyfile-path'
self.addCleanup(get_key.stop)
class TestOvercloudUpgradeRun(utils.TestCommand):

View File

@ -103,7 +103,7 @@ class TestOvercloudUpgradePrepare(fakes.TestOvercloudUpgradePrepare):
mock_enable_ssh_admin.assert_called_once_with(
self.cmd.log, self.app.client_manager, mock_stack,
parsed_args.overcloud_ssh_network,
parsed_args.overcloud_ssh_user, parsed_args.overcloud_ssh_key,
parsed_args.overcloud_ssh_user, mock.ANY,
10, 10)
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'

View File

@ -39,6 +39,6 @@ class TestAdminAuthorize(test_plugin.TestPluginV1):
mock_stack,
parsed_args.overcloud_ssh_network,
parsed_args.overcloud_ssh_user,
parsed_args.overcloud_ssh_key,
mock.ANY,
600,
600)

View File

@ -13,6 +13,8 @@
# under the License.
#
import mock
from tripleoclient.tests import base
from tripleoclient.tests import fakes
@ -35,3 +37,7 @@ class TestPluginV1(base.TestCommand):
endpoint=fakes.AUTH_URL,
token=fakes.AUTH_TOKEN,
)
get_key = mock.patch('tripleoclient.utils.get_key')
get_key.start()
get_key.return_value = 'keyfile-path'
self.addCleanup(get_key.stop)

View File

@ -1052,6 +1052,44 @@ def load_environment_directories(directories):
return environments
def get_key(stack, needs_pair=False):
"""Returns the private key from the local file system.
Searches for and returns the stack private key. If the key is inaccessible
for any reason, the process will fall back to using the users key. If no
key is found, this method will return None.
:params stack: name of the stack to use
:type stack: String
:param needs_pair: Enable key pair search
:type needs_pair: Boolean
:returns: String || None
"""
key_files = list()
stack_dir = os.path.join('/var/lib/mistral', stack)
key_files.append(os.path.join(stack_dir, 'ssh_private_key'))
user_dir = os.path.join(os.path.expanduser("~"), '.ssh')
key_files.append(os.path.join(user_dir, 'id_rsa_tripleo'))
key_files.append(os.path.join(user_dir, 'id_rsa'))
legacy_dir = os.path.join('/var/lib/mistral', '.ssh')
key_files.append(os.path.join(legacy_dir, 'tripleo-admin-rsa'))
for key_file in key_files:
try:
if os.path.exists(key_file):
if needs_pair:
if not os.path.exists('{}.pub'.format(key_file)):
continue
with open(key_file):
return key_file
except IOError:
pass
else:
return
def get_tripleo_ansible_inventory(inventory_file=None,
ssh_user='tripleo-admin',
stack='overcloud',

View File

@ -12,7 +12,6 @@
# License for the specific language governing permissions and limitations
# under the License.
#
import os
from oslo_config import cfg
from oslo_log import log as logging
@ -51,9 +50,9 @@ class Authorize(command.Command):
)
parser.add_argument(
'--overcloud-ssh-key',
default=os.path.join(
os.path.expanduser('~'), '.ssh', 'id_rsa'),
help=_('Key path for ssh access to overcloud nodes.')
default=None,
help=_('Key path for ssh access to overcloud nodes. When'
'undefined the key will be autodetected.')
)
parser.add_argument(
'--overcloud-ssh-network',
@ -83,6 +82,7 @@ class Authorize(command.Command):
self.log, clients, stack,
parsed_args.overcloud_ssh_network,
parsed_args.overcloud_ssh_user,
parsed_args.overcloud_ssh_key,
self.get_key_pair(parsed_args),
parsed_args.overcloud_ssh_enable_timeout,
parsed_args.overcloud_ssh_port_timeout)
parsed_args.overcloud_ssh_port_timeout
)

View File

@ -616,14 +616,17 @@ class DeployOvercloud(command.Command):
with open(parsed_args.baremetal_deployment, 'r') as fp:
roles = yaml.safe_load(fp)
with open(parsed_args.overcloud_ssh_key, 'rt') as fp:
key = self.get_key_pair(parsed_args)
with open('{}.pub'.format(key), 'rt') as fp:
ssh_key = fp.read()
parameter_defaults = baremetal.deploy_roles(
self.app.client_manager,
plan=parsed_args.stack,
roles=roles, ssh_keys=[ssh_key],
ssh_user_name=parsed_args.overcloud_ssh_user)
roles=roles,
ssh_keys=[ssh_key],
ssh_user_name=parsed_args.overcloud_ssh_user
)
env_path, swift_path = self._write_user_environment(
parameter_defaults,
@ -682,9 +685,9 @@ class DeployOvercloud(command.Command):
)
parser.add_argument(
'--overcloud-ssh-key',
default=os.path.join(
os.path.expanduser('~'), '.ssh', 'id_rsa'),
help=_('Key path for ssh access to overcloud nodes.')
default=None,
help=_('Key path for ssh access to overcloud nodes. When'
'undefined the key will be autodetected.')
)
parser.add_argument(
'--overcloud-ssh-network',
@ -967,9 +970,10 @@ class DeployOvercloud(command.Command):
self.log, self.clients, stack,
parsed_args.overcloud_ssh_network,
parsed_args.overcloud_ssh_user,
parsed_args.overcloud_ssh_key,
self.get_key_pair(parsed_args),
parsed_args.overcloud_ssh_enable_timeout,
parsed_args.overcloud_ssh_port_timeout)
parsed_args.overcloud_ssh_port_timeout
)
if parsed_args.config_download_timeout:
timeout = parsed_args.config_download_timeout * 60

View File

@ -93,7 +93,7 @@ class FFWDUpgradePrepare(DeployOvercloud):
stack = oooutils.get_stack(clients.orchestration, parsed_args.stack)
deployment.get_hosts_and_enable_ssh_admin(
self.log, clients, stack, parsed_args.overcloud_ssh_network,
parsed_args.overcloud_ssh_user, parsed_args.overcloud_ssh_key,
parsed_args.overcloud_ssh_user, self.get_key_pair(parsed_args),
parsed_args.overcloud_ssh_enable_timeout,
parsed_args.overcloud_ssh_port_timeout)

View File

@ -616,10 +616,10 @@ class ProvisionNode(command.Command):
help=_('User for SSH access to newly deployed '
'nodes'))
parser.add_argument('--overcloud-ssh-key',
default=os.path.join(
os.path.expanduser('~'), '.ssh', 'id_rsa.pub'),
help=_('Public key path for SSH access to newly '
'deployed nodes'))
default=None,
help=_('Key path for ssh access to'
'overcloud nodes. When undefined the key'
'will be autodetected.'))
return parser
def take_action(self, parsed_args):
@ -628,14 +628,17 @@ class ProvisionNode(command.Command):
with open(parsed_args.input, 'r') as fp:
roles = yaml.safe_load(fp)
with open(parsed_args.overcloud_ssh_key, 'rt') as fp:
key = self.get_key_pair(parsed_args)
with open('{}.pub'.format(key), 'rt') as fp:
ssh_key = fp.read()
output = baremetal.deploy_roles(
self.app.client_manager,
plan=parsed_args.stack,
roles=roles, ssh_keys=[ssh_key],
ssh_user_name=parsed_args.overcloud_ssh_user)
roles=roles,
ssh_keys=[ssh_key],
ssh_user_name=parsed_args.overcloud_ssh_user
)
with open(parsed_args.output, 'w') as fp:
yaml.safe_dump(output['environment'], fp, default_flow_style=False)

View File

@ -83,7 +83,7 @@ class UpgradePrepare(DeployOvercloud):
stack = oooutils.get_stack(clients.orchestration, parsed_args.stack)
deployment.get_hosts_and_enable_ssh_admin(
self.log, clients, stack, parsed_args.overcloud_ssh_network,
parsed_args.overcloud_ssh_user, parsed_args.overcloud_ssh_key,
parsed_args.overcloud_ssh_user, self.get_key_pair(parsed_args),
parsed_args.overcloud_ssh_enable_timeout,
parsed_args.overcloud_ssh_port_timeout)