cluster 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #!/usr/bin/env python
  2. # vim: expandtab:tabstop=4:shiftwidth=4
  3. import argparse
  4. import ConfigParser
  5. import sys
  6. import os
  7. class Cluster(object):
  8. """Python wrapper to ensure environment is correct for running ansible playbooks
  9. """
  10. def __init__(self, args):
  11. self.args = args
  12. # setup ansible ssh environment
  13. if 'ANSIBLE_SSH_ARGS' not in os.environ:
  14. os.environ['ANSIBLE_SSH_ARGS'] = (
  15. '-o ForwardAgent=yes'
  16. ' -o StrictHostKeyChecking=no'
  17. ' -o UserKnownHostsFile=/dev/null'
  18. ' -o ControlMaster=auto'
  19. ' -o ControlPersist=600s'
  20. )
  21. def apply(self):
  22. # setup ansible playbook environment
  23. config = ConfigParser.ConfigParser()
  24. if 'gce' == self.args.provider:
  25. config.readfp(open('inventory/gce/gce.ini'))
  26. for key in config.options('gce'):
  27. os.environ[key] = config.get('gce', key)
  28. inventory = '-i inventory/gce/gce.py'
  29. elif 'aws' == self.args.provider:
  30. config.readfp(open('inventory/aws/ec2.ini'))
  31. for key in config.options('ec2'):
  32. os.environ[key] = config.get('ec2', key)
  33. inventory = '-i inventory/aws/ec2.py'
  34. else:
  35. # this code should never be reached
  36. raise argparse.ArgumentError("invalid PROVIDER {}".format(self.args.provider))
  37. env = {'cluster_id': self.args.cluster_id}
  38. if 'create' == self.args.action:
  39. playbook = "playbooks/{}/openshift-cluster/launch.yml".format(self.args.provider)
  40. env['masters'] = self.args.masters
  41. env['nodes'] = self.args.nodes
  42. elif 'terminate' == self.args.action:
  43. playbook = "playbooks/{}/openshift-cluster/terminate.yml".format(self.args.provider)
  44. elif 'list' == self.args.action:
  45. # todo: implement cluster list
  46. raise argparse.ArgumentError("ACTION {} not implemented".format(self.args.action))
  47. elif 'update' == self.args.action:
  48. # todo: implement cluster update
  49. raise argparse.ArgumentError("ACTION {} not implemented".format(self.args.action))
  50. else:
  51. # this code should never be reached
  52. raise argparse.ArgumentError("invalid ACTION {}".format(self.args.action))
  53. verbose = ''
  54. if self.args.verbose > 0:
  55. verbose = '-{}'.format('v' * self.args.verbose)
  56. ansible_env = '-e \'{}\''.format(
  57. ' '.join(['%s=%s' % (key, value) for (key, value) in env.items()])
  58. )
  59. command = 'ansible-playbook {} {} {} {}'.format(
  60. verbose, inventory, ansible_env, playbook
  61. )
  62. if self.args.verbose > 1:
  63. command = 'time {}'.format(command)
  64. if self.args.verbose > 0:
  65. sys.stderr.write('RUN [{}]\n'.format(command))
  66. sys.stderr.flush()
  67. status = os.system(command)
  68. if status != 0:
  69. sys.stderr.write("RUN [{}] failed with exit status %d".format(command, status))
  70. exit(status)
  71. if __name__ == '__main__':
  72. parser = argparse.ArgumentParser(description='Manage OpenShift Cluster')
  73. parser.add_argument('-m', '--masters', default=1, type=int, help='number of masters to create in cluster')
  74. parser.add_argument('-n', '--nodes', default=2, type=int, help='number of nodes to create in cluster')
  75. parser.add_argument('-v', '--verbose', action='count', help='Multiple -v options increase the verbosity')
  76. parser.add_argument('--version', action='version', version='%(prog)s 0.1')
  77. parser.add_argument('action', choices=['create', 'terminate', 'update', 'list'])
  78. parser.add_argument('provider', choices=['gce', 'aws'])
  79. parser.add_argument('cluster_id', help='prefix for cluster VM names')
  80. args = parser.parse_args()
  81. if 'terminate' == args.action:
  82. sys.stderr.write("This will terminate the ENTIRE {} environment. Are you sure? [y/N] ".format(args.cluster_id))
  83. sys.stderr.flush()
  84. answer = sys.stdin.read(1)
  85. if answer not in ['y', 'Y']:
  86. exit(0)
  87. Cluster(args).apply()