зеркало из https://github.com/mozilla/MozDef.git
Merge pull request #76 from netantho/averez-27-dashboards-listing
Dynamic Kibana dashboards listing
This commit is contained in:
Коммит
86cd2a9ca0
|
@ -191,12 +191,12 @@ You may want to edit the app/lib/settings.js file to properly point to your elas
|
|||
Then start meteor with::
|
||||
|
||||
meteor
|
||||
|
||||
|
||||
|
||||
Node
|
||||
******
|
||||
|
||||
Alternatively you can run the meteor UI in 'deployment' mode using a native node installation.
|
||||
Alternatively you can run the meteor UI in 'deployment' mode using a native node installation.
|
||||
|
||||
First install node::
|
||||
|
||||
|
@ -206,31 +206,31 @@ First install node::
|
|||
cd node-v0.10.25
|
||||
python configure
|
||||
make
|
||||
make install
|
||||
make install
|
||||
|
||||
Then bundle the meteor portion of mozdef::
|
||||
|
||||
cd <your meteor mozdef directory>
|
||||
meteor bundle mozdef.tgz
|
||||
|
||||
You can then deploy the meteor UI for mozdef as necessary::
|
||||
You can then deploy the meteor UI for mozdef as necessary::
|
||||
|
||||
scp mozdef.tgz to your target host
|
||||
tar -xvzf mozdef.tgz
|
||||
|
||||
|
||||
This will create a 'bundle' directory with the entire UI code below that directory.
|
||||
|
||||
|
||||
You will need to update the settings.js file to match your servername/port::
|
||||
|
||||
vim bundle/programs/server/app/app/lib/settings.js
|
||||
|
||||
|
||||
If your development OS is different than your production OS you will also need to update
|
||||
the fibers node module::
|
||||
the fibers node module::
|
||||
|
||||
cd bundle/programs/server/node_modules
|
||||
rm -rf fibers
|
||||
sudo npm install fibers@1.0.1
|
||||
|
||||
|
||||
Then run the mozdef UI via node::
|
||||
|
||||
export MONGO_URL=mongodb://mongoservername:3002/meteor
|
||||
|
@ -273,6 +273,8 @@ We use `uwsgi`_ to interface python and nginx::
|
|||
cp uwsgi ~/envs/mozdef/bin/
|
||||
|
||||
cd rest
|
||||
# modify settings.py
|
||||
vim settings.py
|
||||
# modify uwsgi.ini
|
||||
vim uwsgi.ini
|
||||
uwsgi --ini uwsgi.ini
|
||||
|
|
|
@ -6,13 +6,12 @@
|
|||
standard-app-packages
|
||||
autopublish
|
||||
insecure
|
||||
preserve-inputs
|
||||
bootstrap
|
||||
accounts-ui
|
||||
accounts-password
|
||||
backbone
|
||||
|
||||
iron-router
|
||||
http
|
||||
accounts-persona
|
||||
d3
|
||||
iron-router
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
0.8.0
|
|
@ -0,0 +1,52 @@
|
|||
<!--
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
Copyright (c) 2014 Mozilla Corporation
|
||||
|
||||
Contributors:
|
||||
Jeff Bryner jbryner@mozilla.com
|
||||
Anthony Verez averez@mozilla.com
|
||||
-->
|
||||
|
||||
<template name="menu">
|
||||
<div id="header" role="banner">
|
||||
<h2><a class="mozdef" href="/" title="MOZDEF">MOZDEF</a></h2>
|
||||
<div id="nav-main" role="navigation">
|
||||
<ul>
|
||||
<li class="first"><a href="#">Kibana dashboards</a>
|
||||
<ul>
|
||||
{{#each kibanadashboards as item}}
|
||||
{{>kibanaDashboardItem}}
|
||||
{{/each}}
|
||||
</ul>
|
||||
</li>
|
||||
<li class="first"><a href="/events/">Events</a>
|
||||
<ul>
|
||||
<li class="first"><a href="/logincounts/">logincounts</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="/alerts/">Alerts</a>
|
||||
<ul>
|
||||
<li class="last"><a href="/alerts/setup">setup</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="/Incidents">Incidents</a>
|
||||
<ul>
|
||||
<li class="first"><a href="/incidents/new/">new incident</a></li>
|
||||
<li class="last"><a href="/incidents/attackers">attackers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="/about">About</a></li>
|
||||
</ul>
|
||||
<a class="mozilla" href="http://mozilla.org"><img src="/images/mozilla-tab.png"></a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template name="kibanaDashboardItem">
|
||||
<li class="first">
|
||||
<a href="{{url}}">{{name}}</a>
|
||||
</li>
|
||||
</template>
|
||||
|
|
@ -30,6 +30,12 @@ if (Meteor.isClient) {
|
|||
}
|
||||
});
|
||||
|
||||
// loads kibana dashboards
|
||||
Template.menu.kibanadashboards = function() {
|
||||
Meteor.call('loadKibanaDashboards');
|
||||
return kibanadashboards.find();
|
||||
}
|
||||
|
||||
//helper functions for handlebars
|
||||
UI.registerHelper('now', function() {
|
||||
return new Date();
|
||||
|
@ -413,7 +419,7 @@ if (Meteor.isClient) {
|
|||
.range([0, maxRadius]);
|
||||
|
||||
|
||||
d3.json(mozdef.ldapLoginDataURL, function(error, jsondata) {
|
||||
d3.json(mozdef.rootAPI + '/ldapLogins/' , function(error, jsondata) {
|
||||
//console.log(jsondata)
|
||||
r.domain([0, d3.max(jsondata, function(d) { return d.success+ d.failures; })])
|
||||
jsondata.forEach(function(d){
|
||||
|
@ -583,7 +589,7 @@ if (Meteor.isClient) {
|
|||
.range([0, maxRadius]);
|
||||
|
||||
|
||||
d3.json(mozdef.alertDataURL, function(error, jsondata) {
|
||||
d3.json(mozdef.rootAPI + '/alerts/', function(error, jsondata) {
|
||||
if (typeof console !== 'undefined')
|
||||
console.log(error)
|
||||
r.domain([0, d3.max(jsondata, function(d) { return d.count; })])
|
||||
|
|
|
@ -8,9 +8,11 @@ Contributors:
|
|||
Jeff Bryner jbryner@mozilla.com
|
||||
*/
|
||||
|
||||
//common collections used by clients/server
|
||||
incidents=new Meteor.Collection("incidents");
|
||||
events=new Meteor.Collection("events");
|
||||
alerts=new Meteor.Collection("alerts");
|
||||
eshealth=new Meteor.Collection("eshealth");
|
||||
veris=new Meteor.Collection("veris");
|
||||
// common collections used by clients/server
|
||||
incidents = new Meteor.Collection("incidents");
|
||||
events = new Meteor.Collection("events");
|
||||
alerts = new Meteor.Collection("alerts");
|
||||
eshealth = new Meteor.Collection("eshealth");
|
||||
veris = new Meteor.Collection("veris");
|
||||
kibanadashboards = new Meteor.Collection("kibanadashboards");
|
||||
|
||||
|
|
|
@ -10,19 +10,16 @@ Jeff Bryner jbryner@mozilla.com
|
|||
|
||||
//configuration settings
|
||||
|
||||
elasticsearch={
|
||||
address:"http://localhost:9200/",
|
||||
healthurl:"_cluster/health",
|
||||
docstatsurl:"_stats/docs"
|
||||
elasticsearch = {
|
||||
address: "http://localhost:9200/",
|
||||
healthurl: "_cluster/health",
|
||||
docstatsurl: "_stats/docs",
|
||||
}
|
||||
|
||||
|
||||
mozdef={
|
||||
rootURL:"https://localhost",
|
||||
port:"443",
|
||||
ldapKibana:"http://localhost:9090/#/dashboard/elasticsearch/mozdef%20ldap%20dashboard",
|
||||
eventsKibana:"http://localhost:9090/index.html#/dashboard/elasticsearch/Logstash%20Style%20Search",
|
||||
alertsKibana:"http://localhost:9090/index.html#/dashboard/elasticsearch/Alerts",
|
||||
ldapLoginDataURL:"http://localhost:8081/ldapLogins/", // rest server
|
||||
alertDataURL:"http://localhost:8081/alerts/" // rest server
|
||||
mozdef = {
|
||||
rootURL: "https://localhost",
|
||||
port: "443",
|
||||
rootAPI: "http://localhost:8081"
|
||||
}
|
||||
|
||||
|
|
|
@ -10,43 +10,62 @@ Jeff Bryner jbryner@mozilla.com
|
|||
|
||||
//public functions
|
||||
Meteor.methods({
|
||||
'saySomething':saySomething,
|
||||
'refreshESStatus':refreshESStatus
|
||||
'saySomething': saySomething,
|
||||
'refreshESStatus': refreshESStatus,
|
||||
'loadKibanaDashboards': loadKibanaDashboards
|
||||
});
|
||||
|
||||
function saySomething() {
|
||||
console.log("something is said");
|
||||
}
|
||||
|
||||
function saySomething(){
|
||||
console.log("something is said")
|
||||
function refreshESStatus() {
|
||||
console.log('Refreshing elastic search cluster stats for: ' + elasticsearch.address);
|
||||
var esHealthRequest = HTTP.get(elasticsearch.address + elasticsearch.healthurl);
|
||||
if (esHealthRequest.statusCode==200 && esHealthRequest.data) {
|
||||
//get doc count and add it to the health request data
|
||||
var esDocStatsRequest = HTTP.get(elasticsearch.address + elasticsearch.docstatsurl);
|
||||
if (esDocStatsRequest.statusCode==200 && esDocStatsRequest.data) {
|
||||
//set the current doc stats
|
||||
if (esDocStatsRequest["data"]["_all"]["total"]["docs"]) {
|
||||
esHealthRequest["data"]["total_docs"] = esDocStatsRequest["data"]["_all"]["total"]["docs"].count;
|
||||
}
|
||||
else {
|
||||
esHealthRequest["data"]["total_docs"] = 0;
|
||||
}
|
||||
console.log('Total Docs: ' + esHealthRequest["data"]["total_docs"]);
|
||||
}
|
||||
|
||||
function refreshESStatus(){
|
||||
console.log('Refreshing elastic search cluster stats for: ' + elasticsearch.address);
|
||||
esHealthRequest=HTTP.get(elasticsearch.address + elasticsearch.healthurl)
|
||||
if (esHealthRequest.statusCode==200 && esHealthRequest.data) {
|
||||
//set current status of the elastic search cluster
|
||||
console.log("Updating elastic search cluster health");
|
||||
eshealth.remove({});
|
||||
eshealth.insert(esHealthRequest["data"]);
|
||||
console.log(esHealthRequest["data"]);
|
||||
} else {
|
||||
//note the error
|
||||
console.log("Could not retrieve elastic search cluster health..check settings");
|
||||
console.log(elasticsearch.address + elasticsearch.healthurl);
|
||||
console.log("returned a " + esHealthRequest.statusCode);
|
||||
console.log(esHealthRequest["data"]);
|
||||
}
|
||||
}
|
||||
|
||||
//get doc count and add it to the health request data
|
||||
esDocStatsRequest=HTTP.get(elasticsearch.address + elasticsearch.docstatsurl)
|
||||
if (esDocStatsRequest.statusCode==200 && esDocStatsRequest.data ) {
|
||||
//set the current doc stats
|
||||
if (esDocStatsRequest["data"]["_all"]["total"]["docs"]) {
|
||||
esHealthRequest["data"]["total_docs"]=esDocStatsRequest["data"]["_all"]["total"]["docs"].count
|
||||
}
|
||||
else {
|
||||
esHealthRequest["data"]["total_docs"] = 0
|
||||
}
|
||||
console.log('Total Docs: '+ esHealthRequest["data"]["total_docs"])
|
||||
}
|
||||
function loadKibanaDashboards() {
|
||||
console.log('Loading Kibana dashboards... ' + mozdef.rootAPI + '/kibanadashboards');
|
||||
var dashboardsRequest = HTTP.get(mozdef.rootAPI + '/kibanadashboards');
|
||||
if (dashboardsRequest.statusCode==200 && dashboardsRequest.data) {
|
||||
// set the current dashboards in the mongo collection
|
||||
console.log("Updating kibana dashboards...");
|
||||
kibanadashboards.remove({});
|
||||
dashboardsRequest.data.forEach(function(dashboard, index, arr) {
|
||||
kibanadashboards.insert(dashboard);
|
||||
});
|
||||
console.log(dashboardsRequest.data);
|
||||
} else {
|
||||
console.log("Could not retrieve kibana dashboards... check settings");
|
||||
console.log(mozdef.rootAPI + '/kibanadashboards');
|
||||
console.log("returned a " + dashboardsRequest.statusCode);
|
||||
console.log(dashboardsRequest.data);
|
||||
}
|
||||
}
|
||||
|
||||
//set current status of the elastic search cluster
|
||||
console.log("Updating elastic search cluster health")
|
||||
eshealth.remove({})
|
||||
eshealth.insert(esHealthRequest["data"])
|
||||
console.log(esHealthRequest["data"])
|
||||
}else{
|
||||
//note the error
|
||||
console.log("Could not retrieve elastic search cluster health..check settings")
|
||||
console.log(elasticsearch.address + elasticsearch.healthurl)
|
||||
console.log("returned a " + esHealthRequest.statusCode)
|
||||
console.log(esHealthRequest["data"])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,36 +28,7 @@ Anthony Verez averez@mozilla.com
|
|||
<title>mozdef::mozilla defense platform</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="header" role="banner">
|
||||
<h2><a class="mozdef" href="/" title="MOZDEF">MOZDEF</a></h2>
|
||||
<div id="nav-main" role="navigation">
|
||||
<ul>
|
||||
<li class="first"><a href="/events/">Events</a>
|
||||
<ul>
|
||||
<li class="first"><a href="/logincounts/">logincounts</a></li>
|
||||
<li><a target=" _blank" href="{{mozdef.ldapKibana}}">ldap kibana</a></li>
|
||||
<li class="last"><a target=" _blank" href="{{mozdef.eventsKibana}}">events kibana</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li ><a href="/alerts/">Alerts</a>
|
||||
<ul>
|
||||
<li class="first"><a target="_blank" href="{{mozdef.alertsKibana}}">alerts kibana</a></li>
|
||||
<li class="last"><a href="/alerts/setup">setup</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="/Incidents">Incidents</a>
|
||||
<ul>
|
||||
<li class="first"><a href="/incidents/new/">new incident</a></li>
|
||||
<li class="last"><a href="/incidents/attackers">attackers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="/about">About</a></li>
|
||||
</ul>
|
||||
<a class="mozilla" href="http://mozilla.org"><img src="/images/mozilla-tab.png"></a>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{{> menu}}
|
||||
<div class="loginButtons" >
|
||||
{{#if loggingIn}}
|
||||
Logging In
|
||||
|
@ -81,10 +52,9 @@ Anthony Verez averez@mozilla.com
|
|||
<template name="layout">
|
||||
|
||||
<div>
|
||||
|
||||
{{#if currentUser}}
|
||||
{{>yield}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"packages": {
|
||||
"iron-router": {},
|
||||
"accounts-persona": {}
|
||||
"accounts-persona": {},
|
||||
"iron-router": {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,19 +2,24 @@
|
|||
"meteor": {},
|
||||
"dependencies": {
|
||||
"basePackages": {
|
||||
"iron-router": {},
|
||||
"accounts-persona": {}
|
||||
"accounts-persona": {},
|
||||
"iron-router": {}
|
||||
},
|
||||
"packages": {
|
||||
"iron-router": {
|
||||
"git": "https://github.com/EventedMind/iron-router.git",
|
||||
"tag": "v0.6.2",
|
||||
"commit": "ce56e58b45624dce992490f3a1c10f10d3948bae"
|
||||
},
|
||||
"accounts-persona": {
|
||||
"git": "https://github.com/vladikoff/meteor-accounts-persona.git",
|
||||
"tag": "v0.1.6",
|
||||
"commit": "5b8110dad901a69f674e6a0381e074567fe1b4d9"
|
||||
},
|
||||
"iron-router": {
|
||||
"git": "https://github.com/EventedMind/iron-router.git",
|
||||
"tag": "v0.7.1",
|
||||
"commit": "d1ffb3f06ea4c112132b030f2eb1a70b81675ecb"
|
||||
},
|
||||
"blaze-layout": {
|
||||
"git": "https://github.com/EventedMind/blaze-layout.git",
|
||||
"tag": "v0.2.4",
|
||||
"commit": "b40e9b0612329288d75cf52ad14a7da64bb8618f"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
211
rest/index.py
211
rest/index.py
|
@ -5,13 +5,13 @@
|
|||
#
|
||||
# Contributors:
|
||||
# Jeff Bryner jbryner@mozilla.com
|
||||
# Anthony Verez averez@mozilla.com
|
||||
|
||||
import sys
|
||||
import bottle
|
||||
from bottle import debug,route, run, template, response,request,post, default_app
|
||||
from bottle import _stdout as bottlelog
|
||||
from bottle import debug,route, run, response, request, default_app
|
||||
import json
|
||||
from configlib import getConfig,OptionParser
|
||||
from configlib import getConfig, OptionParser
|
||||
import pyes
|
||||
from elasticutils import S
|
||||
from datetime import datetime
|
||||
|
@ -19,8 +19,10 @@ from datetime import timedelta
|
|||
from dateutil.parser import parse
|
||||
import pytz
|
||||
|
||||
options=None
|
||||
options = None
|
||||
# cors decorator for rest/ajax
|
||||
|
||||
|
||||
def enable_cors(fn):
|
||||
def _enable_cors(*args, **kwargs):
|
||||
# set CORS headers
|
||||
|
@ -34,12 +36,14 @@ def enable_cors(fn):
|
|||
|
||||
return _enable_cors
|
||||
|
||||
|
||||
@route('/test')
|
||||
@route('/test/')
|
||||
def index():
|
||||
ip = request.environ.get('REMOTE_ADDR')
|
||||
#response.headers['X-IP'] = '{0}'.format(ip)
|
||||
response.status=200
|
||||
response.status = 200
|
||||
|
||||
|
||||
@route('/status')
|
||||
@route('/status/')
|
||||
|
@ -47,10 +51,11 @@ def index():
|
|||
if request.body:
|
||||
request.body.read()
|
||||
request.body.close()
|
||||
response.status=200
|
||||
response.content_type="application/json"
|
||||
response.status = 200
|
||||
response.content_type = "application/json"
|
||||
return(json.dumps(dict(status='ok')))
|
||||
|
||||
|
||||
@route('/ldapLogins')
|
||||
@route('/ldapLogins/')
|
||||
@enable_cors
|
||||
|
@ -58,8 +63,8 @@ def index():
|
|||
if request.body:
|
||||
request.body.read()
|
||||
request.body.close()
|
||||
response.content_type="application/json"
|
||||
return(esLdapResults())
|
||||
response.content_type = "application/json"
|
||||
return(esLdapResults())
|
||||
|
||||
|
||||
@route('/alerts')
|
||||
|
@ -69,42 +74,55 @@ def index():
|
|||
if request.body:
|
||||
request.body.read()
|
||||
request.body.close()
|
||||
response.content_type="application/json"
|
||||
return(esAlertsSummary())
|
||||
|
||||
response.content_type = "application/json"
|
||||
return(esAlertsSummary())
|
||||
|
||||
|
||||
@route('/kibanadashboards')
|
||||
@route('/kibanadashboards/')
|
||||
@enable_cors
|
||||
def index():
|
||||
if request.body:
|
||||
request.body.read()
|
||||
request.body.close()
|
||||
response.content_type = "application/json"
|
||||
return(kibanaDashboards())
|
||||
|
||||
|
||||
#debug(True)
|
||||
def toUTC(suspectedDate,localTimeZone="US/Pacific"):
|
||||
def toUTC(suspectedDate, localTimeZone="US/Pacific"):
|
||||
'''make a UTC date out of almost anything'''
|
||||
utc=pytz.UTC
|
||||
objDate=None
|
||||
if type(suspectedDate)==str:
|
||||
objDate=parse(suspectedDate,fuzzy=True)
|
||||
elif type(suspectedDate)==datetime:
|
||||
objDate=suspectedDate
|
||||
|
||||
utc = pytz.UTC
|
||||
objDate = None
|
||||
if type(suspectedDate) == str:
|
||||
objDate = parse(suspectedDate, fuzzy=True)
|
||||
elif type(suspectedDate) == datetime:
|
||||
objDate = suspectedDate
|
||||
|
||||
if objDate.tzinfo is None:
|
||||
objDate=pytz.timezone(localTimeZone).localize(objDate)
|
||||
objDate=utc.normalize(objDate)
|
||||
objDate = pytz.timezone(localTimeZone).localize(objDate)
|
||||
objDate = utc.normalize(objDate)
|
||||
else:
|
||||
objDate=utc.normalize(objDate)
|
||||
objDate = utc.normalize(objDate)
|
||||
if objDate is not None:
|
||||
objDate=utc.normalize(objDate)
|
||||
|
||||
objDate = utc.normalize(objDate)
|
||||
|
||||
return objDate
|
||||
|
||||
|
||||
def esAlertsSummary(begindateUTC=None, enddateUTC=None):
|
||||
resultsList=list()
|
||||
resultsList = list()
|
||||
if begindateUTC is None:
|
||||
begindateUTC=datetime.now() - timedelta(hours=12)
|
||||
begindateUTC=toUTC(begindateUTC)
|
||||
begindateUTC = datetime.now() - timedelta(hours=12)
|
||||
begindateUTC = toUTC(begindateUTC)
|
||||
if enddateUTC is None:
|
||||
enddateUTC= datetime.now()
|
||||
enddateUTC= toUTC(enddateUTC)
|
||||
enddateUTC = datetime.now()
|
||||
enddateUTC = toUTC(enddateUTC)
|
||||
try:
|
||||
|
||||
#q=S().es(urls=['http://{0}:{1}'.format(options.esserver,options.esport)]).query(_type='alert').filter(utctimestamp__range=[begindateUTC.isoformat(),enddateUTC.isoformat()])
|
||||
#f=q.facet_raw(alerttype={"terms" : {"script_field" : "_source.type","size" : 500}})
|
||||
|
||||
|
||||
#get all alerts
|
||||
#q= S().es(urls=['http://{0}:{1}'.format(options.esserver,options.esport)]).query(_type='alert')
|
||||
q= S().es(urls=list('{0}'.format(s) for s in options.esservers)).query(_type='alert')
|
||||
|
@ -114,80 +132,119 @@ def esAlertsSummary(begindateUTC=None, enddateUTC=None):
|
|||
"facet_filter":{'range': {'utctimestamp': \
|
||||
{'gte': begindateUTC.isoformat(), 'lte': enddateUTC.isoformat()}}}\
|
||||
|
||||
})
|
||||
})
|
||||
return(json.dumps(f.facet_counts()['alerttype']))
|
||||
|
||||
except Exception as e :
|
||||
sys.stderr.write('%r'%e)
|
||||
|
||||
|
||||
except Exception as e:
|
||||
sys.stderr.write('%r' % e)
|
||||
|
||||
|
||||
def esLdapResults(begindateUTC=None, enddateUTC=None):
|
||||
resultsList=list()
|
||||
resultsList = list()
|
||||
if begindateUTC is None:
|
||||
begindateUTC=datetime.now() - timedelta(hours=12)
|
||||
begindateUTC=toUTC(begindateUTC)
|
||||
begindateUTC = datetime.now() - timedelta(hours=12)
|
||||
begindateUTC = toUTC(begindateUTC)
|
||||
if enddateUTC is None:
|
||||
enddateUTC= datetime.now()
|
||||
enddateUTC= toUTC(enddateUTC)
|
||||
enddateUTC = datetime.now()
|
||||
enddateUTC = toUTC(enddateUTC)
|
||||
try:
|
||||
es=pyes.ES((list('{0}'.format(s) for s in options.esservers)))
|
||||
es = pyes.ES((list('{0}'.format(s) for s in options.esservers)))
|
||||
#qDate=e=pyes.MatchQuery("message",options.datePhrase,"phrase")
|
||||
qDate=pyes.RangeQuery(qrange=pyes.ESRange('utctimestamp',from_value=begindateUTC,to_value=enddateUTC))
|
||||
qDate = pyes.RangeQuery(qrange=pyes.ESRange('utctimestamp',
|
||||
from_value=begindateUTC, to_value=enddateUTC))
|
||||
q = pyes.MatchAllQuery()
|
||||
q = pyes.FilteredQuery(q,qDate)
|
||||
q = pyes.FilteredQuery(q,pyes.TermFilter('tags','ldap'))
|
||||
q = pyes.FilteredQuery(q,pyes.TermFilter('details.result','ldap_invalid_credentials'))
|
||||
q2=q.search()
|
||||
q = pyes.FilteredQuery(q, qDate)
|
||||
q = pyes.FilteredQuery(q, pyes.TermFilter('tags', 'ldap'))
|
||||
q = pyes.FilteredQuery(q,
|
||||
pyes.TermFilter('details.result', 'ldap_invalid_credentials'))
|
||||
q2 = q.search()
|
||||
q2.facet.add_term_facet('details.result')
|
||||
q2.facet.add_term_facet('details.dn',size=20)
|
||||
results=es.search(q2, indices='events')
|
||||
q2.facet.add_term_facet('details.dn', size=20)
|
||||
results = es.search(q2, indices='events')
|
||||
#sys.stdout.write('{0}\n'.format(results.facets))
|
||||
|
||||
stoplist=('o','mozilla','dc','com','mozilla.com','mozillafoundation.org','org')
|
||||
|
||||
stoplist = ('o', 'mozilla', 'dc', 'com', 'mozilla.com',
|
||||
'mozillafoundation.org', 'org')
|
||||
for t in results.facets['details.dn'].terms:
|
||||
if t['term'] in stoplist:
|
||||
continue
|
||||
#print(t['term'])
|
||||
failures=0
|
||||
success=0
|
||||
dn=t['term']
|
||||
failures = 0
|
||||
success = 0
|
||||
dn = t['term']
|
||||
|
||||
#re-query with the terms of the details.dn
|
||||
qt = pyes.MatchAllQuery()
|
||||
qt = pyes.FilteredQuery(qt,qDate)
|
||||
qt = pyes.FilteredQuery(qt,pyes.TermFilter('tags','ldap'))
|
||||
qt = pyes.FilteredQuery(qt,pyes.TermFilter('details.dn',t['term']))
|
||||
qt2=qt.search()
|
||||
qt = pyes.FilteredQuery(qt, qDate)
|
||||
qt = pyes.FilteredQuery(qt, pyes.TermFilter('tags', 'ldap'))
|
||||
qt = pyes.FilteredQuery(qt,
|
||||
pyes.TermFilter('details.dn', t['term']))
|
||||
qt2 = qt.search()
|
||||
qt2.facet.add_term_facet('details.result')
|
||||
results=es.search(qt2)
|
||||
results = es.search(qt2)
|
||||
#sys.stdout.write('{0}\n'.format(results.facets['details.result'].terms))
|
||||
|
||||
|
||||
for t in results.facets['details.result'].terms:
|
||||
#print(t['term'],t['count'])
|
||||
if t['term']=='ldap_success':
|
||||
success=t['count']
|
||||
if t['term']=='ldap_invalid_credentials':
|
||||
failures=t['count']
|
||||
resultsList.append(dict(dn=dn,failures=failures,success=success,begin=begindateUTC.isoformat(),end=enddateUTC.isoformat()))
|
||||
|
||||
if t['term'] == 'ldap_success':
|
||||
success = t['count']
|
||||
if t['term'] == 'ldap_invalid_credentials':
|
||||
failures = t['count']
|
||||
resultsList.append(dict(dn=dn, failures=failures,
|
||||
success=success, begin=begindateUTC.isoformat(),
|
||||
end=enddateUTC.isoformat()))
|
||||
|
||||
return(json.dumps(resultsList))
|
||||
except pyes.exceptions.NoServerAvailable:
|
||||
sys.stderr.write('Elastic Search server could not be reached, check network connectivity\n')
|
||||
|
||||
|
||||
|
||||
|
||||
def kibanaDashboards():
|
||||
try:
|
||||
resultsList = []
|
||||
es = pyes.ES((list('{0}'.format(s) for s in options.esservers)))
|
||||
r = es.search(pyes.Search(pyes.MatchAllQuery(), size=100),
|
||||
'kibana-int', 'dashboard')
|
||||
if r:
|
||||
for dashboard in r:
|
||||
dashboardJson = json.loads(dashboard.dashboard)
|
||||
resultsList.append({
|
||||
'name': dashboardJson['title'],
|
||||
'url': "%s/%s/%s" % (options.kibanaurl,
|
||||
"index.html#/dashboard/elasticsearch",
|
||||
dashboardJson['title'])
|
||||
})
|
||||
return json.dumps(resultsList)
|
||||
else:
|
||||
sys.stderr.write('No Kibana dashboard found\n')
|
||||
except pyes.exceptions.NoServerAvailable:
|
||||
sys.stderr.write('Elastic Search server could not be reached, check network connectivity\n')
|
||||
|
||||
|
||||
def initConfig():
|
||||
#change this to your default zone for when it's not specified
|
||||
options.defaultTimeZone=getConfig('defaulttimezone','US/Pacific',options.configfile)
|
||||
options.esservers=list(getConfig('esservers','http://localhost:9200',options.configfile).split(','))
|
||||
options.defaultTimeZone = getConfig('defaulttimezone', 'US/Pacific',
|
||||
options.configfile)
|
||||
options.esservers = list(getConfig('esservers', 'http://localhost:9200',
|
||||
options.configfile).split(','))
|
||||
options.kibanaurl = getConfig('kibanaurl', 'http://localhost:9090',
|
||||
options.configfile)
|
||||
print(options)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser=OptionParser()
|
||||
parser.add_option("-c", dest='configfile' , default=sys.argv[0].replace('.py','.conf'), help="configuration file to use")
|
||||
(options,args) = parser.parse_args()
|
||||
parser = OptionParser()
|
||||
parser.add_option("-c", dest='configfile',
|
||||
default=sys.argv[0].replace('.py', '.conf'),
|
||||
help="configuration file to use")
|
||||
(options, args) = parser.parse_args()
|
||||
initConfig()
|
||||
run(host="localhost", port=8081)
|
||||
else:
|
||||
parser=OptionParser()
|
||||
parser.add_option("-c", dest='configfile' , default=sys.argv[0].replace('.py','.conf'), help="configuration file to use")
|
||||
(options,args) = parser.parse_args()
|
||||
initConfig()
|
||||
parser = OptionParser()
|
||||
parser.add_option("-c", dest='configfile',
|
||||
default=sys.argv[0].replace('.py', '.conf'),
|
||||
help="configuration file to use")
|
||||
(options, args) = parser.parse_args()
|
||||
initConfig()
|
||||
application = default_app()
|
||||
|
|
Загрузка…
Ссылка в новой задаче