broken
Harald Wolff 2019-08-03 12:57:32 +02:00
parent c0bf3fb3c9
commit 8c62f00e00
22 changed files with 1098 additions and 2760 deletions

View File

@ -29,30 +29,22 @@ namespace ln.skyscanner
public static void Main(string[] args)
{
new IPv4(0);
FileLogger fileLogger = new FileLogger("skyscanner.log");
fileLogger.MaxLogLevel = LogLevel.INFO;
Logger.Default.Backends.Add(fileLogger);
Logger.ConsoleLogger.MaxLogLevel = LogLevel.INFO;
SkyScanner skyScanner = new SkyScanner(args);
SkyScanner skyScanner = new SkyScanner();
Initialize();
skyScanner.Start();
skyScanner.Start(args);
}
private static void Initialize()
{
SNMPEngine.DefaultEngine.Timeout = 3500;
if (!SkyScanner.Instance.Entities.BlockedNetworks.Contains(Network4.Parse("192.168.0.0/16")))
SkyScanner.Instance.Entities.BlockedNetworks.Insert(Network4.Parse("192.168.0.0/16"));
if (!SkyScanner.Instance.Entities.BlockedNetworks.Contains(Network4.Parse("10.200.0.0/16")))
SkyScanner.Instance.Entities.BlockedNetworks.Insert(Network4.Parse("10.200.0.0/16"));
// SNMPEngine.DefaultEngine.Timeout = 3500;
}
}

View File

