Francesco Romani has uploaded a new change for review.

Change subject: services, setup: vmconsole/openssh integration
......................................................................

services, setup: vmconsole/openssh integration

integration between ovirt-engine and ovirt-vmconsole-proxy, using
the openssh certificates

Includes:
- helpers to integrate ovirt-engine and ovirt-vmconsole-proxy
- setup plugins for PKI artifacts

Feature wiki page: http://www.ovirt.org/Features/Serial_Console

Bug-Url: https://bugzilla.redhat.com/1223671
Change-Id: I740e37d5c34633bbe51922fb047d6b1a0a2431b6
Signed-off-by: Francesco Romani <from...@redhat.com>
---
M packaging/setup/ovirt_engine_setup/vmconsole_proxy/constants.py
M packaging/setup/plugins/ovirt-engine-setup/vmconsole_proxy/pki.py
2 files changed, 186 insertions(+), 16 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/29/41329/1

diff --git a/packaging/setup/ovirt_engine_setup/vmconsole_proxy/constants.py 
b/packaging/setup/ovirt_engine_setup/vmconsole_proxy/constants.py
index c6c0bbe..3c3e4ab 100644
--- a/packaging/setup/ovirt_engine_setup/vmconsole_proxy/constants.py
+++ b/packaging/setup/ovirt_engine_setup/vmconsole_proxy/constants.py
@@ -39,7 +39,7 @@
     VMCONSOLE_PROXY_PACKAGE_NAME = 'ovirt-engine-vmconsole-proxy'
     VMCONSOLE_PROXY_SETUP_PACKAGE_NAME = \
         'ovirt-engine-setup-plugin-vmconsole-proxy'
-    VMCONSOLE_PROXY_CERT_NAME = 'vmconsole-proxy'
+    VMCONSOLE_PROXY_PKI_NAME = 'vmconsole-proxy'
 
 
 @util.export
@@ -73,16 +73,16 @@
 
     OVIRT_ENGINE_PKI_VMCONSOLE_PROXY_KEY = os.path.join(
         OVIRT_ENGINE_PKIKEYSDIR,
-        '%s.key.nopass' % Const.VMCONSOLE_PROXY_CERT_NAME,
+        '%s.key.nopass' % Const.VMCONSOLE_PROXY_PKI_NAME,
     )
     OVIRT_ENGINE_PKI_VMCONSOLE_PROXY_CERT = os.path.join(
         OVIRT_ENGINE_PKICERTSDIR,
-        '%s.cer' % Const.VMCONSOLE_PROXY_CERT_NAME,
+        '%s.cer' % Const.VMCONSOLE_PROXY_PKI_NAME,
     )
 
     OVIRT_ENGINE_PKI_VMCONSOLE_PROXY_REQ = os.path.join(
         OVIRT_ENGINE_PKICERTSDIR,
-        '%s.req' % Const.VMCONSOLE_PROXY_CERT_NAME,
+        '%s.req' % Const.VMCONSOLE_PROXY_PKI_NAME,
     )
     OVIRT_ENGINE_PKI_ENGINE_CERT = os.path.join(
         OVIRT_ENGINE_PKICERTSDIR,
@@ -111,6 +111,19 @@
     OVIRT_VMCONSOLE_PROXY_ENGINE_HELPER = \
         vmpconfig.VMCONSOLE_PROXY_HELPER_PATH
 
+    OVIRT_VMCONSOLE_PROXY_PKIDIR = \
+        '/etc/pki/ovirt-vmconsole/'
+
+    OVIRT_VMCONSOLE_PKI_PROXY_HOST_CERT = os.path.join(
+        OVIRT_VMCONSOLE_PROXY_PKIDIR,
+        'proxy-ssh_host_rsa-cert.pub'
+    )
+
+    OVIRT_VMCONSOLE_PKI_PROXY_HOST_KEY = os.path.join(
+        OVIRT_VMCONSOLE_PROXY_PKIDIR,
+        'proxy-ssh_host_rsa'
+    )
+
 
 @util.export
 class Stages(object):
diff --git a/packaging/setup/plugins/ovirt-engine-setup/vmconsole_proxy/pki.py 
b/packaging/setup/plugins/ovirt-engine-setup/vmconsole_proxy/pki.py
index 87cc386..28af1a7 100644
--- a/packaging/setup/plugins/ovirt-engine-setup/vmconsole_proxy/pki.py
+++ b/packaging/setup/plugins/ovirt-engine-setup/vmconsole_proxy/pki.py
@@ -21,8 +21,9 @@
 
 import gettext
 import os
+import shutil
 
-from otopi import plugin, util
+from otopi import filetransaction, plugin, util
 from otopi import constants as otopicons
 from ovirt_engine import util as outil
 
@@ -43,7 +44,6 @@
     def __init__(self, context):
         super(Plugin, self).__init__(context=context)
         self._enabled = False
-        self._name = "vmconsole-proxy"
 
     def _subjectComponentEscape(self, s):
         return outil.escape(s, '/\\')
@@ -70,7 +70,7 @@
             ]
         ),
     )
