summaryrefslogtreecommitdiffstats
path: root/roles/lib_openshift_api/build/src/router.py
blob: 69454d5949cb771998a34c21baec3be67c6cacf8 (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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# pylint: skip-file

import time

class RouterConfig(object):
    ''' RouterConfig is a DTO for the router.  '''
    def __init__(self, rname, kubeconfig, router_options):
        self.name = rname
        self.kubeconfig = kubeconfig
        self._router_options = router_options

    @property
    def router_options(self):
        ''' return router options '''
        return self._router_options

    def to_option_list(self):
        ''' return all options as a string'''
        return RouterConfig.stringify(self.router_options)

    @staticmethod
    def stringify(options):
        ''' return hash as list of key value pairs '''
        rval = []
        for key, data in options.items():
            if data['include'] and data['value']:
                rval.append('--%s=%s' % (key.replace('_', '-'), data['value']))

        return rval

class Router(OpenShiftCLI):
    ''' Class to wrap the oc command line tools '''
    def __init__(self,
                 router_config,
                 verbose=False):
        ''' Constructor for OpenshiftOC

           a router consists of 3 or more parts
           - dc/router
           - svc/router
           - endpoint/router
        '''
        super(Router, self).__init__('default', router_config.kubeconfig, verbose)
        self.rconfig = router_config
        self.verbose = verbose
        self.router_parts = [{'kind': 'dc', 'name': self.rconfig.name},
                             {'kind': 'svc', 'name': self.rconfig.name},
                             #{'kind': 'endpoints', 'name': self.rconfig.name},
                            ]
    def get(self, filter_kind=None):
        ''' return the self.router_parts '''
        rparts = self.router_parts
        parts = []
        if filter_kind:
            rparts = [part for part in self.router_parts if filter_kind == part['kind']]

        for part in rparts:
            parts.append(self._get(part['kind'], rname=part['name']))

        return parts

    def exists(self):
        '''return a deploymentconfig by name '''
        parts = self.get()
        for part in parts:
            if part['returncode'] != 0:
                return False

        return True

    def delete(self):
        '''return all pods '''
        parts = []
        for part in self.router_parts:
            parts.append(self._delete(part['kind'], part['name']))

        return parts

    def create(self, dryrun=False, output=False, output_type='json'):
        '''Create a deploymentconfig '''
        # We need to create the pem file
        router_pem = '/tmp/router.pem'
        with open(router_pem, 'w') as rfd:
            rfd.write(open(self.rconfig.router_options['cert_file']['value']).read())
            rfd.write(open(self.rconfig.router_options['key_file']['value']).read())

        atexit.register(Utils.cleanup, [router_pem])
        self.rconfig.router_options['default_cert']['value'] = router_pem

        options = self.rconfig.to_option_list()

        cmd = ['router']
        cmd.extend(options)
        if dryrun:
            cmd.extend(['--dry-run=True', '-o', 'json'])

        results = self.openshift_cmd(cmd, oadm=True, output=output, output_type=output_type)

        return results

    def update(self):
        '''run update for the router.  This performs a delete and then create '''
        parts = self.delete()
        if any([part['returncode'] != 0 for part in parts]):
            return parts

        # Ugly built in sleep here.
        time.sleep(15)

        return self.create()

    def needs_update(self, verbose=False):
        ''' check to see if we need to update '''
        dc_inmem = self.get(filter_kind='dc')[0]
        if dc_inmem['returncode'] != 0:
            return dc_inmem

        user_dc = self.create(dryrun=True, output=True, output_type='raw')
        if user_dc['returncode'] != 0:
            return user_dc

        # Since the output from oadm_router is returned as raw
        # we need to parse it.  The first line is the stats_password
        user_dc_results = user_dc['results'].split('\n')
        # stats_password = user_dc_results[0]

        # Load the string back into json and get the newly created dc
        user_dc = json.loads('\n'.join(user_dc_results[1:]))['items'][0]

        # Router needs some exceptions.
        # We do not want to check the autogenerated password for stats admin
        if not self.rconfig.router_options['stats_password']['value']:
            for idx, env_var in enumerate(user_dc['spec']['template']['spec']['containers'][0]['env']):
                if env_var['name'] == 'STATS_PASSWORD':
                    env_var['value'] = \
                      dc_inmem['results'][0]['spec']['template']['spec']['containers'][0]['env'][idx]['value']

        # dry-run doesn't add the protocol to the ports section.  We will manually do that.
        for idx, port in enumerate(user_dc['spec']['template']['spec']['containers'][0]['ports']):
            if not port.has_key('protocol'):
                port['protocol'] = 'TCP'

        # These are different when generating
        skip = ['dnsPolicy',
                'terminationGracePeriodSeconds',
                'restartPolicy', 'timeoutSeconds',
                'livenessProbe', 'readinessProbe',
                'terminationMessagePath',
                'rollingParams',
               ]

        return not Utils.check_def_equal(user_dc, dc_inmem['results'][0], skip_keys=skip, debug=verbose)