diff --git a/app/create_db.py b/app/create_db.py index cc4b6613..fca42693 100644 --- a/app/create_db.py +++ b/app/create_db.py @@ -518,7 +518,7 @@ def update_db_v_3(**kwargs): except sqltool.Error as e: if kwargs.get('silent') != 1: if e.args[0] == 'duplicate column name: section' or e == " 1060 (42S21): Duplicate column name 'section' ": - print('DB was update to 3.0 It\' last version') + print('Updating... go to version 3.2') else: print("An error occurred:", e) return False @@ -558,7 +558,7 @@ def update_db_v_31(**kwargs): except sqltool.Error as e: if kwargs.get('silent') != 1: if e.args[0] == 'duplicate column name: desc' or e == "1060 (42S21): Duplicate column name 'desc' ": - print('DB was update to 3.0 It\' last version') + print('') else: print("An error occurred:", e) return False @@ -567,6 +567,42 @@ def update_db_v_31(**kwargs): return True cur.close() con.close() + +def update_db_v_3_2(**kwargs): + con, cur = get_cur() + sql = """CREATE TABLE IF NOT EXISTS `waf` (`server_id` INTEGER UNIQUE, metrics INTEGER); """ + try: + cur.execute(sql) + con.commit() + except sqltool.Error as e: + if kwargs.get('silent') != 1: + if e.args[0] == 'duplicate column name: server_id' or e == "1060 (42S21): Duplicate column name 'server_id' ": + print('DB was updated') + else: + print("An error occurred:", e.args[0]) + return False + else: + return True + cur.close() + con.close() + +def update_db_v_3_21(**kwargs): + con, cur = get_cur() + sql = """CREATE TABLE IF NOT EXISTS `waf_metrics` (`serv` varchar(64), conn INTEGER, `date` DATETIME default '0000-00-00 00:00:00'); """ + try: + cur.execute(sql) + con.commit() + except sqltool.Error as e: + if kwargs.get('silent') != 1: + if e.args[0] == 'duplicate column name: token' or e == "1060 (42S21): Duplicate column name 'token' ": + print('Updating... go to version 2.6') + else: + print("An error occurred:", e.args[0]) + return False + else: + return True + cur.close() + con.close() def update_all(): update_db_v_2_0_1() @@ -586,6 +622,8 @@ def update_all(): update_db_v_2_91() update_db_v_3() update_db_v_31() + update_db_v_3_2() + update_db_v_3_21() def update_all_silent(): update_db_v_2_0_1(silent=1) @@ -605,4 +643,6 @@ def update_all_silent(): update_db_v_2_91(silent=1) update_db_v_3(silent=1) update_db_v_31(silent=1) + update_db_v_3_2(silent=1) + update_db_v_3_21(silent=1) \ No newline at end of file diff --git a/app/funct.py b/app/funct.py index b8ef1b36..594c2003 100644 --- a/app/funct.py +++ b/app/funct.py @@ -270,16 +270,12 @@ def install_haproxy(serv, **kwargs): " STATS_USER="+stats_user+" STATS_PASS="+stats_password ] upload(serv, tmp_config_path, script) + os.system("rm -f %s" % script) ssh_command(serv, commands, print_out="1") if kwargs.get('syn_flood') == "1": syn_flood_protect(serv) - if kwargs.get('waf') == "1": - waf_install(serv) - - os.system("rm -f %s" % script) - def syn_flood_protect(serv, **kwargs): import sql script = "syn_flood_protect.sh" @@ -295,9 +291,8 @@ def syn_flood_protect(serv, **kwargs): commands = [ "chmod +x "+tmp_config_path+script, tmp_config_path+script+ " "+enable ] upload(serv, tmp_config_path, script) - ssh_command(serv, commands, print_out="1") - os.system("rm -f %s" % script) + ssh_command(serv, commands, print_out="1") def waf_install(serv, **kwargs): import sql @@ -313,9 +308,9 @@ def waf_install(serv, **kwargs): " HAPROXY_PATH="+haproxy_dir +" VERSION="+ver ] upload(serv, tmp_config_path, script) - ssh_command(serv, commands, print_out="1") - os.system("rm -f %s" % script) + sql.insert_waf_metrics_enable(serv, "0") + ssh_command(serv, commands, print_out="1") def check_haproxy_version(serv): import sql diff --git a/app/metrics.py b/app/metrics.py index 4589c26a..0c261dc7 100644 --- a/app/metrics.py +++ b/app/metrics.py @@ -15,9 +15,7 @@ try: cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) user_id = cookie.get('uuid') user = sql.get_user_name_by_uuid(user_id.value) - servers = sql.get_dick_permit() token = sql.get_token(user_id.value) - table_stat = sql.select_table_metrics(user_id.value) except: pass diff --git a/app/options.py b/app/options.py index b52f4d6e..a6805eed 100644 --- a/app/options.py +++ b/app/options.py @@ -114,7 +114,7 @@ if act == "overview": ovw.get_overview() if act == "overviewwaf": - ovw.get_overviewWaf() + ovw.get_overviewWaf(form.getvalue('page')) if act == "overviewServers": ovw.get_overviewServers() @@ -389,8 +389,14 @@ if form.getvalue('masteradd'): os.system("rm -f %s" % script) if form.getvalue('haproxyaddserv'): - funct.install_haproxy(form.getvalue('haproxyaddserv'), syn_flood=form.getvalue('syn_flood'), waf=form.getvalue('waf')) + funct.install_haproxy(form.getvalue('haproxyaddserv'), syn_flood=form.getvalue('syn_flood')) +if form.getvalue('installwaf'): + funct.waf_install(form.getvalue('installwaf')) + +if form.getvalue('metrics_waf'): + sql.update_waf_metrics_enable(form.getvalue('metrics_waf'), form.getvalue('enable')) + if form.getvalue('table_metrics'): import http.cookies from jinja2 import Environment, FileSystemLoader @@ -489,6 +495,78 @@ if form.getvalue('metrics'): grid = gridplot(plots, ncols=2, plot_width=800, plot_height=250, toolbar_location = "left", toolbar_options=dict(logo=None)) show(grid) +if form.getvalue('waf_metrics'): + from datetime import timedelta + from bokeh.plotting import figure, output_file, show + from bokeh.models import ColumnDataSource, HoverTool, DatetimeTickFormatter, DatePicker + from bokeh.layouts import widgetbox, gridplot + from bokeh.models.widgets import Button, RadioButtonGroup, Select + import pandas as pd + import http.cookies + + cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) + user_id = cookie.get('uuid') + servers = sql.select_waf_servers_metrics(user_id.value) + + p = {} + for serv in servers: + serv = serv[0] + p[serv] = {} + metric = sql.select_waf_metrics(serv) + metrics = {} + + for i in metric: + rep_date = str(i[2]) + metrics[rep_date] = {} + metrics[rep_date]['conn'] = str(i[1]) + + df = pd.DataFrame.from_dict(metrics, orient="index") + df = df.fillna(0) + df.index = pd.to_datetime(df.index) + df.index.name = 'Date' + df.sort_index(inplace=True) + source = ColumnDataSource(df) + + output_file("templates/metrics_waf_out.html") + + x_min = df.index.min() - pd.Timedelta(hours=1) + x_max = df.index.max() + pd.Timedelta(minutes=1) + + p[serv] = figure( + tools="pan,box_zoom,reset,xwheel_zoom", + title=metric[0][0], + x_axis_type="datetime", y_axis_label='Connections', + x_range = (x_max.timestamp()*1000-60*100000, x_max.timestamp()*1000) + ) + + hover = HoverTool( + tooltips=[ + ("Connections", "@conn"), + ], + mode='mouse' + ) + + p[serv].ygrid.band_fill_color = "#f3f8fb" + p[serv].ygrid.band_fill_alpha = 0.9 + p[serv].y_range.start = 0 + p[serv].y_range.end = int(df['conn'].max()) + 150 + p[serv].add_tools(hover) + p[serv].title.text_font_size = "20px" + + + p[serv].line("Date", "conn", source=source, alpha=0.5, color='#5cb85c', line_width=2, legend="Conn") + p[serv].legend.orientation = "horizontal" + p[serv].legend.location = "top_left" + p[serv].legend.padding = 5 + + plots = [] + i = 0 + for key, value in p.items(): + plots.append(value) + + grid = gridplot(plots, ncols=2, plot_width=800, plot_height=250, toolbar_location = "left", toolbar_options=dict(logo=None)) + show(grid) + if form.getvalue('get_hap_v'): output = funct.check_haproxy_version(serv) print(output) diff --git a/app/ovw.py b/app/ovw.py index 8088a3d5..dff776f1 100644 --- a/app/ovw.py +++ b/app/ovw.py @@ -29,7 +29,7 @@ def get_overview(): template = template.render(service_status = servers, role = sql.get_user_role_by_uuid(user_id.value)) print(template) -def get_overviewWaf(): +def get_overviewWaf(url): import http.cookies from jinja2 import Environment, FileSystemLoader env = Environment(loader=FileSystemLoader('templates/ajax')) @@ -46,10 +46,10 @@ def get_overviewWaf(): for server in listhap: server_status = () - server_status = (server[1],server[2], funct.ssh_command(server[2], commands), funct.ssh_command(server[2], commands1)) + server_status = (server[1],server[2], funct.ssh_command(server[2], commands), funct.ssh_command(server[2], commands1), sql.select_waf_metrics_enable_server(server[2])) servers.append(server_status) - template = template.render(service_status = servers, role = sql.get_user_role_by_uuid(user_id.value)) + template = template.render(service_status = servers, role = sql.get_user_role_by_uuid(user_id.value), url=url) print(template) def get_overviewServers(): diff --git a/app/scripts/waf.sh b/app/scripts/waf.sh index c5b6c3a0..7ba115ee 100644 --- a/app/scripts/waf.sh +++ b/app/scripts/waf.sh @@ -28,7 +28,8 @@ fi if [ -f $HAPROXY_PATH/waf/modsecurity.conf ];then echo -e 'error: Haproxy WAF already installed. You can edit confighere