@ -6,26 +6,30 @@ using ln.skyscanner.http;
using System.IO;
using ln.skyscanner.crawl;
using ln.types.threads;
using System.Threading;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using ln.skyscanner.checks;
using System.Collections.Generic;
using ln.skyscanner.import.skytron;
using System.Linq;
using ln.skyscanner.entities;
using ln.types.json;
using Newtonsoft.Json.Linq;
using ln.types.net;
using ln.application;
using ln.application.service;
using ln.skyscanner.services;
using Renci.SshNet.Messages;
using System.Threading;
using ln.http.resources;
using ln.types.rpc;
namespace ln.skyscanner
{
[JsonConverter(typeof(StringEnumConverter))]
public enum ComponentState { STOPPED, INITIALIZED, STARTED, FAILED, STOPPING }
public class SkyScanner
public class SkyScanner : Application
{
public static SkyScanner Instance { get; private set; }
public String[] Arguments { get; }
public String BasePath { get; private set; }
public Pool ConveniencePool { get; }
@ -35,192 +39,169 @@ namespace ln.skyscanner
public SkyEntities Entities { get; private set; }
public SkyChecker Checker { get; private set; }
public MemoryLogger MemoryLogger { get; private set; }
public bool OptionDisableChecker { get; private set; }
public String OptionCrawlVendor { get; private set; }
public SkyScanner(String[] args)
:this()
public SkyScanner()
{
MemoryLogger = new MemoryLogger(4096);
Logger.Default.Backends.Add(MemoryLogger);
if (Instance != null)
throw new NotSupportedException("only one SkyScanner may be created");
Instance = this;
Arguments
.Add(0, "base-path", Path.GetFullPath("/var/cache/ln.skyscanner"))
.Add(0, "import-skytron", null)
.Add(0, "benchmark", null)
.Add(0, "debug-check", null)
.Add("disable-checker")
.Add(0, "crawl-vendor", null)
.Add(0, "crawl", null)
;
Logging.Log(LogLevel.INFO, "SkyScanner: Constructor");
BasePath = Path.GetFullPath("/var/cache/ln.skyscanner");
BasePath = Arguments["base-path"].Value;
Logging.Log(LogLevel.INFO, "SkyScanner: BasePath={0}", BasePath);
ConveniencePool = new Pool();
}
Arguments = args;
public override void PrepareStart()
{
base.PrepareStart();
String skytronImport = null;
String benchMark = null;
String debugCheckNode = null;
Queue<string> qArguments = new Queue<string>(Arguments);
while (qArguments.Count > 0)
if (Arguments["import-skytron"].IsSet)
{
string arg = qArguments.Dequeue();
switch (arg)
{
case "-p":
BasePath = Path.GetFullPath(qArguments.Dequeue());
break;
case "--import-skytron":
skytronImport = qArguments.Dequeue();
break;
case "--benchmark":
benchMark = qArguments.Dequeue();
break;
case "--debug-check":
debugCheckNode = qArguments.Dequeue();
break;
}
}
Entities = new SkyEntities(this);
Checker = new SkyChecker();
if (skytronImport != null)
{
SkytronImport si = new SkytronImport(skytronImport);
SkytronImport si = new SkytronImport(Arguments["import-skytron"].Value);
si.Import();
}
if (benchMark != null)
if (Arguments["benchmark"].IsSet)
{
switch (benchMark)
switch (Arguments["benchmark"].Value)
{
case "odb":
BenchmarkODB();
break;
default:
Logging.Log(LogLevel.ERROR, "Unknown Benchmark: {0}", benchMark);
Logging.Log(LogLevel.ERROR, "Unknown Benchmark: {0}", Arguments["benchmark"].Value);
break;
}
throw new Exception("Quitting after benchmarking");
}
/*
if (crawlHost != null)
{
CrawlHost(crawlHost);
throw new Exception("Quitting after --crawl");
}
if (debugCheckNode != null)
if (debugCheckNode != null)
{
DebugCheck(debugCheckNode);
throw new Exception("Quitting after --debug-check");
}
*/
ServiceContainer.Add(ServiceDefinition.From<Service>(true));
ServiceContainer.Add(ServiceDefinition.From<EntityService>(true));
ServiceContainer.Add(ServiceDefinition.From<CheckService>(true));
ServiceContainer.Add(ServiceDefinition.From<CrawlService>(true));
}
public class Service : ApplicationServiceBase
{
public WebSocketInterface webSocketInterface { get; private set; }
public RPCContainer RPCContainer { get; private set; }
public Service()
: base("SkyScanner Application Service")
{
DebugCheck(debugCheckNode);
throw new Exception("Qutting after --debug-check");
RPCContainer = new RPCContainer();
}
}
private SkyScanner()
{
if (Instance != null)
throw new NotSupportedException("only one SkyScanner may be created");
Instance = this;
}
public void Start()
{
Logging.Log(LogLevel.INFO, "SkyScanner: Start()");
StartHttpServer();
StartCrawler();
Checker.Start();
lock (this)
public override void ServiceMain(IApplicationInterface applicationInterface)
{
Monitor.Wait(this);
}
}
String BasePath = ".";
public void Stop()
{
Logging.Log(LogLevel.INFO, "SkyScanner: Stop()");
Resource rootResource = applicationInterface.HTTPApplication.RootResource;
String TemplatesBasePath = Path.Combine(BasePath, "templates", "static");
Checker.Stop();
/* Development hint */
if (Directory.Exists("../../templates/static"))
TemplatesBasePath = Path.Combine(BasePath, "..", "..", "templates", "static");
StopCrawler();
DirectoryResource staticTemplates = new DirectoryResource(rootResource, TemplatesBasePath);
new Thread(() => ConveniencePool.Close()).Start();
staticTemplates.ResourceTypeHook = ResourceTypeHook;
staticTemplates.DefaultResource = staticTemplates.GetResource("index.html");
StopHttpServer();
rootResource.DefaultResource = staticTemplates;
lock (this)
{
Monitor.Pulse(this);
}
}
webSocketInterface = new WebSocketInterface(rootResource, this);
RPCContainer.Add("", new SkyScannerRpc(this));
/** HTTP Server **/
long nextCycle = DateTimeOffset.Now.ToUnixTimeMilliseconds();
public ComponentState HttpStatus
{
get
{
if (HTTPServer != null)
while (!StopRequested)
{
if (HTTPServer.IsRunning)
return ComponentState.STARTED;
while ((nextCycle - DateTimeOffset.Now.ToUnixTimeMilliseconds()) < 0)
nextCycle += 1000;
return ComponentState.INITIALIZED;
try
{
int timeOut = (int)(nextCycle - DateTimeOffset.Now.ToUnixTimeMilliseconds());
if (timeOut > 0)
Thread.Sleep(timeOut);
}
catch (ThreadInterruptedException)
{
if (StopRequested)
break;
}
/* Send Application State to WebSockets */
JObject msg = new JObject();
JObject stateObject = new JObject();
stateObject["currentTime"] = DateTimeOffset.Now.ToUnixTimeMilliseconds();
msg["state"] = stateObject;
webSocketInterface.Broadcast(msg);
}
return ComponentState.STOPPED;
}
}
public void StartHttpServer()
{
HTTPServer = new HTTPServer();
HTTPServer.AddEndpoint(new System.Net.IPEndPoint(IPAddress.Any,8080));
HTTPServer.DefaultApplication = new SkyScannerHttpApplication(this);
HTTPServer.Start();
}
public void StopHttpServer()
{
if (HTTPServer != null)
private Resource ResourceTypeHook(DirectoryResource directoryResource, FileInfo fileInfo)
{
if (HTTPServer.IsRunning)
if (fileInfo.Extension.Equals(".html"))
return new TemplateResource(directoryResource, fileInfo.FullName);
return null;
}
class SkyScannerRpc
{
Service skyscannerService;
public SkyScannerRpc(Service skyscannerService)
{
HTTPServer.Stop();
this.skyscannerService = skyscannerService;
}
}
}
/** Crawler **/
public ComponentState CrawlerStatus
{
get
{
if (Crawler != null)
public string GetServerString()
{
return Crawler.CrawlerState;
return "SkyScanner 0.1a";
}
return ComponentState.STOPPED;
}
}
public void StartCrawler()
{
if (Crawler == null)
{
Crawler = new Crawler(this);
}
else
{
Crawler.Start();
}
}
public void StopCrawler()
{
if (Crawler != null)
{
Crawler.Stop();
}
}
public void BenchmarkODB()
@ -244,6 +225,23 @@ namespace ln.skyscanner
}
public void CrawlHost(IPv4 ip)
{
Logger.ConsoleLogger.MaxLogLevel = LogLevel.DEBUGFULL;
CrawledHost crawledHost = new CrawledHost();
crawledHost.Name = ip.ToString();
crawledHost.PrimaryIP = ip;
crawledHost.IPAddresses = new IPv4[] { ip };
Crawl crawl = new Crawl(Crawler, crawledHost);
crawl.Prepare();
crawl.RunJob();
Logging.Log(LogLevel.INFO, "CrawledHost: {0}", JObject.FromObject(crawledHost).ToString());
}
public void DebugCheck(String uniqueID)
{
Logger.ConsoleLogger.MaxLogLevel = LogLevel.DEBUGFULL;

View File

@ -0,0 +1,64 @@
using System;
using ln.skyscanner.entities;
using ln.logging;
using ln.types;
using ln.snmp;
using ln.snmp.types;
namespace ln.skyscanner.checks
{
public class SikluCheck : SkyCheck
{
public SikluCheck()
:base("siklu")
{
}
public override void Check(SkyChecker skyChecker, ref SkyCheckState checkState, Node node)
{
foreach (URI snmpUri in node.FindURIs("snmp"))
{
try
{
using (SnmpInterface snmp = SnmpInterface.FromURI(snmpUri, skyChecker.SNMPEngine))
{
Sequence[][] ptp = snmp.snmpWalk(new string[] {
"1.3.6.1.4.1.31926.2.1.1.19", // RX PWR
"1.3.6.1.4.1.31926.2.1.1.18", // SNR
"1.3.6.1.4.1.31926.2.1.1.42" // TX PWR
});
int n = 0;
foreach (Sequence[] row in ptp)
{
checkState.WritePerformanceValue(String.Format("ptp_rx_pwr_{0}", n), (double)((Integer)(row[0].Items[1])).LongValue, -75.0, 0, -80.0, 0);
checkState.WritePerformanceValue(String.Format("ptp_tx_snr_{0}", n), (double)((Integer)(row[1].Items[1])).LongValue);
checkState.WritePerformanceValue(String.Format("ptp_tx_pwr_{0}", n), (double)((Integer)(row[2].Items[1])).LongValue);
/* long rxBytes = ((Integer)(row[4].Items[1])).LongValue;
long txBytes = ((Integer)(row[5].Items[1])).LongValue;
ubiquityCheckState.RXRate.Update(rxBytes * 8);
ubiquityCheckState.TXRate.Update(txBytes * 8);
ubiquityCheckState.WritePerformanceValue("ptp_rx_rate", ubiquityCheckState.RXRate.Current);
ubiquityCheckState.WritePerformanceValue("ptp_tx_rate", ubiquityCheckState.TXRate.Current);
*/
n++;
}
}
break;
} catch (Exception e)
{
Logging.Log(LogLevel.DEBUG, "Exception caught in SikluCheck: {0}", e);
continue;
}
}
}
public override bool IsValid(Node node)
{
return (node.Vendor != null) && node.Vendor.Equals("Siklu");
}
}
}

View File

@ -43,6 +43,7 @@ namespace ln.skyscanner.checks
AddSkyCheck(new Hostalive());
AddSkyCheck(new Ubiquiti());
AddSkyCheck(new Mimosa());
//AddSkyCheck(new SikluCheck());
AddSkyCheck(new APC());
}
}

