Yedidyah Bar David has uploaded a new change for review. Change subject: packaging: setup: use ssh public key for allinone ......................................................................
packaging: setup: use ssh public key for allinone Instead of asking for the local root password, add the engine's public key to ~root/.ssh/authorized_keys and change the sdk call to use public key authentication. Change-Id: I885894bba4c998e5dd3e9b2fd4da61d833f7a3a1 Signed-off-by: Yedidyah Bar David <d...@redhat.com> --- M ovirt-engine.spec.in M packaging/setup/ovirt_engine_setup/constants.py M packaging/setup/plugins/ovirt-engine-setup/all-in-one/__init__.py M packaging/setup/plugins/ovirt-engine-setup/all-in-one/sshd.py D packaging/setup/plugins/ovirt-engine-setup/all-in-one/super_user.py M packaging/setup/plugins/ovirt-engine-setup/all-in-one/vdsm.py M packaging/setup/plugins/ovirt-engine-setup/pki/ssh.py 7 files changed, 70 insertions(+), 127 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/66/18266/1 diff --git a/ovirt-engine.spec.in b/ovirt-engine.spec.in index bd9e10c..30ab293 100644 --- a/ovirt-engine.spec.in +++ b/ovirt-engine.spec.in @@ -284,7 +284,6 @@ Requires: openssl Requires: otopi >= 1.1.0 Requires: policycoreutils-python -Requires: python-paramiko Requires: python-psycopg2 Requires: yum @@ -427,7 +426,7 @@ %package setup-plugin-allinone Summary: All-in-one plugin for %{ovirt_product_name_short}'s setup Group: Virtualization/Management -Requires: %{name}-sdk >= 3.1.0.6 +Requires: %{name}-sdk >= 3.3.0 Requires: %{name}-setup >= %{version}-%{release} Requires: openssh-server Requires: ovirt-host-deploy >= 1.1.0 diff --git a/packaging/setup/ovirt_engine_setup/constants.py b/packaging/setup/ovirt_engine_setup/constants.py index 63d99cb..544e70b 100644 --- a/packaging/setup/ovirt_engine_setup/constants.py +++ b/packaging/setup/ovirt_engine_setup/constants.py @@ -527,6 +527,7 @@ CONFIG_APPLICATION_MODE_AVAILABLE = \ 'osetup.config.applicationMode.available' CA_AVAILABLE = 'osetup.pki.ca.available' + SSH_KEY_AVAILABLE = 'osetup.pki.ssh.available' SYSTEM_NFS_CONFIG_AVAILABLE = 'osetup.system.nfs.available' SYSTEM_SYSCTL_CONFIG_AVAILABLE = 'osetup.system.sysctl.available' CONFIG_ISO_DOMAIN_AVAILABLE = 'osetup.config.iso_domain.available' @@ -553,7 +554,6 @@ DIALOG_TITLES_E_SUMMARY = 'osetup.dialog.titles.summary.end' AIO_CONFIG_AVAILABLE = 'osetup.aio.config.available' - AIO_CONFIG_ROOT_PASSWORD = 'osetup.aio.config.rootpassword' AIO_CONFIG_STORAGE = 'osetup.aio.config.storage' AIO_CONFIG_VDSM = 'osetup.aio.config.vdsm' @@ -782,6 +782,8 @@ ) def ORG(self): return 'OVESETUP_PKI/organization' + + ENGINE_SSH_PUBLIC_KEY_VALUE = 'OVESETUP_PKI/sshPublicKey' @util.export @@ -1030,13 +1032,6 @@ ) def CONFIGURE(self): return 'OVESETUP_AIO/configure' - - @osetupattrs( - answerfile=True, - summary=False, - ) - def ROOT_PASSWORD(self): - return 'OVESETUP_AIO/rootPassword' LOCAL_DATA_CENTER = 'OVESETUP_AIO/localDataCenter' LOCAL_CLUSTER = 'OVESETUP_AIO/localCluster' diff --git a/packaging/setup/plugins/ovirt-engine-setup/all-in-one/__init__.py b/packaging/setup/plugins/ovirt-engine-setup/all-in-one/__init__.py index 0039c94..73c8d05 100644 --- a/packaging/setup/plugins/ovirt-engine-setup/all-in-one/__init__.py +++ b/packaging/setup/plugins/ovirt-engine-setup/all-in-one/__init__.py @@ -27,7 +27,6 @@ from . import core from . import cpu from . import sshd -from . import super_user from . import vdsm from . import storage from . import firewall @@ -38,7 +37,6 @@ core.Plugin(context=context) cpu.Plugin(context=context) sshd.Plugin(context=context) - super_user.Plugin(context=context) vdsm.Plugin(context=context) storage.Plugin(context=context) firewall.Plugin(context=context) diff --git a/packaging/setup/plugins/ovirt-engine-setup/all-in-one/sshd.py b/packaging/setup/plugins/ovirt-engine-setup/all-in-one/sshd.py index 1365d0c..fff24c2 100644 --- a/packaging/setup/plugins/ovirt-engine-setup/all-in-one/sshd.py +++ b/packaging/setup/plugins/ovirt-engine-setup/all-in-one/sshd.py @@ -21,10 +21,13 @@ """ +import os import gettext _ = lambda m: gettext.dgettext(message=m, domain='ovirt-engine-setup') +from otopi import constants as otopicons +from otopi import filetransaction from otopi import util from otopi import plugin @@ -59,9 +62,6 @@ after=( osetupcons.Stages.AIO_CONFIG_AVAILABLE, ), - before=( - osetupcons.Stages.AIO_CONFIG_ROOT_PASSWORD, - ), ) def _customization(self): if not self.services.exists(name='sshd'): @@ -70,6 +70,51 @@ self.services.state( name='sshd', state=True, + ) + + @plugin.event( + stage=plugin.Stages.STAGE_MISC, + condition=lambda self: ( + self._enabled and + self.environment[osetupcons.AIOEnv.CONFIGURE] + ), + after=( + osetupcons.Stages.SSH_KEY_AVAILABLE, + ), + ) + def _misc(self): + authorized_keys_line = self.environment[ + osetupcons.PKIEnv.ENGINE_SSH_PUBLIC_KEY_VALUE + ] + ' ovirt-engine' + + authorized_keys_file = os.path.join( + os.path.expanduser('~root'), + '.ssh', + 'authorized_keys' + ) + + content = [] + if os.path.exists(authorized_keys_file): + with open(authorized_keys_file, 'r') as f: + content = f.read().splitlines() + + if not authorized_keys_line in content: + self.environment[ + osetupcons.CoreEnv.UNINSTALL_UNREMOVABLE_FILES + ].append(authorized_keys_file) + + content.append(authorized_keys_line) + self.environment[otopicons.CoreEnv.MAIN_TRANSACTION].append( + filetransaction.FileTransaction( + name=authorized_keys_file, + content=content, + mode=0o600, + owner='root', + enforcePermissions=True, + modifiedList=self.environment[ + otopicons.CoreEnv.MODIFIED_FILES + ], + ) ) @plugin.event( @@ -84,7 +129,6 @@ name='sshd', state=True ) - # vim: expandtab tabstop=4 shiftwidth=4 diff --git a/packaging/setup/plugins/ovirt-engine-setup/all-in-one/super_user.py b/packaging/setup/plugins/ovirt-engine-setup/all-in-one/super_user.py deleted file mode 100644 index b264888..0000000 --- a/packaging/setup/plugins/ovirt-engine-setup/all-in-one/super_user.py +++ /dev/null @@ -1,106 +0,0 @@ -# -# ovirt-engine-setup -- ovirt engine setup -# Copyright (C) 2013 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. -# - - -""" -AIO super user password plugin. -""" - -import gettext -_ = lambda m: gettext.dgettext(message=m, domain='ovirt-engine-setup') - - -from otopi import util -from otopi import plugin -from otopi import constants as otopicons - - -from ovirt_engine_setup import constants as osetupcons - - -@util.export -class Plugin(plugin.PluginBase): - """ - AIO super user password plugin. - """ - - def __init__(self, context): - super(Plugin, self).__init__(context=context) - - def _validateUserPasswd(self, host, user, password): - valid = False - import paramiko - try: - cli = paramiko.SSHClient() - cli.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - cli.connect( - hostname=host, - username=user, - password=password - ) - valid = True - except paramiko.AuthenticationException: - pass - finally: - cli.close() - return valid - - @plugin.event( - stage=plugin.Stages.STAGE_INIT, - ) - def _init(self): - self.environment.setdefault( - osetupcons.AIOEnv.ROOT_PASSWORD, - None - ) - - @plugin.event( - stage=plugin.Stages.STAGE_CUSTOMIZATION, - condition=lambda self: self.environment[ - osetupcons.AIOEnv.CONFIGURE - ], - name=osetupcons.Stages.AIO_CONFIG_ROOT_PASSWORD - ) - def _customization(self): - interactive = ( - self.environment[osetupcons.AIOEnv.ROOT_PASSWORD] is None - ) - while self.environment[osetupcons.AIOEnv.ROOT_PASSWORD] is None: - password = self.dialog.queryString( - name='AIO_ROOT_PASSWORD', - note=_("Enter 'root' user password: "), - prompt=True, - hidden=True, - ) - if self._validateUserPasswd( - host='localhost', - user='root', - password=password - ): - self.environment[osetupcons.AIOEnv.ROOT_PASSWORD] = password - else: - if interactive: - self.logger.error(_('Wrong root password, try again')) - else: - raise RuntimeError(_('Wrong root password')) - - self.environment[otopicons.CoreEnv.LOG_FILTER].append( - self.environment[osetupcons.AIOEnv.ROOT_PASSWORD] - ) - - -# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/packaging/setup/plugins/ovirt-engine-setup/all-in-one/vdsm.py b/packaging/setup/plugins/ovirt-engine-setup/all-in-one/vdsm.py index ce7533e..780496e 100644 --- a/packaging/setup/plugins/ovirt-engine-setup/all-in-one/vdsm.py +++ b/packaging/setup/plugins/ovirt-engine-setup/all-in-one/vdsm.py @@ -170,7 +170,6 @@ osetupcons.AIOEnv.CONFIGURE ], after=( - osetupcons.Stages.AIO_CONFIG_ROOT_PASSWORD, osetupcons.Stages.AIO_CONFIG_STORAGE, osetupcons.Stages.CORE_ENGINE_START, osetupcons.Stages.APACHE_RESTART, @@ -247,7 +246,9 @@ cluster=engine_api.clusters.get( self.environment[osetupcons.AIOEnv.LOCAL_CLUSTER] ), - root_password=self.environment[osetupcons.AIOEnv.ROOT_PASSWORD] + ssh=self._ovirtsdk_xml.params.SSH( + authentication_method='publickey', + ), ) ) if not self._waitVDSMHostUp( diff --git a/packaging/setup/plugins/ovirt-engine-setup/pki/ssh.py b/packaging/setup/plugins/ovirt-engine-setup/pki/ssh.py index d2e9f23..960d07d 100644 --- a/packaging/setup/plugins/ovirt-engine-setup/pki/ssh.py +++ b/packaging/setup/plugins/ovirt-engine-setup/pki/ssh.py @@ -45,17 +45,17 @@ stage=plugin.Stages.STAGE_SETUP, ) def _setup(self): - self.command.detect('openssl') self.command.detect('ssh-keygen') @plugin.event( stage=plugin.Stages.STAGE_MISC, + name=osetupcons.Stages.SSH_KEY_AVAILABLE, after=( osetupcons.Stages.CA_AVAILABLE, ), ) def _misc(self): - rc, stdout, stderr = self.execute( + rc, privkey, stderr = self.execute( ( osetupcons.FileLocations.OVIRT_ENGINE_PKI_PKCS12_EXTRACT, '--name=engine', @@ -69,7 +69,7 @@ self.environment[otopicons.CoreEnv.MAIN_TRANSACTION].append( filetransaction.FileTransaction( name=osetupcons.FileLocations.OVIRT_ENGINE_PKI_ENGINE_SSH_KEY, - content=stdout, + content=privkey, mode=0o600, owner=self.environment[osetupcons.SystemEnv.USER_ROOT], enforcePermissions=True, @@ -78,6 +78,18 @@ ], ) ) + rc, pubkey, stderr = self.execute( + ( + self.command.get('ssh-keygen'), + '-y', + '-f', '/dev/fd/0', + ), + stdin=privkey, + logStreams=False, + ) + self.environment[ + osetupcons.PKIEnv.ENGINE_SSH_PUBLIC_KEY_VALUE + ] = pubkey[0] @plugin.event( stage=plugin.Stages.STAGE_CLOSEUP, -- To view, visit http://gerrit.ovirt.org/18266 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I885894bba4c998e5dd3e9b2fd4da61d833f7a3a1 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: ovirt-engine-3.3 Gerrit-Owner: Yedidyah Bar David <d...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches