def get_device_metrics(self): """See base class.""" try: self._snmp_connection = PanoptesSNMPConnectionFactory.get_snmp_connection( plugin_context=self._plugin_context, resource=self._device) except Exception as e: self._polling_status.handle_exception(u'device', e) finally: if self._polling_status.device_status != polling_status.DEVICE_METRICS_STATES.SUCCESS: self._metrics.add( self._polling_status.device_status_metrics_group) return self._metrics try: self._get_config() self._process_config() try: self._get_oids() self._process_metrics() except Exception as e: self._polling_status.handle_exception('metrics', e) except Exception as e: self._polling_status.handle_exception('enrichment', e) self._metrics.add(self._polling_status.device_status_metrics_group) return self._metrics
def get_device_metrics(self): start_time = time.time() try: start_time = time.time() self._snmp_connection = PanoptesSNMPConnectionFactory.get_snmp_connection( plugin_context=self._plugin_context, resource=self._device) except Exception as e: self._polling_status.handle_exception(u'device', e) finally: if self._polling_status.device_status != DEVICE_METRICS_STATES.SUCCESS: self._asr_device_metrics.add( self._polling_status.device_status_metrics_group) return self._asr_device_metrics self._get_system_cpu_metrics() self._get_memory_metrics() self._get_environment_metrics() self._get_crypto_metrics() self._get_load_metrics() end_time = time.time() self._logger.info(u'SNMP calls for ASR %s completed in %.2f seconds' % (self._device_host, end_time - start_time)) self._asr_device_metrics.add( self._polling_status.device_status_metrics_group) return self._asr_device_metrics
def _get_ping_stats(self): x509_secure_connection, x509_key_file, x509_cert_file = \ PanoptesSNMPConnectionFactory.parse_x509_config(self._plugin_context) connection = PanoptesSNMPSteamRollerAgentConnection._make_connection(x509_secure_connection, x509_key_file, x509_cert_file) request = dict() request['count'] = self._count request['timeout'] = self._timeout endpoint = 'https://{}/ping/{}'.format(self._get_proxy_host(), self._resource.resource_endpoint) try: response = connection.post(endpoint, json=request) response.raise_for_status() except requests.exceptions.HTTPError as e: raise PanoptesPingException('Error in getting response from SteamRoller SNMP Agent: {} -> {}'. format(str(e), response.text)) except requests.exceptions.Timeout as e: raise PanoptesPingTimeoutException(str(e)) except requests.exceptions.ConnectionError as e: raise PanoptesPingConnectionError(str(e)) except requests.exceptions.RequestException as e: raise PanoptesPingRequestException(str(e)) try: decoded_response = response.json() except ValueError as e: raise PanoptesPingException('Error Parsing Response From Steamroller -> {}'.format(str(e))) self.setPingStatsAPIResponse(decoded_response)
def run(self, context): """ The main entry point to the plugin Args: context (PanoptesPluginContext): The Plugin Context passed by the Enrichment Plugin Agent Returns: PanoptesEnrichmentGroupSet: A enrichment group e set Raises: PanoptesEnrichmentPluginError: This exception is raised if any part of the enrichment process has errors """ self._plugin_context = context self._device_resource = context.data self._logger = context.logger self._plugin_conf = context.config self._plugin_name = self._plugin_conf[u'Core'][u'name'] self._device_fqdn = self._device_resource.resource_endpoint try: self._execute_frequency = int( self._plugin_conf[u'main'][u'execute_frequency']) self._enrichment_ttl = int( self._plugin_conf[u'main'][u'enrichment_ttl']) self._enrichment_namespace = self._plugin_conf.get( u'main', {}).get(u'enrichment_namespace', _DEFAULT_METRICS_SCHEMA_NAMESPACE) self._snmp_timeout = int( self._plugin_conf.get(u'snmp', {}).get(u'timeout', _DEFAULT_SNMP_TIMEOUT)) self._snmp_retries = int( self._plugin_conf.get(u'snmp', {}).get(u'retries', _DEFAULT_SNMP_RETRIES)) self._snmp_non_repeaters = int( self._plugin_conf.get(u'snmp', {}).get(u'non_repeaters', _DEFAULT_SNMP_NON_REPEATERS)) self._snmp_max_repetitions = int( self._plugin_conf.get(u'snmp', {}).get(u'max_repetitions', _DEFAULT_SNMP_MAX_REPETITIONS)) except Exception as e: raise PanoptesEnrichmentPluginError( u'[{}] Error while parsing configuration for device "{}": {}'. format(self._plugin_name, self._device_fqdn, repr(e))) self._logger.debug(u'[{}] For device "{}", ' u'going to use enrichment namespace "{}"'.format( self._plugin_name, self.device_fqdn, self._enrichment_namespace)) self._enrichment_group = self.metrics_enrichment_class( enrichment_ttl=self._enrichment_ttl, execute_frequency=self._execute_frequency) self._enrichment_group_set = PanoptesEnrichmentGroupSet( self._device_resource) self._metrics_groups = None try: self._snmp_connection = PanoptesSNMPConnectionFactory.get_snmp_connection( plugin_context=context, resource=self._device_resource, timeout=self._snmp_timeout, retries=self._snmp_retries) except Exception as e: raise PanoptesEnrichmentPluginError( u'[{}] Error while creating SNMP connection for the device "{}": {}' .format(self._plugin_name, self._device_fqdn, repr(e))) self._oids_map = None start_time = time.time() self._logger.info( u'[{}] Going to poll device "{}" for metrics enrichment'.format( self._plugin_name, self._device_fqdn)) device_results = self.get_enrichment() end_time = time.time() if device_results: self._logger.info( u'[{}] Done polling enrichment for device "{}" in {:.2f} seconds, {} elements' .format(self._plugin_name, self._device_fqdn, end_time - start_time, len(device_results))) else: self._logger.warn( u'[{}] Error polling metrics enrichment for device "{}"'. format(self._plugin_name, self._device_fqdn)) return device_results
def test_get_snmp_connection(self): with self.assertRaises(AssertionError): PanoptesSNMPConnectionFactory.get_snmp_connection( plugin_context=None, resource=None) with self.assertRaises(AssertionError): PanoptesSNMPConnectionFactory.get_snmp_connection( plugin_context=self._panoptes_plugin_context, resource=None) with self.assertRaises(AssertionError): PanoptesSNMPConnectionFactory.get_snmp_connection( plugin_context=None, resource=self._resource) with self.assertRaises(AssertionError): PanoptesSNMPConnectionFactory.get_snmp_connection( plugin_context=self._panoptes_plugin_context, resource=self._resource, timeout='1') # Test that defaults (from the panoptes.ini) are set when no values are given connection = PanoptesSNMPConnectionFactory.get_snmp_connection( self._panoptes_plugin_context, self._resource) self.assertIsInstance(connection, PanoptesSNMPV2Connection) self.assertEqual(connection.host, '127.0.0.1') self.assertEqual(connection.port, 10161) self.assertEqual(connection.timeout, 5) self.assertEqual(connection.retries, 1) # Test that the community string is fetched and populated for the give site self.assertEqual(connection.community, 'public') # Test that when values for SNMP parameters are provided, the defaults are overwritten connection = PanoptesSNMPConnectionFactory.get_snmp_connection( self._panoptes_plugin_context, self._resource, timeout=1) self.assertIsInstance(connection, PanoptesSNMPV2Connection) self.assertEqual(connection.timeout, 1) connection = PanoptesSNMPConnectionFactory.get_snmp_connection( self._panoptes_plugin_context, self._resource, retries=2) self.assertIsInstance(connection, PanoptesSNMPV2Connection) self.assertEqual(connection.retries, 2) connection = PanoptesSNMPConnectionFactory.get_snmp_connection( self._panoptes_plugin_context, self._resource, port=10162) self.assertIsInstance(connection, PanoptesSNMPV2Connection) self.assertEqual(connection.port, 10162) # Test that the community suffixed is, er, suffixed connection = PanoptesSNMPConnectionFactory.get_snmp_connection( self._panoptes_plugin_context, self._resource, community_suffix='123') self.assertIsInstance(connection, PanoptesSNMPV2Connection) self.assertEqual(connection.community, 'public@123') # Test passing various combinations of x509 parameters key_file = os.path.join(self._my_path, 'key.pem') cert_file = os.path.join(self._my_path, 'certificate.pem') # Test that when x509_secure_connection is not set, the key and cert files are not needed connection = PanoptesSNMPConnectionFactory.get_snmp_connection( self._panoptes_plugin_context, self._resource, x509_secure_connection=0) self.assertIsInstance(connection, PanoptesSNMPV2Connection) # Test when x509_secure_connection is set, but the key and cert files aren't readable with self.assertRaises(PanoptesSNMPException): PanoptesSNMPConnectionFactory.get_snmp_connection( self._panoptes_plugin_context, self._resource, x509_secure_connection=1) # Test when x509_secure_connection is set, but the key file isn't readable with self.assertRaises(PanoptesSNMPException): PanoptesSNMPConnectionFactory.get_snmp_connection( self._panoptes_plugin_context, self._resource, x509_secure_connection=1, x509_key_file=key_file) # Test when x509_secure_connection is set, but the cert file isn't readable with self.assertRaises(PanoptesSNMPException): PanoptesSNMPConnectionFactory.get_snmp_connection( self._panoptes_plugin_context, self._resource, x509_secure_connection=1, x509_cert_file=cert_file) # Test when x509_secure_connection is set, and both the key and cert files are readable connection = PanoptesSNMPConnectionFactory.get_snmp_connection( self._panoptes_plugin_context, self._resource, x509_secure_connection=1, x509_key_file=key_file, x509_cert_file=cert_file) self.assertIsInstance(connection, PanoptesSNMPV2Connection) # Test that when the snmp_proxy_hosts metadata key is set, we get PanoptesSNMPSteamRollerAgentConnection self._resource.add_metadata('snmp_proxy_hosts', '127.0.0.1:10161') connection = PanoptesSNMPConnectionFactory.get_snmp_connection( self._panoptes_plugin_context, self._resource) self.assertIsInstance(connection, PanoptesSNMPSteamRollerAgentConnection) # Test that an PanoptesSNMPException is thrown if the community string for the given site is empty # Note that this should be the last test - otherwise other tests would fail self._secrets_store.delete('snmp_community_string:test_site') with self.assertRaises(PanoptesSNMPException): PanoptesSNMPConnectionFactory.get_snmp_connection( self._panoptes_plugin_context, self._resource)