View File

@ -18,10 +18,8 @@ using System.Linq;
using ln.logging;
using ln.snmp;
using ln.http.resources;
using ln.types.odb;
using System.Collections.Generic;
using ln.types.odb.mapped;
using System.Runtime.CompilerServices;
namespace ln.skyscanner.checks
{
public class SkyChecker
@ -87,7 +85,7 @@ namespace ln.skyscanner.checks
if ((threadScheduler != null) && (threadScheduler.IsAlive))
throw new NotSupportedException("SkyChecker.scheduler() already running");
checkPool.SetPoolSize(128);
checkPool.SetPoolSize(256);
Thread.Sleep(2500);

View File

@ -19,6 +19,7 @@ using ln.types.odb;
using ln.skyscanner.crawl.service;
using ln.skyscanner.crawl.tests;
using ln.types.net;
using ln.skyscanner.entities;
namespace ln.skyscanner.crawl
{
@ -26,6 +27,8 @@ namespace ln.skyscanner.crawl
{
static Crawler()
{
CrawlService.RegisterService(new TCP(new int[] { 13080, 13022, 80, 22, 443, 13443 }));
CrawlService.RegisterService(new SNMP(new string[] { "VhclfC7lfIojYZ", "Vhclf(C7$lfIojYZ", "ByFR4oW98hap", "qVy3hnZJ2fov" }));
CrawlService.RegisterService(new RFC1213());
@ -53,6 +56,8 @@ namespace ln.skyscanner.crawl
[JsonConverter(typeof(StringEnumConverter))]
public ComponentState CrawlerState { get; private set; }
public CredentialsGenerator Credentials { get; } = new CredentialsGenerator();
Thread threadScheduler;
public Crawler(SkyScanner skyScanner)
@ -68,6 +73,26 @@ namespace ln.skyscanner.crawl
Directory.CreateDirectory(PoolPath);
CrawlerState = ComponentState.INITIALIZED;
Credentials
.AddPasswords(new string[]{
"MNX3oTzhp9am",
"f1whWdj5E2Mo",
"f1whWdj5",
"0Sl71eGw",
"0Sl71eGwVdjI6WeW",
"67E3xpTc",
"67E3xpTcMbwR",
"v1kXbeCux0Td",
"v1kXbeCu",
"YNZRtVUFH94b",
"67E3xpTcMbwR",
"v1kXbeCux0Td",
"DVqxof1JQ9at"
})
.AddUserNames(new string[] { "skytron", "admin", "root" })
;
}
catch (Exception)
{
@ -98,6 +123,16 @@ namespace ln.skyscanner.crawl
}
CrawlerState = ComponentState.STARTED;
if (SkyScanner.Instance.OptionCrawlVendor != null)
{
foreach (Node node in SkyScanner.Instance.Entities.NodeCollection.Query("Vendor", SkyScanner.Instance.OptionCrawlVendor))
{
CrawledHost crawledHost = FindHostForIP(node.PrimaryIP);
Crawl(crawledHost);
}
}
}
}

View File

@ -0,0 +1,67 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace ln.skyscanner.crawl
{
public class CredentialsGenerator : IEnumerable<Credential>
{
HashSet<String> userNames = new HashSet<string>();
HashSet<String> passWords = new HashSet<string>();
public CredentialsGenerator()
{
}
public CredentialsGenerator AddUserNames(IEnumerable<string> usernames)
{
foreach (String userName in usernames)
AddUserName(userName);
return this;
}
public CredentialsGenerator AddUserName(String username)
{
userNames.Add(username);
return this;
}
public CredentialsGenerator AddPasswords(IEnumerable<string> passwords)
{
foreach (String pw in passwords)
AddPassword(pw);
return this;
}
public CredentialsGenerator AddPassword(String password)
{
passWords.Add(password);
return this;
}
public IEnumerator<Credential> GetEnumerator()
{
foreach (String username in userNames)
foreach (String pw in passWords)
yield return new Credential(username, pw);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public class Credential
{
public String Username { get; }
public String Password { get; }
public Credential(String username,String password)
{
Username = username;
Password = password;
}
}
}

View File

@ -14,27 +14,11 @@ using Renci.SshNet.Common;
using System.Net.Sockets;
using ln.types.net;
using ln.skyscanner.crawl.service;
using ln.logging;
namespace ln.skyscanner.crawl.tests
{
public class SSH : CrawlService
{
static string[] defaultPasswords = new string[]
{
"MNX3oTzhp9am",
"f1whWdj5E2Mo",
"f1whWdj5",
"0Sl71eGw",
"0Sl71eGwVdjI6WeW",
"67E3xpTc",
"67E3xpTcMbwR",
"v1kXbeCux0Td",
"v1kXbeCu",
"YNZRtVUFH94b",
"67E3xpTcMbwR",
"v1kXbeCux0Td",
"DVqxof1JQ9at"
};
public SSH()
: base("ssh")
{
@ -68,11 +52,14 @@ namespace ln.skyscanner.crawl.tests
{
foreach (int port in new int[] { 13022, 22 })
{
if (crawledHost.HasHint(String.Format("tcp.{0}",port)) && crawledHost.GetHint<bool>(String.Format("tcp.{0}", port)))
try
{
foreach (string password in defaultPasswords)
foreach (Credential credential in SkyScanner.Instance.Crawler.Credentials)
{
if (CanConnect(crawledHost, ip, port, "skytron", password, true))
Logging.Log(LogLevel.DEBUG, "SSH trying {0}:{1}...", credential.Username, credential.Password.Substring(0, 4));
if (CanConnect(crawledHost, ip, port, credential.Username, credential.Password, true))
return true;
}
} catch (SocketException)
@ -88,9 +75,12 @@ namespace ln.skyscanner.crawl.tests
{
using (SshClient client = new SshClient(host.ToString(), port, username, password))
{
client.ConnectionInfo.Timeout = TimeSpan.FromSeconds(1);
client.ConnectionInfo.Timeout = TimeSpan.FromSeconds(5);
try
{
String authBanner = null;
client.ConnectionInfo.AuthenticationBanner += (object sender, AuthenticationBannerEventArgs e) => authBanner = e.BannerMessage;
client.Connect();
crawledHost.SetHint("ssh.port", client.ConnectionInfo.Port);
@ -98,12 +88,14 @@ namespace ln.skyscanner.crawl.tests
crawledHost.SetHint("ssh.login", client.ConnectionInfo.Username);
crawledHost.SetHint("ssh.password", password);
crawledHost.SetHint("ssh.version", client.ConnectionInfo.ServerVersion);
crawledHost.SetHint("ssh.authbanner", authBanner);
client.Disconnect();
return true;
}
catch (SshException)
catch (SshException sshe)
{
Logging.Log(sshe);
}
catch (SocketException)
{

78
devices/Siklu.cs 100644
View File

@ -0,0 +1,78 @@
using System;
using ln.types.net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using ln.logging;
namespace ln.skyscanner.devices
{
public class Siklu
{
public IPv4 IPAddress { get; }
public String Username { get; set; }
public string Password { get; set; }
CookieContainer cookieContainer = new CookieContainer();
WebRequestHandler webRequestHandler;
HttpClient httpClient;
public Siklu(IPv4 ip,string username,string password)
{
IPAddress = ip;
Username = username;
Password = password;
webRequestHandler = new WebRequestHandler();
webRequestHandler.ServerCertificateValidationCallback = (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => true;
webRequestHandler.UseCookies = true;
webRequestHandler.CookieContainer = cookieContainer;
webRequestHandler.AllowAutoRedirect = true;
httpClient = new HttpClient(webRequestHandler);
Logging.Log(LogLevel.INFO, "Siklu: {0}", IPAddress);
}
public void Close()
{
httpClient.Dispose();
httpClient = null;
}
public bool Index()
{
HttpResponseMessage responseMessage = httpClient.GetAsync(String.Format("https://{0}/",IPAddress.ToString())).Result;
foreach (var h in responseMessage.Content.Headers)
{
Logging.Log(LogLevel.INFO, "Siklue Header: {0}: [{1}]", h.Key, string.Join(",", h.Value));
}
return true;
}
public bool Authenticate()
{
MultipartFormDataContent mfdc = new MultipartFormDataContent();
mfdc.Add(new StringContent(Username), "user");
mfdc.Add(new StringContent(Password), "password");
mfdc.Add(new StringContent("/"), "caller_url");
try
{
HttpResponseMessage responseMessage = httpClient.PostAsync(String.Format("https://{0}/handleform", IPAddress.ToString()), mfdc).Result;
}
catch (Exception e)
{
Logging.Log(e);
}
return true;
}
}
}

View File

@ -28,7 +28,7 @@ namespace ln.skyscanner.http
{
SkyScanner = skyScanner;
}
/*
[Callable]
public SkyScannerStatistics GetStatistics()
{
@ -78,7 +78,6 @@ namespace ln.skyscanner.http
{
ServerTime = DateTime.Now.ToString();
States.HttpServer = skyScanner.HttpStatus;
States.Crawler = skyScanner.CrawlerStatus;
States.Checks = ComponentState.STOPPED;
@ -97,5 +96,7 @@ namespace ln.skyscanner.http
public ComponentState Checks;
public ComponentState Dispatcher;
}
*/
}
}

View File

@ -0,0 +1,86 @@
using System;
using ln.http.resources.websocket;
using ln.http.resources;
using Newtonsoft.Json.Linq;
using ln.logging;
using System.Collections.Generic;
using ln.http.websocket;
using System.Linq;
using ln.types.rpc;
using Newtonsoft.Json;
namespace ln.skyscanner.http
{
public class WebSocketInterface : WebsocketResource
{
SkyScanner.Service SkyScannerService { get; }
public WebSocket[] CurrentWebSockets {
get
{
lock (currentWebSockets)
{
return currentWebSockets.ToArray();
}
}
}
HashSet<WebSocket> currentWebSockets = new HashSet<WebSocket>();
public WebSocketInterface(Resource container,SkyScanner.Service skyscannerService)
:base(container,"socket")
{
SkyScannerService = skyscannerService;
Connection += WebSocketInterface_Connection;
}
void WebSocketInterface_Connection(WebsocketResource webSocketResource, ln.http.websocket.WebSocket webSocket, WSREvent ev)
{
lock (currentWebSockets)
{
switch (ev)
{
case WSREvent.CONNECT:
currentWebSockets.Add(webSocket);
break;
case WSREvent.CLOSE:
currentWebSockets.Remove(webSocket);
break;
}
}
}
public void Broadcast(JObject json)
{
Broadcast(json.ToString());
}
public void Broadcast(String text)
{
foreach (WebSocket webSocket in CurrentWebSockets)
{
webSocket.Send(text);
}
}
public override void MessageReceived(WebSocketResourceRequestContext requestContext, string textMessage)
{
try
{
JObject json = JObject.Parse(textMessage);
RPCCall rpcCall = new RPCCall(json);
RPCResult rpcResult = SkyScannerService.RPCContainer.Invoke(rpcCall);
requestContext.WebSocket.Send(
rpcResult.ToJSON().ToString()
);
}
catch (Exception e)
{
Logging.Log(e);
}
}
}
}

View File

@ -96,10 +96,13 @@ namespace ln.skyscanner.import.skytron
if (reader.GetInt32("http_port") != 0)
{
string proto = reader.GetInt32("http_port") == 443 ? "https" : "http";
node.RemoveURI("http");
node.AddURI(new URI(String.Format("http://{0}:{1}",
node.RemoveURI("https");
node.AddURI(new URI(String.Format("{2}://{0}:{1}",
primaryIP,
reader.GetString("http_port")
reader.GetString("http_port"),
proto
)));
}
if (reader.GetInt32("ssh_port") != 0)

View File

@ -57,6 +57,7 @@
<Reference Include="System.Management" />
<Reference Include="System.Transactions" />
<Reference Include="System.Xml" />
<Reference Include="System.Net.Http.WebRequest" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
@ -105,6 +106,13 @@
<Compile Include="import\skytron\SkytronImport.cs" />
<Compile Include="entities\L2Segment.cs" />
<Compile Include="checks\Mimosa.cs" />
<Compile Include="checks\SikluCheck.cs" />
<Compile Include="devices\Siklu.cs" />
<Compile Include="crawl\CredentialsGenerator.cs" />
<Compile Include="http\WebSocketInterface.cs" />
<Compile Include="services\CheckService.cs" />
<Compile Include="services\CrawlService.cs" />
<Compile Include="services\EntityService.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
@ -255,6 +263,8 @@
<Folder Include="templates\static\crawler\" />
<Folder Include="import\" />
<Folder Include="import\skytron\" />
<Folder Include="devices\" />
<Folder Include="services\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ln.snmp\ln.snmp.csproj">
@ -285,6 +295,10 @@
<Project>{AD0267BB-F08C-4BE1-A88D-010D49041761}</Project>
<Name>ln.templates</Name>
</ProjectReference>
<ProjectReference Include="..\ln.application\ln.application.csproj">
<Project>{44AA3A50-7214-47F2-9D60-6FF34C0FE6D3}</Project>
<Name>ln.application</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,65 @@
using System;
using ln.application;
using System.Threading;
using ln.logging;
using ln.application.service;
namespace ln.skyscanner.services
{
public class CheckService : ApplicationServiceBase
{
public CheckService()
:base("Check Service")
{
DependOnService<EntityService>();
}
public override void ServiceMain(IApplicationInterface applicationInterface)
{
long nextMinute = DateTimeOffset.Now.ToUnixTimeMilliseconds();
while (!StopRequested)
{
/*
List<CheckJob> checkJobs = new List<CheckJob>();
Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): scheduler save CheckStates");
lock (saveQueue)
{
foreach (SkyCheckState checkState in saveQueue)
{
SkyScanner.Instance.Entities.SkyCheckStates.Upsert(checkState);
}
saveQueue.Clear();
}
Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): scheduler starts");
foreach (Node node in SkyScanner.Instance.Entities.NodeCollection)
{
CheckJob checkJob = new CheckJob(node);
checkJobs.Add(checkJob);
}
Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): prepared {0} checks", checkJobs.Count);
Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): scheduled {0} checks", checkPool.Enqueue(checkJobs));
*/
while (true)
{
while ((nextMinute - DateTimeOffset.Now.ToUnixTimeMilliseconds()) < 0)
nextMinute += 60000;
try
{
Thread.Sleep((int)(nextMinute - DateTimeOffset.Now.ToUnixTimeMilliseconds()));
} catch (ThreadInterruptedException)
{
Logging.Log(LogLevel.INFO, "CheckService: scheduler was interrupted");
if (StopRequested)
break;
}
}
}
}
}
}

View File

@ -0,0 +1,18 @@
using System;
using ln.application;
using ln.application.service;
namespace ln.skyscanner.services
{
public class CrawlService : ApplicationServiceBase
{
public CrawlService()
:base("Crawler Service")
{
DependOnService<EntityService>();
}
public override void ServiceMain(IApplicationInterface applicationInterface)
{
}
}
}

View File

@ -0,0 +1,92 @@
using System;
using ln.application;
using ln.application.service;
using System.Threading;
using System.IO;
using ln.types.odb;
using ln.types.odb.mapped;
using ln.skyscanner.entities;
using ln.skyscanner.crawl;
using ln.types.net;
using ln.skyscanner.checks;
using ln.logging;
namespace ln.skyscanner.services
{
public class EntityService : ApplicationServiceBase
{
public string BasePath { get; private set; }
public ODB ODB { get; private set; }
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; }
public ODBCollection<Network4> BlockedNetworks { get; private set; }
public ODBCollection<SkyCheckState> SkyCheckStates { get; private set; }
public EntityService()
:base("Entity Service")
{
}
public override void ServiceMain(IApplicationInterface applicationInterface)
{
BasePath = Path.Combine(
CurrentApplicationInterface.Arguments["base-path"].Value,
"entities"
);
Logging.Log(LogLevel.INFO, "Entity Service: Initializing");
ODB = new ODB(BasePath);
NodeCollection = ODB.GetCollection<Node>();
NodeCollection.EnableStrongCache(true);
NodeCollection.EnsureIndex("uniqueIdentity", true);
NodeCollection.EnsureIndeces(
"PrimaryIP",
"Interfaces[].ConfiguredIPs[].IP",
"Interfaces[].ConfiguredIPs[].Network"
);
SubnetCollection = ODB.GetCollection<Subnet>();
SubnetCollection.EnsureIndeces("Network");
PointOfPresenceCollection = ODB.GetCollection<PointOfPresence>();
PointOfPresenceCollection.EnsureIndeces("ForeignName");
L2SegmentCollection = ODB.GetCollection<L2Segment>();
L2SegmentCollection.EnsureIndeces("Network", "PoPs");
CrawledHosts = ODB.GetCollection<CrawledHost>();
CrawledHosts.EnsureIndeces("PrimaryIP", "IPAddresses[]");
CrawledSubnets = ODB.GetCollection<CrawledSubnet>();
BlockedNetworks = ODB.GetCollection<Network4>("blockedNetworks");
SkyCheckStates = ODB.GetCollection<SkyCheckState>();
SkyCheckStates.EnableStrongCache(true);
SkyCheckStates.EnsureIndeces("Node");
SkyCheckStates.EnsureUniqueness("Node", "CheckName");
lock (Thread.CurrentThread)
{
Monitor.Wait(Thread.CurrentThread);
}
BasePath = null;
}
}
}

View File

@ -135,55 +135,59 @@
{
var chartColor = performanceValue.CheckState == "CRITICAL" ? '#FF0000' : (performanceValue.CheckState == "WARN") ? '#C0C000' : '#000000';
var htmlChart = $("canvas", graphDiv);
var chart = new Chart( htmlChart, {
type: 'bar',
data: {
datasets: [
{
label: "-",
data: [],
backgroundColor: chartColor,
}
]
},
options: {
scales: {
yAxes: [
var chart = htmlChart.data("chart");
if (!chart){
chart = new Chart( htmlChart, {
type: 'bar',
data: {
datasets: [
{
ticks: {
callback: ScaleSI,
beginAtZero: true,
}
label: "-",
data: [],
backgroundColor: chartColor,
}
],
xAxes: [{
type: 'time',
time: {
unit: "minute",
tooltipFormat: "DD.MM.YYYY HH:mm",
displayFormats: {
minute: "DD.MM.YYYY HH:mm"
},
parser: moment.unix
}
}]
]
},
responsive: true,
maintainAspectRatio: false
}
} );
options: {
scales: {
yAxes: [
{
ticks: {
callback: ScaleSI,
beginAtZero: true,
}
}
],
xAxes: [{
type: 'time',
time: {
unit: "minute",
tooltipFormat: "DD.MM.YYYY HH:mm",
displayFormats: {
minute: "DD.MM.YYYY HH:mm"
},
parser: moment.unix
}
}]
},
responsive: true,
maintainAspectRatio: false
}
} );
}
chart.data.labels.length = 0;
chart.data.datasets[0].data.length = 0;
chart.data.datasets[0].label = performanceValue.PerfName;
$("#chart", htmlChart).data("chart", chart);
htmlChart.data("chart", chart);
$.each( perfData, function(){
if (this.TimeStamp != 0)
chart.data.datasets[0].data.push( { x: this.TimeStamp, y: this.Value } );
});
graphDiv.prependTo( $("#graphs") );
chart.update();
}

View File

@ -61,7 +61,6 @@ table > thead {
}
table > tbody {
font-style: italic;
}
table td {

View File

@ -11,7 +11,8 @@
<link href="/static/css/style.css" rel="stylesheet" />
<script type="text/javascript" src="/static/skyapi.js"></script>
<script type="text/javascript" src="/static/ln.application.js"></script>
<script type="text/javascript" src="/static/dist/jquery.min.js"></script>
<script type="text/javascript" src="/static/dist/jquery-ui.min.js"></script>
<script type="text/javascript" src="/static/dist/moment-with-locales.js"></script>
@ -22,7 +23,9 @@
<body>
<script type="text/javascript">
$( document ).tooltip();
setInterval( updateStatistics, 1000 );
LN().rpc(null,"GetServerString",[],function(r){
alert(JSON.stringify(r));
});
</script>
<div id="body">

View File

@ -0,0 +1,335 @@
var LN = (function(){
var appInterface;
var defaultOptions = {
url: null,
};
class LNInterface {
constructor(opt){
var self = this;
this.options = {}
Object.assign(this.options,opt);
if (this.options.url == null)
this.options.url = this.constructURL();
this.rpcCallbacks = [];
this.rpcNextID = 1;
this.websocket = new WebSocket(this.options.url);
this.websocket.onerror = function(e){
alert("WebSocket caught error: " + e.date);
}
this.websocket.onmessage = function(e){
var j = JSON.parse(e.data);
if (j.state){
updateState(j.state);
} else if (j.id)
{
for (var n=0;n<self.rpcCallbacks.length;n++)
{
if (self.rpcCallbacks[n].id == j.id)
{
self.rpcCallbacks[n].cbfn({
"result": j.result,
"error": j.error,
});
self.rpcCallbacks.splice(n,1);
return;
}
}
}
}
}
rpc(module,method,parameters,cbfn){
var rpcCall = {
module: module,
method: method,
parameters: parameters,
id: this.rpcNextID++,
};
if (this.websocket.readyState != 1)
{
setTimeout(function(){
LN().rpc(module,method,parameters,cbfn);
},250);
} else {
this.rpcCallbacks.push( { id: rpcCall.id, cbfn: cbfn } );
this.websocket.send(
JSON.stringify(rpcCall)
);
}
}
constructURL(){
var pageURI = window.location;
var scheme = pageURI.scheme == "https" ? "wss:" : "ws:";
var host = pageURI.host;
return scheme + "//" + host + "/socket";
}
}
return function(options){
if (!appInterface)
appInterface = new LNInterface(options);
return appInterface;
};
})();
/*
Object.values = function(o) {
var values = [];
for(var property in o) {
values.push(o[property]);
}
return values;
}
function encodeID( t )
{
return ("" + t).replace( /[\.\/]/g, "_");
}
var lagDetector = null;
function updateState(state)
{
try
{
if (lagDetector)
clearTimeout(lagDetector);
$("#ServerTime").text("ServerTime: " + moment(state.currentTime).format());
lagDetector = setTimeout(function(){
$("#ServerTime").text("Server lag detected");
}, 2000);
} catch (e)
{
$("#ServerTime").text("Server state unexpected!");
}
}
function SKYAPI(baseurl){
this.baseurl = baseurl;
this.refresh = []
this.websocket = new WebSocket("ws://localhost:8080/socket");
this.websocket.onerror = function(e){
alert("WebSocket Error: " + e);
}
this.websocket.onmessage = function(e){
var j = JSON.parse(e.data);
if (j.state){
updateState(j.state);
}
}
this.setBaseURL = function(url){ this.baseurl = url; }
this.addRefresh = function( rh, seconds = null ){ this.refresh.push( { interval: seconds ? seconds : 5, refresh: rh } ); }
this.get = function(page, json, handler = null){ return this.__request("GET", page, json, handler); }
this.post = function(page, json, handler = null){ return this.__request("POST", page, json, handler); }
this.put = function(page, json, handler = null){ return this.__request("PUT", page, json, handler); }
this.__request = function(method, page, json, handler = null){
if (page[0] == '/')
page = page.substr(1);
var x = new XMLHttpRequest();
if (handler != null)
{
x.onload = function(){
var responseText = x.responseText;
if (json && !content)
handler( JSON.parse( responseText ) );
else
handler( responseText );
}
}
x.open(method, this.baseurl + page);
if (json)
x.send(JSON.stringify(json));
else
x.send();
}
this.getJson = function(page, handler){
var j = function(t){
handler(JSON.parse(t));
};
return this.get( page, null, j );
}
this.call = function(endpoint,method,parameters = [], receiver = null){
var x = new XMLHttpRequest();
x.open("POST", this.baseurl + endpoint, (receiver != null));
x.setRequestHeader("content-type","application/json");
if (receiver)
{
x.onload = function(){ var r = JSON.parse(this.responseText).Result; receiver(r); }
x.onerror = function(){ receiver(false); }
}
var methodCall = {
"MethodName": method,
"Parameters": parameters
}
x.send(JSON.stringify(methodCall));
if (!receiver)
{
var result = JSON.parse(x.responseText);
if (result.Exception != null)
throw result.Exception;
return result.Result;
}
return x;
}
this.loadPage = function (page) {
if (page[0] == '/')
page = page.substr(1);
var x = new XMLHttpRequest();
x.open("GET", this.baseurl + page);
x.setRequestHeader("x-template-unframed","unframed");
x.onload = function()
{
$("#content").empty();
$("#content").append(this.responseText);
history.pushState(null, page, skyapi().baseurl + page);
}
this.refresh = []
x.send();
return false;
}
this.fireOnLoad = function(element){
if (element.onload != null)
{
element.onload();
}
for (var n=0;n<element.children.length;n++)
this.fireOnLoad(element.children[n]);
}
this.__refresh_index = 0;
this.UIRefresh = function(){
this.__refresh_index++;
for (var n=0;n<this.refresh.length;n++)
{
var r = this.refresh[n];
if ((this.__refresh_index % r.interval)==0)
r.refresh();
}
}
setInterval( function(){ skyapi().UIRefresh(); }, 1000 );
}
function showStatistics(stats)
{
try
{
$("#ServerTime").text("ServerTime: " + stats.ServerTime);
$("#indHttpServer").attr("state",stats.States.HttpServer);
$("#indManager").attr("state",stats.States.Manager);
$("#indCrawler").attr("state",stats.States.Crawler);
$("#indChecks").attr("state",stats.States.Checks);
$("#indDispatcher").attr("state",stats.States.Dispatcher);
$("#indHttpServer").attr("title",stats.States.HttpServer);
$("#indManager").attr("title",stats.States.Manager);
$("#indCrawler").attr("title",stats.States.Crawler);
$("#indChecks").attr("title",stats.States.Checks);
$("#indDispatcher").attr("title",stats.States.Dispatcher);
} catch (e)
{
$("#ServerTime").text("Server unreachable");
$("#indHttpServer").attr("state",3);
$("#indManager").attr("state",0);
$("#indCrawler").attr("state",0);
$("#indChecks").attr("state",0);
$("#indDispatcher").attr("state",0);
$("#indHttpServer").attr("title","UNKNOWN");
$("#indManager").attr("title","UNKNOWN");
$("#indCrawler").attr("title","UNKNOWN");
$("#indChecks").attr("title","UNKNOWN");
$("#indDispatcher").attr("title","UNKNOWN");
}
}
function updateStatistics()
{
try
{
var request = skyapi().call("api/management","GetStatistics",[],showStatistics);
} catch (e)
{
showStatistics(false);
}
}
var __skyapi = new SKYAPI("/");
function skyapi()
{
return __skyapi;
}
function ScaleSI(value)
{
if (value > 1000000000)
return ((value / 1000000000) | 0) + "G";
if (value > 1000000)
return ((value / 1000000) | 0) + "M";
if (value > 1000)
return ((value / 1000) | 0) + "k";
return value;
}
*/

View File

@ -11,11 +11,43 @@ function encodeID( t )
return ("" + t).replace( /[\.\/]/g, "_");
}
var lagDetector = null;
function updateState(state)
{
try
{
if (lagDetector)
clearTimeout(lagDetector);
$("#ServerTime").text("ServerTime: " + moment(state.currentTime).format());
lagDetector = setTimeout(function(){
$("#ServerTime").text("Server lag detected");
}, 2000);
} catch (e)
{
$("#ServerTime").text("Server state unexpected!");
}
}
function SKYAPI(baseurl){
this.baseurl = baseurl;
this.refresh = []
/* this.websocket = new WebSocket("ws://localhost:8080/socket");
this.websocket.onerror = function(e){
alert("WebSocket Error: " + e);
}
this.websocket.onmessage = function(e){
var j = JSON.parse(e.data);
if (j.state){
updateState(j.state);
}
}
*/
this.setBaseURL = function(url){ this.baseurl = url; }
this.addRefresh = function( rh, seconds = null ){ this.refresh.push( { interval: seconds ? seconds : 5, refresh: rh } ); }