Coverage for src/zenossapi/routers/__init__.py: 85%
52 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-25 05:47 +0000
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-25 05:47 +0000
1# -*- coding: utf-8 -*-
2import logging
3import requests
4import json
5from requests import ReadTimeout
6from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
7from requests.exceptions import ConnectionError
8from zenossapi.apiclient import ZenossAPIClientError, ZenossAPIClientAuthenticationError
11class ZenossRouter(object):
12 """
13 Base class for Zenoss router classes
14 """
15 def __init__(self, url, headers, ssl_verify, endpoint, action, timeout=5, maxattempts=3):
16 self.api_url = url
17 self.api_headers = headers
18 self.ssl_verify = ssl_verify
19 self.api_endpoint = endpoint
20 self.api_action = action
21 self.api_timeout = timeout
22 self.api_maxattempts = maxattempts
24 def _check_uid(self, uid):
25 if not uid.startswith('Devices'):
26 if uid.startswith('/'):
27 uid = 'Devices{0}'.format(uid)
28 else:
29 uid = 'Devices/{0}'.format(uid)
31 return uid
33 def _make_request_data(self, method, data=None):
34 if data is None:
35 return dict(
36 action=self.api_action,
37 method=method,
38 tid=1,
39 )
40 else:
41 return dict(
42 action=self.api_action,
43 method=method,
44 data=[data],
45 tid=1,
46 )
47 @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=2, min=2, max=20), retry=retry_if_exception_type(ReadTimeout))
48 def _router_request(self, data, response_timeout=None):
49 # Disable warnings from urllib3 if ssl_verify is False, otherwise
50 # every request will print an InsecureRequestWarning
51 if not self.ssl_verify:
52 requests.urllib3.disable_warnings()
54 if response_timeout is None:
55 response_timeout = self.api_timeout
57 try:
58 response = requests.request("POST",
59 '{0}/{1}'.format(self.api_url, self.api_endpoint),
60 headers=self.api_headers,
61 data=json.dumps(data).encode('utf-8'),
62 verify=self.ssl_verify,
63 timeout=response_timeout
64 )
65 except ConnectionError as e:
66 logging.warning('Error calling Zenoss API: %s\n Request data: %s' % (e, data))
67 # Atempt to display the failure reason from Zenoss
68 try:
69 logging.warning("Query failure reason from Zensos: %s" % response['result']['msg'])
70 except:
71 pass
73 if response.ok:
74 if response.url.find('login_form') > -1:
75 raise ZenossAPIClientAuthenticationError('API Login Failed')
76 response_json = response.json()
77 if 'result' in response_json:
78 if response_json['result']:
79 if 'success' in response_json['result']:
80 if not response_json['result']['success']:
81 raise ZenossAPIClientError('Request failed: {}'.format(response_json['result']['msg']))
82 else:
83 raise ZenossAPIClientError('Request failed, no response data returned!')
85 return response_json['result']
87 else:
88 raise ZenossAPIClientError('Request failed: {0} {1}'.format(response.status_code, response.reason))