Copy certificate from master to slaves
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
2.9 KiB

7 years ago
7 years ago
  1. #!/usr/bin/python
  2. import paramiko
  3. import argparse
  4. import os
  5. import posixpath
  6. from subprocess import list2cmdline
  7. def connection_from_config(name):
  8. """Create a connection from a Host entry in the .ssh/config file"""
  9. config = paramiko.config.SSHConfig()
  10. cp = os.path.expanduser('~/.ssh/config')
  11. with open(cp) as file:
  12. config.parse(file)
  13. info = config.lookup(name)
  14. info['username'] = info.pop('user')
  15. info['key_filename'] = info.pop('identityfile')
  16. info['port'] = int(info['port'])
  17. client = paramiko.client.SSHClient()
  18. client.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
  19. client.connect(**info)
  20. return client
  21. def scp(connection: paramiko.sftp_client.SFTPClient, src, dst):
  22. """Function to copy files from src to dst using connection"""
  23. connection.put(src, dst)
  24. def exec_remote(connection: paramiko.SSHClient, command):
  25. """Function to execute specified command on conection"""
  26. if not isinstance(command, str):
  27. command = list2cmdline(command)
  28. stdin, stdout, stderr = connection.exec_command(command)
  29. return stdout, stderr
  30. if __name__ == "__main__":
  31. parser = argparse.ArgumentParser(prefix_chars="*")
  32. parser.add_argument(
  33. 'cert_path', help="location of the certificate to install")
  34. parser.add_argument(
  35. 'key_path', help="localtion of the private key to install")
  36. parser.add_argument(
  37. 'store_path',
  38. help="directory to store the private key and certificate")
  39. parser.add_argument('*d', '**dry', action='store_true')
  40. args = parser.parse_args()
  41. # Connect to host
  42. router = connection_from_config('router')
  43. stdout, stderr = exec_remote(router, ['ls', args.store_path])
  44. # Check to see if remote directory exists
  45. if stdout.channel.recv_exit_status() == 0:
  46. files = list(filter(bool, stdout.read().decode().split('\n')))
  47. # Delete old certificate and key
  48. for file in files:
  49. if file in ('cert.pem', 'key.pem'):
  50. if args.dry:
  51. print("Removing {}".format(
  52. posixpath.join(args.store_path, file)))
  53. else:
  54. exec_remote(
  55. router, ['rm', posixpath.join(
  56. args.store_path, file)]
  57. )
  58. else:
  59. # Create missing directory
  60. if args.dry:
  61. print("Creating missing dir {}".format(args.store_path))
  62. else:
  63. exec_remote(router, ['mkdir', args.store_path])
  64. sftp = router.open_sftp()
  65. # Copy certificate and key to store_path
  66. for src, dst in zip(
  67. [args.cert_path, args.key_path],
  68. [posixpath.join(args.store_path, "cert.pem"),
  69. posixpath.join(args.store_path, "key.pem")]
  70. ):
  71. if args.dry:
  72. print("{} -> {}".format(src, dst))
  73. else:
  74. scp(sftp, src, dst)
  75. sftp.close()
  76. router.close()