/// <summary> /// Upload all Sensor Capsule records to Azure SQL Server. /// </summary> /// <param name="capsule"></param> public static void Execute(IKLog klog, Capsule capsule) { try { string result = AddRecords.Insert(capsule.GenerateSQLRecords(klog)); if (!string.IsNullOrEmpty(result) && result.Contains("Result: True")) { klog.Trace($"{result}"); } else { klog.Error($"Capsule Upload Failure: {result}"); } } catch (Exception ex) { klog.Error($"UploadCapsule::Execute | {ex}"); } }
/// <summary> /// Get and serve configuration document response. /// </summary> public static OkObjectResult Execute(HttpRequest req, IKLog klog) { try { string cfkKey = req.Query["key"]; string cfgApp = req.Query["app"]; if (string.IsNullOrEmpty(cfkKey)) { klog.Info("NULL CFG KEY"); return(new OkObjectResult(null)); } if (string.IsNullOrEmpty(cfgApp)) { klog.Info("NULL APP KEY"); return(new OkObjectResult(null)); } klog.Info($"CfgKey: {cfkKey}, CfkApp: {cfgApp}"); var document = GetCfg(cfkKey, cfgApp); if (document != null) { klog.Info($"PASS"); return(new OkObjectResult(document)); } else { klog.Error($"FAIL: NULL DOC"); return(new OkObjectResult(null)); } } catch (Exception ex) { klog.Error($"Exception: {ex.ToString()}"); return(new OkObjectResult(null)); } }
/// <summary> /// Get the Endpoints and their Configs. /// </summary> /// <returns></returns> public static List <DNSRecord> Execute(IKLog klog) { try { return(GetDNSRecords.GetArticle()); } catch (Exception ex) { klog.Error($"GetArticles::Execute | {ex}"); return(new List <DNSRecord>()); } }
/// <summary> /// Convert Sensor Capusle records into single row SQL records for uploading. /// </summary> /// <returns></returns> public List <SQLRecord> GenerateSQLRecords(IKLog klog) { List <SQLRecord> sqlRecords = new List <SQLRecord>(); var session = Session; var source = Source; foreach (var dnsRecord in DNSRecords) { try { var dnsName = dnsRecord.DNSName; var dnsStatus = dnsRecord.DNSStatus; foreach (var ipRecord in dnsRecord.IPRecords) { var ip = ipRecord.IP.ToString(); var ipStatus = ipRecord.IPStatus; var datacenter = ipRecord.Datacenter; var datacenterTag = ipRecord.DatacenterTag; var tcpRecord = ipRecord.TCPRecord; var port = tcpRecord.Port; var latency = tcpRecord.Latency; SQLRecord record = new SQLRecord { Session = session, Source = source, DNSName = dnsName, DNSStatus = dnsStatus, IP = ip, IPStatus = ipStatus, Datacenter = datacenter, DatacenterTag = datacenterTag, Port = port, Latency = latency }; sqlRecords.Add(record); } } catch (Exception ex) { klog.Error($"Capsule::GenerateSQLRecords - EXCEPTION: {ex}"); } } return(sqlRecords); }
/// <summary> /// Preform DNS Query to gather IPV4 IP's. /// </summary> /// <param name="capsule"></param> public static void Execute(IKLog klog, ref Capsule capsule) { try { // for each DNS Record foreach (var article in capsule.DNSRecords) { try { var count = 0; List <IPRecord> ipRecordQuickList = new List <IPRecord>(); List <IPRecord> ipRecordTransferList = new List <IPRecord>(); // DNS query multiple times while (count < 3) { var ips = Dns.GetHostAddresses(article.DNSName); klog.Metric($"ipcount-{article.DNSName}", ips.Length); // DNS query may return more than one ip foreach (var ip in ips) { IPRecord record = new IPRecord(); record.IP = ip; record.IPStatus = "ONLINE"; ipRecordQuickList.Add(record); } Thread.Sleep(5); count++; } var ipRecordDistinctList = ipRecordQuickList.GroupBy(ip => ip.IP).Select(y => y.First()); foreach (var ipRecord in ipRecordDistinctList) { var hitCount = ipRecordQuickList.Select(x => x.IP == ipRecord.IP).Count(); ipRecordTransferList.Add(ipRecord); } article.IPRecords = ipRecordTransferList; article.DNSStatus = "ONLINE"; } catch (Exception ex) { if (ex.ToString().Contains("No such host is known")) { klog.Error($"Exception: Unknow Host. {article.DNSName}"); } else { klog.Error($"Exception: {ex}"); } article.SetOffline(); } } } catch (Exception e) { klog.Error($"GetIPAddress - Exception: {e}"); } }
/// <summary> /// Evaluate IP address for match on a known provided region. /// </summary> /// <param name="capsule"></param> public static void Execute(IKLog klog, ref Capsule capsule) { foreach (var article in capsule.DNSRecords) { var dnsConfig = article.DNSConfiguration; var ips = article.IPRecords; try { foreach (var ipRecord in ips) { var ipString = ipRecord.IP.ToString(); if (ipRecord.IPStatus == "OFFLINE") { ipRecord.Datacenter = "ERROR"; ipRecord.DatacenterTag = "ERR"; break; } // Check if configuration data exsits and deserialize if (dnsConfig.Contains(Configuration.IpAddress)) { var jsonObject = JsonConvert.DeserializeObject <List <EndpointRecord> >(dnsConfig); // Match IPAddress with Data Center ipRecord.Datacenter = jsonObject.Where(x => x.IpAddress == ipString).Select(x => x.DataCenter).FirstOrDefault(); ipRecord.DatacenterTag = jsonObject.Where(x => x.IpAddress == ipString).Select(x => x.DataCenterTag).FirstOrDefault(); // Set sensor with Data Center ipRecord.IPStatus = Configuration.StatusOnline; } else { if (dnsConfig.Contains("empty")) { klog.Error($"DNS Config is missing"); } else { klog.Error($"DNS Config is malformed"); } ipRecord.Datacenter = Configuration.UnknownDataCenter; ipRecord.DatacenterTag = Configuration.UnknownDataCenterTag; } if (ipRecord.Datacenter == null) { ipRecord.Datacenter = Configuration.UnknownDataCenter; ipRecord.DatacenterTag = Configuration.UnknownDataCenterTag; } klog.Trace($"DNS: {article.DNSName} IP: {ipRecord.IP} Datacenter: {ipRecord.Datacenter} Tag: {ipRecord.DatacenterTag}"); } } catch (Exception e) { klog.Error($"TagIPAddress - Excepection: {e}"); } } }
/// <summary> /// TCP Ping IPV4 IP for latency. /// </summary> /// <param name="capsule"></param> public static void Execute(IKLog klog, ref Capsule capsule) { // TODO: Hard code loop size, in future allow for use config. Add logic to check loop count, and check if it's above 3, otherwise enforce 3. // 3 because, remove 1 min, remove 1 max, atleast one remains as "base" value. foreach (var article in capsule.DNSRecords) { klog.Trace($"DNS: {article.DNSName}"); var ips = article.IPRecords; try { foreach (var ip in ips) { TCPRecord tcpRecord = new TCPRecord(); var ipString = ip.IP.ToString(); if (ip.IPStatus == "OFFLINE") { tcpRecord.SetOffline(); ip.TCPRecord = tcpRecord; break; } uint ipUint = BitConverter.ToUInt32(System.Net.IPAddress.Parse(ipString).GetAddressBytes(), 0); IPEndPoint ipEndpoint = new IPEndPoint(ipUint, 443); var latencyList = new List <double>(); for (int i = 0; i < 4; i++) { var sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); sock.Blocking = true; var stopwatch = new Stopwatch(); // Measure the Connect call only stopwatch.Start(); sock.Connect(ipEndpoint); stopwatch.Stop(); double t = stopwatch.Elapsed.TotalMilliseconds; latencyList.Add(t); sock.Close(); Thread.Sleep(1000); } // logic to remove min and max, avg the rest klog.Trace($"IP: {ipString} Min: {latencyList.Min()}"); latencyList.Remove(latencyList.Min()); klog.Trace($"IP: {ipString} Max: {latencyList.Max()}"); latencyList.Remove(latencyList.Max()); klog.Trace($"IP: {ipString} Avg: {latencyList.Average()}"); var avgLatency = latencyList.Average(); // Add Avg Latency to the IPRecord tcpRecord.Latency = avgLatency; tcpRecord.Port = "443"; ip.TCPRecord = tcpRecord; } } catch (Exception e) { klog.Error($"GetTCPLatency - Exception: {e.ToString()}"); } } }