' exit 1 -fiif hash apt-get 2>/dev/null; then +fi +if hash apt-get 2>/dev/null; then sudo apt-get install yajl-dev libevent-dev httpd-dev libxml2-dev gcc curl-dev -y else wget -O /tmp/yajl-devel-2.0.4-4.el7.x86_64.rpm http://rpmfind.net/linux/centos/7.5.1804/os/x86_64/Packages/yajl-devel-2.0.4-4.el7.x86_64.rpm diff --git a/app/sql.py b/app/sql.py index 2468d2b0..f4cf0fbc 100644 --- a/app/sql.py +++ b/app/sql.py @@ -652,6 +652,137 @@ def insert_mentrics(serv, curr_con, cur_ssl_con, sess_rate, max_sess_rate): cur.close() con.close() +def select_waf_metrics_enable(id): + con, cur = create_db.get_cur() + sql = """ select waf.metrics from waf left join servers as serv on waf.server_id = serv.id where server_id = '%s' """ % id + try: + cur.execute(sql) + except sqltool.Error as e: + print('An error occurred: ' + e.args[0] + ' X') + else: + return cur.fetchall() + cur.close() + con.close() + +def select_waf_metrics_enable_server(ip): + con, cur = create_db.get_cur() + sql = """ select waf.metrics from waf left join servers as serv on waf.server_id = serv.id where ip = '%s' """ % ip + try: + cur.execute(sql) + except sqltool.Error as e: + print('An error occurred: ' + e.args[0] + ' X') + else: + for enable in cur.fetchall(): + return enable[0] + cur.close() + con.close() + +def select_waf_servers(): + con, cur = create_db.get_cur() + sql = """ select serv.ip from waf left join servers as serv on waf.server_id = serv.id where waf.metrics = '1'""" + try: + cur.execute(sql) + except sqltool.Error as e: + print('An error occurred: ' + e.args[0] + ' X') + else: + return cur.fetchall() + cur.close() + con.close() + +def select_waf_servers_metrics(uuid, **kwargs): + con, cur = create_db.get_cur() + sql = """ select * from user where username = '%s' """ % get_user_name_by_uuid(uuid) + + if kwargs.get('disable') == 0: + disable = 'or enable = 0' + else: + disable = '' + + try: + cur.execute(sql) + except sqltool.Error as e: + print("An error occurred:", e) + else: + for group in cur: + if group[5] == '1': + sql = """ select servers.ip from servers left join waf as waf on waf.server_id = servers.id where servers.enable = 1 %s and waf.metrics = '1' """ % (disable) + else: + sql = """ select servers.ip from servers left join waf as waf on waf.server_id = servers.id where servers.enable = 1 %s and waf.metrics = '1' and servers.groups like '%{group}%' """.format(group=group[5]) + try: + cur.execute(sql) + except sqltool.Error as e: + print("An error occurred:", e.args[0]) + else: + return cur.fetchall() + cur.close() + con.close() + +def select_waf_metrics(serv, **kwargs): + con, cur = create_db.get_cur() + sql = """ select * from waf_metrics where serv = '%s' order by `date` desc """ % serv + try: + cur.execute(sql) + except sqltool.Error as e: + print('An error occurred: ' + e + ' X') + else: + return cur.fetchall() + cur.close() + con.close() + +def insert_waf_metrics_enable(serv, enable): + con, cur = create_db.get_cur() + sql = """ insert into waf (server_id, metrics) values((select id from servers where ip = '%s'), '%s') """ % (serv, enable) + try: + cur.execute(sql) + con.commit() + except sqltool.Error as e: + print('An error occurred: ' + e.args[0] + ' X') + con.rollback() + cur.close() + con.close() + +def insert_waf_mentrics(serv, conn): + con, cur = create_db.get_cur() + if mysql_enable == '1': + sql = """ insert into waf_metrics (serv, conn, date) values('%s', '%s', now()) """ % (serv, con) + else: + sql = """ insert into waf_metrics (serv, conn, date) values('%s', '%s', datetime('now', 'localtime')) """ % (serv, conn) + try: + cur.execute(sql) + con.commit() + except sqltool.Error as e: + print('An error occurred: ' + e.args[0] + ' X') + con.rollback() + cur.close() + con.close() + +def delete_waf_mentrics(): + con, cur = create_db.get_cur() + if mysql_enable == '1': + sql = """ delete from metrics where date < now() - INTERVAL 3 day """ + else: + sql = """ delete from metrics where date < datetime('now', '-3 days') """ + try: + cur.execute(sql) + con.commit() + except sqltool.Error as e: + print('An error occurred: ' + e.args[0] + ' X') + con.rollback() + cur.close() + con.close() + +def update_waf_metrics_enable(name, enable): + con, cur = create_db.get_cur() + sql = """ update waf set metrics = %s where server_id = (select id from servers where hostname = '%s') """ % (enable, name) + try: + cur.execute(sql) + con.commit() + except sqltool.Error as e: + print('An error occurred: ' + e.args[0] + ' X') + con.rollback() + cur.close() + con.close() + def delete_mentrics(): con, cur = create_db.get_cur() if mysql_enable == '1': diff --git a/app/templates/ajax/overivewWaf.html b/app/templates/ajax/overivewWaf.html index 337be011..423168a2 100644 --- a/app/templates/ajax/overivewWaf.html +++ b/app/templates/ajax/overivewWaf.html @@ -1,4 +1,5 @@ {% for service in service_status %} + {% if service.3 or url == "waf.py" %} {{ service.0 }} @@ -27,9 +28,21 @@ {% if service.3 %} {{ service.3 }} {%else %} - WAF not installed + {% endif %} + {% if url == "waf.py" %} + + {% if service.3 %} + {% if service.4|int() == 1 %} + + {% else %} + + {% endif %} + {% endif %} + + {% endif %} + {% endif %} {% endfor %} \ No newline at end of file diff --git a/app/templates/base.html b/app/templates/base.html index 8d09503d..ade98679 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -2,6 +2,9 @@ {{title}} - HAproxy-WI + + + +{% endblock %} \ No newline at end of file diff --git a/app/tools/metrics_master.py b/app/tools/metrics_master.py index 92859635..33be65b5 100644 --- a/app/tools/metrics_master.py +++ b/app/tools/metrics_master.py @@ -20,6 +20,7 @@ class GracefulKiller: def main(): sql.delete_mentrics() + sql.delete_waf_mentrics() servers = sql.select_servers_metrics_for_master() started_workers = get_worker() servers_list = [] @@ -37,6 +38,24 @@ def main(): if need_start: for serv in need_start: start_worker(serv) + + waf_servers = sql.select_waf_servers() + waf_started_workers = get_waf_worker() + waf_servers_list = [] + + for serv in waf_servers: + waf_servers_list.append(serv[0]) + + waf_need_kill=list(set(waf_started_workers) - set(waf_servers_list)) + waf_need_start=list(set(waf_servers_list) - set(waf_started_workers)) + + if waf_need_kill: + for serv in waf_need_kill: + kill_waf_worker(serv) + + if waf_need_start: + for serv in waf_need_start: + start_waf_worker(serv) def start_worker(serv): port = sql.get_setting('haproxy_sock_port') @@ -50,6 +69,19 @@ def kill_worker(serv): funct.logging("localhost", " Masrer killed metrics worker for: "+serv, metrics=1) if stderr: funct.logging("localhost", stderr, metrics=1) + +def start_waf_worker(serv): + port = sql.get_setting('haproxy_sock_port') + cmd = "tools/metrics_waf_worker.py %s --port %s &" % (serv, port) + os.system(cmd) + funct.logging("localhost", " Masrer started new metrics worker for: "+serv, metrics=1) + +def kill_waf_worker(serv): + cmd = "ps ax |grep 'tools/metrics_waf_worker.py %s'|grep -v grep |awk '{print $1}' |xargs kill" % serv + output, stderr = funct.subprocess_execute(cmd) + funct.logging("localhost", " Masrer killed metrics worker for: "+serv, metrics=1) + if stderr: + funct.logging("localhost", stderr, metrics=1) def kill_all_workers(): cmd = "ps ax |grep -e 'tools/metrics_worker.py\|tools/metrics_waf_worker.py' |grep -v grep |awk '{print $1}' |xargs kill" @@ -65,6 +97,13 @@ def get_worker(): funct.logging("localhost", stderr, metrics=1) return output +def get_waf_worker(): + cmd = "ps ax |grep 'tools/metrics_waf_worker.py' |grep -v grep |awk '{print $7}'" + output, stderr = funct.subprocess_execute(cmd) + if stderr: + funct.logging("localhost", stderr, metrics=1) + return output + if __name__ == "__main__": funct.logging("localhost", " Metrics master started", metrics=1) killer = GracefulKiller() diff --git a/app/tools/metrics_waf_worker.py b/app/tools/metrics_waf_worker.py new file mode 100644 index 00000000..a35c412f --- /dev/null +++ b/app/tools/metrics_waf_worker.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +import subprocess +from subprocess import check_output, CalledProcessError +import time +import argparse +import os, sys +sys.path.append(os.path.join(sys.path[0], os.path.dirname(os.getcwd()))) +sys.path.append(os.path.join(sys.path[0], os.getcwd())) +import sql +import signal + +class GracefulKiller: + kill_now = False + def __init__(self): + signal.signal(signal.SIGINT, self.exit_gracefully) + signal.signal(signal.SIGTERM, self.exit_gracefully) + + def exit_gracefully(self,signum, frame): + self.kill_now = True + +def main(serv, port): + port = str(port) + firstrun = True + readstats = "" + killer = GracefulKiller() + + while True: + try: + cmd = "echo 'show stat' |nc "+serv+" "+port+" | cut -d ',' -f 1-2,34 |grep waf |grep BACKEND |awk -F',' '{print $3}'" + readstats = subprocess.check_output([cmd], shell=True) + except CalledProcessError as e: + print("Command error") + except OSError as e: + print(e) + sys.exit() + readstats = readstats.decode(encoding='UTF-8') + metric = readstats.splitlines() + metrics = [] + + if metric: + for i in range(0,len(metric)): + sql.insert_waf_mentrics(serv, metric[i]) + + time.sleep(10) + + if killer.kill_now: + break + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Metrics HAProxy service.', prog='metrics_worker.py', formatter_class=argparse.ArgumentDefaultsHelpFormatter) + + parser.add_argument('IP', help='Start get metrics from HAProxy service at this ip', nargs='?', type=str) + parser.add_argument('--port', help='Start get metrics from HAProxy service at this port', nargs='?', default=1999, type=int) + + args = parser.parse_args() + if args.IP is None: + parser.print_help() + import sys + sys.exit() + else: + try: + main(args.IP, args.port) + except KeyboardInterrupt: + pass \ No newline at end of file diff --git a/app/waf.py b/app/waf.py new file mode 100644 index 00000000..e3d0fce7 --- /dev/null +++ b/app/waf.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 +import os +import sql +import http +import funct +import sql +from jinja2 import Environment, FileSystemLoader +env = Environment(loader=FileSystemLoader('templates/')) +template = env.get_template('waf.html') + +print('Content-type: text/html\n') +funct.check_login() + +try: + cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) + user_id = cookie.get('uuid') + user = sql.get_user_name_by_uuid(user_id.value) + token = sql.get_token(user_id.value) +except: + pass + +template = template.render(h2 = 1, title = "Web application firewall", + autorefresh = 1, + role = sql.get_user_role_by_uuid(user_id.value), + user = user, + table_stat = sql.select_table_metrics(user_id.value), + token = token) +print(template) \ No newline at end of file diff --git a/inc/script.js b/inc/script.js index 065be087..ceb47afa 100644 --- a/inc/script.js +++ b/inc/script.js @@ -104,6 +104,11 @@ function startSetInterval(interval) { intervalId = setInterval('loadMetrics()', interval); loadMetrics(); } + else if (cur_url[0] == "waf.py") { + intervalId = setInterval('loadMetrics()', interval); + showOverviewWaf(); + loadMetrics(); + } } else { pauseAutoRefresh(); } @@ -156,11 +161,11 @@ function showOverview() { } ); } function showOverviewWaf() { - showOverviewServers(); $.ajax( { url: "options.py", data: { act: "overviewwaf", + page: cur_url[0], token: $('#token').val() }, type: "GET", @@ -168,6 +173,8 @@ function showOverviewWaf() { $("#ajaxwafstatus").empty(); $("#ajaxwafstatus").html(data); $.getScript('/inc/overview.js'); + $.getScript('/inc/waf.js'); + $.getScript(url); } } ); } diff --git a/inc/users.js b/inc/users.js index 9147854a..f298e4b4 100644 --- a/inc/users.js +++ b/inc/users.js @@ -100,13 +100,9 @@ $( function() { $('#install').click(function() { $("#ajax").html('') var syn_flood = 0; - var waf = 0; if ($('#syn_flood').is(':checked')) { syn_flood = '1'; } - if ($('#waf').is(':checked')) { - waf = '1'; - } $("#ajax").html('
Please don\'t close and don\'t represh page. Wait until the work is completed. This may take some time
'); $.ajax( { url: "options.py", @@ -128,9 +124,7 @@ $( function() { } } } ); - }); - //$('.alert-danger').remove(); - + }); $('#add-user').click(function() { $('#error').remove(); $.ajax( { @@ -393,7 +387,9 @@ $( function() { var id = $(this).attr('id').split('-'); updateTelegram(id[1]) }); + } ); + function updateSettings(param, val) { $('.alert-danger').remove(); $.ajax( { diff --git a/inc/waf.js b/inc/waf.js new file mode 100644 index 00000000..12846c9c --- /dev/null +++ b/inc/waf.js @@ -0,0 +1,50 @@ +$( function() { + $( "#ajaxwafstatus input" ).change(function() { + var id = $(this).attr('id'); + console.log(id); + metrics_waf(id); + }); +} ); +function metrics_waf(name) { + var enable = 0; + if ($('#'+name).is(':checked')) { + enable = '1'; + } + $.ajax( { + url: "options.py", + data: { + metrics_waf: name, + enable: enable, + token: $('#token').val() + }, + type: "GET", + success: function( data ) { + showOverviewWaf(); + setTimeout(function() { + $( "#"+name ).parent().parent().removeClass( "update" ); + }, 2500 ); + } + } ); +} +function installWaf(ip) { + $("#ajax").html('') + $("#ajax").html('
Please don\'t close and don\'t represh page. Wait until the work is completed. This may take some time
'); + $.ajax( { + url: "options.py", + data: { + installwaf: ip, + token: $('#token').val() + }, + type: "GET", + success: function( data ) { + data = data.replace(/\s+/g,' '); + if (data.indexOf('error') != '-1' || data.indexOf('Failed') != '-1') { + $("#ajax").html('
'+data+''); + } else if (data.indexOf('success') != '-1' ){ + $('.alert-danger').remove(); + $('.alert-warning').remove(); + $("#ajax").html('
'+data+''); + } + } + } ); +} \ No newline at end of file