def get_probe_edit_form(probe_class, resource_identifier=None): """get the form to edit a Probe""" probe_obj = Factory.create_obj(probe_class) if resource_identifier: resource = views.get_resource_by_id(resource_identifier) if resource: probe_obj.expand_params(resource) probe_info = probe_obj.get_plugin_vars() probe_vars = ProbeVars( None, probe_class, probe_obj.get_default_parameter_values()) # Get only the default Checks for this Probe class checks_avail = probe_obj.get_checks_info_defaults() checks_avail = probe_obj.expand_check_vars(checks_avail) for check_class in checks_avail: check_obj = Factory.create_obj(check_class) check_params = check_obj.get_default_parameter_values() probe_check_param_defs = \ probe_info['CHECKS_AVAIL'][check_class]['PARAM_DEFS'] for param in probe_check_param_defs: if 'value' in probe_check_param_defs[param]: check_params[param] = probe_check_param_defs[param]['value'] # Appends 'check_vars' to 'probe_vars' (SQLAlchemy) CheckVars(probe_vars, check_class, check_params) return render_template('includes/probe_edit_form.html', lang=g.current_lang, probe=probe_vars, probe_info=probe_info)
def testPluginChecks(self): plugin_obj = Factory.create_obj( 'GeoHealthCheck.plugins.check.checks.NotContainsStrings') self.assertIsNotNone(plugin_obj) plugin_obj = Factory.create_obj( 'GeoHealthCheck.plugins.check.checks.ContainsStrings') self.assertIsNotNone(plugin_obj) plugin_vars = plugin_obj.get_plugin_vars() self.assertIsNotNone(plugin_vars) parameters = plugin_obj.PARAM_DEFS self.assertEqual(len(parameters), 1, 'PARAM_DEFS should have 1 Parameter') self.assertEqual(parameters['strings']['type'], 'stringlist', 'PARAM_DEFS.strings[type] should be stringlist') plugin_obj = Factory.create_obj( 'GeoHealthCheck.plugins.check.checks.NotContainsOwsException') self.assertIsNotNone(plugin_obj) parameters = plugin_obj.PARAM_DEFS self.assertEqual(len(parameters), 1, 'PARAM_DEFS should have 1 Parameter') self.assertEqual(parameters['strings']['value'][0], 'ExceptionReport>', 'PARAM_DEFS.strings[0] should be ExceptionReport>')
def get_probe_edit_form(probe_class): """get the form to edit a Probe""" probe_obj = Factory.create_obj(probe_class) probe_info = probe_obj.get_plugin_vars() probe_vars = ProbeVars(None, probe_class, probe_obj.get_default_parameter_values()) # Get only the default Checks for this Probe class checks_avail = probe_obj.get_checks_info_defaults() checks_avail = probe_obj.expand_check_vars(checks_avail) for check_class in checks_avail: check_obj = Factory.create_obj(check_class) check_params = check_obj.get_default_parameter_values() probe_check_param_defs = \ probe_info['CHECKS_AVAIL'][check_class]['PARAM_DEFS'] for param in probe_check_param_defs: if 'value' in probe_check_param_defs[param]: check_params[param] = probe_check_param_defs[param]['value'] # Appends 'check_vars' to 'probe_vars' (SQLAlchemy) CheckVars(probe_vars, check_class, check_params) return render_template('includes/probe_edit_form.html', lang=g.current_lang, probe=probe_vars, probe_info=probe_info)
def testPluginsPresent(self): plugins = Plugin.get_plugins('GeoHealthCheck.probe.Probe') for plugin in plugins: plugin = Factory.create_obj(plugin) self.assertIsNotNone(plugin) # Must have run_request method self.assertIsNotNone(plugin.run_request) plugins = Plugin.get_plugins('GeoHealthCheck.check.Check') for plugin in plugins: plugin = Factory.create_obj(plugin) self.assertIsNotNone(plugin) # Must have perform method self.assertIsNotNone(plugin.perform) plugins = Plugin.get_plugins( 'GeoHealthCheck.resourceauth.ResourceAuth') for plugin in plugins: plugin = Factory.create_obj(plugin) self.assertIsNotNone(plugin) # Must have encode method self.assertIsNotNone(plugin.encode) plugins = Plugin.get_plugins('GeoHealthCheck.probe.Probe', filters=[('RESOURCE_TYPE', 'OGC:*'), ('RESOURCE_TYPE', 'OGC:WMS')]) for plugin in plugins: plugin_class = Factory.create_class(plugin) self.assertIsNotNone(plugin_class) plugin_obj = Factory.create_obj(plugin) self.assertIsNotNone( plugin_obj, 'Cannot create Plugin from string %s' + plugin) parameters = plugin_obj.PARAM_DEFS self.assertTrue( type(parameters) is dict, 'Plugin Parameters not a dict') checks = plugin_obj.CHECKS_AVAIL self.assertTrue(type(checks) is dict, 'Plugin checks not a dict') # Must have run_request method self.assertIsNotNone(plugin_obj.run_request) # Must have class var RESOURCE_TYPE='OGC:WMS' class_vars = Factory.get_class_vars(plugin) self.assertIn(class_vars['RESOURCE_TYPE'], ['OGC:WMS', 'OGC:*'])
def run_checks(self): """ Do the checks on the response from request""" # Do not run Checks if Probe already failed if not self.result.success: return # Config also determines which actual checks are performed # from possible Checks in Probe. Checks are performed # by Check instances. for check_var in self._check_vars: check = None try: check_class = check_var.check_class check = Factory.create_obj(check_class) except Exception: LOGGER.error("Cannot create Check class: %s %s" % (check_class, str(sys.exc_info()))) if not check: continue try: check.init(self, check_var) check.perform() except Exception: msg = "Check Err: %s" % str(sys.exc_info()) LOGGER.error(msg) check.set_result(False, msg) self.log('Check: fun=%s result=%s' % (check_class, check._result.success)) self.result.add_result(check._result)
def run(resource, probe_vars): """ Class method to create and run a single Probe instance. Follows strict sequence of method calls. Each method can be overridden in subclass. """ probe = None try: # Create Probe instance from module.class string probe = Factory.create_obj(probe_vars.probe_class) except: LOGGER.error("Cannot create Probe class: %s %s" % (probe_vars.probe_class, str(sys.exc_info()))) if not probe: return # Initialize with actual parameters probe.init(resource, probe_vars) # Perform request probe.run_request() # Perform the Probe's checks probe.run_checks() # Determine result probe.calc_result() # Lifecycle probe.exit() # Return result return probe.result
def create(auth_dict): auth_type = auth_dict['type'] auth_obj_def = ResourceAuth.get_auth_defs()[auth_type] auth_obj = Factory.create_obj( Factory.full_class_name_for_obj(auth_obj_def)) auth_obj.init(auth_dict) return auth_obj
def run(resource, probe_vars): """ Class method to create and run a single Probe instance. Follows strict sequence of method calls. Each method can be overridden in subclass. """ probe = None try: # Create Probe instance from module.class string probe = Factory.create_obj(probe_vars.probe_class) except Exception: LOGGER.error("Cannot create Probe class: %s %s" % (probe_vars.probe_class, str(sys.exc_info()))) if not probe: return # Initialize with actual parameters probe.init(resource, probe_vars) # Perform request probe.run_request() # Perform the Probe's checks probe.run_checks() # Determine result probe.calc_result() # Lifecycle probe.exit() # Return result return probe.result
def get_probes_avail(resource_type=None, resource=None): """ Get all available Probes with their attributes. :param resource_type: optional resource type e.g. OGC:WMS :param resource: optional Resource instance :return: """ # Assume no resource type filters = None if resource_type: filters = [('RESOURCE_TYPE', resource_type), ('RESOURCE_TYPE', '*:*')] probe_classes = Plugin.get_plugins('GeoHealthCheck.probe.Probe', filters) result = dict() for probe_class in probe_classes: probe = Factory.create_obj(probe_class) if probe: if resource: try: probe.expand_params(resource) except Exception as err: msg = 'Cannot expand plugin vars for %s err=%s' \ % (probe_class, str(err)) LOGGER.warning(msg) result[probe_class] = probe.get_plugin_vars() return result
def run_checks(self): """ Do the checks on the response from request""" # Config also determines which actual checks are performed # from possible Checks in Probe. Checks are performed # by Check instances. for check_var in self._check_vars: check = None try: check_class = check_var.check_class check = Factory.create_obj(check_class) except: LOGGER.error("Cannot create Check class: %s %s" % (check_class, str(sys.exc_info()))) if not check: continue try: check.init(self, check_var) check.perform() except: msg = "Check Err: %s" % str(sys.exc_info()) LOGGER.error(msg) check.set_result(False, msg) self.log('Check: fun=%s result=%s' % (check_class, check._result.success)) self.result.add_result(check._result)
def testPluginParamDefs(self): plugin_obj = Factory.create_obj( 'GeoHealthCheck.plugins.probe.owsgetcaps.WmsGetCaps') self.assertIsNotNone(plugin_obj) checks = plugin_obj.CHECKS_AVAIL self.assertEqual(len(checks), 4, 'WmsGetCaps should have 4 Checks') parameters = plugin_obj.PARAM_DEFS self.assertEqual(len(parameters), 2, 'WmsGetCaps should have 2 Parameters') probe_obj = Factory.create_obj( 'GeoHealthCheck.plugins.probe.http.HttpGet') self.assertIsNotNone(probe_obj) check_vars = probe_obj.expand_check_vars(probe_obj.CHECKS_AVAIL) self.assertIsNotNone(check_vars) plugin_vars = probe_obj.get_plugin_vars() self.assertIsNotNone(plugin_vars)
def testProbeViews(self): # All Probes available probes = get_probes_avail() total_probes_count = len(probes) self.assertIsNotNone(probes) self.assertGreater(total_probes_count, 0, 'zero Probes found in app') for probe in probes: plugin_obj = Factory.create_obj(probe) self.assertIsNotNone(plugin_obj, 'Probe create err: %s' % probe) # Probes per Resource Type resource_types = ['OGC:WMS', 'OGC:WFS', 'OGC:CSW', 'OGC:SOS'] for resource_type in resource_types: probes = get_probes_avail(resource_type) self.assertIsNotNone(probes) self.assertGreater( len(probes), 0, 'zero Probes for resource type %s' % resource_type) self.assertGreater( total_probes_count, len(probes), 'total Probes must be greater than for %s' % resource_type) for probe in probes: plugin_obj = Factory.create_obj(probe) self.assertIsNotNone(plugin_obj, 'cannot create Probe for %s' % probe) # Probes per Resource instance resources = Resource.query.all() for resource in resources: probes = get_probes_avail(resource.resource_type, resource) self.assertIsNotNone(probes) self.assertGreater(len(probes), 0, 'zero Probes for resource %s' % resource) for probe in probes: plugin_obj = Factory.create_obj(probe) self.assertIsNotNone(plugin_obj, 'Probe create err: %s' % resource.url)
def geocode(value, spatial_keyword_type='hostname'): """convenience function to geocode a value""" lat, lon = 0.0, 0.0 geocoder = Factory.create_obj(CONFIG['GEOIP']['plugin']) geocoder.init(CONFIG['GEOIP']['parameters']) try: lat, lon = geocoder.locate(urlparse(value).hostname) except Exception as err: # skip storage msg = 'Could not derive coordinates: %s' % err LOGGER.warning(msg) return lat, lon
def get_check_edit_form(check_class): """get the form to edit a Check""" check_obj = Factory.create_obj(check_class) check_info = check_obj.get_plugin_vars() check_vars = CheckVars( None, check_class, check_obj.get_default_parameter_values()) return render_template('includes/check_edit_form.html', lang=g.current_lang, check=check_vars, check_info=check_info)
def get_check_edit_form(check_class): """get the form to edit a Check""" check_obj = Factory.create_obj(check_class) check_info = check_obj.get_plugin_vars() check_vars = CheckVars( None, check_class, check_obj.get_default_parameter_values()) # print(str(check_info)) return render_template('includes/check_edit_form.html', lang=g.current_lang, check=check_vars, check_info=check_info)
def get_auth_defs(): """ Get available ResourceAuth definitions. :return: dict keyed by NAME with object instance values """ auth_classes = Plugin.get_plugins( baseclass='GeoHealthCheck.resourceauth.ResourceAuth') result = {} for auth_class in auth_classes: auth_obj = Factory.create_obj(auth_class) result[auth_obj.NAME] = auth_obj return result
def expand_check_vars(self, checks_avail): for check_class in checks_avail: check_avail = checks_avail[check_class] check = Factory.create_obj(check_class) check_vars = Plugin.copy(check.get_plugin_vars()) # Check if Probe class overrides Check Params # mainly "value" entries. if 'set_params' in check_avail: set_params = check_avail['set_params'] for set_param in set_params: if set_param in check_vars['PARAM_DEFS']: param_orig = check_vars['PARAM_DEFS'][set_param] param_override = set_params[set_param] param_def = Plugin.merge(param_orig, param_override) check_vars['PARAM_DEFS'][set_param] = param_def checks_avail[check_class] = check_vars return checks_avail
def expand_check_vars(self, checks_avail): for check_class in checks_avail: check_avail = checks_avail[check_class] check = Factory.create_obj(check_class) check_vars = Plugin.copy(check.get_plugin_vars()) # Check if Probe class overrides Check Params # mainly "value" entries. if 'set_params' in check_avail: set_params = check_avail['set_params'] for set_param in set_params: if set_param in check_vars['PARAM_DEFS']: param_orig = check_vars['PARAM_DEFS'][set_param] param_override = set_params[set_param] param_def = Plugin.merge(param_orig, param_override) check_vars['PARAM_DEFS'][set_param] = param_def checks_avail[check_class] = check_vars return checks_avail
def get_probes_avail(resource_type=None): """ Get all available Probes with their attributes. :param resource_type: optional resource type e.g. OGC:WMS :return: """ # Assume no resource type filters = None if resource_type: filters = [('RESOURCE_TYPE', resource_type), ('RESOURCE_TYPE', '*:*')] probe_classes = Plugin.get_plugins('GeoHealthCheck.probe.Probe', filters) result = dict() for probe_class in probe_classes: probe = Factory.create_obj(probe_class) result[probe_class] = probe.get_plugin_vars() return result
def testProbeMetadata(self): # Some probes cache metadata probe_class = 'GeoHealthCheck.plugins.probe.wms.WmsGetMapV1' plugin_obj = Factory.create_obj(probe_class) self.assertIsNotNone(plugin_obj) self.assertEqual(plugin_obj.layer_count, 0, 'non-zero layer_count %s' % probe_class) # Probes per Resource instance resources = Resource.query.all() for resource in resources: if resource.resource_type == 'OGC:WMS': md = plugin_obj.get_metadata(resource) md_c1 = plugin_obj.get_metadata_cached(resource, version='1.1.1') self.assertNotEqual(md, md_c1) md_c2 = plugin_obj.get_metadata_cached(resource, version='1.1.1') self.assertEqual(md_c1, md_c2) plugin_obj.expand_params(resource) for key in Probe.METADATA_CACHE: entry = Probe.METADATA_CACHE[key] self.assertIsNotNone(entry)
def probe_instance(self): return Factory.create_obj(self.probe_class)
def add(): """add resource""" if not g.user.is_authenticated(): return render_template('add.html') if request.method == 'GET': return render_template('add.html') tag_list = [] resource_type = request.form['resource_type'] tags = request.form.getlist('tags') url = request.form['url'].strip() resource = Resource.query.filter_by(resource_type=resource_type, url=url).first() if resource is not None: msg = gettext('Service already registered') flash('%s (%s, %s)' % (msg, resource_type, url), 'danger') if 'resource_type' in request.args: rtype = request.args.get('resource_type') return redirect( url_for('add', lang=g.current_lang, resource_type=rtype)) return redirect(url_for('add', lang=g.current_lang)) [title, success, response_time, message, start_time] = sniff_test_resource(APP.config, resource_type, url) if not success: flash(message, 'danger') return redirect( url_for('add', lang=g.current_lang, resource_type=resource_type)) if tags: for tag in tags: tag_found = False for tag_obj in Tag.query.all(): if tag == tag_obj.name: # use existing tag_found = True tag_list.append(tag_obj) if not tag_found: # add new tag_list.append(Tag(name=tag)) resource_to_add = Resource(current_user, resource_type, title, url, tags=tag_list) probe_to_add = None checks_to_add = [] # Always add a default Probe and Check(s) from the GHC_PROBE_DEFAULTS conf if resource_type in APP.config['GHC_PROBE_DEFAULTS']: resource_settings = APP.config['GHC_PROBE_DEFAULTS'][resource_type] probe_class = resource_settings['probe_class'] if probe_class: # Add the default Probe probe_obj = Factory.create_obj(probe_class) probe_to_add = ProbeVars(resource_to_add, probe_class, probe_obj.get_default_parameter_values()) # Add optional default (parameterized) Checks to add to this Probe checks_info = probe_obj.get_checks_info() checks_param_info = probe_obj.get_plugin_vars()['CHECKS_AVAIL'] for check_class in checks_info: check_param_info = checks_param_info[check_class] if 'default' in checks_info[check_class]: if checks_info[check_class]['default']: # Filter out params for Check with fixed values param_defs = check_param_info['PARAM_DEFS'] param_vals = {} for param in param_defs: if param_defs[param]['value']: param_vals[param] = param_defs[param]['value'] check_vars = CheckVars(probe_to_add, check_class, param_vals) checks_to_add.append(check_vars) result = run_test_resource(resource_to_add) run_to_add = Run(resource_to_add, result) DB.session.add(resource_to_add) if probe_to_add: DB.session.add(probe_to_add) for check_to_add in checks_to_add: DB.session.add(check_to_add) DB.session.add(run_to_add) try: DB.session.commit() msg = gettext('Service registered') flash('%s (%s, %s)' % (msg, resource_type, url), 'success') except Exception as err: DB.session.rollback() flash(str(err), 'danger') return redirect(url_for('home', lang=g.current_lang)) else: return edit_resource(resource_to_add.identifier)
def add(): """add resource""" if not g.user.is_authenticated(): return render_template('add.html') if request.method == 'GET': return render_template('add.html') resource_type = request.form['resource_type'] tags = request.form.getlist('tags') url = request.form['url'].strip() resources_to_add = [] from healthcheck import sniff_test_resource, run_test_resource sniffed_resources = sniff_test_resource(CONFIG, resource_type, url) if not sniffed_resources: msg = gettext("No resources detected") LOGGER.exception() flash(msg, 'danger') for ( resource_type, resource_url, title, success, response_time, message, start_time, resource_tags, ) in sniffed_resources: # sniffed_resources may return list of resource # types different from initial one # so we need to test each row separately resource = Resource.query.filter_by(resource_type=resource_type, url=url).first() if resource is not None: msg = gettext('Service already registered') flash('%s (%s, %s)' % (msg, resource_type, url), 'danger') if len(sniffed_resources) == 1 and 'resource_type' in request.args: return redirect(url_for('add', lang=g.current_lang)) tags_to_add = [] for tag in chain(tags, resource_tags): tag_obj = tag if not isinstance(tag, Tag): tag_obj = Tag.query.filter_by(name=tag).first() if tag_obj is None: tag_obj = Tag(name=tag) tags_to_add.append(tag_obj) resource_to_add = Resource(current_user, resource_type, title, resource_url, tags=tags_to_add) resources_to_add.append(resource_to_add) probe_to_add = None checks_to_add = [] # Always add a default Probe and Check(s) # from the GHC_PROBE_DEFAULTS conf if resource_type in CONFIG['GHC_PROBE_DEFAULTS']: resource_settings = CONFIG['GHC_PROBE_DEFAULTS'][resource_type] probe_class = resource_settings['probe_class'] if probe_class: # Add the default Probe probe_obj = Factory.create_obj(probe_class) probe_to_add = ProbeVars( resource_to_add, probe_class, probe_obj.get_default_parameter_values()) # Add optional default (parameterized) # Checks to add to this Probe checks_info = probe_obj.get_checks_info() checks_param_info = probe_obj.get_plugin_vars()['CHECKS_AVAIL'] for check_class in checks_info: check_param_info = checks_param_info[check_class] if 'default' in checks_info[check_class]: if checks_info[check_class]['default']: # Filter out params for Check with fixed values param_defs = check_param_info['PARAM_DEFS'] param_vals = {} for param in param_defs: if param_defs[param]['value']: param_vals[param] = \ param_defs[param]['value'] check_vars = CheckVars(probe_to_add, check_class, param_vals) checks_to_add.append(check_vars) result = run_test_resource(resource_to_add) run_to_add = Run(resource_to_add, result) DB.session.add(resource_to_add) # prepopulate notifications for current user resource_to_add.set_recipients('email', [g.user.email]) if probe_to_add: DB.session.add(probe_to_add) for check_to_add in checks_to_add: DB.session.add(check_to_add) DB.session.add(run_to_add) try: DB.session.commit() msg = gettext('Services registered') flash('%s (%s, %s)' % (msg, resource_type, url), 'success') except Exception as err: DB.session.rollback() flash(str(err), 'danger') return redirect(url_for('home', lang=g.current_lang)) if len(resources_to_add) == 1: return edit_resource(resources_to_add[0].identifier) return redirect(url_for('home', lang=g.current_lang))
def add(): """add resource""" if not g.user.is_authenticated(): return render_template('add.html') if request.method == 'GET': return render_template('add.html') resource_type = request.form['resource_type'] tags = request.form.getlist('tags') url = request.form['url'].strip() resources_to_add = [] sniffed_resources = sniff_test_resource(CONFIG, resource_type, url) if not sniffed_resources: msg = gettext("No resources detected") LOGGER.exception() flash(msg, 'danger') for (resource_type, resource_url, title, success, response_time, message, start_time, resource_tags,) in sniffed_resources: # sniffed_resources may return list of resource # types different from initial one # so we need to test each row separately resource = Resource.query.filter_by(resource_type=resource_type, url=url).first() if resource is not None: msg = gettext('Service already registered') flash('%s (%s, %s)' % (msg, resource_type, url), 'danger') if len(sniffed_resources) == 1 and 'resource_type' in request.args: return redirect(url_for('add', lang=g.current_lang)) tags_to_add = [] for tag in chain(tags, resource_tags): tag_obj = tag if not isinstance(tag, Tag): tag_obj = Tag.query.filter_by(name=tag).first() if tag_obj is None: tag_obj = Tag(name=tag) tags_to_add.append(tag_obj) resource_to_add = Resource(current_user, resource_type, title, resource_url, tags=tags_to_add) resources_to_add.append(resource_to_add) probe_to_add = None checks_to_add = [] # Always add a default Probe and Check(s) # from the GHC_PROBE_DEFAULTS conf if resource_type in CONFIG['GHC_PROBE_DEFAULTS']: resource_settings = CONFIG['GHC_PROBE_DEFAULTS'][resource_type] probe_class = resource_settings['probe_class'] if probe_class: # Add the default Probe probe_obj = Factory.create_obj(probe_class) probe_to_add = ProbeVars( resource_to_add, probe_class, probe_obj.get_default_parameter_values()) # Add optional default (parameterized) # Checks to add to this Probe checks_info = probe_obj.get_checks_info() checks_param_info = probe_obj.get_plugin_vars()['CHECKS_AVAIL'] for check_class in checks_info: check_param_info = checks_param_info[check_class] if 'default' in checks_info[check_class]: if checks_info[check_class]['default']: # Filter out params for Check with fixed values param_defs = check_param_info['PARAM_DEFS'] param_vals = {} for param in param_defs: if param_defs[param]['value']: param_vals[param] =\ param_defs[param]['value'] check_vars = CheckVars( probe_to_add, check_class, param_vals) checks_to_add.append(check_vars) result = run_test_resource(resource_to_add) run_to_add = Run(resource_to_add, result) DB.session.add(resource_to_add) # prepopulate notifications for current user resource_to_add.set_recipients('email', [g.user.email]) if probe_to_add: DB.session.add(probe_to_add) for check_to_add in checks_to_add: DB.session.add(check_to_add) DB.session.add(run_to_add) try: DB.session.commit() msg = gettext('Services registered') flash('%s (%s, %s)' % (msg, resource_type, url), 'success') except Exception as err: DB.session.rollback() flash(str(err), 'danger') return redirect(url_for('home', lang=g.current_lang)) if len(resources_to_add) == 1: return edit_resource(resources_to_add[0].identifier) return redirect(url_for('home', lang=g.current_lang))
def probe_instance(self): return Factory.create_obj(self.probe_class)