-
Notifications
You must be signed in to change notification settings - Fork 9
/
storage_objects_discovery.py
executable file
·161 lines (126 loc) · 6.21 KB
/
storage_objects_discovery.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/usr/bin/env python3
#
# IBM Storwize objects discovery for Zabbix
#
# 2016-2020 Denis Pavlov
#
# Discover storage objects from Storwize including physical and logical disks, via CIM/WBEM and sends it to Zabbix Server via Zabbix Sender API
#
# Use with template Template Storage Pystormon
#
import os
import sys
from configread import configread
from functions import slack_post, zabbix_send
from json import load
from pynetdevices import WBEMDevice
from pywbem import _exceptions
from pyzabbix import ZabbixMetric
# set project as current directory name, software as name of current script
project = os.path.abspath(__file__).split('/')[-2]
software = sys.argv[0]
def storage_objects_discovery(wbem_connection, storage_name, cim_class, cim_property_name):
""" get list of storage objects """
# create empty list for storage object names
result = []
# form "SELECT" request string
request = f'SELECT {cim_property_name} FROM {cim_class}'
# try to request storage via WBEM
try:
storage_response = wbem_connection.ExecQuery('DMTF:CQL', request)
except _exceptions.AuthError as error:
print((f'{project}_error: exception in {software}: can\'t exec query on {storage_name}: {error} '
f'Check your username/password and permissions of user.'),
file=sys.stderr)
slack_post(software, (f'can\'t exec query on {storage_name}: {error} .'
f'Check your username/password and permissions of user.'))
exit(1)
except _exceptions.ConnectionError as error:
print((f'{project}_error: exception in {software}: can\'t exec query on {storage_name}: {error}. '
f'Check the connection to storage or try later.'),
file=sys.stderr)
slack_post(software, (f'can\'t exec query on {storage_name}: {error}. '
f'Check the connection to storage or try later.'))
exit(1)
except _exceptions.HTTPError as error:
print((f'{project}_error: exception in {software}: WBEM server return code 400 (Bad Request) on {storage_name}: {error}. '
f'Check the your request.'),
file=sys.stderr)
slack_post(software, (f'WBEM server return code 400 (Bad Request) on {storage_name}: {error}. '
f'Check the your request {request}.'))
exit(1)
except:
print(f'{project}_error: exception in {software}: {sys.exc_info()}',
file=sys.stderr)
slack_post(software, sys.exc_info())
exit(1)
# parse reply and form a list of storage objects
for cim_object in storage_response:
object_name = cim_object.properties[cim_property_name].value
result.append(object_name)
return result
def main():
# get config file name
conf_file = (
f'/etc/zabbix/externalscripts/{project}/conf.d/{project}.conf')
# read network device parameters from config and save it to dict
nd_parameters = configread(conf_file, 'NetworkDevice', 'device_file',
'login', 'password', 'name_space', 'printing')
# read storage device parameters from config and save it to another dict
sd_parameters = configread(conf_file, 'StorageDevice',
'monitored_properties_file')
# get printing boolean variable from config for debugging enable/disable
printing = eval(nd_parameters['printing'])
# get variables
login = nd_parameters['login']
password = nd_parameters['password']
# form dictionary of matching storage concepts and cim properties
# more details in https://www.ibm.com/support/knowledgecenter/STHGUJ_8.3.1/com.ibm.storwize.v5000.831.doc/svc_conceptsmaptocimconcepts_3skacv.html
with open(sd_parameters['monitored_properties_file'], "r") as monitored_properties_file:
monitored_properties = load(monitored_properties_file)
# open config file with list of monitored storages
device_list_file = open(nd_parameters['device_file'])
# unpack storage list to variables
for device_line in device_list_file:
device_type, device_name, device_ip = device_line.split(':')
device_ip = device_ip.rstrip('\n')
# connect to each storage via WBEM, get conn object
if device_type == 'storwize':
device = WBEMDevice(device_name, device_ip, login, password)
# get namespace from config, root/ibm by default
namespace = nd_parameters.get('name_space', 'root/ibm')
conn = device.Connect(namespace)
# initialize packet for sending to zabbix
packet = []
# iterate through dictionary of monitored storage concepts
for storage_concept in monitored_properties:
# get list of storage objects
so_names = storage_objects_discovery(conn, device_name,
monitored_properties[storage_concept]['cim_class'],
monitored_properties[storage_concept]['cim_property_name'])
so_names_dict = {}
so_names_list = []
# create list of disk types and names in JSON
for so_name in so_names:
so_name_json = {"{#SO_TYPE}": storage_concept,
"{#SO_NAME}": so_name}
so_names_list.append(so_name_json)
# form data for send to zabbix
so_names_dict['data'] = so_names_list
trapper_key = monitored_properties[storage_concept]['zabbix_discovery_key']
trapper_value = str(so_names_dict).replace("\'", "\"")
# form packet for sending to zabbix
packet.append(ZabbixMetric(device_name, trapper_key,
trapper_value))
# print data for visual check
if printing:
print(device_name)
print(trapper_key)
print(trapper_value)
# trying send data to zabbix
zabbix_send(packet, printing, software)
device_list_file.close()
if __name__ == "__main__":
main()
else:
print("Please execute this program as main\n")