blob: 0b539c9ba4ba40034a0266e88b68d711bd9f16d1 [file] [log] [blame]
Anton Samoylov28ad4fa2018-10-02 14:45:41 +04001#!/usr/bin/python
2# Copyright 2018 Mirantis, Inc.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
Anton Samoylov7a8d83c2018-10-11 12:33:36 +040015import logging
Anton Samoylov28ad4fa2018-10-02 14:45:41 +040016import os
17import subprocess
Svimbaec6e7a72019-01-10 15:53:56 +010018import time
19
20# Import Salt Libs
21import salt.utils.http
Anton Samoylov28ad4fa2018-10-02 14:45:41 +040022
23
Anton Samoylov7a8d83c2018-10-11 12:33:36 +040024MODULE_NAME = 'contrail_health'
25LOG = logging.getLogger(__name__)
26
27
Anton Samoylov28ad4fa2018-10-02 14:45:41 +040028def __virtual__():
29 '''
30 Only load this module if contrail-status or doctrail utility
31 (in case of containerized contrail version) is available.
32 '''
33 if _is_cmd_available('contrail-status') or _is_cmd_available('doctrail'):
Anton Samoylov7a8d83c2018-10-11 12:33:36 +040034 return MODULE_NAME
Anton Samoylov28ad4fa2018-10-02 14:45:41 +040035 return False
36
37
38def _is_cmd_available(cmd_name):
39 try:
40 with open(os.devnull) as devnull:
41 subprocess.Popen(
42 [cmd_name], stdout=devnull, stderr=devnull
43 ).communicate()
44 except OSError as e:
45 if e.errno == os.errno.ENOENT:
46 return False
47 return True
48
49
50def get_services_status():
Anton Samoylov7a8d83c2018-10-11 12:33:36 +040051 cs_out = None
Anton Samoylov28ad4fa2018-10-02 14:45:41 +040052
53 if _is_cmd_available('contrail-status'):
Anton Samoylov7a8d83c2018-10-11 12:33:36 +040054 LOG.info('Trying to get status of contrail services '
55 'using contrail-status utility on host ...')
56 try:
57 cs_out = str(subprocess.check_output(['contrail-status']))
58 except subprocess.CalledProcessError as e:
59 LOG.warn('Status of contrail services cannot be checked '
60 'by contrail-status utility from host')
61 if cs_out is None and _is_cmd_available('doctrail'):
62 LOG.info('Trying to get status of contrail services inside containers '
63 'using doctrail utility ...')
64 try:
65 cs_out = str(subprocess.check_output(
66 ['doctrail', 'all', 'contrail-status'])
67 )
68 except subprocess.CalledProcessError as e:
69 LOG.warn('Status of contrail services inside containers cannot '
70 'be checked by contrail-status utility via doctrail cmd')
Anton Samoylov28ad4fa2018-10-02 14:45:41 +040071
Anton Samoylov28ad4fa2018-10-02 14:45:41 +040072 status_map = {}
73
Anton Samoylov7a8d83c2018-10-11 12:33:36 +040074 if cs_out:
75 for line in cs_out.split('\n'):
76 line_list = line.split()
77 if (not line.startswith("==") and "FOR NODE" not in line and
78 len(line_list) >= 2):
79 status_map[line_list[0].split(":")[0]] = line_list[1]
80 else:
81 LOG.error('Status of contrail services cannot be checked '
82 'by {0} module.'.format(MODULE_NAME))
Anton Samoylov28ad4fa2018-10-02 14:45:41 +040083
84 return status_map
Svimbaec6e7a72019-01-10 15:53:56 +010085
86'''
87 Check status of Contail API service on Virtual IP which is defined by pillars.
88
89 CLI Example:
90
91 .. code-block:: bash
92
93 salt 'ntw01*' contrail_health.get_api_status [wait_for=300] \\
94 [tries=20]
95
96 wait_for
97 Number of seconds how long to wait for API response.
98
99 tries
100 Number of tries. After each unsuccessful try will sleep for \\
101 (wait_for/tries).
102'''
103
104
105def get_api_status(wait_for=180, tries=20):
106 api_host = __pillar__['opencontrail'].get('client', {}).get('api', {}).get('host', {})
107 api_port = __pillar__['opencontrail']['client']['api']['port']
108 for t in range(0, tries):
109 try:
110 data = salt.utils.http.query("http://{0}:{1}".format(api_host, api_port), status=True)
111 except:
112 time.sleep(int(wait_for / tries))
113 continue
114 if data['status'] == 200:
115 return True
116
117 return False