broken
Harald Wolff 2019-06-28 10:01:30 +02:00
parent 67f69d4b1e
commit 07062a2c3a
19 changed files with 490 additions and 47 deletions

View File

@ -19,6 +19,7 @@ using ln.types.odb.index;
using ln.types.odb.values;
using ln.skyscanner.checks;
using System.Linq;
using ln.skyscanner.import.skytron;
namespace ln.skyscanner
{

View File

@ -34,7 +34,9 @@ namespace ln.skyscanner
public ODBCollection<Node> NodeCollection { get; private set; }
public ODBCollection<Subnet> SubnetCollection { get; private set; }
public ODBCollection<PointOfPresence> PointOfPresenceCollection { get; private set; }
public ODBCollection<L2Segment> L2SegmentCollection { get; private set; }
public ODBCollection<CrawledHost> CrawledHosts { get; private set; }
public ODBCollection<CrawledSubnet> CrawledSubnets { get; private set; }
@ -75,6 +77,9 @@ namespace ln.skyscanner
PointOfPresenceCollection = ODB.GetCollection<PointOfPresence>();
PointOfPresenceCollection.EnsureIndeces("ForeignName");
L2SegmentCollection = ODB.GetCollection<L2Segment>();
L2SegmentCollection.EnsureIndeces("Network","PoPs");
CrawledHosts = ODB.GetCollection<CrawledHost>();
CrawledHosts.EnsureIndeces("PrimaryIP","IPAddresses[]");

View File

@ -7,11 +7,12 @@ using System.IO;
using ln.skyscanner.crawl;
using ln.types.threads;
using System.Threading;
using sharp.logging;
using ln.logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using ln.skyscanner.checks;
using System.Collections.Generic;
using ln.skyscanner.import.skytron;
namespace ln.skyscanner
{
[JsonConverter(typeof(StringEnumConverter))]
@ -49,6 +50,9 @@ namespace ln.skyscanner
Arguments = args;
String skytronImport = null;
Queue<string> qArguments = new Queue<string>(Arguments);
while (qArguments.Count > 0)
{
@ -58,11 +62,21 @@ namespace ln.skyscanner
case "-p":
BasePath = Path.GetFullPath(qArguments.Dequeue());
break;
case "--import-skytron":
skytronImport = qArguments.Dequeue();
break;
}
}
Entities = new SkyEntities(this);
Checker = new SkyChecker();
if (skytronImport != null)
{
SkytronImport si = new SkytronImport(skytronImport);
si.Import();
}
}
private SkyScanner()
{

View File

@ -41,7 +41,7 @@ namespace ln.skyscanner.checks
static SkyCheck()
{
AddSkyCheck(new Hostalive());
AddSkyCheck(new Ubiquity());
AddSkyCheck(new Ubiquiti());
AddSkyCheck(new APC());
}
}

View File

@ -78,7 +78,7 @@ namespace ln.skyscanner.checks
if ((threadScheduler != null) && (threadScheduler.IsAlive))
throw new NotSupportedException("SkyChecker.scheduler() already running");
checkPool.SetPoolSize(256);
checkPool.SetPoolSize(128);
Thread.Sleep(2500);

View File

