Skip to content

Commit 5b822c9

Browse files
committed
added an missing script for external check
1 parent 9a1bf19 commit 5b822c9

2 files changed

Lines changed: 548 additions & 0 deletions

File tree

Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
#!/usr/bin/python3
2+
# -*- coding: utf-8 -*-
3+
4+
import os
5+
import json
6+
import requests
7+
import argparse
8+
import time
9+
import subprocess
10+
import tempfile
11+
import sys
12+
import urllib3
13+
import logging
14+
import logging.handlers
15+
#urllib3.disable_warnings()
16+
#urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
17+
from requests.packages.urllib3.exceptions import InsecureRequestWarning
18+
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
19+
20+
21+
22+
23+
24+
LOG_FILENAME = "/tmp/huawei_state.log"
25+
HUAWEI_NAME = sys.argv[5][15:]
26+
huawei_Logger = logging.getLogger("huawei_logger")
27+
huawei_Logger.setLevel(logging.INFO)
28+
29+
huawei_Handler = logging.handlers.RotatingFileHandler(LOG_FILENAME, maxBytes=(1024**2)*5, backupCount=5)
30+
huawei_Formatter = logging.Formatter("{0} - %(asctime)s - %(name)s - %(levelname)s - %(message)s".format(HUAWEI_NAME), datefmt = '%Y-%m-%d %H:%M:%S')
31+
32+
huawei_Handler.setFormatter(huawei_Formatter)
33+
huawei_Logger.addHandler(huawei_Handler)
34+
35+
36+
37+
38+
39+
def api_connect(api_user, api_password, api_ip, api_port):
40+
api_url = "https://{0}:{1}/deviceManager/rest/xxxxx/sessions".format(api_ip, api_port)
41+
api_data = json.dumps({'scope': '0', 'username': api_user, 'password': api_password})
42+
headers = {'Connection': 'keep-alive', 'Content-Type': 'application/json', 'Accept': 'application/json'}
43+
44+
try:
45+
api_connect = requests.post(api_url, verify=False, data = api_data, headers = headers, timeout=3)
46+
api_connect_info = (json.loads(api_connect.content.decode('utf8')),api_connect.cookies) #Decode нужен потому что объект имеет тип bytes
47+
except requests.exceptions.ConnectTimeout:
48+
huawei_Logger.error("*********************** Connection Timeout Error Occurs***********************\n\n\n")
49+
sys.exit("102")
50+
except Exception as oops:
51+
exc_type, exc_value, exc_traceback = sys.exc_info()
52+
huawei_Logger.error("Exception type - {0}\nException value - {1}\nException traceback - {2}".format(exc_type, exc_value, exc_traceback))
53+
huawei_Logger.error("*********************** Connect to API is failed ***********************\n\n\n")
54+
sys.exit("103")
55+
return api_connect_info
56+
57+
58+
59+
def api_logout(api_ip, api_port, api_cookies, device_id, iBaseToken):
60+
headers = {'Connection': 'keep-alive', 'Content-Type': 'application/json', 'Accept': 'application/json', 'iBaseToken':iBaseToken}
61+
api_url_exit = "https://{0}:{1}/deviceManager/rest/{2}/sessions".format(api_ip, api_port, device_id)
62+
exit = requests.delete(api_url_exit, verify=False, headers = headers, cookies = api_cookies)
63+
64+
convert_exit = json.loads(exit.content.decode('utf8'))
65+
return convert_exit['error']['code']
66+
67+
68+
69+
def convert_to_zabbix_json(data):
70+
output = json.dumps({"data": data}, indent = None, separators = (',',': '))
71+
return output
72+
73+
74+
75+
def send_data_to_zabbix(zabbix_data, storage_name):
76+
sender_command = "/usr/bin/zabbix_sender"
77+
config_path = "/etc/zabbix/zabbix_agentd.conf"
78+
time_of_create_file = int(time.time())
79+
temp_file = "/tmp/{0}_{1}.tmp".format(storage_name, time_of_create_file)
80+
81+
with open(temp_file, "w") as f:
82+
f.write("")
83+
f.write("\n".join(zabbix_data))
84+
85+
send_to_zabbix = subprocess.Popen([sender_command, "-vv", "-c", config_path, "-s", storage_name, "-T", "-i", temp_file], stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
86+
send_to_zabbix.wait()
87+
try:
88+
debug_of_send_to_zabbix = send_to_zabbix.communicate(timeout=10)
89+
huawei_Logger.info("{0}{1}".format(debug_of_send_to_zabbix[0].decode("utf-8"), debug_of_send_to_zabbix[1].decode("utf-8")))
90+
except subprocess.TimeoutExpired:
91+
send_to_zabbix.kill()
92+
huawei_Logger.error("------------- Shit happens ----------------\n\n\n")
93+
huawei_Logger.info("ReturnCode of zabbix_sender = {0}".format(send_to_zabbix.returncode))
94+
os.remove(temp_file)
95+
return send_to_zabbix.returncode
96+
97+
98+
99+
def discovering_resources(api_user, api_password, api_ip, api_port, storage_name, list_resources):
100+
api_connection = api_connect(api_user, api_password, api_ip, api_port)
101+
102+
device_id = api_connection[0]['data']['deviceid']
103+
iBaseToken = api_connection[0]['data']['iBaseToken']
104+
api_cookies = api_connection[1]
105+
headers = {'Connection': 'keep-alive', 'Content-Type': 'application/json', 'Accept': 'application/json', 'iBaseToken':iBaseToken}
106+
107+
something = []
108+
try:
109+
for resource in list_resources:
110+
resource_url = "https://{0}:{1}/deviceManager/rest/{2}/{3}".format(api_ip, api_port, device_id, resource)
111+
resource_info = requests.get(resource_url, verify=False, cookies = api_cookies, headers = headers)
112+
resource_info = json.loads(resource_info.content.decode('cp1251')) # Конвертация из JSON-объекта в словарь
113+
114+
115+
discovered_resource = []
116+
for one_res in resource_info['data']:
117+
resources_list = dict()
118+
if resource == 'disk':
119+
resources_list["{#ID}"] = one_res['ID']
120+
resources_list["{#LOCATION}"] = one_res['LOCATION'].replace(' ', '_')
121+
discovered_resource.append(resources_list)
122+
elif ['diskpool', 'storagepool', 'lun'].count(resource) == 1:
123+
resources_list["{#NAME}"] = one_res['NAME'].replace(' ','_')
124+
discovered_resource.append(resources_list)
125+
else:
126+
resources_list["{#NAME}"] = one_res['NAME'].replace(' ','_')
127+
resources_list["{#ID}"] = one_res['ID']
128+
resources_list["{#LOCATION}"] = one_res['LOCATION'].replace(' ','_')
129+
discovered_resource.append(resources_list)
130+
131+
converted_resource = convert_to_zabbix_json(discovered_resource)
132+
timestampnow = int(time.time())
133+
something.append("%s %s %s %s" % (storage_name, resource, timestampnow, converted_resource))
134+
135+
exit_code = api_logout(api_ip, api_port, api_cookies, device_id, iBaseToken)
136+
except Exception as oops:
137+
exc_type, exc_value, exc_traceback = sys.exc_info()
138+
huawei_Logger.error("Exception type - {0}\nException value - {1}\nException traceback - {2}".format(exc_type, exc_value, exc_traceback))
139+
huawei_Logger.error("*********************** Discovering is failed ***********************\n\n\n")
140+
sys.exit("1000")
141+
# if exit_code != 0:
142+
# return 5
143+
144+
return send_data_to_zabbix(something, storage_name)
145+
146+
147+
148+
149+
def get_status_resources(api_user, api_password, api_ip, api_port, storage_name, list_resources):
150+
api_connection = api_connect(api_user, api_password, api_ip, api_port)
151+
152+
device_id = api_connection[0]['data']['deviceid']
153+
iBaseToken = api_connection[0]['data']['iBaseToken']
154+
api_cookies = api_connection[1]
155+
headers = {'Connection': 'keep-alive', 'Content-Type': 'application/json', 'Accept': 'application/json', 'iBaseToken':iBaseToken}
156+
157+
158+
state_resources = [] # В этот список будут складываться состояние каждого ресурса (объекта) в формате zabbix
159+
try:
160+
for resource in list_resources:
161+
resource_url = "https://{0}:{1}/deviceManager/rest/{2}/{3}".format(api_ip, api_port, device_id, resource)
162+
resource_info = requests.get(resource_url, verify=False, cookies = api_cookies, headers = headers)
163+
resource_info = json.loads(resource_info.content.decode('cp1251')) # Конвертация из JSON-объекта в словарь
164+
timestampnow = int(time.time())
165+
166+
if ['fc_port','sas_port', 'eth_port'].count(resource) == 1:
167+
for one_res in resource_info['data']:
168+
key_health = "health.{0}.[{1}]".format(resource, one_res['LOCATION'].replace(' ','_')) # Создаем ключ для каждого объекта и заменяем пробелы
169+
key_status = "running.{0}.[{1}]".format(resource, one_res['LOCATION'].replace(' ','_')) # Создаем ключ для каждого объекта и заменяем пробелы
170+
state_resources.append("%s %s %s %s" % (storage_name, key_health, timestampnow, one_res['HEALTHSTATUS']))
171+
state_resources.append("%s %s %s %s" % (storage_name, key_status, timestampnow, one_res['RUNNINGSTATUS']))
172+
elif ['diskpool'].count(resource) == 1:
173+
for one_res in resource_info['data']:
174+
key_health = "health.{0}.[{1}]".format(resource, one_res['NAME'])
175+
key_status = "running.{0}.[{1}]".format(resource, one_res['NAME'])
176+
state_resources.append("%s %s %s %s" % (storage_name, key_health, timestampnow, one_res['HEALTHSTATUS']))
177+
state_resources.append("%s %s %s %s" % (storage_name, key_status, timestampnow, one_res['RUNNINGSTATUS']))
178+
elif ['lun'].count(resource) == 1:
179+
subscribed_capacity_pools = {} # Здесь будет: имя пула - сумма объемов лунов, принадлежащих этому пулу
180+
for one_res in resource_info['data']:
181+
key_health = "health.{0}.[{1}]".format(resource, one_res['NAME'])
182+
key_status = "running.{0}.[{1}]".format(resource, one_res['NAME'])
183+
state_resources.append("%s %s %s %s" % (storage_name, key_health, timestampnow, one_res['HEALTHSTATUS']))
184+
state_resources.append("%s %s %s %s" % (storage_name, key_status, timestampnow, one_res['RUNNINGSTATUS']))
185+
186+
187+
# Блок кода, подсчитывает сумму "выделенных объемов" лунов для каждого пула. Нужно для подсчета подписанного места на каждом пуле
188+
pool_name = one_res['PARENTNAME']
189+
abr = list(subscribed_capacity_pools.keys()) #Конвертируем ключи словаря в список, что бы было легче сравнивать
190+
if abr.count(pool_name) == 0: #А есть ли в словаре такой лун?
191+
subscribed_capacity_pools[pool_name] = 0 #Нету луна? добавь его имя как ключ в словарь. Начальное значение = 0, сюда суммируются объемы лунов
192+
capacity_lun_in_blocks = int(one_res['CAPACITY']) # Конвертируем из строки в число
193+
size_block = int(one_res['SECTORSIZE'])
194+
subscribed_capacity_pools[pool_name] += capacity_lun_in_blocks * size_block # Умножением переводим из блоков в байты
195+
196+
197+
# Формируется формат zabbix для подписанного места из словаря
198+
for key in subscribed_capacity_pools.keys():
199+
key_subscribed_capacity = "subscribed.capacity.{0}.[{1}]".format('storagepool', key) # key - принимает имя пула
200+
state_resources.append("%s %s %s %s" %(storage_name, key_subscribed_capacity, timestampnow, subscribed_capacity_pools[key]))
201+
202+
elif ['storagepool'].count(resource) == 1:
203+
for one_res in resource_info['data']:
204+
key_health = "health.{0}.[{1}]".format(resource, one_res['NAME'])
205+
key_status = "running.{0}.[{1}]".format(resource, one_res['NAME'])
206+
key_total_capacity = "total.capacity.{0}.[{1}]".format(resource, one_res['NAME'])
207+
key_free_capacity = "free.capacity.{0}.[{1}]".format(resource, one_res['NAME'])
208+
key_used_capacity = "used.capacity.{0}.[{1}]".format(resource, one_res['NAME'])
209+
210+
state_resources.append("%s %s %s %s" % (storage_name, key_health, timestampnow, one_res['HEALTHSTATUS']))
211+
state_resources.append("%s %s %s %s" % (storage_name, key_status, timestampnow, one_res['RUNNINGSTATUS']))
212+
state_resources.append("%s %s %s %s" % (storage_name, key_total_capacity, timestampnow, int(one_res['USERTOTALCAPACITY']) * 512))
213+
state_resources.append("%s %s %s %s" % (storage_name, key_free_capacity, timestampnow, int(one_res['USERFREECAPACITY']) * 512))
214+
state_resources.append("%s %s %s %s" % (storage_name, key_used_capacity, timestampnow, int(one_res['USERCONSUMEDCAPACITY']) * 512))
215+
216+
"""
217+
Обход момента, когда в пуле нет лунов (т.е. used_capacity пула равен нулю).
218+
Когда нет лунов в пуле, невозможно вычислить подписанное место,
219+
т.к. подписанное место вычисляется в разделе лунов путем сложения total_capacity всех лунов, принадлежащих данному пулу.
220+
"""
221+
if int(one_res['USERCONSUMEDCAPACITY']) == 0:
222+
key_subscribed_capacity = "subscribed.capacity.{0}.[{1}]".format(resource,one_res['NAME'])
223+
state_resources.append("%s %s %s %s" % (storage_name, key_subscribed_capacity, timestampnow, 0))
224+
225+
else:
226+
for one_res in resource_info['data']:
227+
key_health = "health.{0}.[{1}]".format(resource, one_res['LOCATION'].replace(' ','_')) # Создаем ключ для каждого объекта и заменяем пробелы
228+
key_status = "running.{0}.[{1}]".format(resource, one_res['LOCATION'].replace(' ','_'))
229+
state_resources.append("%s %s %s %s" % (storage_name, key_health, timestampnow, one_res['HEALTHSTATUS']))
230+
state_resources.append("%s %s %s %s" % (storage_name, key_status, timestampnow, one_res['RUNNINGSTATUS']))
231+
232+
exit_code = api_logout(api_ip, api_port, api_cookies, device_id, iBaseToken)
233+
except Exception as oops:
234+
exc_type, exc_value, exc_traceback = sys.exc_info()
235+
huawei_Logger.error("Exception type - {0}\nException value - {1}\nException traceback - {2}".format(exc_type, exc_value, exc_traceback))
236+
huawei_Logger.error("*********************** Get status is failed ***********************\n\n\n")
237+
sys.exit("1000")
238+
# if exit_code != 0:
239+
# return 5
240+
# print (state_resources)
241+
return send_data_to_zabbix(state_resources, storage_name)
242+
243+
244+
def main():
245+
246+
huawei_parser = argparse.ArgumentParser()
247+
huawei_parser.add_argument('--api_ip', action="store", help="Where to connect", required=True)
248+
huawei_parser.add_argument('--api_port', action="store", required=True)
249+
huawei_parser.add_argument('--api_user', action="store", required=True)
250+
huawei_parser.add_argument('--api_password', action="store", required=True)
251+
huawei_parser.add_argument('--storage_name', action="store", required=True)
252+
253+
group = huawei_parser.add_mutually_exclusive_group(required=True)
254+
group.add_argument('--discovery', action ='store_true')
255+
group.add_argument('--status', action='store_true')
256+
arguments = huawei_parser.parse_args()
257+
258+
259+
list_resources = ['disk', 'power', 'enclosure', 'controller', 'backup_power', 'expboard', 'intf_module', 'eth_port', 'sas_port', 'fc_port', 'fan', 'lun', 'diskpool', 'storagepool']
260+
261+
if arguments.discovery:
262+
huawei_Logger.info("********************************* Discovery is starting *********************************")
263+
result_discovery = discovering_resources(arguments.api_user, arguments.api_password, arguments.api_ip, arguments.api_port, arguments.storage_name, list_resources)
264+
huawei_Logger.info("********************************* Discovery is ended *********************************\n\n\n")
265+
print (result_discovery)
266+
elif arguments.status:
267+
huawei_Logger.info("********************************* Get State is starting *********************************")
268+
result_status = get_status_resources(arguments.api_user, arguments.api_password, arguments.api_ip, arguments.api_port, arguments.storage_name, list_resources)
269+
huawei_Logger.info("********************************* Get State is ended *********************************\n\n\n")
270+
print (result_status)
271+
272+
273+
if __name__ == "__main__":
274+
main()

0 commit comments

Comments
 (0)