create K8S cluster by TOSCA
[oom.git] / TOSCA / kubernetes-cluster-TOSCA / scripts / kubernetes_master / configure.py
1 #!/usr/bin/env python
2
3 # ============LICENSE_START==========================================
4 # ===================================================================
5 # Copyright © 2017 AT&T
6 #
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
22 import pwd
23 import grp
24 import os
25 import re
26 import getpass
27 import subprocess
28 from cloudify import ctx
29 from cloudify.exceptions import OperationRetry
30 from cloudify_rest_client.exceptions import CloudifyClientError
31
32 JOIN_COMMAND_REGEX = '^kubeadm join[\sA-Za-z0-9\.\:\-\_]*'
33 BOOTSTRAP_TOKEN_REGEX = '[a-z0-9]{6}.[a-z0-9]{16}'
34 IP_PORT_REGEX = '[0-9]+(?:\.[0-9]+){3}:[0-9]+'
35 NOT_SHA_REGEX='^(?!.*sha256)'
36 JCRE_COMPILED = re.compile(JOIN_COMMAND_REGEX)
37 BTRE_COMPILED = re.compile(BOOTSTRAP_TOKEN_REGEX)
38 IPRE_COMPILED = re.compile(IP_PORT_REGEX)
39 SHA_COMPILED=re.compile(NOT_SHA_REGEX)
40
41 def 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
68 def 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
75 def 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
90 def 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
121 if __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)