def get_LicenseExport(self): #logger.info("get_LicenseExport has been called") licenseExpURL = f"{self.url}/api/cluster/v2/license/consumption/hour" endTs = int(round(time.time() * 1000)) endTs = int(endTs // 3600000 * 3600000) endTs = endTs - 2 * 3600000 startTs = endTs - 3600000 params = {'startTs': startTs, 'endTs': endTs} logger.info('The params are "%s"' % params) try: getlicenseExp = requests.get(licenseExpURL, headers=self.auth_header, params=params, verify=False) logger.info('get_LicenseExport response code was "%s"' % getlicenseExp.status_code) if getlicenseExp.status_code == 401: error = getlicenseExp.json()['error']['message'] raise AuthException( 'Get License Export Error. Ensure your Cluster Token is correct, active and has the role ServiceProviderAPI. The message was - %s' % error) except requests.exceptions.ConnectTimeout as ex: raise ConfigException('Timeout on connecting with "%s"' % licenseExpURL) from ex except requests.exceptions.RequestException as ex: raise ConfigException('Unable to connect to "%s"' % licenseExpURL) from ex except json.JSONDecodeError as ex: raise ConfigException('Server response from %s is not json' % licenseExpURL) from ex #logger.info('The json item is "%s"' % getlicenseExp.json()) return getlicenseExp.json()['environmentBillingEntries']
def query(self, **kwargs): # *************** # READ PROPERTIES # *************** config = kwargs['config'] group = config['group'] name = config['name'] custom_property = config['custom_property'] # *************** # CAN VALIDATE CONFIG/AUTH AND RAISE EXCEPTIONS # *************** if not name: raise ConfigException('Need a device name') if not group: # e.g. test device connection raise AuthException('Need a device group') # *************** # CREATE DYNATRACE DEVICE ENTITIES # *************** g1 = self.topology_builder.create_group(group, group) e1 = g1.create_device(name, name) # *************** # COLLECT METRICS # *************** metric1 = random.randint(0, 101) metric2 = [] for i in range(5): dim = { 'dimension': { 'Dimension': 'dimension{}'.format(i) }, 'value': random.randint(0, 101) } metric2.append(dim) metric3 = random.randint(0, 1001) # *************** # SEND METRICS TO DYNATRACE SERVER # *************** e1.absolute(key='metric1', value=metric1) for dim in metric2: e1.absolute(key='metric2', value=dim['value'], dimensions=dim['dimension']) e1.relative(key='metric3', value=metric3) # *************** # SEND PROPERTIES TO DYNATRACE SERVER # *************** e1.report_property('extension', 'random') if custom_property: e1.report_property('custom', custom_property)
def query(self, **kwargs): device = self.device authentication = self.authentication # Connection check and system properties snmpv2_mib = SNMPv2MIB(device, authentication) property_dict = {} try: property_dict = snmpv2_mib.poll_properties() except Exception as e: # Just report the pysnmp exception back to the end user info = 'Device connection issue: check snmp access' raise AuthException('{}: {}'.format(info,str(e))) from e # Create the group/device entities in Dynatrace g1_name = '{0} - {1}'.format(device['type'], device['group']) g1 = self.topology_builder.create_group(g1_name, g1_name) e1_name = '{0} - {1}'.format(device['type'], device['host']) e1 = g1.create_device(e1_name, e1_name) # Poll for snmp metrics metric_queue = Queue() thread_list = [] mib_list = [] avodaq_mib = AvodaqProcessMIB(device, authentication) mib_list.append(avodaq_mib) for mib in mib_list: # Lambda function - so that the thread can write poll_metrics() into the queue t = Thread(target=lambda q,mib: q.put(mib.poll_metrics()), args=([metric_queue, mib])) t.start() thread_list.append(t) for t in thread_list: t.join() # Keep track of the custom metrics consumed custom_metrics = 0 # Send metrics and dimensions through to DT while not metric_queue.empty(): for endpoint,metrics in metric_queue.get().items(): for metric in metrics: if metric['is_absolute_number']: e1.absolute(key=endpoint, value=metric['value'], dimensions=metric['dimension']) else: e1.relative(key=endpoint, value=metric['value'], dimensions=metric['dimension']) custom_metrics += 1 if custom_metrics == 0: raise NothingToReportException('Connected: But no metrics were returned when polling {}:{}'.format(device['host'], device['port'])) e1.add_endpoint(socket.gethostbyname(device['host'])) property_dict['Custom metrics'] = str(custom_metrics) for key,value in property_dict.items(): e1.report_property(key, value)
def getResponseFromHttp(self, url): try: response = requests.get(url, auth=self.auth, verify=self.verify, timeout=self.timeout) except (requests.exceptions.MissingSchema, requests.exceptions.InvalidSchema, requests.exceptions.InvalidURL) as ex: raise ConfigException('URL: "%s" does not appear to be valid' % url) from ex except requests.exceptions.ConnectTimeout as ex: raise ConfigException('Timeout on connecting with "%s"' % url) from ex except requests.exceptions.RequestException as ex: raise ConfigException('Unable to connect to "%s"' % url) from ex if response.status_code == requests.codes.UNAUTHORIZED: raise AuthException(response) return response
def query(self, **kwargs): device = self.device authentication = self.authentication # Connection check and system properties snmpv2_mib = SNMPv2MIB(device, authentication) property_dict = {} try: property_dict = snmpv2_mib.poll_properties() except Exception as e: # Just report the pysnmp exception back to the end user info = 'Device connection issue: check snmp access' raise AuthException('{}: {}'.format(info, str(e))) from e # Create the group/device entities in Dynatrace g1_name = '{0} - {1}'.format(device['type'], device['group']) g1 = self.topology_builder.create_group(g1_name, g1_name) e1_name = '{0} - {1}'.format(device['type'], device['host']) e1 = g1.create_device(e1_name, e1_name) # Poll for snmp metrics metric_queue = Queue() thread_list = [] mib_list = [] # VENDOR/DEVICE SPECIFIC POLLING DEVICE_OBJECT_ID = property_dict['sysObjectID'] F5_OBJECT_ID = '1.3.6.1.4.1.3375' CISCO_OBJECT_ID = '1.3.6.1.4.1.9' CA_VAPP_OBJECT_ID = '1.3.6.1.4.1.8072' # HOST METRICS if DEVICE_OBJECT_ID.startswith(CISCO_OBJECT_ID): # Use CISCO PROCESS MIB for Cisco devices cisco_mib = CiscoProcessMIB(device, authentication) mib_list.append(cisco_mib) elif DEVICE_OBJECT_ID.startswith(F5_OBJECT_ID): # USE F5 BIGIP SYSTEM MIB FOR F5 devices f5_mib = F5BigIPSystemMIB(device, authentication) mib_list.append(f5_mib) elif DEVICE_OBJECT_ID.startswith(CA_VAPP_OBJECT_ID): ca_mib = CAVappMIB(device, authentication) mib_list.append(ca_mib) else: # HOST RESOURCE MIB - Default fallback hr_mib = HostResourceMIB(device, authentication) mib_list.append(hr_mib) # NETWORK METRICS # IF MIB if_mib = IFMIB(device, authentication) mib_list.append(if_mib) logger.info(mib_list) for mib in mib_list: # Lambda function - so that the thread can write poll_metrics() into the queue t = Thread(target=lambda q, mib: q.put(mib.poll_metrics()), args=([metric_queue, mib])) t.start() thread_list.append(t) for t in thread_list: t.join() ### time.sleep(1) ### # Keep track of the custom metrics consumed custom_metrics = 0 # Send metrics and dimensions through to DT while not metric_queue.empty(): for endpoint, metrics in metric_queue.get().items(): for metric in metrics: if metric['is_absolute_number']: e1.absolute(key=endpoint, value=metric['value'], dimensions=metric['dimension']) else: e1.relative(key=endpoint, value=metric['value'], dimensions=metric['dimension']) custom_metrics += 1 if custom_metrics == 0: raise NothingToReportException( 'Connected: But no metrics were returned when polling {}:{}'. format(device['host'], device['port'])) e1.add_endpoint(socket.gethostbyname(device['host'])) property_dict['Custom metrics'] = str(custom_metrics) for key, value in property_dict.items(): e1.report_property(key, value)
def get_environments(self): environmentsURL = f"{self.url}/api/cluster/v2/environments" params = {'filter': 'state(ENABLED)', 'pageSize': 1000} try: getEnvironments = requests.get(environmentsURL, headers=self.auth_header, params=params, verify=False) if getEnvironments.status_code == 401: error = getEnvironments.json()['error']['message'] raise AuthException( 'Get Environments Error. Ensure your Cluster Token is correct, active and has the role ServiceProviderAPI. The message was - %s' % error) except requests.exceptions.ConnectTimeout as ex: raise ConfigException('Timeout on connecting with "%s"' % environmentsURL) from ex except requests.exceptions.RequestException as ex: raise ConfigException('Unable to connect to "%s"' % environmentsURL) from ex except json.JSONDecodeError as ex: raise ConfigException('Server response from %s is not json' % environmentsURL) from ex if "nextPageKey" in getEnvironments.json(): environments = getEnvironments.json()['environments'] nextPageKey = getEnvironments.json()['nextPageKey'] requiredCalls = math.ceil( int(getEnvironments.json()['totalCount']) / int(getEnvironments.json()['pageSize'])) i = 1 while i < requiredCalls: if getEnvironments.json()['nextPageKey']: nextPageKey = getEnvironments.json()['nextPageKey'] params = {'nextPageKey': nextPageKey} try: getEnvironments = requests.get(environmentsURL, headers=self.auth_header, params=params) if getEnvironments.status_code == 401: error = getEnvironments.json()['error']['message'] raise AuthException( 'Get Environments Error. Ensure your Cluster Token is correct, active and has the role ServiceProviderAPI. The message was - %s' % error) except requests.exceptions.ConnectTimeout as ex: raise ConfigException('Timeout on connecting with "%s"' % environmentsURL) from ex except requests.exceptions.RequestException as ex: raise ConfigException('Unable to connect to "%s"' % environmentsURL) from ex except json.JSONDecodeError as ex: raise ConfigException( 'Server response from %s is not json' % environmentsURL) from ex pageDataEnvs = getEnvironments.json()['environments'] for item in pageDataEnvs: environments.append(item) i += 1 else: environments = getEnvironments.json()['environments'] # Convert to dict envDict = {} for e in environments: envDict[e['id']] = e return envDict