blob: 0ec2cb2e3462805a8f2ccd4626c92de60c5daf62 [file] [log] [blame]
Jun Hu9e45abc2018-01-17 17:07:36 -05001#!/usr/bin/env python
2
3# ============LICENSE_START==========================================
4# ===================================================================
Jun (Nicolas) Hu8cbcb302018-02-21 14:18:44 -05005# Copyright (c) 2017 AT&T
Jun Hu9e45abc2018-01-17 17:07:36 -05006#
7# Licensed under the Apache License, Version 2.0 (the "License");
8# you may not use this file except in compliance with the License.
9# You may obtain a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS,
15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16# See the License for the specific language governing permissions and
17# limitations under the License.
18#============LICENSE_END============================================
19
20# This script will be executed on Kubernetes master host. It will initialize the master, and install a pod network.
21
22import pwd
23import grp
24import os
25import re
26import getpass
27import subprocess
28from cloudify import ctx
29from cloudify.exceptions import OperationRetry
30from cloudify_rest_client.exceptions import CloudifyClientError
31
32JOIN_COMMAND_REGEX = '^kubeadm join[\sA-Za-z0-9\.\:\-\_]*'
33BOOTSTRAP_TOKEN_REGEX = '[a-z0-9]{6}.[a-z0-9]{16}'
34IP_PORT_REGEX = '[0-9]+(?:\.[0-9]+){3}:[0-9]+'
35NOT_SHA_REGEX='^(?!.*sha256)'
36JCRE_COMPILED = re.compile(JOIN_COMMAND_REGEX)
37BTRE_COMPILED = re.compile(BOOTSTRAP_TOKEN_REGEX)
38IPRE_COMPILED = re.compile(IP_PORT_REGEX)
39SHA_COMPILED=re.compile(NOT_SHA_REGEX)
40
41def execute_command(_command):
42
43 ctx.logger.debug('_command {0}.'.format(_command))
44
45 subprocess_args = {
46 'args': _command.split(),
47 'stdout': subprocess.PIPE,
48 'stderr': subprocess.PIPE
49 }
50
51 ctx.logger.debug('subprocess_args {0}.'.format(subprocess_args))
52
53 process = subprocess.Popen(**subprocess_args)
54 output, error = process.communicate()
55
56 ctx.logger.debug('command: {0} '.format(_command))
57 ctx.logger.debug('output: {0} '.format(output))
58 ctx.logger.debug('error: {0} '.format(error))
59 ctx.logger.debug('process.returncode: {0} '.format(process.returncode))
60
61 if process.returncode:
62 ctx.logger.error('Running `{0}` returns error.'.format(_command))
63 return False
64
65 return output
66
67
68def cleanup_and_retry():
69 reset_cluster_command = 'sudo kubeadm reset'
70 output = execute_command(reset_cluster_command)
71 ctx.logger.info('reset_cluster_command {1}'.format(reset_cluster_command, output))
72 raise OperationRetry('Restarting kubernetes because of a problem.')
73
74
75def configure_admin_conf():
76 # Add the kubeadmin config to environment
77 agent_user = getpass.getuser()
78 uid = pwd.getpwnam(agent_user).pw_uid
79 gid = grp.getgrnam('docker').gr_gid
80 admin_file_dest = os.path.join(os.path.expanduser('~'), 'admin.conf')
81
82 execute_command('sudo cp {0} {1}'.format('/etc/kubernetes/admin.conf', admin_file_dest))
83 execute_command('sudo chown {0}:{1} {2}'.format(uid, gid, admin_file_dest))
84
85 with open(os.path.join(os.path.expanduser('~'), '.bashrc'), 'a') as outfile:
86 outfile.write('export KUBECONFIG=$HOME/admin.conf')
87 os.environ['KUBECONFIG'] = admin_file_dest
88
89
90def setup_secrets(_split_master_port, _bootstrap_token):
91 master_ip = split_master_port[0]
92 master_port = split_master_port[1]
93 ctx.instance.runtime_properties['master_ip'] = _split_master_port[0]
94 ctx.instance.runtime_properties['master_port'] = _split_master_port[1]
95 ctx.instance.runtime_properties['bootstrap_token'] = _bootstrap_token
96 from cloudify import manager
97 cfy_client = manager.get_rest_client()
98
99 _secret_key = 'kubernetes_master_ip'
100 if cfy_client and not len(cfy_client.secrets.list(key=_secret_key)) == 1:
101 cfy_client.secrets.create(key=_secret_key, value=master_ip)
102 else:
103 cfy_client.secrets.update(key=_secret_key, value=master_ip)
104 ctx.logger.info('Set secret: {0}.'.format(_secret_key))
105
106 _secret_key = 'kubernetes_master_port'
107 if cfy_client and not len(cfy_client.secrets.list(key=_secret_key)) == 1:
108 cfy_client.secrets.create(key=_secret_key, value=master_port)
109 else:
110 cfy_client.secrets.update(key=_secret_key, value=master_port)
111 ctx.logger.info('Set secret: {0}.'.format(_secret_key))
112
113 _secret_key = 'bootstrap_token'
114 if cfy_client and not len(cfy_client.secrets.list(key=_secret_key)) == 1:
115 cfy_client.secrets.create(key=_secret_key, value=_bootstrap_token)
116 else:
117 cfy_client.secrets.update(key=_secret_key, value=_bootstrap_token)
118 ctx.logger.info('Set secret: {0}.'.format(_secret_key))
119
120
121if __name__ == '__main__':
122
123 ctx.instance.runtime_properties['KUBERNETES_MASTER'] = True
124 cniCommand1=subprocess.Popen(["sudo", "sysctl", 'net.bridge.bridge-nf-call-iptables=1'], stdout=subprocess.PIPE)
125 # Start Kubernetes Master
126 ctx.logger.info('Attempting to start Kubernetes master.')
127 start_master_command = 'sudo kubeadm init'
128 start_output = execute_command(start_master_command)
129 ctx.logger.debug('start_master_command output: {0}'.format(start_output))
130 # Check if start succeeded.
131 if start_output is False or not isinstance(start_output, basestring):
132 ctx.logger.error('Kubernetes master failed to start.')
133 cleanup_and_retry()
134 ctx.logger.info('Kubernetes master started successfully.')
135
136 # Slice and dice the start_master_command start_output.
137 ctx.logger.info('Attempting to retrieve Kubernetes cluster information.')
138 split_start_output = \
139 [line.strip() for line in start_output.split('\n') if line.strip()]
140 del line
141
142 ctx.logger.debug(
143 'Kubernetes master start output, split and stripped: {0}'.format(
144 split_start_output))
145 split_join_command = ''
146 for li in split_start_output:
147 ctx.logger.debug('li in split_start_output: {0}'.format(li))
148 if re.match(JCRE_COMPILED, li):
149 split_join_command = re.split('\s', li)
150 del li
151 ctx.logger.info('split_join_command: {0}'.format(split_join_command))
152
153 if not split_join_command:
154 ctx.logger.error('No join command in split_start_output: {0}'.format(split_join_command))
155 cleanup_and_retry()
156
157 for li in split_join_command:
158 ctx.logger.info('Sorting bits and pieces: li: {0}'.format(li))
159 if (re.match(BTRE_COMPILED, li) and re.match(SHA_COMPILED, li)):
160 bootstrap_token = li
161 elif re.match(IPRE_COMPILED, li):
162 split_master_port = li.split(':')
163 setup_secrets(split_master_port, bootstrap_token)
164 configure_admin_conf()
165
166 weaveCommand1=subprocess.Popen(["kubectl", "version"], stdout=subprocess.PIPE)
167 weaveCommand2=subprocess.Popen(["base64"],stdin=weaveCommand1.stdout, stdout=subprocess.PIPE)
168 kubever = weaveCommand2.communicate()[0]
169 kubever = kubever.replace('\n', '').replace('\r', '')
170 ctx.logger.info("kubever :"+kubever)
171 weaveURL=('https://cloud.weave.works/k8s/net?k8s-version={0}'.format(kubever))
172 ctx.logger.info("weaveURL:" + weaveURL)
173 weaveCommand4=subprocess.Popen(["kubectl","apply","-f",weaveURL],stdout=subprocess.PIPE)
174 weaveResult= weaveCommand4.communicate()[0]
175 ctx.logger.info("weaveResult :"+weaveResult)