@ -8,10 +8,10 @@ using ln.logging;
namespace ln.skyscanner.checks
{
public class Ubiquity : SkyCheck
public class Ubiquiti : SkyCheck
{
public Ubiquity()
:base("ubiquity")
public Ubiquiti()
:base("ubiquiti")
{
}
@ -57,7 +57,7 @@ namespace ln.skyscanner.checks
public override bool IsValid(Node node)
{
return (node.Vendor != null) && node.Vendor.Equals("Ubiquity");
return (node.Vendor != null) && node.Vendor.Equals("Ubiquiti");
}
public override SkyCheckState PrepareCheckState(SkyChecker skyChecker, Node node)

View File

@ -0,0 +1,23 @@
using System;
using ln.types.odb.attributes;
using System.Collections.Generic;
using ln.types.net;
namespace ln.skyscanner.entities
{
public class L2Segment
{
[DocumentID]
public Guid ID = Guid.NewGuid();
public String Name;
public Network4 Network;
public String Comment;
public List<PointOfPresence> PoPs { get; } = new List<PointOfPresence>();
public L2Segment()
{
}
}
}

View File

@ -27,6 +27,7 @@ namespace ln.skyscanner.entities
public String PrimaryMac { get; set; }
public String Name { get; set; }
public String Comment { get; set; }
public DateTime Created { get; }
public DateTime LastUpdate { get; set; }

View File

@ -30,6 +30,15 @@ namespace ln.skyscanner.entities
public GeoLocation GeoLocation { get; set; }
public DateTime Created { get; private set; } = DateTime.Now;
[JsonIgnore]
public IEnumerable<L2Segment> L2Segments
{
get
{
return SkyScanner.Instance.Entities.L2SegmentCollection.Query("PoPs[]", this);
}
}
public PointOfPresence()
{
}

View File

@ -11,7 +11,7 @@ using System;
using ln.http.resources;
using ln.logging;
using System.Threading;
using sharp.logging;
using ln.logging;
namespace ln.skyscanner.http
{
public class SkyScannerHttpManagement : JsonCallResource

View File

@ -0,0 +1,200 @@
using System;
using MySql.Data.MySqlClient;
using ln.logging;
using ln.skyscanner.entities;
using System.Linq;
using ln.types.net;
using ln.types;
using System.Globalization;
namespace ln.skyscanner.import.skytron
{
public class SkytronImport
{
MySqlConnection mysql;
public SkytronImport(String connectionString)
{
mysql = new MySqlConnection(connectionString);
}
public void Import()
{
try
{
mysql.Open();
ImportStammdaten();
ImportNodes();
ImportL2Segmente();
} catch (Exception e)
{
Logging.Log(e);
if (mysql != null)
mysql.Close();
throw;
}
}
public void ImportStammdaten()
{
MySqlCommand command = mysql.CreateCommand();
command.CommandText = "SELECT * FROM sender_stammdaten";
using (MySqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
PointOfPresence pop = SkyScanner.Instance.Entities.PointOfPresenceCollection.Query("ForeignName", reader.GetInt32("senderid").ToString()).FirstOrDefault();
if (pop == null)
{
Logging.Log(LogLevel.INFO, "New PoP: {0} / {1}", reader.GetInt32("senderid"), reader.GetString("stationsname"));
pop = new PointOfPresence();
pop.ForeignName = reader.GetInt32("senderid").ToString();
pop.Name = reader.GetString("stationsname");
String lati = reader.GetString("koordinaten_breite");
String longi = reader.GetString("koordinaten_laenge");
if (!String.Empty.Equals(lati) && !String.Empty.Equals(longi))
pop.GeoLocation = new GeoLocation(float.Parse(lati,CultureInfo.InvariantCulture.NumberFormat),float.Parse(longi, CultureInfo.InvariantCulture.NumberFormat));
SkyScanner.Instance.Entities.PointOfPresenceCollection.Insert(pop);
}
}
}
}
public void ImportNodes()
{
MySqlCommand command = mysql.CreateCommand();
command.CommandText = "SELECT * FROM sender_ip_discovery";
using (MySqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
String id = reader.GetString("id");
IPv4 primaryIP = IPv4.Parse(reader.GetString("ip"));
Node node = SkyScanner.Instance.Entities.NodeCollection.Query("uniqueIdentity", id).FirstOrDefault();
if (node == null)
{
node = new Node(primaryIP);
node.UniqueIdentity = id;
Logging.Log(LogLevel.INFO, "New Node: {0} / {1}",id,primaryIP);
}
node.Vendor = reader.GetString("hersteller");
node.Product = reader.GetString("produkt");
node.Comment = reader.GetString("devicename");
if (reader.GetInt32("http_port") != 0)
{
node.RemoveURI("http");
node.AddURI(new URI(String.Format("http://{0}:{1}",
primaryIP,
reader.GetString("http_port")
)));
}
if (reader.GetInt32("ssh_port") != 0)
{
node.RemoveURI("ssh");
node.AddURI(new URI(String.Format("ssh://{0}:{1}@{2}:{3}",
reader.GetString("ssh_user"),
reader.GetString("ssh_passwort"),
primaryIP,
reader.GetString("ssh_port")
)));
}
if (!String.Empty.Equals(reader.GetString("snmp_community")))
{
node.RemoveURI("snmp");
node.AddURI(new URI(String.Format("snmp://{0}@{1}#1",
reader.GetString("snmp_community"),
primaryIP
)));
}
if (!String.Empty.Equals(reader.GetString("snmp_v3_user")))
{
node.RemoveURI("snmp");
node.AddURI(new URI(String.Format("snmp://{0}:{1}:{2}@{3}#3",
reader.GetString("snmp_v3_user"),
reader.GetString("snmp_v3_auth_password"),
reader.GetString("snmp_v3_encrypt_password"),
primaryIP
)));
}
node.Severity = CheckSeverity.PRODUCTION;
SkyScanner.Instance.Entities.NodeCollection.Upsert(node);
}
}
}
public void ImportL2Segmente()
{
MySqlCommand command = mysql.CreateCommand();
command.CommandText = "SELECT * FROM sender_ip_subnetze";
using (MySqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Network4 net4 = Network4.Parse(reader.GetString("cidr"));
L2Segment l2 = SkyScanner.Instance.Entities.L2SegmentCollection.Query("Network", net4).FirstOrDefault();
if (l2 == null)
{
l2 = new L2Segment();
l2.Name = String.Format("SUB#{0}", reader.GetInt32("id").ToString());
l2.Comment = reader.GetString("beschreibung");
l2.Network = net4;
Logging.Log(LogLevel.INFO, "New L2Segment: {0} / {1}",net4,l2.Name);
String sid = reader.GetString("senderid1");
if ((sid != null) && !String.Empty.Equals(sid))
{
PointOfPresence pop = SkyScanner.Instance.Entities.PointOfPresenceCollection.Query("ForeignName", sid).FirstOrDefault();
if (pop != null)
l2.PoPs.Add(pop);
}
sid = reader.GetString("senderid2");
if ((sid != null) && !String.Empty.Equals(sid))
{
PointOfPresence pop = SkyScanner.Instance.Entities.PointOfPresenceCollection.Query("ForeignName", sid).FirstOrDefault();
if (pop != null)
l2.PoPs.Add(pop);
}
sid = reader.GetString("senderid3");
if ((sid != null) && !String.Empty.Equals(sid))
{
PointOfPresence pop = SkyScanner.Instance.Entities.PointOfPresenceCollection.Query("ForeignName", sid).FirstOrDefault();
if (pop != null)
l2.PoPs.Add(pop);
}
sid = reader.GetString("senderid4");
if ((sid != null) && !String.Empty.Equals(sid))
{
PointOfPresence pop = SkyScanner.Instance.Entities.PointOfPresenceCollection.Query("ForeignName", sid).FirstOrDefault();
if (pop != null)
l2.PoPs.Add(pop);
}
SkyScanner.Instance.Entities.L2SegmentCollection.Insert(l2);
}
}
}
}
}
}

