private IReadOnlyList <DnsResourceRecord> GetAnswers(string domain, DnsQuestionRecord question, string zoneName, uint appRecordTtl, string healthCheck) { HealthCheckStatus status = _healthMonitor.QueryStatus(domain, question.Type, healthCheck, true); if (status is null) { if (question.Name.Equals(zoneName, StringComparison.OrdinalIgnoreCase)) //check for zone apex { return new DnsResourceRecord[] { new DnsResourceRecord(question.Name, DnsResourceRecordType.ANAME, DnsClass.IN, 30, new DnsANAMERecord(domain)) } } ; //use ANAME else { return new DnsResourceRecord[] { new DnsResourceRecord(question.Name, DnsResourceRecordType.CNAME, DnsClass.IN, 30, new DnsCNAMERecord(domain)) } }; } else if (status.IsHealthy) { if (question.Name.Equals(zoneName, StringComparison.OrdinalIgnoreCase)) //check for zone apex { return new DnsResourceRecord[] { new DnsResourceRecord(question.Name, DnsResourceRecordType.ANAME, DnsClass.IN, appRecordTtl, new DnsANAMERecord(domain)) } } ; //use ANAME else { return new DnsResourceRecord[] { new DnsResourceRecord(question.Name, DnsResourceRecordType.CNAME, DnsClass.IN, appRecordTtl, new DnsCNAMERecord(domain)) } }; } return(null); }
private void GetStatusAnswers(dynamic jsonAddresses, bool primary, DnsQuestionRecord question, uint appRecordTtl, string healthCheck, List <DnsResourceRecord> answers) { if (jsonAddresses == null) { return; } foreach (dynamic jsonAddress in jsonAddresses) { IPAddress address = IPAddress.Parse(jsonAddress.Value); HealthCheckStatus status = _healthMonitor.QueryStatus(address, healthCheck, false); string text = "app=failover; addressType=" + (primary ? "primary" : "secondary") + "; address=" + address.ToString() + "; healthCheck=" + healthCheck; if (status is null) { text += "; healthStatus=Unknown;"; } else if (status.IsHealthy) { text += "; healthStatus=Healthy;"; } else { text += "; healthStatus=Failed; failureReason=" + status.FailureReason + ";"; } answers.Add(new DnsResourceRecord(question.Name, DnsResourceRecordType.TXT, question.Class, appRecordTtl, new DnsTXTRecord(text))); } }
private void GetAnswers(dynamic jsonAddresses, DnsQuestionRecord question, uint appRecordTtl, string healthCheck, List <DnsResourceRecord> answers) { if (jsonAddresses == null) { return; } switch (question.Type) { case DnsResourceRecordType.A: foreach (dynamic jsonAddress in jsonAddresses) { IPAddress address = IPAddress.Parse(jsonAddress.Value); if (address.AddressFamily == AddressFamily.InterNetwork) { HealthCheckStatus status = _healthMonitor.QueryStatus(address, healthCheck, true); if (status is null) { answers.Add(new DnsResourceRecord(question.Name, DnsResourceRecordType.A, question.Class, 30, new DnsARecord(address))); } else if (status.IsHealthy) { answers.Add(new DnsResourceRecord(question.Name, DnsResourceRecordType.A, question.Class, appRecordTtl, new DnsARecord(address))); } } } break; case DnsResourceRecordType.AAAA: foreach (dynamic jsonAddress in jsonAddresses) { IPAddress address = IPAddress.Parse(jsonAddress.Value); if (address.AddressFamily == AddressFamily.InterNetworkV6) { HealthCheckStatus status = _healthMonitor.QueryStatus(address, healthCheck, true); if (status is null) { answers.Add(new DnsResourceRecord(question.Name, DnsResourceRecordType.AAAA, question.Class, 30, new DnsAAAARecord(address))); } else if (status.IsHealthy) { answers.Add(new DnsResourceRecord(question.Name, DnsResourceRecordType.AAAA, question.Class, appRecordTtl, new DnsAAAARecord(address))); } } } break; } }
public Task SendAlertAsync(IPAddress address, string healthCheck, HealthCheckStatus healthCheckStatus) { if (!_enabled || (_mailFrom is null) || (_alertTo is null) || (_alertTo.Length == 0)) { return(Task.CompletedTask); } MailMessage message = new MailMessage(); message.From = _mailFrom; foreach (MailAddress alertTo in _alertTo) { message.To.Add(alertTo); } if (healthCheckStatus.IsHealthy) { message.Subject = "[Alert] Address [" + address.ToString() + "] Status Is Healthy"; message.Body = @"Hi, The DNS Failover App was successfully able to perform a health check [" + healthCheck + "] on the address [" + address.ToString() + @"] and found that the address was healthy. Alert time: " + healthCheckStatus.DateTime.ToLongDateString() + @" Regards, DNS Failover App "; } else { message.Subject = "[Alert] Address [" + address.ToString() + "] Status Is Failed"; message.Body = @"Hi, The DNS Failover App was successfully able to perform a health check [" + healthCheck + "] on the address [" + address.ToString() + @"] and found that the address failed to respond. The failure reason is: " + healthCheckStatus.FailureReason + @" Alert time: " + healthCheckStatus.DateTime.ToLongDateString() + @" Regards, DNS Failover App "; } return(SendMailAsync(message)); }
private void GetStatusAnswers(string domain, bool primary, DnsQuestionRecord question, uint appRecordTtl, string healthCheck, List <DnsResourceRecord> answers) { { HealthCheckStatus status = _healthMonitor.QueryStatus(domain, DnsResourceRecordType.A, healthCheck, false); string text = "app=failover; cnameType=" + (primary ? "primary" : "secondary") + "; domain=" + domain + "; qType: A; healthCheck=" + healthCheck; if (status is null) { text += "; healthStatus=Unknown;"; } else if (status.IsHealthy) { text += "; healthStatus=Healthy;"; } else { text += "; healthStatus=Failed; failureReason=" + status.FailureReason + ";"; } answers.Add(new DnsResourceRecord(question.Name, DnsResourceRecordType.TXT, question.Class, appRecordTtl, new DnsTXTRecord(text))); } { HealthCheckStatus status = _healthMonitor.QueryStatus(domain, DnsResourceRecordType.AAAA, healthCheck, false); string text = "app=failover; cnameType=" + (primary ? "primary" : "secondary") + "; domain=" + domain + "; qType: AAAA; healthCheck=" + healthCheck; if (status is null) { text += "; healthStatus=Unknown;"; } else if (status.IsHealthy) { text += "; healthStatus=Healthy;"; } else { text += "; healthStatus=Failed; failureReason=" + status.FailureReason + ";"; } answers.Add(new DnsResourceRecord(question.Name, DnsResourceRecordType.TXT, question.Class, appRecordTtl, new DnsTXTRecord(text))); } }
public Task CallAsync(IPAddress address, string healthCheck, HealthCheckStatus healthCheckStatus) { if (!_enabled) { return(Task.CompletedTask); } HttpContent content; { using (MemoryStream mS = new MemoryStream()) { JsonTextWriter jsonWriter = new JsonTextWriter(new StreamWriter(mS)); jsonWriter.WriteStartObject(); jsonWriter.WritePropertyName("address"); jsonWriter.WriteValue(address.ToString()); jsonWriter.WritePropertyName("healthCheck"); jsonWriter.WriteValue(healthCheck); jsonWriter.WritePropertyName("isHealthy"); jsonWriter.WriteValue(healthCheckStatus.IsHealthy); jsonWriter.WritePropertyName("failureReason"); jsonWriter.WriteValue(healthCheckStatus.FailureReason); jsonWriter.WritePropertyName("dateTime"); jsonWriter.WriteValue(healthCheckStatus.DateTime); jsonWriter.WriteEndObject(); jsonWriter.Flush(); content = new ByteArrayContent(mS.ToArray()); content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); } } return(CallAsync(content)); }
public HealthMonitor(IDnsServer dnsServer, IPAddress address, HealthCheck healthCheck) { _dnsServer = dnsServer; _address = address; _healthCheck = healthCheck; _healthCheckTimer = new Timer(async delegate(object state) { try { if (_healthCheck is null) { _healthCheckStatus = null; } else { HealthCheckStatus healthCheckStatus = await _healthCheck.IsHealthyAsync(_address); bool sendAlert = false; if (_healthCheckStatus is null) { if (!healthCheckStatus.IsHealthy) { sendAlert = true; } } else { if (_healthCheckStatus.IsHealthy != healthCheckStatus.IsHealthy) { sendAlert = true; } else if (_healthCheckStatus.FailureReason != healthCheckStatus.FailureReason) { sendAlert = true; } } if (sendAlert) { EmailAlert emailAlert = _healthCheck.EmailAlert; if (emailAlert is not null) { _ = emailAlert.SendAlertAsync(_address, _healthCheck.Name, healthCheckStatus); } WebHook webHook = _healthCheck.WebHook; if (webHook is not null) { _ = webHook.CallAsync(_address, _healthCheck.Name, healthCheckStatus); } } _healthCheckStatus = healthCheckStatus; } } catch (Exception ex) { _dnsServer.WriteLog(ex); if (_healthCheckStatus is null) { EmailAlert emailAlert = _healthCheck.EmailAlert; if (emailAlert is not null) { _ = emailAlert.SendAlertAsync(_address, _healthCheck.Name, ex); } WebHook webHook = _healthCheck.WebHook; if (webHook is not null) { _ = webHook.CallAsync(_address, _healthCheck.Name, ex); } _healthCheckStatus = new HealthCheckStatus(false, ex.ToString()); } else { _healthCheckStatus = null; } } finally { if (!_disposed && (_healthCheck is not null)) { _healthCheckTimer.Change(_healthCheck.Interval, Timeout.Infinite); } } }, null, Timeout.Infinite, Timeout.Infinite); _healthCheckTimer.Change(0, Timeout.Infinite); }