Hello Ayal Baron, Timothy Asir, Saggi Mizrahi, Federico Simoncelli, Dan Kenigsberg,
I'd like you to do a code review. Please visit
to review the following change.
Change subject: [WIP] Added gluster geo-replication support ......................................................................
[WIP] Added gluster geo-replication support
Below new verbs are added
glusterValidateSshConnection glusterSetupSshConnection
Change-Id: Ic783abd5f1b63bc5116ce4ff2a3c7be92001a387 Signed-off-by: Bala.FA barumuga@redhat.com --- M vdsm.spec.in M vdsm/gluster/api.py M vdsm/gluster/exception.py 3 files changed, 137 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/75/8375/1
diff --git a/vdsm.spec.in b/vdsm.spec.in index 22e48fb..020344f 100644 --- a/vdsm.spec.in +++ b/vdsm.spec.in @@ -352,6 +352,7 @@
Requires: %{name} = %{version}-%{release} Requires: glusterfs glusterfs-server glusterfs-fuse +Requires: python-paramiko
%description gluster Gluster plugin enables VDSM to serve Gluster functionalities. diff --git a/vdsm/gluster/api.py b/vdsm/gluster/api.py index a825de2..338cb06 100644 --- a/vdsm/gluster/api.py +++ b/vdsm/gluster/api.py @@ -19,11 +19,24 @@ #
from functools import wraps +import socket +import paramiko +import re
from vdsm.define import doneCode import supervdsm as svdsm +from vdsm.config import config +from vdsm import utils +import exception as ge
_SUCCESS = {'status': doneCode} +_KEYFILE = config.get('vars', 'trust_store_path') + '/keys/vdsmkey.pem' +_sshKeyGenCommandPath = utils.CommandPath("ssh-keygen", + "/usr/bin/ssh-keygen", + ) +_SSH_COPY_ID_CMD = "umask 077; test -d ~/.ssh || mkdir ~/.ssh ; " \ + "cat >> ~/.ssh/authorized_keys && (test -x /sbin/restorecon && " \ + "/sbin/restorecon ~/.ssh ~/.ssh/authorized_keys >/dev/null 2>&1 || true)"
def exportAsVerb(func): @@ -43,6 +56,52 @@ class VolumeStatus(): ONLINE = 'ONLINE' OFFLINE = 'OFFLINE' + + +class HostKeyMatchException(paramiko.SSHException): + def __init__(self, hostname, fingerprint, expected_fingerprint): + err = 'Fingerprint of Host key ' \ + '%s for server %s does not match with %s' % \ + (fingerprint, hostname, expected_fingerprint) + paramiko.SSHException.__init__(self, err) + self.hostname = hostname + self.fingerprint = fingerprint + self.expected_fingerprint = expected_fingerprint + + +class HostKeyMatchPolicy(paramiko.AutoAddPolicy): + def __init__(self, expected_fingerprint): + self.expected_fingerprint = expected_fingerprint + + def missing_host_key(self, client, hostname, key): + s = paramiko.util.hexlify(key.get_fingerprint()) + fingerprint = ':'.join(re.findall('..', s)) + if fingerprint == self.expected_fingerprint.upper(): + paramiko.AutoAddPolicy.missing_host_key(self, client, hostname, + key) + else: + raise HostKeyMatchException(hostname, fingerprint, + self.expected_fingerprint) + + +class GlusterSsh(paramiko.SSHClient): + def __init__(self, hostname, fingerprint, port=22, username=None, + password=None, pkey=None, key_filename=None, timeout=None, + allow_agent=True, look_for_keys=True, compress=False): + paramiko.SSHClient.__init__(self) + key_file_list = [_KEYFILE] + if key_filename: + key_file_list.append(list(key_filename)) + self.set_missing_host_key_policy(HostKeyMatchPolicy(fingerprint)) + try: + paramiko.SSHClient.connect(self, hostname, port, username, + password, pkey, key_file_list, timeout, + allow_agent, look_for_keys, compress) + except socket.error, e: + err = ['%s: %s' % (hostname, e)] + raise ge.GlusterSshConnectionFailedException(err=err) + except HostKeyMatchException, e: + raise ge.GlusterSshHostKeyMismatchException(err=[e.err])
class GlusterApi(object): @@ -236,6 +295,47 @@ def volumeProfileStop(self, volumeName, options=None): self.svdsmProxy.glusterVolumeProfileStop(volumeName)
+ def _validateSshConnection(self, hostname, fingerprint, username): + try: + ssh = GlusterSsh(hostname, + fingerprint, + username=username) + ssh.close() + return True + except paramiko.AuthenticationException, e: + raise ge.GlusterSshHostKeyAuthException(err=[str(e)]) + + @exportAsVerb + def validateSshConnection(self, hostname, fingerprint, username): + return self._validateSshConnection(hostname, fingerprint, username) + + @exportAsVerb + def setupSshConnection(self, hostname, fingerprint, username, password): + rc, out, err = utils.execCmd([_sshKeyGenCommandPath.cmd, '-y', '-f', + _KEYFILE]) + if rc != 0: + raise ge.GlusterSshPubKeyGenerationFailedException(rc=rc, err=err) + + try: + ssh = GlusterSsh(hostname, + fingerprint, + username=username, + password=password) + c = ssh.get_transport().open_session() + stdin, stdout, stderr = c.exec_command(_SSH_COPY_ID_CMD) + stdin.write('\n'.join(out) + '\n') + stdin.flush() + stdin.close() + rc = c.recv_exit_status() + ssh.close() + if rc != 0: + err = stderr.read().splitlines() + raise ge.GlusterSshSetupExecFailedException(rc=rc, err=err) + except paramiko.AuthenticationException, e: + raise ge.GlusterSshHostAuthException(err=[str(e)]) + + return self._validateSshConnection(hostname, fingerprint, username) +
def getGlusterMethods(gluster): l = [] diff --git a/vdsm/gluster/exception.py b/vdsm/gluster/exception.py index 6d94ae3..0143a5e 100644 --- a/vdsm/gluster/exception.py +++ b/vdsm/gluster/exception.py @@ -377,3 +377,39 @@ class GlusterHostsListFailedException(GlusterHostException): code = 4407 message = "Hosts list failed" + + +# Ssh +class GlusterSshException(GlusterException): + code = 4500 + message = "Gluster ssh exception" + + +class GlusterSshConnectionFailedException(GlusterSshException): + code = 4501 + message = "SSH connection failed" + + +class GlusterSshHostKeyMismatchException(GlusterSshException): + code = 4502 + message = "Host key match failed" + + +class GlusterSshHostKeyAuthException(GlusterSshException): + code = 4503 + message = "SSH host key authentication failed" + + +class GlusterSshHostAuthException(GlusterSshException): + code = 4504 + message = "SSH host authentication failed" + + +class GlusterSshPubKeyGenerationFailedException(GlusterSshException): + code = 4505 + message = "SSH public key generation failed" + + +class GlusterSshSetupExecFailedException(GlusterSshException): + code = 4506 + message = "SSH key setup execution failed"
-- To view, visit http://gerrit.ovirt.org/8375 To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange Gerrit-Change-Id: Ic783abd5f1b63bc5116ce4ff2a3c7be92001a387 Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Bala.FA barumuga@redhat.com Gerrit-Reviewer: Ayal Baron abaron@redhat.com Gerrit-Reviewer: Dan Kenigsberg danken@redhat.com Gerrit-Reviewer: Federico Simoncelli fsimonce@redhat.com Gerrit-Reviewer: Saggi Mizrahi smizrahi@redhat.com Gerrit-Reviewer: Timothy Asir tjeyasin@redhat.com
oVirt Jenkins CI Server has posted comments on this change.
Change subject: gluster: Setup and verify ssl connection between nodes. ......................................................................
Patch Set 6:
Build Successful
http://jenkins.ovirt.org/job/vdsm_unit_tests_gerrit/3756/ : SUCCESS
http://jenkins.ovirt.org/job/vdsm_pep8_gerrit/3672/ : SUCCESS
http://jenkins.ovirt.org/job/vdsm_unit_tests_gerrit_el/2865/ : SUCCESS
Bala.FA has posted comments on this change.
Change subject: gluster: Setup and verify ssl connection between nodes. ......................................................................
Patch Set 6: Code-Review-1
If this patch has to be split in multiples, please use different change-id. once its fully taken, i will abandon this patch.
Itamar Heim has posted comments on this change.
Change subject: gluster: Setup and verify ssl connection between nodes. ......................................................................
Patch Set 6:
ping
Itamar Heim has abandoned this change.
Change subject: gluster: Setup and verify ssl connection between nodes. ......................................................................
Abandoned
abandoning - old. no reply. not touched for a while. please restore if relevant
vdsm-patches@lists.fedorahosted.org