View File

@ -34,10 +34,29 @@
<HintPath>..\packages\SSH.NET.2016.1.0\lib\net40\Renci.SshNet.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System.Configuration" />
<Reference Include="System.Net.Http" />
<Reference Include="BouncyCastle.Crypto">
<HintPath>..\packages\BouncyCastle.1.8.3.1\lib\BouncyCastle.Crypto.dll</HintPath>
</Reference>
<Reference Include="Google.Protobuf">
<HintPath>..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="MySql.Data">
<HintPath>..\packages\MySql.Data.8.0.16\lib\net452\MySql.Data.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.ComponentModel" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Configuration.Install" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Drawing.Design" />
<Reference Include="System.Management" />
<Reference Include="System.Transactions" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
@ -76,13 +95,15 @@
<Compile Include="checks\SkyCheck.cs" />
<Compile Include="checks\CheckJob.cs" />
<Compile Include="http\CheckerApi.cs" />
<Compile Include="checks\Ubiquity.cs" />
<Compile Include="checks\Ubiquiti.cs" />
<Compile Include="checks\SkyCheckState.cs" />
<Compile Include="entities\PointOfPresence.cs" />
<Compile Include="entities\CheckSeverity.cs" />
<Compile Include="entities\DeviceType.cs" />
<Compile Include="checks\APC.cs" />
<Compile Include="checks\PerformanceValue.cs" />
<Compile Include="import\skytron\SkytronImport.cs" />
<Compile Include="entities\L2Segment.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
@ -205,6 +226,9 @@
<None Include="templates\static\checks\checks.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\network\l2segments.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="identify\" />
@ -222,6 +246,8 @@
<Folder Include="templates\static\checks\" />
<Folder Include="templates\static\system\" />
<Folder Include="templates\static\crawler\" />
<Folder Include="import\" />
<Folder Include="import\skytron\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ln.snmp\ln.snmp.csproj">