-    def _misc_pki_engine(self):
+    def _miscPKIEngine(self):
         self._enabled = True
         uninstall_files = []
         self.environment[
@@ -90,7 +90,7 @@
         self.execute(
             (
                 oenginecons.FileLocations.OVIRT_ENGINE_PKI_CA_ENROLL,
-                '--name=%s' % self._name,
+                '--name=%s' % ovmpcons.Const.VMCONSOLE_PROXY_PKI_NAME,
                 '--password=%s' % (
                     self.environment[oenginecons.PKIEnv.STORE_PASS],
                 ),
@@ -126,7 +126,7 @@
         self.execute(
             args=(
                 oenginecons.FileLocations.OVIRT_ENGINE_PKI_PKCS12_EXTRACT,
-                '--name=%s' % self._name,
+                '--name=%s' % ovmpcons.Const.VMCONSOLE_PROXY_PKI_NAME,
                 '--passin=%s' % (
                     self.environment[oenginecons.PKIEnv.STORE_PASS],
                 ),
@@ -146,6 +146,140 @@
             self.logger,
             ovmpcons.FileLocations.OVIRT_ENGINE_PKI_VMCONSOLE_PROXY_KEY,
             ovmpcons.FileLocations.OVIRT_ENGINE_PKI_VMCONSOLE_PROXY_STORE
+        )
+
+    @plugin.event(
+        stage=plugin.Stages.STAGE_MISC,
+        name=ovmpcons.Stages.CONFIG_VMCONSOLE_PKI_PROXY,
+        after=(
+            ovmpcons.Stages.CA_AVAILABLE,
+        ),
+        condition=lambda self: (
+            self.environment[
+                ovmpcons.ConfigEnv.VMCONSOLE_PROXY_CONFIG
+            ]
+        ),
+    )
+    def _miscPKIProxy(self):
+        self._enabled = True
+        uninstall_files = []
+        self.environment[
+            osetupcons.CoreEnv.REGISTER_UNINSTALL_GROUPS
+        ].createGroup(
+            group='ca_pki_vmp_proxy',
+            description='VMP PKI Proxy keys',
+            optional=True,
+        ).addFiles(
+            group='ca_pki_vmp_proxy',
+            fileList=uninstall_files,
+        )
+
+        self.logger.info(_('Setting up vmconsole proxy helper PKI artifacts'))
+
+        self._enrollSSHKeys(
+            host_mode=True
+        )
+        self._expandPKCS12SSHKey(
+            host_mode=True,
+            owner=ovmpcons.PKIEnv.OVIRT_VMCONSOLE_ALLOWED_USER,
+            uninstall_files=uninstall_files
+        )
+
+        self._enrollSSHKeys(
+            host_mode=False
+        )  # user mode
+        self._expandPKCS12SSHKey(
+            host_mode=False,
+            owner=ovmpcons.PKIEnv.OVIRT_VMCONSOLE_ALLOWED_USER,
+            uninstall_files=uninstall_files
+        )
+
+    def _enrollSSHKeys(self, host_mode):
+        suffix = 'host' if host_mode else 'user'
+        name = '%s-%s' (
+            ovmpcons.Const.VMCONSOLE_PROXY_PKI_NAME,
+            suffix
+        )
+
+        self.execute(
+            (
+                oenginecons.FileLocations.OVIRT_ENGINE_PKI_CA_ENROLL,
+                '--name=%s' % name,
+                '--password=%s' % (
+                    self.environment[oenginecons.PKIEnv.STORE_PASS],
+                ),
+                '--subject=/CN=%s' % (
+                    self._subjectComponentEscape(self.name)
+                ),
+            ),
+        )
+        self.execute(
+            (
+                oenginecons.FileLocations.OVIRT_ENGINE_PKI_SSH_ENROLL,
+                '--name=%s' % name,
+                '--id=%s' % ovmpcons.Const.VMCONSOLE_PROXY_PKI_NAME,
+                '--host' if host_mode else '',
+                '--principals=%s' % (
+                    self._subjectComponentEscape(
+                        self.environment[osetupcons.ConfigEnv.FQDN]
+                        if host_mode else
+                        ovmpcons.Const.VMCONSOLE_PROXY_SERVICE_NAME,
+                    ),
+                ),
+
+            ),
+        )
+
+        # prepare final path in the engine pki directory.
+        # copy in the vmconsole pki directory later
+        shutil.copyfile(
+            os.path.join(
+                ovmpcons.FileLocations.OVIRT_ENGINE_PKICERTSDIR,
+                name),
+            os.path.join(
+                ovmpcons.FileLocations.OVIRT_ENGINE_PKICERTSDIR,
+                'proxy-ssh_%s_rsa-cert.pub' % (
+                    suffix
+                )
+            )
+        )
+
+    def _expandPKCS12SSHKey(self, host_mode, owner, uninstall_files):
+
+        name = 'host' if host_mode else 'user'
+        pkcs12 = os.path.join(
+            ovmpcons.FileLocations.OVIRT_ENGINE_PKIKEYSDIR,
+            '%s-%s.p12' % (
+                ovmpcons.Const.VMCONSOLE_PROXY_PKI_NAME,
+                name,
+            ),
+        )
+
+        rc, key, stderr = self.execute(
+            args=(
+                self.command.get('openssl'),
+                'pkcs12',
+                '-in', pkcs12,
+                '-passin', 'pass:%s' % self.environment[
+                    oenginecons.PKIEnv.STORE_PASS
+                ],
+                '-nodes',
+                '-nocerts',
+            ),
+            logStreams=False,
+        )
+
+        self.environment[otopicons.CoreEnv.MAIN_TRANSACTION].append(
+            filetransaction.FileTransaction(
+                name=os.path.join(
+                    oenginecons.FileLocations.OVIRT_ENGINE_PKIDIR,
+                    'proxy-ssh_%s_rsa' % name,
+                ),
+                content=key,
+                mode=0o600,
+                owner=owner,
+                modifiedList=uninstall_files,
+            )
         )
 
 
@@ -168,14 +302,37 @@
 
     else:
         for f in pki_artifacts:
-            os.chown(f,
-                     osetuputil.getUid(
-                         ovmpcons.PKIEnv.OVIRT_VMCONSOLE_ALLOWED_USER
-                     ),
-                     osetuputil.getGid(
-                         ovmpcons.PKIEnv.OVIRT_VMCONSOLE_ALLOWED_USER
-                     )
+            os.chown(
+                f,
+                osetuputil.getUid(
+                    ovmpcons.PKIEnv.OVIRT_VMCONSOLE_ALLOWED_USER
+                ),
+                osetuputil.getGid(
+                    ovmpcons.PKIEnv.OVIRT_VMCONSOLE_ALLOWED_USER
+                )
             )
 
 
+def _deployVMConsolePKIArtifacts(log, pki_artifacts):
+    if os.geteuid() != 0:
+        log.warning(
+            _(
+                'Manual intervention is required, because'
+                'Setup was run under unprivileged user.\n'
+                'Cannot copy ovirt-vmconsole PKI artifacts'
+                'into the proper PKI directory'
+                'Please make sure to run as root:\n'
+                'cp -p {files} {vmconsole_pkidir}\n'.format(
+                    files=' '.join(pki_artifacts),
+                    pkidr=ovmpcons.FileLocations.OVIRT_VMCONSOLE_PROXY_PKIDIR,
+                )
+            )
+        )
+
+    else:
+        for f in pki_artifacts:
+            shutil.copy2(f,
+                         ovmpcons.FileLocations.OVIRT_VMCONSOLE_PROXY_PKIDIR)
+
+
 # vim: expandtab tabstop=4 shiftwidth=4


-- 
To view, visit https://gerrit.ovirt.org/41329
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I740e37d5c34633bbe51922fb047d6b1a0a2431b6
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Francesco Romani <from...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to