diff options
author | Richard Holland <richard.holland@codethink.co.uk> | 2013-04-03 13:56:46 +0000 |
---|---|---|
committer | Richard Holland <richard.holland@codethink.co.uk> | 2013-04-03 13:56:46 +0000 |
commit | 27428c744c862ecf37866312cc95c3e9398eb271 (patch) | |
tree | 5f779e72803a38f0b24b0db3d5768e901d9d0655 /morphlib/exts | |
parent | 8b8cce2f44cc912124c8c7cc0fb0af5315977833 (diff) | |
download | morph-27428c744c862ecf37866312cc95c3e9398eb271.tar.gz |
SSH Configuration Extension
Added a configuration extension that copies SSH keys across to the
deployed system.
Diffstat (limited to 'morphlib/exts')
-rwxr-xr-x | morphlib/exts/ssh.configure | 141 |
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() |