22# =================================================================
33#
44# Authors: Tom Kralidis <tomkralidis@gmail.com>
5+ # Just van den Broecke <justb4@gmail.com>
56#
67# Copyright (c) 2014 Tom Kralidis
78#
3738from flask .ext .babel import Babel , gettext
3839from flask .ext .login import (LoginManager , login_user , logout_user ,
3940 current_user , login_required )
41+ from flask_migrate import Migrate
4042
4143from __init__ import __version__
42- from healthcheck import run_test_resource
44+ from healthcheck import sniff_test_resource , run_test_resource
4345from init import DB
4446from enums import RESOURCE_TYPES
45- from models import Resource , Run , Tag , User
47+ from models import Resource , Run , ProbeVars , CheckVars , Tag , User
48+ from factory import Factory
4649from util import render_template2 , send_email
4750import views
4851
5255APP .config .from_pyfile ('../instance/config_site.py' )
5356APP .secret_key = APP .config ['SECRET_KEY' ]
5457
58+ MIGRATE = Migrate (APP , DB )
59+
5560LOGIN_MANAGER = LoginManager ()
5661LOGIN_MANAGER .init_app (APP )
5762
@@ -145,15 +150,15 @@ def cssize_reliability(value, css_type=None):
145150 number = int (value )
146151
147152 if APP .config ['GHC_RELIABILITY_MATRIX' ]['red' ]['min' ] <= number <= \
148- APP .config ['GHC_RELIABILITY_MATRIX' ]['red' ]['max' ]:
153+ APP .config ['GHC_RELIABILITY_MATRIX' ]['red' ]['max' ]:
149154 score = 'danger'
150155 panel = 'red'
151156 elif (APP .config ['GHC_RELIABILITY_MATRIX' ]['orange' ]['min' ] <= number <=
152- APP .config ['GHC_RELIABILITY_MATRIX' ]['orange' ]['max' ]):
157+ APP .config ['GHC_RELIABILITY_MATRIX' ]['orange' ]['max' ]):
153158 score = 'warning'
154159 panel = 'yellow'
155160 elif (APP .config ['GHC_RELIABILITY_MATRIX' ]['green' ]['min' ] <= number <=
156- APP .config ['GHC_RELIABILITY_MATRIX' ]['green' ]['max' ]):
161+ APP .config ['GHC_RELIABILITY_MATRIX' ]['green' ]['max' ]):
157162 score = 'success'
158163 panel = 'green'
159164 else : # should never really get here
@@ -204,7 +209,6 @@ def home():
204209 """homepage"""
205210
206211 resource_type = None
207- tag = None
208212
209213 if request .args .get ('resource_type' ) in RESOURCE_TYPES .keys ():
210214 resource_type = request .args ['resource_type' ]
@@ -250,7 +254,8 @@ def export():
250254 'min_response_time' : round (r .min_response_time , 2 ),
251255 'average_response_time' : round (r .average_response_time , 2 ),
252256 'max_response_time' : round (r .max_response_time , 2 ),
253- 'reliability' : round (r .reliability , 2 )
257+ 'reliability' : round (r .reliability , 2 ),
258+ 'last_report' : r .last_run .report
254259 })
255260 return jsonify (json_dict )
256261 elif request .url_rule .rule == '/csv' :
@@ -321,7 +326,8 @@ def export_resource(identifier):
321326 'last_run' : resource .last_run .checked_datetime .strftime (
322327 '%Y-%m-%dT%H:%M:%SZ' ),
323328 'history_csv' : history_csv ,
324- 'history_json' : history_json
329+ 'history_json' : history_json ,
330+ 'last_report' : resource .last_run .report
325331 }
326332 return jsonify (json_dict )
327333 elif 'csv' in request .url_rule .rule :
@@ -466,7 +472,7 @@ def add():
466472 resource_type = rtype ))
467473 return redirect (url_for ('add' , lang = g .current_lang ))
468474
469- [title , success , response_time , message , start_time ] = run_test_resource (
475+ [title , success , response_time , message , start_time ] = sniff_test_resource (
470476 APP .config , resource_type , url )
471477
472478 if not success :
@@ -486,19 +492,59 @@ def add():
486492
487493 resource_to_add = Resource (current_user , resource_type , title , url ,
488494 tags = tag_list )
489- run_to_add = Run (resource_to_add , success , response_time , message ,
490- start_time )
495+
496+ probe_to_add = None
497+ checks_to_add = []
498+
499+ # Always add a default Probe and Check(s) from the GHC_PROBE_DEFAULTS conf
500+ if resource_type in APP .config ['GHC_PROBE_DEFAULTS' ]:
501+ resource_settings = APP .config ['GHC_PROBE_DEFAULTS' ][resource_type ]
502+ probe_class = resource_settings ['probe_class' ]
503+ if probe_class :
504+ # Add the default Probe
505+ probe_obj = Factory .create_obj (probe_class )
506+ probe_to_add = ProbeVars (
507+ resource_to_add , probe_class ,
508+ probe_obj .get_default_parameter_values ())
509+
510+ # Add optional default (parameterized) Checks to add to this Probe
511+ checks_info = probe_obj .get_checks_info ()
512+ checks_param_info = probe_obj .get_plugin_vars ()['CHECKS_AVAIL' ]
513+ for check_class in checks_info :
514+ check_param_info = checks_param_info [check_class ]
515+ if 'default' in checks_info [check_class ]:
516+ if checks_info [check_class ]['default' ]:
517+ # Filter out params for Check with fixed values
518+ param_defs = check_param_info ['PARAM_DEFS' ]
519+ param_vals = {}
520+ for param in param_defs :
521+ if param_defs [param ]['value' ]:
522+ param_vals [param ] = param_defs [param ]['value' ]
523+ check_vars = CheckVars (
524+ probe_to_add , check_class , param_vals )
525+ checks_to_add .append (check_vars )
526+
527+ result = run_test_resource (resource_to_add )
528+
529+ run_to_add = Run (resource_to_add , result )
491530
492531 DB .session .add (resource_to_add )
532+ if probe_to_add :
533+ DB .session .add (probe_to_add )
534+ for check_to_add in checks_to_add :
535+ DB .session .add (check_to_add )
493536 DB .session .add (run_to_add )
537+
494538 try :
495539 DB .session .commit ()
496540 msg = gettext ('Service registered' )
497541 flash ('%s (%s, %s)' % (msg , resource_type , url ), 'success' )
498542 except Exception as err :
499543 DB .session .rollback ()
500544 flash (str (err ), 'danger' )
501- return redirect (url_for ('home' , lang = g .current_lang ))
545+ return redirect (url_for ('home' , lang = g .current_lang ))
546+ else :
547+ return edit_resource (resource_to_add .identifier )
502548
503549
504550@APP .route ('/resource/<int:resource_identifier>/update' , methods = ['POST' ])
@@ -544,6 +590,26 @@ def update(resource_identifier):
544590 resource .tags .remove (tag_to_delete )
545591
546592 update_counter += 1
593+ elif key == 'probes' :
594+ # Remove all existing ProbeVars for Resource
595+ for probe_var in resource .probe_vars :
596+ resource .probe_vars .remove (probe_var )
597+
598+ # Add ProbeVars anew each with optional CheckVars
599+ for probe in value :
600+ print ('adding Probe class=%s parms=%s' %
601+ (probe ['probe_class' ], str (probe )))
602+ probe_vars = ProbeVars (resource , probe ['probe_class' ],
603+ probe ['parameters' ])
604+ for check in probe ['checks' ]:
605+ check_vars = CheckVars (
606+ probe_vars , check ['check_class' ],
607+ check ['parameters' ])
608+ probe_vars .check_vars .append (check_vars )
609+
610+ resource .probe_vars .append (probe_vars )
611+
612+ update_counter += 1
547613
548614 elif getattr (resource , key ) != resource_identifier_dict [key ]:
549615 # Update other resource attrs, mainly 'name'
@@ -562,10 +628,10 @@ def update(resource_identifier):
562628 if err :
563629 status = str (err )
564630
565- return str ({'status' : status })
631+ return jsonify ({'status' : status })
566632
567633
568- @APP .route ('/resource/<int:resource_identifier>/test' )
634+ @APP .route ('/resource/<int:resource_identifier>/test' , methods = [ 'GET' , 'POST' ] )
569635@login_required
570636def test (resource_identifier ):
571637 """test a resource"""
@@ -574,17 +640,35 @@ def test(resource_identifier):
574640 flash (gettext ('Resource not found' ), 'danger' )
575641 return redirect (request .referrer )
576642
577- [ title , success , response_time , message , start_time ] = run_test_resource (
578- APP . config , resource . resource_type , resource . url )
643+ result = run_test_resource (
644+ resource )
579645
580- if message not in ['OK' , None , 'None' ]:
581- msg = gettext ('ERROR' )
582- flash ('%s: %s' % (msg , message ), 'danger' )
583- else :
584- flash (gettext ('Resource tested successfully' ), 'success' )
646+ if request .method == 'GET' :
647+ if result .message not in ['OK' , None , 'None' ]:
648+ msg = gettext ('ERROR' )
649+ flash ('%s: %s' % (msg , result .message ), 'danger' )
650+ else :
651+ flash (gettext ('Resource tested successfully' ), 'success' )
585652
586- return redirect (url_for ('get_resource_by_id' , lang = g .current_lang ,
587- identifier = resource_identifier ))
653+ return redirect (url_for ('get_resource_by_id' , lang = g .current_lang ,
654+ identifier = resource_identifier ))
655+ elif request .method == 'POST' :
656+ return jsonify (result .get_report ())
657+
658+
659+ @APP .route ('/resource/<int:resource_identifier>/edit' )
660+ @login_required
661+ def edit_resource (resource_identifier ):
662+ """edit a resource"""
663+ resource = Resource .query .filter_by (identifier = resource_identifier ).first ()
664+ if resource is None :
665+ flash (gettext ('Resource not found' ), 'danger' )
666+ return redirect (request .referrer )
667+
668+ probes_avail = views .get_probes_avail (resource .resource_type )
669+
670+ return render_template ('edit_resource.html' , lang = g .current_lang ,
671+ resource = resource , probes_avail = probes_avail )
588672
589673
590674@APP .route ('/resource/<int:resource_identifier>/delete' )
@@ -619,6 +703,45 @@ def delete(resource_identifier):
619703 return redirect (url_for (request .referrer ))
620704
621705
706+ @APP .route ('/probe/<string:probe_class>/edit_form' )
707+ @login_required
708+ def get_probe_edit_form (probe_class ):
709+ """get the form to edit a Probe"""
710+
711+ probe_obj = Factory .create_obj (probe_class )
712+ probe_info = probe_obj .get_plugin_vars ()
713+ probe_vars = ProbeVars (
714+ None , probe_class , probe_obj .get_default_parameter_values ())
715+ # checks_avail = probe_obj.expand_check_vars(probe_obj.CHECKS_AVAIL)
716+ # for check_class in checks_avail:
717+ # check_obj = Factory.create_obj(check_class)
718+ # # check_info = check_obj.get_plugin_vars()
719+ # check_vars = CheckVars(
720+ # probe_vars, check_class, check_obj.get_default_parameter_values())
721+ # probe_vars.check_vars.append(check_vars)
722+ print (str (probe_vars ))
723+
724+ return render_template ('includes/probe_edit_form.html' ,
725+ lang = g .current_lang ,
726+ probe = probe_vars , probe_info = probe_info )
727+
728+
729+ @APP .route ('/check/<string:check_class>/edit_form' )
730+ @login_required
731+ def get_check_edit_form (check_class ):
732+ """get the form to edit a Check"""
733+
734+ check_obj = Factory .create_obj (check_class )
735+ check_info = check_obj .get_plugin_vars ()
736+ check_vars = CheckVars (
737+ None , check_class , check_obj .get_default_parameter_values ())
738+
739+ print (str (check_info ))
740+ return render_template ('includes/check_edit_form.html' ,
741+ lang = g .current_lang ,
742+ check = check_vars , check_info = check_info )
743+
744+
622745@APP .route ('/login' , methods = ['GET' , 'POST' ])
623746def login ():
624747 """login"""
@@ -655,7 +778,7 @@ def recover():
655778 if request .method == 'GET' :
656779 return render_template ('recover_password.html' )
657780 username = request .form ['username' ]
658- registered_user = User .query .filter_by (username = username ,).first ()
781+ registered_user = User .query .filter_by (username = username , ).first ()
659782 if registered_user is None :
660783 flash (gettext ('Invalid username' ), 'danger' )
661784 return redirect (url_for ('recover' , lang = g .current_lang ))
@@ -679,8 +802,26 @@ def recover():
679802 return redirect (url_for ('home' , lang = g .current_lang ))
680803
681804
805+ #
806+ # REST Interface Calls
807+ #
808+
809+
810+ @APP .route ('/api/v1.0/probes-avail/' )
811+ @APP .route ('/api/v1.0/probes-avail/<resource_type>' )
812+ def api_probes_avail (resource_type = None ):
813+ """
814+ Get available (configured) Probes for this
815+ installation, optional for resource type
816+ """
817+
818+ probes = views .get_probes_avail (resource_type )
819+ return jsonify (probes )
820+
821+
682822if __name__ == '__main__' : # run locally, for fun
683823 import sys
824+
684825 HOST = '0.0.0.0'
685826 PORT = 8000
686827 if len (sys .argv ) > 1 :
0 commit comments