summaryrefslogtreecommitdiff
path: root/morphlib
diff options
context:
space:
mode:
authorRichard Holland <richard.holland@codethink.co.uk>2013-04-03 13:56:46 +0000
committerRichard Holland <richard.holland@codethink.co.uk>2013-04-03 13:56:46 +0000
commit27428c744c862ecf37866312cc95c3e9398eb271 (patch)
tree5f779e72803a38f0b24b0db3d5768e901d9d0655 /morphlib
parent8b8cce2f44cc912124c8c7cc0fb0af5315977833 (diff)
downloadmorph-27428c744c862ecf37866312cc95c3e9398eb271.tar.gz
SSH Configuration Extension
Added a configuration extension that copies SSH keys across to the deployed system.
Diffstat (limited to 'morphlib')
-rwxr-xr-xmorphlib/exts/ssh.configure141
1 files changed, 141 insertions, 0 deletions
diff --git a/morphlib/exts/ssh.configure b/morphlib/exts/ssh.configure
new file mode 100755
index 00000000..8650b4f5
--- /dev/null
+++ b/morphlib/exts/ssh.configure
@@ -0,0 +1,141 @@
+#!/usr/bin/python
+# Copyright (C) 2013 Codethink Limited
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+'''A Morph deployment configuration to copy SSH keys.
+
+Keys are copied from the host to the new system.
+'''
+
+import cliapp
+import os
+import sys
+import shutil
+import glob
+import logging
+
+import morphlib
+
+class SshConfigurationExtension(cliapp.Application):
+
+ '''Copy over SSH keys to new system from host.
+
+ The extension requires SSH_KEY_DIR to be set at the command line as it
+ will otherwise pass with only a status update. SSH_KEY_DIR should be
+ set to the location of the SSH keys to be passed to the new system.
+
+ '''
+
+ def process_args(self, args):
+ if 'SSH_KEY_DIR' in os.environ:
+ # Copies ssh_host keys.
+ key = 'ssh_host_*_key'
+ mode = 0755
+ dest = os.path.join(args[0], 'etc/ssh/')
+ sshhost, sshhostpub = self.find_keys(key)
+ if sshhost or sshhostpub:
+ self.check_dir(dest, mode)
+ self.copy_keys(sshhost, sshhostpub, dest)
+
+ # Copies root keys.
+ key = 'root_*_key'
+ mode = 0700
+ dest = os.path.join(args[0], 'root/.ssh/')
+ roothost, roothostpub = self.find_keys(key)
+ key = 'root_authorized_key_*.pub'
+ authkey, bleh = self.find_keys(key)
+ if roothost or roothostpub:
+ self.check_dir(dest, mode)
+ self.copy_rename_keys(roothost,
+ roothostpub, dest, 'id_', [15, 4])
+ if authkey:
+ self.check_dir(dest, mode)
+ self.comb_auth_key(authkey, dest)
+ else:
+ self.status(msg="No SSH key directory found.")
+ pass
+
+ def find_keys(self, key_name):
+ '''Uses glob to find public and
+ private SSH keys and returns their path'''
+
+ src = os.path.join(os.environ['SSH_KEY_DIR'], key_name)
+ keys = glob.glob(src)
+ pubkeys = glob.glob(src + '.pub')
+ if not (keys or pubkeys):
+ self.status(msg="No SSH keys of pattern %(src)s found.", src=src)
+ return keys, pubkeys
+
+ def check_dir(self, dest, mode):
+ '''Checks if destination directory exists
+ and creates it if necessary'''
+
+ if os.path.exists(dest) == False:
+ self.status(msg="Creating SSH key directory: %(dest)s", dest=dest)
+ os.mkdir(dest)
+ os.chmod(dest, mode)
+ else:
+ pass
+
+ def copy_keys(self, keys, pubkeys, dest):
+ '''Copies SSH keys to new VM'''
+
+ for key in keys:
+ shutil.copy(key, dest)
+ os.chmod(dest, 0600)
+ for key in pubkeys:
+ shutil.copy(key, dest)
+ os.chmod(dest, 0644)
+
+ def copy_rename_keys(self, keys, pubkeys, dest, new, snip):
+ '''Copies SSH keys to new VM and renames them'''
+
+ st, fi = snip
+ for key in keys:
+ s = len(key)
+ nw_dst = os.path.join(dest, new + key[st:s-fi])
+ shutil.copy(key, nw_dst)
+ os.chmod(nw_dst, 0600)
+ for key in pubkeys:
+ s = len(key)
+ nw_dst = os.path.join(dest, new + key[st:s-fi-4])
+ shutil.copy(key, nw_dst + '.pub')
+ os.chmod(nw_dst, 0644)
+
+ def comb_auth_key(self, keys, dest):
+ '''Combines authorized_keys file in new VM'''
+
+ dest = os.path.join(dest, 'authorized_keys')
+ fout = open(dest, 'a')
+ for key in keys:
+ fin = open(key, 'r')
+ data = fin.read()
+ fout.write(data)
+ fin.close()
+ fout.close()
+ os.chmod(dest, 0600)
+
+ def status(self, **kwargs):
+ '''Provide status output.
+
+ The ``msg`` keyword argument is the actual message,
+ the rest are values for fields in the message as interpolated
+ by %.
+
+ '''
+
+ self.output.write('%s\n' % (kwargs['msg'] % kwargs))
+
+SshConfigurationExtension().run()