-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcheck_vcd_avi_lb.py
executable file
·144 lines (121 loc) · 7.22 KB
/
check_vcd_avi_lb.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
#!/usr/bin/env python3
import argparse
import logging
import os
from pprint import pformat
import requests
logging.basicConfig(level=logging.ERROR)
def get_access_token(vcd_host, vcd_token, vcd_org_name):
"""
# How to get a "Bearer Token" with an "API Token" via curl
uri="https://$vcdhost/oauth/tenant/$org/token?grant_type=refresh_token&refresh_token=$token"
$ accesstok=`curl -s -k -X POST $uri -H "Accept: application/json" | jq -r '.access_token'`
$ headers=`curl -s -H "Accept: application/*+xml;version=36.1" -H "Authorization: Bearer $accesstok" -k -I -X GET https://$vcdhost/api/session`
$ export VCD_TOKEN=`echo "$headers" | grep X-VMWARE-VCLOUD-ACCESS-TOKEN: | cut -f2- -d: | awk '{$1=$1};1'`
"""
data = {'grant_type': 'refresh_token', 'refresh_token': vcd_token, 'filter': f'name=={vcd_org_name}'}
access_token_response = requests.post(f'{vcd_host}/oauth/tenant/{vcd_org_name}/token', data=data, headers={'Accept': "application/json"})
logging.debug('access_token_response result:')
logging.debug(pformat(access_token_response.json()))
if access_token_response.status_code == 200:
return access_token_response.json()['access_token']
else:
print(f'UNKNOWN - get_access_token() {access_token_response.status_code}- Unable to get access token in check_avi-lb')
logging.error(f'UNKNOWN - get_access_token() {access_token_response.status_code} - Unable to get access token in check_avi-lb')
exit(3)
def get_edge_gateway(vcd_host, access_token):
# get the edge gateway id
headers = {'Authorization': f'Bearer {access_token}', 'accept': 'application/json;version=38.1'}
data = '' # {'filter': f'name==T1-1-2-nbg'}
edge_gateways_response = requests.get(f'{vcd_host}/cloudapi/1.0.0/edgeGateways', data=data, headers=headers)
if edge_gateways_response.status_code == 200:
return edge_gateways_response.json()['values'][0]['id']
else:
print(f'UNKNOWN - get_edge_gateway() {edge_gateways_response.status_code} - Unable to get edge gateway in check_avi-lb')
logging.error(f'UNKNOWN - get_edge_gateway() {edge_gateways_response.status_code} - Unable to get edge gateway in check_avi-lb')
exit(3)
def pool_health(vcd_host, access_token, edge_gateway_id):
# get filtered pool Summaries
headers = {'Authorization': f'Bearer {access_token}', 'accept': 'application/json;version=38.1'}
params = '' # {'filter': 'name==elasticsearch*'}
pool_response = requests.get(f'{vcd_host}/cloudapi/1.0.0/edgeGateways/{edge_gateway_id}/loadBalancer/poolSummaries', params=params, headers=headers).json()
logging.debug('pool health status response:')
for pool in pool_response['values']:
logging.debug(pformat({key: pool[key] for key in ('name', 'healthStatus')}))
pools_not_up = [pool for pool in pool_response['values'] if pool['healthStatus'] not in ('UP', 'RUNNING') and pool['enabled']]
pools_warning = [pool for pool in pool_response['values'] if pool['healthStatus'] in 'RUNNING' and pool['enabled']]
try:
if len(pools_not_up) > 0:
print(f"CRITICAL - Some Pools are UNAVAILABLE. {', '.join([pool['name'] for pool in pools_not_up])}")
logging.info(f"CRITICAL - Some Pools are UNAVAILABLE. {', '.join([pool['name'] for pool in pools_not_up])}")
exit(2)
elif len(pools_warning) > 0:
print(f"WARNING - Some Pools are not fully UP. {', '.join([pool['name'] for pool in pools_warning])}")
logging.info(f"WARNING - Some Pools are not fully UP. {', '.join([pool['name'] for pool in pools_warning])}")
exit(1)
elif len(pools_not_up) == 0:
print('OK - All Pools are fully UP.')
logging.info('OK - All Pools are fully UP.')
exit(0)
else:
print('UNKNOWN - ')
logging.info('UNKNOWN - ')
exit(3)
except Exception as e:
print(f'UNKNOWN - Unhandled exception - {e}')
logging.info(f'UNKNOWN - Unhandled exception - {e}')
exit(3)
def virtual_services_health(vcd_host, access_token, edge_gateway_id):
# Step 3: get filtered pool Summaries
headers = {'Authorization': f'Bearer {access_token}', 'accept': 'application/json;version=38.1'}
params = '' # {'filter': 'name==elasticsearch*'}
virtual_service_response = requests.get(f'{vcd_host}/cloudapi/1.0.0/edgeGateways/{edge_gateway_id}/loadBalancer/virtualServiceSummaries', params=params, headers=headers).json()
logging.info('virtual service health status response:')
for virtual_service in virtual_service_response['values']:
logging.info(pformat({key: virtual_service[key] for key in ('name', 'healthStatus')}))
virtual_services_not_up = [virtual_service for virtual_service in virtual_service_response['values'] if virtual_service['healthStatus'] not in 'UP' and virtual_service['enabled']]
try:
if len(virtual_services_not_up) > 0:
print(f"CRITICAL - Some Virtual Services are DOWN. {[virtual_service['name'] for virtual_service in virtual_services_not_up]}")
exit(2)
# elif len(virtual_services_warning) > 0:
# # not implemented yet
# print(f"WARNING - Some Virtual Services are not fully UP. {[virtual_service['name'] for virtual_service in virtual_services_warning]}")
# exit(1)
if len(virtual_services_not_up) == 0:
print('OK - All Virtual Services are fully UP.')
exit(0)
else:
# This should not happen
print('UNKNOWN - ')
exit(3)
except Exception as e:
print(f'UNKNOWN - Unhandled exception - {e}')
exit(3)
def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.RawTextHelpFormatter,
description=f'''
Icinga Check Command for AVI Loadbalancer running in VMware CLoud Director.
Call it like:
{os.path.basename(__file__)} --checkmode pools --vcd_org_name 1-2 --vcd_token JoAsnNx4ECWje1h2l7jhahsmCgLVzIij
''',
epilog='''
The access-tokens user account only needs the following permissions:
- View Gateway
- Load Balancer View Only
''')
parser.add_argument('--checkmode', required=True, choices=['pools', 'virtual_services'],
help='Whether to check Pools or Virtual Services.')
parser.add_argument('--vcd_org_name', required=True, help='ORG name of tenant to check loadbalancer, e.g.: 1-2')
parser.add_argument('--vcd_host', required=False, default='https://vcd-nbg.nec.noris.de', help='Hostname of API Endpoint. (Default: https://vcd-nbg.nec.noris.de)')
parser.add_argument('--vcd_token', required=True, help='VCD API ACCESS TOKEN, e.g.: JoAsnNx4ECWje1h2l7jhahsmCgLVzIij')
args = vars(parser.parse_args())
access_token = get_access_token(args['vcd_host'], args['vcd_token'], args['vcd_org_name'])
edge_gateway = get_edge_gateway(args['vcd_host'], access_token)
if args['checkmode'] == 'pools':
print(pool_health(args['vcd_host'], access_token, edge_gateway))
elif args['checkmode'] == 'virtual_services':
print(virtual_services_health(args['vcd_host'], access_token, edge_gateway))
if __name__ == '__main__':
main()