summaryrefslogtreecommitdiffstats
path: root/bin/cluster
blob: 823f50671e964d00ba9973bba3369ad75a6c73e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/usr/bin/env python
# vim: expandtab:tabstop=4:shiftwidth=4

import argparse
import ConfigParser
import sys
import os


class Cluster(object):
    """Python wrapper to ensure environment is correct for running ansible playbooks
    """

    def __init__(self, args):
        self.args = args

        # setup ansible ssh environment
        if 'ANSIBLE_SSH_ARGS' not in os.environ:
            os.environ['ANSIBLE_SSH_ARGS'] = (
                '-o ForwardAgent=yes'
                ' -o StrictHostKeyChecking=no'
                ' -o UserKnownHostsFile=/dev/null'
                ' -o ControlMaster=auto'
                ' -o ControlPersist=600s'
            )

    def apply(self):
        # setup ansible playbook environment
        config = ConfigParser.ConfigParser()
        if 'gce' == self.args.provider:
            config.readfp(open('inventory/gce/gce.ini'))

            for key in config.options('gce'):
                os.environ[key] = config.get('gce', key)

            inventory = '-i inventory/gce/gce.py'
        elif 'aws' == self.args.provider:
            config.readfp(open('inventory/aws/ec2.ini'))

            for key in config.options('ec2'):
                os.environ[key] = config.get('ec2', key)

            inventory = '-i inventory/aws/ec2.py'
        else:
            # this code should never be reached
            raise argparse.ArgumentError("invalid PROVIDER {}".format(self.args.provider))

        env = {'cluster_id': self.args.cluster_id}

        if 'create' == self.args.action:
            playbook = "playbooks/{}/openshift-cluster/launch.yml".format(self.args.provider)
            env['masters'] = self.args.masters
            env['nodes'] = self.args.nodes

        elif 'terminate' == self.args.action:
            playbook = "playbooks/{}/openshift-cluster/terminate.yml".format(self.args.provider)
        elif 'list' == self.args.action:
            # todo: implement cluster list
            raise argparse.ArgumentError("ACTION {} not implemented".format(self.args.action))
        elif 'update' == self.args.action:
            # todo: implement cluster update
            raise argparse.ArgumentError("ACTION {} not implemented".format(self.args.action))
        else:
            # this code should never be reached
            raise argparse.ArgumentError("invalid ACTION {}".format(self.args.action))

        verbose = ''
        if self.args.verbose > 0:
            verbose = '-{}'.format('v' * self.args.verbose)

        ansible_env = '-e \'{}\''.format(
            ' '.join(['%s=%s' % (key, value) for (key, value) in env.items()])
        )

        command = 'ansible-playbook {} {} {} {}'.format(
            verbose, inventory, ansible_env, playbook
        )

        if self.args.verbose > 1:
            command = 'time {}'.format(command)

        if self.args.verbose > 0:
            sys.stderr.write('RUN [{}]\n'.format(command))
            sys.stderr.flush()

        status = os.system(command)
        if status != 0:
            sys.stderr.write("RUN [{}] failed with exit status %d".format(command, status))
            exit(status)



if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Manage OpenShift Cluster')
    parser.add_argument('-m', '--masters', default=1, type=int, help='number of masters to create in cluster')
    parser.add_argument('-n', '--nodes', default=2, type=int, help='number of nodes to create in cluster')
    parser.add_argument('-v', '--verbose', action='count', help='Multiple -v options increase the verbosity')
    parser.add_argument('--version', action='version', version='%(prog)s 0.1')
    parser.add_argument('action', choices=['create', 'terminate', 'update', 'list'])
    parser.add_argument('provider', choices=['gce', 'aws'])
    parser.add_argument('cluster_id', help='prefix for cluster VM names')
    args = parser.parse_args()

    if 'terminate' == args.action:
        sys.stderr.write("This will terminate the ENTIRE {} environment. Are you sure? [y/N] ".format(args.cluster_id))
        sys.stderr.flush()
        answer = sys.stdin.read(1)
        if answer not in ['y', 'Y']:
            exit(0)

    Cluster(args).apply()