blob: 84e4827aa919bedb83444abba45b59bed9e57a9a [file] [log] [blame]
Dennis Dmitriev010f4cd2016-11-01 20:43:51 +02001# Copyright 2016 Mirantis, Inc.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14
Dmitry Tyzhnenkob8641832017-11-07 17:02:47 +020015import netaddr
Dennis Dmitrievad5f8582019-04-12 13:15:08 +030016import pkg_resources
Dmitry Tyzhnenkob8641832017-11-07 17:02:47 +020017
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +030018from collections import defaultdict
19
20from datetime import datetime
Dennis Dmitrievb8115f52017-12-15 13:09:56 +020021from pepper import libpepper
22from tcp_tests.helpers import utils
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +030023from tcp_tests import logger
Dmitry Tyzhnenko35413c02018-03-05 14:12:37 +020024from tcp_tests import settings
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +030025from tcp_tests.managers.execute_commands import ExecuteCommandsMixin
26
27LOG = logger.logger
28
29
30class SaltManager(ExecuteCommandsMixin):
Dennis Dmitriev010f4cd2016-11-01 20:43:51 +020031 """docstring for SaltManager"""
32
Dmitry Tyzhnenkobc0f8262017-04-28 15:39:26 +030033 __config = None
34 __underlay = None
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +030035 _map = {
36 'enforceState': 'enforce_state',
37 'enforceStates': 'enforce_states',
38 'runState': 'run_state',
39 'runStates': 'run_states',
40 }
Dennis Dmitriev010f4cd2016-11-01 20:43:51 +020041
Dmitry Tyzhnenko5a5d8da2017-12-14 14:14:42 +020042 def __init__(self, config, underlay, host=None, port='6969',
43 username=None, password=None):
Dmitry Tyzhnenkobc0f8262017-04-28 15:39:26 +030044 self.__config = config
45 self.__underlay = underlay
Dennis Dmitriev2d60c8e2017-05-12 18:34:01 +030046 self.__port = port
47 self.__host = host
48 self.__api = None
Dmitry Tyzhnenko5a5d8da2017-12-14 14:14:42 +020049 self.__user = username or settings.SALT_USER
50 self.__password = password or settings.SALT_PASSWORD
Dennis Dmitrieveac3aab2017-07-12 16:36:41 +030051 self._salt = self
Dennis Dmitriev010f4cd2016-11-01 20:43:51 +020052
Dmitry Tyzhnenkobc0f8262017-04-28 15:39:26 +030053 super(SaltManager, self).__init__(config=config, underlay=underlay)
Dennis Dmitriev010f4cd2016-11-01 20:43:51 +020054
55 def install(self, commands):
Dina Belovae6fdffb2017-09-19 13:58:34 -070056 # if self.__config.salt.salt_master_host == '0.0.0.0':
Dennis Dmitriev2d60c8e2017-05-12 18:34:01 +030057 # # Temporary workaround. Underlay should be extended with roles
58 # salt_nodes = self.__underlay.node_names()
59 # self.__config.salt.salt_master_host = \
60 # self.__underlay.host_by_node_name(salt_nodes[0])
Dennis Dmitriev010f4cd2016-11-01 20:43:51 +020061
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +030062 self.execute_commands(commands=commands,
63 label="Install and configure salt")
Dennis Dmitrievad5f8582019-04-12 13:15:08 +030064 self.create_env_salt()
65 self.create_env_jenkins_day01()
Oleksii Butenko3b3bab12019-05-23 17:30:15 +030066 # self.create_env_jenkins_cicd()
67 # self.create_env_k8s()
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +030068
Dmitry Tyzhnenko5a5d8da2017-12-14 14:14:42 +020069 def change_creds(self, username, password):
70 self.__user = username
71 self.__password = password
72
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +030073 @property
74 def port(self):
Dennis Dmitriev2d60c8e2017-05-12 18:34:01 +030075 return self.__port
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +030076
77 @property
78 def host(self):
Dennis Dmitriev2d60c8e2017-05-12 18:34:01 +030079 if self.__host:
80 return self.__host
81 else:
Dina Belovae6fdffb2017-09-19 13:58:34 -070082 # TODO(ddmitriev): consider to add a check and raise
Dennis Dmitriev2d60c8e2017-05-12 18:34:01 +030083 # exception if 'salt_master_host' is not initialized.
84 return self.__config.salt.salt_master_host
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +030085
86 @property
87 def api(self):
88 def login():
89 LOG.info("Authentication in Salt API")
Dennis Dmitriev2d60c8e2017-05-12 18:34:01 +030090 self.__api.login(
91 username=self.__user,
92 password=self.__password,
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +030093 eauth='pam')
94 return datetime.now()
95
Dennis Dmitriev2d60c8e2017-05-12 18:34:01 +030096 if self.__api:
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +030097 if (datetime.now() - self.__session_start).seconds < 5 * 60:
Dennis Dmitriev2d60c8e2017-05-12 18:34:01 +030098 return self.__api
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +030099 else:
100 # FIXXME: Change to debug
101 LOG.info("Session's expired")
102 self.__session_start = login()
Dennis Dmitriev2d60c8e2017-05-12 18:34:01 +0300103 return self.__api
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +0300104
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +0300105 url = "http://{host}:{port}".format(
106 host=self.host, port=self.port)
Dennis Dmitriev2d60c8e2017-05-12 18:34:01 +0300107 LOG.info("Connecting to Salt API {0}".format(url))
Dennis Dmitrievb8115f52017-12-15 13:09:56 +0200108 self.__api = libpepper.Pepper(url)
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +0300109 self.__session_start = login()
Dennis Dmitriev2d60c8e2017-05-12 18:34:01 +0300110 return self.__api
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +0300111
Dennis Dmitrievb6bcc5c2018-09-26 11:07:53 +0000112 def local(self, tgt, fun, args=None, kwargs=None, timeout=None):
113 return self.api.local(tgt, fun, args, kwargs, timeout=timeout,
114 expr_form='compound')
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +0300115
Dennis Dmitrievb6bcc5c2018-09-26 11:07:53 +0000116 def local_async(self, tgt, fun, args=None, kwargs=None, timeout=None):
117 return self.api.local_async(tgt, fun, args, kwargs, timeout=timeout)
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +0300118
119 def lookup_result(self, jid):
120 return self.api.lookup_jid(jid)
121
122 def check_result(self, r):
123 if len(r.get('return', [])) == 0:
124 raise LookupError("Result is empty or absent")
125
126 result = r['return'][0]
Dmitry Tyzhnenkobc0f8262017-04-28 15:39:26 +0300127 if len(result) == 0:
128 raise LookupError("Result is empty or absent")
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +0300129 LOG.info("Job has result for %s nodes", result.keys())
130 fails = defaultdict(list)
131 for h in result:
132 host_result = result[h]
133 LOG.info("On %s executed:", h)
134 if isinstance(host_result, list):
135 fails[h].append(host_result)
136 continue
137 for t in host_result:
138 task = host_result[t]
139 if task['result'] is False:
140 fails[h].append(task)
141 LOG.error("%s - %s", t, task['result'])
142 else:
143 LOG.info("%s - %s", t, task['result'])
144
145 return fails if fails else None
146
Dennis Dmitrievb6bcc5c2018-09-26 11:07:53 +0000147 def enforce_state(self, tgt, state, args=None, kwargs=None, timeout=None):
148 r = self.local(tgt=tgt, fun='state.sls', args=state, timeout=timeout)
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +0300149 f = self.check_result(r)
150 return r, f
151
Dennis Dmitrievb6bcc5c2018-09-26 11:07:53 +0000152 def enforce_states(self, tgt, state, args=None, kwargs=None, timeout=None):
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +0300153 rets = []
154 for s in state:
Dennis Dmitrievb6bcc5c2018-09-26 11:07:53 +0000155 r = self.enforce_state(tgt=tgt, state=s, timeout=timeout)
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +0300156 rets.append(r)
157 return rets
158
Dennis Dmitrievb6bcc5c2018-09-26 11:07:53 +0000159 def run_state(self, tgt, state, args=None, kwargs=None, timeout=None):
160 return self.local(tgt=tgt, fun=state, args=args, kwargs=kwargs,
161 timeout=timeout), None
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +0300162
Dennis Dmitrievb6bcc5c2018-09-26 11:07:53 +0000163 def run_states(self, tgt, state, args=None, kwargs=None, timeout=None):
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +0300164 rets = []
165 for s in state:
Dennis Dmitrievb6bcc5c2018-09-26 11:07:53 +0000166 r = self.run_state(tgt=tgt, state=s, args=args, kwargs=kwargs,
167 timeout=timeout)
Dmitry Tyzhnenko2b730a02017-04-07 19:31:32 +0300168 rets.append(r)
169 return rets
Artem Panchenko0594cd72017-06-12 13:25:26 +0300170
171 def get_pillar(self, tgt, pillar):
172 result = self.local(tgt=tgt, fun='pillar.get', args=pillar)
173 return result['return']
Dmitry Tyzhnenkob8641832017-11-07 17:02:47 +0200174
Dennis Dmitriev2a498732018-12-21 18:30:23 +0200175 def get_single_pillar(self, tgt, pillar):
176 """Get a scalar value from a single node
177
178 :return: pillar value
179 """
180
181 result = self.get_pillar(tgt, pillar)
182 nodes = result[0].keys()
183
184 if not nodes:
185 raise LookupError("No minions selected "
186 "for the target '{0}'".format(tgt))
187 if len(nodes) > 1:
188 raise LookupError("Too many minions selected "
189 "for the target '{0}' , expected one: {1}"
190 .format(tgt, nodes))
191 return result[0][nodes[0]]
192
Dennis Dmitriev2d643bc2017-12-04 12:23:47 +0200193 def get_grains(self, tgt, grains):
194 result = self.local(tgt=tgt, fun='grains.get', args=grains)
195 return result['return']
196
Dmitry Tyzhnenkob8641832017-11-07 17:02:47 +0200197 def get_ssh_data(self):
198 """Generate ssh config for Underlay
199
200 :param roles: list of strings
201 """
202
203 pool_name = self.__config.underlay.net_mgmt
204 pool_net = netaddr.IPNetwork(self.__config.underlay.address_pools[
205 self.__config.underlay.net_mgmt])
206 hosts = self.local('*', 'grains.item', ['host', 'ipv4'])
207
208 if len(hosts.get('return', [])) == 0:
209 raise LookupError("Hosts is empty or absent")
210 hosts = hosts['return'][0]
211 if len(hosts) == 0:
212 raise LookupError("Hosts is empty or absent")
213
Dennis Dmitriev83cc1d52018-11-09 15:35:30 +0200214 def host(minion_id, ip):
Dmitry Tyzhnenkob8641832017-11-07 17:02:47 +0200215 return {
216 'roles': ['salt_minion'],
217 'keys': [
218 k['private'] for k in self.__config.underlay.ssh_keys
219 ],
Dennis Dmitriev83cc1d52018-11-09 15:35:30 +0200220 'node_name': minion_id,
221 'minion_id': minion_id,
Dmitry Tyzhnenkob8641832017-11-07 17:02:47 +0200222 'host': ip,
223 'address_pool': pool_name,
224 'login': settings.SSH_NODE_CREDENTIALS['login'],
225 'password': settings.SSH_NODE_CREDENTIALS['password']
226 }
227
Dmitry Tyzhnenkob610afd2018-02-19 15:43:45 +0200228 try:
229 ret = [
230 host(k, next(i for i in v['ipv4'] if i in pool_net))
231 for k, v in hosts.items()
232 if next(i for i in v['ipv4'] if i in pool_net)]
233 LOG.debug("Fetched ssh data from salt grains - {}".format(ret))
234 return ret
235 except StopIteration:
236 msg = ("Can't match nodes ip address with network cidr\n"
237 "Managment network - {net}\n"
238 "Host with address - {host_list}".format(
239 net=pool_net,
240 host_list={k: v['ipv4'] for k, v in hosts.items()}))
241 raise StopIteration(msg)
Dennis Dmitriev2d643bc2017-12-04 12:23:47 +0200242
Dennis Dmitriev83cc1d52018-11-09 15:35:30 +0200243 def update_ssh_data_from_minions(self):
244 """Combine existing underlay.ssh with VCP salt minions"""
245 salt_nodes = self.get_ssh_data()
246
247 for salt_node in salt_nodes:
248 nodes = [n for n in self.__config.underlay.ssh
249 if salt_node['host'] == n['host']
250 and salt_node['address_pool'] == n['address_pool']]
251 if nodes:
252 # Assume that there can be only one node with such IP address
253 # Just update minion_id for this node
254 nodes[0]['minion_id'] = salt_node['minion_id']
255 else:
256 # New node, add to config.underlay.ssh
257 self.__config.underlay.ssh.append(salt_node)
258
259 self.__underlay.config_ssh = []
260 self.__underlay.add_config_ssh(self.__config.underlay.ssh)
261
Dennis Dmitriev2d643bc2017-12-04 12:23:47 +0200262 def service_status(self, tgt, service):
263 result = self.local(tgt=tgt, fun='service.status', args=service)
264 return result['return']
265
266 def service_restart(self, tgt, service):
267 result = self.local(tgt=tgt, fun='service.restart', args=service)
268 return result['return']
269
270 def service_stop(self, tgt, service):
271 result = self.local(tgt=tgt, fun='service.stop', args=service)
272 return result['return']
Dennis Dmitrievb8115f52017-12-15 13:09:56 +0200273
Victor Ryzhenkin95046882018-12-29 19:18:40 +0400274 def cmd_run(self, tgt, cmd):
275 result = self.local(tgt=tgt, fun='cmd.run', args=cmd)
276 return result['return']
277
Dennis Dmitrievfa1774a2019-05-28 15:27:44 +0300278 @utils.retry(10, exception=libpepper.PepperException)
Dennis Dmitriev427e4152019-05-08 15:12:43 +0300279 def sync_time(self, tgt='*'):
Dennis Dmitrievb8115f52017-12-15 13:09:56 +0200280 LOG.info("NTP time sync on the salt minions '{0}'".format(tgt))
281 # Force authentication update on the next API access
282 # because previous authentication most probably is not valid
283 # before or after time sync.
284 self.__api = None
Dmitry Tyzhnenko80ce0202019-02-07 13:27:19 +0200285 if not settings.SKIP_SYNC_TIME:
Andrew Baraniuk5da5c582019-06-20 12:12:45 +0300286 cmd = ('chmod -x /usr/sbin/ntpd'
287 'service ntp stop;'
Dennis Dmitrievfa1774a2019-05-28 15:27:44 +0300288 # note: maas-rackd will return 'pool' after start
Andrew Baraniukab06b7a2019-06-18 13:53:00 +0300289 'sed -i \'s/^pool ntp.ubuntu.com/server ntp.cesnet.cz/g\' '
290 '/etc/ntp/maas.conf;'
Andrew Baraniuk5da5c582019-06-20 12:12:45 +0300291 'sed -i \'s/^pool ntp.ubuntu.com/server ntp.cesnet.cz/g\' '
292 '/etc/ntp.conf;'
Dennis Dmitriev427e4152019-05-08 15:12:43 +0300293 'if [ -x /usr/sbin/ntpdate ]; then'
Andrew Baraniuk5da5c582019-06-20 12:12:45 +0300294 ' ntpdate -s ntp.cesnet.cz;'
Dennis Dmitriev427e4152019-05-08 15:12:43 +0300295 'else'
296 ' ntpd -gq;'
297 'fi;'
Andrew Baraniuk5da5c582019-06-20 12:12:45 +0300298 'chmod +x /usr/sbin/ntpd'
Dennis Dmitriev427e4152019-05-08 15:12:43 +0300299 'service ntp start;'
Andrew Baraniuk5da5c582019-06-20 12:12:45 +0300300 'sleep 3; ntpq -pn;')
Dmitry Tyzhnenko80ce0202019-02-07 13:27:19 +0200301 self.run_state(
302 tgt,
Dennis Dmitrievfa1774a2019-05-28 15:27:44 +0300303 'cmd.run', cmd, timeout=360) # noqa
Dennis Dmitrievb8115f52017-12-15 13:09:56 +0200304 new_time_res = self.run_state(tgt, 'cmd.run', 'date')
305 for node_name, time in sorted(new_time_res[0]['return'][0].items()):
306 LOG.info("{0}: {1}".format(node_name, time))
307 self.__api = None
Dennis Dmitrievad5f8582019-04-12 13:15:08 +0300308
309 def create_env_salt(self):
310 """Creates static utils/env_salt file"""
311
312 env_salt_filename = pkg_resources.resource_filename(
313 settings.__name__, 'utils/env_salt')
314 with open(env_salt_filename, 'w') as f:
315 f.write(
316 'export SALT_MASTER_IP={host}\n'
317 'export SALTAPI_URL=http://{host}:{port}/\n'
318 'export SALTAPI_USER="{user}"\n'
319 'export SALTAPI_PASS="{password}"\n'
320 'export SALTAPI_EAUTH="pam"\n'
321 'echo "export SALT_MASTER_IP=${{SALT_MASTER_IP}}"\n'
322 'echo "export SALTAPI_URL=${{SALTAPI_URL}}"\n'
323 'echo "export SALTAPI_USER=${{SALTAPI_USER}}"\n'
324 'echo "export SALTAPI_PASS=${{SALTAPI_PASS}}"\n'
325 'echo "export SALTAPI_EAUTH=${{SALTAPI_EAUTH}}"\n'
326 .format(host=self.host, port=self.port,
327 user=self.__user, password=self.__password)
328 )
329
330 def create_env_jenkins_day01(self):
331 """Creates static utils/env_jenkins_day01 file"""
332
333 env_jenkins_day01_filename = pkg_resources.resource_filename(
334 settings.__name__, 'utils/env_jenkins_day01')
335
336 tgt = 'I@docker:client:stack:jenkins and cfg01*'
337 jenkins_params = self.get_single_pillar(
338 tgt=tgt, pillar="jenkins:client:master")
obutenkoca858402019-07-04 18:31:39 +0300339 jenkins_host = jenkins_params.get('host')
340 jenkins_port = jenkins_params.get('port')
341 jenkins_protocol = jenkins_params.get('proto', 'http')
342 jenkins_user = jenkins_params.get('username', 'admin')
343 jenkins_pass = jenkins_params.get('password')
344
345 if not all([jenkins_host,
346 jenkins_port,
347 jenkins_protocol,
348 jenkins_user,
349 jenkins_pass]):
350 raise LookupError(
351 "Some of the required parameters for Jenkins not set in the "
352 "pillar jenkins:client:master on {0}: {1}"
353 .format(tgt, jenkins_params))
Dennis Dmitrievad5f8582019-04-12 13:15:08 +0300354
355 with open(env_jenkins_day01_filename, 'w') as f:
356 f.write(
obutenkoca858402019-07-04 18:31:39 +0300357 'export JENKINS_URL={protocol}://{host}:{port}\n'
Dennis Dmitrievad5f8582019-04-12 13:15:08 +0300358 'export JENKINS_USER={user}\n'
359 'export JENKINS_PASS={password}\n'
360 'export JENKINS_START_TIMEOUT=60\n'
361 'export JENKINS_BUILD_TIMEOUT=1800\n'
362 'echo "export JENKINS_URL=${{JENKINS_URL}}'
363 ' # Jenkins API URL"\n'
364 'echo "export JENKINS_USER=${{JENKINS_USER}}'
365 ' # Jenkins API username"\n'
366 'echo "export JENKINS_PASS=${{JENKINS_PASS}}'
367 ' # Jenkins API password or token"n\n'
368 'echo "export JENKINS_START_TIMEOUT=${{JENKINS_START_TIMEOUT}}'
369 ' # Timeout waiting for job in queue to start building"\n'
370 'echo "export JENKINS_BUILD_TIMEOUT=${{JENKINS_BUILD_TIMEOUT}}'
371 ' # Timeout waiting for building job to complete"\n'
obutenkoca858402019-07-04 18:31:39 +0300372 .format(host=jenkins_host, port=jenkins_port,
373 protocol=jenkins_protocol, user=jenkins_user,
374 password=jenkins_pass)
Dennis Dmitrievad5f8582019-04-12 13:15:08 +0300375 )
376
Hanna Arhipova71ecc272019-08-20 14:54:22 +0300377 def get_cluster_jenkins_creds(self):
378 """
379 Requests cluster Jenkins's login parameters from pillars
380 :return: dict {'url': jenkins_url,
381 'user': jenkins_user,
382 'pass': jenkins_pass}
383 """
384 tgt = 'I@docker:client:stack:jenkins and cid01*'
385 jenkins_host = self.get_single_pillar(
386 tgt=tgt, pillar="jenkins:client:master:host")
387 jenkins_port = self.get_single_pillar(
388 tgt=tgt, pillar="jenkins:client:master:port")
389 jenkins_protocol = self.get_single_pillar(
390 tgt=tgt, pillar="jenkins:client:master:proto")
391 jenkins_url = '{0}://{1}:{2}'.format(jenkins_protocol,
392 jenkins_host,
393 jenkins_port)
394 jenkins_user = self.get_single_pillar(
395 tgt=tgt, pillar="jenkins:client:master:username")
396 jenkins_pass = self.get_single_pillar(
397 tgt=tgt, pillar="jenkins:client:master:password")
398 return {'url': jenkins_url, 'user': jenkins_user, 'pass': jenkins_pass}
399
Dennis Dmitrievad5f8582019-04-12 13:15:08 +0300400 def create_env_jenkins_cicd(self):
401 """Creates static utils/env_jenkins_cicd file"""
402
403 env_jenkins_cicd_filename = pkg_resources.resource_filename(
404 settings.__name__, 'utils/env_jenkins_cicd')
Oleksii Butenko3b3bab12019-05-23 17:30:15 +0300405
406 tgt = 'I@docker:client:stack:jenkins and cid01*'
407 try:
408 jenkins_params = self.get_single_pillar(
409 tgt=tgt, pillar="jenkins:client:master")
410 except LookupError as e:
411 LOG.error("Skipping creation {0} because cannot get Jenkins CICD "
412 "parameters from '{1}': {2}"
413 .format(env_jenkins_cicd_filename, tgt, e.message))
Dennis Dmitrievad5f8582019-04-12 13:15:08 +0300414 return
Oleksii Butenko3b3bab12019-05-23 17:30:15 +0300415
obutenkoca858402019-07-04 18:31:39 +0300416 jenkins_host = jenkins_params.get('host')
417 jenkins_port = jenkins_params.get('port')
418 jenkins_protocol = jenkins_params.get('proto', 'http')
419 jenkins_user = jenkins_params.get('username', 'admin')
420 jenkins_pass = jenkins_params.get('password')
421
422 if not all([jenkins_host,
423 jenkins_port,
424 jenkins_protocol,
425 jenkins_user,
426 jenkins_pass]):
427 raise LookupError(
428 "Some of the required parameters for Jenkins not set in the "
429 "pillar jenkins:client:master on {0}: {1}"
430 .format(tgt, jenkins_params))
Dennis Dmitrievad5f8582019-04-12 13:15:08 +0300431
432 with open(env_jenkins_cicd_filename, 'w') as f:
433 f.write(
obutenkoca858402019-07-04 18:31:39 +0300434 'export JENKINS_URL={protocol}://{host}:{port}\n'
Dennis Dmitrievad5f8582019-04-12 13:15:08 +0300435 'export JENKINS_USER={user}\n'
436 'export JENKINS_PASS={password}\n'
437 'export JENKINS_START_TIMEOUT=60\n'
438 'export JENKINS_BUILD_TIMEOUT=1800\n'
439 'echo "export JENKINS_URL=${{JENKINS_URL}}'
440 ' # Jenkins API URL"\n'
441 'echo "export JENKINS_USER=${{JENKINS_USER}}'
442 ' # Jenkins API username"\n'
443 'echo "export JENKINS_PASS=${{JENKINS_PASS}}'
444 ' # Jenkins API password or token"n\n'
445 'echo "export JENKINS_START_TIMEOUT=${{JENKINS_START_TIMEOUT}}'
446 ' # Timeout waiting for job in queue to start building"\n'
447 'echo "export JENKINS_BUILD_TIMEOUT=${{JENKINS_BUILD_TIMEOUT}}'
448 ' # Timeout waiting for building job to complete"\n'
449 .format(host=jenkins_host, port=jenkins_port,
obutenkoca858402019-07-04 18:31:39 +0300450 protocol=jenkins_protocol, user=jenkins_user,
451 password=jenkins_pass)
Dennis Dmitrievad5f8582019-04-12 13:15:08 +0300452 )
453
Hanna Arhipova71ecc272019-08-20 14:54:22 +0300454 def add_cluster_reclass(self, key, value, path):
455 # TODO : add reclass tools as a library to tcp-qa
456 self.cmd_run('I@salt:master',
457 "reclass-tools add-key {key} {value} {path}")
458
Dennis Dmitrievad5f8582019-04-12 13:15:08 +0300459 def create_env_k8s(self):
460 """Creates static utils/env_k8s file"""
461
462 env_k8s_filename = pkg_resources.resource_filename(
463 settings.__name__, 'utils/env_k8s')
Oleksii Butenko3b3bab12019-05-23 17:30:15 +0300464
465 tgt = 'I@haproxy:proxy:enabled:true and I@kubernetes:master and *01*'
466 try:
467 haproxy_params = self.get_single_pillar(
468 tgt=tgt, pillar="haproxy:proxy:listen:k8s_secure:binds")[0]
469 k8s_params = self.get_single_pillar(
470 tgt=tgt, pillar="kubernetes:master:admin")
471 except LookupError as e:
472 LOG.error("Skipping creation {0} because cannot get Kubernetes "
473 "parameters from '{1}': {2}"
474 .format(env_k8s_filename, tgt, e.message))
Dennis Dmitrievad5f8582019-04-12 13:15:08 +0300475 return
Oleksii Butenko3b3bab12019-05-23 17:30:15 +0300476
Dennis Dmitrievad5f8582019-04-12 13:15:08 +0300477 kube_host = haproxy_params['address']
478 kube_apiserver_port = haproxy_params['port']
479 kubernetes_admin_user = k8s_params['username']
480 kubernetes_admin_password = k8s_params['password']
481
482 with open(env_k8s_filename, 'w') as f:
483 f.write(
484 'export kube_host={host}\n'
485 'export kube_apiserver_port={port}\n'
486 'export kubernetes_admin_user={user}\n'
487 'export kubernetes_admin_password={password}\n'
488 'echo "export kube_host=${{kube_host}}'
489 ' # Kube API host"\n'
490 'echo "export kube_apiserver_port=${{kube_apiserver_port}}'
491 ' # Kube API port"\n'
492 'echo "export kubernetes_admin_user=${{kubernetes_admin_user}}'
493 ' # Kube API username"\n'
494 'echo "export kubernetes_admin_password='
495 '${{kubernetes_admin_password}} # Kube API password"n\n'
496 .format(host=kube_host, port=kube_apiserver_port,
497 user=kubernetes_admin_user,
498 password=kubernetes_admin_password)
499 )