View File

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="12.0.1" targetFramework="net47" />
<package id="BouncyCastle" version="1.8.3.1" targetFramework="net47" />
<package id="Google.Protobuf" version="3.6.1" targetFramework="net47" />
<package id="MySql.Data" version="8.0.16" targetFramework="net47" />
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net47" />
<package id="SSH.NET" version="2016.1.0" targetFramework="net47" />
</packages>

View File

@ -6,33 +6,41 @@
Warnungen: <span id="nWARN" class="WARN"></span><br/>
</div>
<br/>
<select id="interval" style="width: 180px;">
<option value="3600">1 Stunde</option>
<option value="21600">6 Stunden</option>
<option value="43200">12 Stunden</option>
<option value="86400">1 Tag</option>
<option value="604800">1 Woche</option>
</select>
<button onclick="refresh();">Aktualisieren</button>
<br/>
<div class="flex row">
<div class="">
<div id="CRITICAL"></div>
<div id="WARN"></div>
<div id="FAIL"></div>
<div id="ERROR"></div>
</div>
<div id="Charts" class="grow" style="">
</div>
<div>
<select id="interval" style="width: 180px;">
<option value="3600">1 Stunde</option>
<option value="21600">6 Stunden</option>
<option value="43200">12 Stunden</option>
<option value="86400">1 Tag</option>
<option value="604800">1 Woche</option>
</select>
<button onclick="refresh();">Aktualisieren</button>
</div>
<div style="visibility: hidden;">
<div class="fill flex row">
<div style="position: relative; width: 1000px;">
<div id="issue-frame" class="scroll">
<div id="CRITICAL"></div>
<div id="WARN"></div>
<div id="FAIL"></div>
<div id="ERROR"></div>
</div>
</div>
<div id="Charts" class="scroll" style="min-width: 50%; position: inherit;">&nbsp;</div>
</div>
<div style="visibility:hidden; display:none;">
<div id="nodetemplate" class="issue-box" style="margin-bottom: 16px;">
<h2 id="title"></h2>
&nbsp;
<a id="webui" href="" target="_blank" rel="noopener">[ WebUI ]</a>
<div class="flex row">
<div class="fill">
Last Check: <span id="LastCheckTime"></span><br>
Current State for: <span id="UnchangedTime"></span><br>
<br>
<span id="Comment"></span>
</div>
<div id="History">
</div>
@ -107,6 +115,8 @@
chart.data.labels.length = 0;
chart.data.datasets[0].data.length = 0;
chart.data.datasets[0].label = performanceValue.PerfName;
$("#chart", htmlChart).data("chart", chart);
$.each( perfData, function(){
if (this.TimeStamp != 0)
@ -118,6 +128,13 @@
function showCharts(issue)
{
var htmlCharts = $("#Charts");
$("canvas", htmlCharts).each(function(i,e){
var htmlCanvas = $(e);
htmlCanvas.data("chart").destroy();
htmlCanvas.data("chart",null);
});
htmlCharts.empty();
$.each( issue.PerformanceValues, function(){
@ -153,6 +170,17 @@
});
$("#LastCheckTime", ne).text(issue.LastCheckTime);
$("#UnchangedTime", ne).text(issue.UnchangedTime);
$("#Comment", ne).text(issue.Node.Comment);
var awebui = $("#webui", ne);
awebui.hide();
issue.Node.URIs.forEach(function(e,i){
if (e.Scheme == "http"){
awebui.show();
awebui.attr("href", "http://" + e.Host + ":" + e.Port);
}
}, this);
var histParent = $("#History", ne);
histParent.empty();
@ -201,7 +229,7 @@
currentUpdateCycle++;
$.each( issueList , function(){
if (this.Node.DeviceType != "UNKNOWN")
// if (this.Node.DeviceType != "UNKNOWN")
updateIssue(this);
});

View File

@ -17,7 +17,7 @@
div {
margin: 0px;
padding: 0px;
flex-grow: 0;
flex-grow: 0;
}
div#body {
@ -25,12 +25,12 @@ div#body {
height: 100%;
width: 100%;
flex-direction: column;
flex-direction: column;
}
h1,h2,h3,h4,h5,h6 {
margin: 0px;
padding:2px;
padding:2px;
}
table {
@ -82,7 +82,7 @@ button {
}
#header > div {
margin: 4px;
margin: 4px;
}
@ -130,13 +130,21 @@ button {
}
.scroll {
display: inline-block;
overflow: scroll;
position: absolute;
top: 0;
bottom: 0;
overflow: scroll;
}
.scroll-y {
overflow-y: scroll;
}
.scroll-x {
overflow-x: scroll;
}
.fill {
flex-grow: 1;
flex-shrink: 1;
flex-shrink: 1;
}
.right {
@ -146,7 +154,7 @@ button {
.flex {
display: flex;
position: relative;
position: relative;
}
.flex.row {
@ -159,10 +167,15 @@ button {
.flex > div {
margin: 4px;
display: inline-block;
display: inline-block;
}
.flex > div.flex {
display: flex;
}
.skylogo {
display: inline-block;
border: 1px solid black;
@ -228,7 +241,7 @@ button {
#navigation h1 {
font-size: 14px;
border: none;
border: none;
}
#navigation > div {
@ -246,7 +259,7 @@ button {
}
#content > div {
margin: 6px;
margin: 6px;
}
@ -327,6 +340,18 @@ fieldset > label {
background-image: url(images/ui-icons_6495ED_256x240.png);
}
.viewport {
position: relative;
display: block;
border: 1px dotted black;
max-height: 100%;
}
#issue-frame {
}
.issue-box {
display: block;

View File

@ -32,7 +32,7 @@
<%include "topnav.html"%>
</div>
<div id="page">
<div id="content">
<div id="content" class="flex column">
<%=__frame__%>
</div>
</div>

View File

@ -104,7 +104,8 @@
{ title: "Hersteller", data: "Vendor" },
{ title: "Produkt", data: "Product" },
{ title: "Gerätetyp", data: "DeviceType" },
{ title: "Standort", data: "Location", render: function(d,t,r){ return d.Latitude + "/" + d.Longitude; } }
{ title: "Standort", data: "Location", render: function(d,t,r){ return d.Latitude + "/" + d.Longitude; } },
{ title: "UniqueIdentity", data: "UniqueIdentity" }
],
columnDefs: [
{ targets: 0, data: null, defaultContent: "<button>?</button>" }

View File

@ -0,0 +1,107 @@
<%frame "frame.html"%>
<h1>Points of Presence</h1>
<br/>
<h2>List <span class="ui-icon ui-icon-refresh" onclick="$('#l2sTable').DataTable().ajax.reload(null, false);"></span></h2>
<br/>
<table id="l2sTable"></table>
<br/>
<div id="details">
<h2>Details <span class="ui-icon ui-icon-circle-plus" onclick="createPOP();"></span></h2>
<fieldset>
<label for="">Bezeichnung</label><input type="text" id="Name"><br/>
<label for="">Sender#</label><input type="text" id="ForeignName"><br/>
</fieldset>
<fieldset>
<label for="">Standort</label><input type="text" id="Latitude"><br/>
<label for=""></label><input type="text" id="Longitude"><br/>
</fieldset>
<button onclick="savePOP();">Speichern</button>
</div>
<script type="text/javascript">
var currentPOP = null;
$("#popTable").DataTable({
columns: [
{ title: "", data: null },
{ title: "Bezeichnung", data: "Name" },
{ title: "Sender#", data: "ForeignName" },
{ title: "Erstellt", data: "Created" },
{ title: "Geräte", data: null, render: function(d,t,r){ return "N/A"; } },
{ title: "Standort", data: "GeoLocation", render: function(d,t,r){ return d.Latitude + "/" + d.Longitude; } }
],
columnDefs: [
{ targets: 0, data: null, defaultContent: "<span class='ui-icon ui-icon-info'></span>" }
],
select: "single",
height: 300,
fixedHeader: true,
ajax: {
url: "/collections/PointOfPresence",
dataSrc: ''
},
serverSide: false,
})
.on( "select", function(e,dt,type,indexes){
if (indexes.length > 0)
showPOP(dt.rows( indexes ).data()[0]);
})
.on( "deselect", function(e,dt,type,indexes){
showPOP(null);
});
function refreshPopTable()
{
$("#popTable").DataTable().ajax.reload(null, false);
}
function showPOP(pop)
{
currentPOP = pop;
if (pop)
{
$("#Name").val(pop.Name);
$("#ForeignName").val(pop.ForeignName);
$("#details input").removeAttr("disabled");
} else {
$("#details input").prop("disabled","disabled");
}
}
function createPOP()
{
var pop = {
Name: "noname",
ForeignName: "",
GeoLocation: {
Latitude: 0,
Longitude: 0
}
};
showPOP(pop);
}
function savePOP()
{
if (currentPOP)
{
currentPOP.Name = $('#Name').val();
currentPOP.ForeignName = $('#ForeignName').val();
currentPOP.GeoLocation.Latitude = parseFloat($('#Latitude').val()) || 0;
currentPOP.GeoLocation.Longitude = parseFloat($('#Longitude').val()) || 0;
if (currentPOP.ID)
{
skyapi().put("/collections/PointOfPresence/" + currentPOP.ID, currentPOP, function(pop){ showPOP(pop); refreshPopTable(); } );
} else
{
skyapi().post("/collections/PointOfPresence",currentPOP, function(pop){ showPOP(pop); refreshPopTable(); } );
}
}
}
showPOP(null);
</script>

View File

@ -12,7 +12,7 @@
<a href="/static/network/pops.html"><div>PoP Liste</div></a>
</div>
<div>
<a href="/static/network/index.html"><div>PtP Strecken</div></a>
<a href="/static/network/l2segments.html"><div>L2 Segmente</div></a>
</div>
<div>
<a href="/static/network/index.html"><div>PtmP Stationen</div></a>