// Copyright (c) 2011, Outercurve Foundation. // All rights reserved. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // // - Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // // - Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // - Neither the name of the Outercurve Foundation nor the names of its // contributors may be used to endorse or promote products derived from this // software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using System; using System.Collections.Generic; using System.Data; using System.Text; using MySql.Data.MySqlClient; using WebsitePanel.Server.Utils; using WebsitePanel.Providers.Utils; using System.IO; using System.Reflection; namespace WebsitePanel.Providers.DNS { public class PowerDNS : HostingServiceProviderBase, IDnsServer { #region Constants //pdns mysql db settings const string PDNSDbServer = "PDNSDbServer"; const string PDNSDbPort = "PDNSDbPort"; const string PDNSDbName = "PDNSDbName"; const string PDNSDbUser = "PDNSDbUser"; const string PDNSDbPassword = "PDNSDbPassword"; //soa record settings const string ResponsiblePerson = "ResponsiblePerson"; const string RefreshInterval = "RefreshInterval"; const string RetryDelay = "RetryDelay"; const string ExpireLimit = "ExpireLimit"; const string MinimumTTL = "MinimumTTL"; //name servers const string NameServers = "NameServers"; #endregion #region Static ctor static PowerDNS() { AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); } static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { // if (!args.Name.Contains("MySql.Data")) return null; // string connectorKeyName = "SOFTWARE\\MySQL AB\\MySQL Connector/Net"; string connectorLocation = String.Empty; string connectorVersion = String.Empty; // if (PInvoke.RegistryHive.HKLM.SubKeyExists_x86(connectorKeyName)) { connectorLocation = PInvoke.RegistryHive.HKLM.GetSubKeyValue_x86(connectorKeyName, "Location"); connectorVersion = PInvoke.RegistryHive.HKLM.GetSubKeyValue_x86(connectorKeyName, "Version"); } // if (String.IsNullOrEmpty(connectorLocation)) { Log.WriteInfo("Connector location is either null or empty"); return null; } // string assemblyFile = String.Empty; // Versions 5.x.x compatibility if (connectorVersion.StartsWith("5.")) assemblyFile = Path.Combine(connectorLocation, @"Binaries\.NET 2.0\" + args.Name.Split(',')[0] + ".dll"); // Newest versions compatibility else assemblyFile = Path.Combine(connectorLocation, @"Assemblies\" + args.Name.Split(',')[0] + ".dll"); // Log.WriteInfo(assemblyFile); // if (!File.Exists(assemblyFile)) { Log.WriteInfo("Connector assembly could not be found or does not exist"); return null; } // return Assembly.LoadFrom(assemblyFile); } #endregion #region Provider Properties public string SOARefreshInterval { get { return ProviderSettings[RefreshInterval]; } } public string SOARetryDelay { get { return ProviderSettings[RetryDelay]; } } public string SOAExpireLimit { get { return ProviderSettings[ExpireLimit]; } } public string SOAMinimumTTL { get { return ProviderSettings[MinimumTTL]; } } public string DNSNameServers { get { return ProviderSettings[NameServers]; } } public string DbServer { get { return ProviderSettings[PDNSDbServer]; } } public string DbPort { get { return ProviderSettings[PDNSDbPort]; } } public string DbName { get { return ProviderSettings[PDNSDbName]; } } public string DbUser { get { return ProviderSettings[PDNSDbUser]; } } public string DbPassword { get { return ProviderSettings[PDNSDbPassword]; } } #endregion #region IDnsServer Members /// /// Used to check whether the particular zone exits. /// Return true if yes and false otherwise. /// /// Name of zone to be found. /// Bollean value. True if zone exists and false otherwise. public bool ZoneExists(string zoneName) { bool result = false; try { MySqlParameter ZoneName = new MySqlParameter("?ZoneName", MySqlDbType.VarString); ZoneName.Value = zoneName; IDataReader reader = ExecuteReader( "SELECT name FROM domains WHERE name = ?ZoneName LIMIT 1" , ZoneName ); if (reader.Read()) { result = true; } reader.Close(); } catch (Exception ex) { Log.WriteError(String.Format("Error locating '{0}' Power DNS zone", zoneName), ex); } return result; } /// /// Returns the list of zones from Power DNS. /// /// Array of zone names public string[] GetZones() { List zones = new List(); try { IDataReader reader = ExecuteReader( "SELECT name FROM domains" ); while (reader.Read()) { zones.Add( reader["name"].ToString() ); } reader.Close(); } catch (Exception ex) { Log.WriteError("Error getting the list of Power DNS zones.", ex); } return zones.ToArray(); } /// /// This method is being called when Power DNS server is a primary DNS server. /// By primary we mean that Power DNS is the only DNS server, or it is primary (can have secondary) /// server for this zone. /// /// Domain name in the Power DNS database. /// IP Addresses of servers bound to Power DNS server public void AddPrimaryZone(string zoneName, string[] secondaryServers) { PDNSAddZone(zoneName, "NATIVE", secondaryServers); } /// /// This methodis is being called when Power DNS server is a secondary DNS server for some other DNS server. /// So, firstly, AddPrimaryZone is callled for those DNS server to which Power DNS is bound and only then, /// this method is called to write zone data to Power DNS. /// /// Domain name in Power DNS database. /// Primary DNS for current Power DNS instance. public void AddSecondaryZone(string zoneName, string[] masterServers) { PDNSAddZone(zoneName, "SLAVE", masterServers); } /// /// Removes zone from Power DNS database by name. /// /// public void DeleteZone(string zoneName) { try { string domainId = GetDomainId(zoneName); if (string.IsNullOrEmpty(domainId)) return; MySqlParameter DomainId = new MySqlParameter("?DomainId", MySqlDbType.Int32); DomainId.Value = domainId; //clear records table ExecuteNonQuery( "DELETE FROM records WHERE domain_id = ?DomainId" , DomainId ); //clear domains table ExecuteNonQuery( "DELETE FROM domains WHERE id = ?DomainId" , DomainId ); } catch (Exception ex) { Log.WriteError(String.Format("Error deleting '{0}' Power DNS zone", zoneName), ex); } } //partially tested public void UpdateSoaRecord(string zoneName, string host, string primaryNsServer, string primaryPerson) { string recordId = string.Empty; string recordContent = string.Empty; try { MySqlParameter ZoneName = new MySqlParameter("?Name", MySqlDbType.VarString); ZoneName.Value = zoneName; MySqlParameter RecordType = new MySqlParameter("?Type", MySqlDbType.VarString); RecordType.Value = ConvertDnsRecordTypeToString(DnsRecordType.SOA); IDataReader reader = ExecuteReader( "SELECT id, content FROM records WHERE name = ?Name AND type = ?Type LIMIT 1" , ZoneName , RecordType ); if (reader.Read()) { recordId = reader["id"].ToString(); recordContent = reader["content"].ToString(); } reader.Close(); if (string.IsNullOrEmpty(recordId)) throw new ArgumentOutOfRangeException(string.Format("Not SOA record for Power DNS zone '{0}'", zoneName)); PowerDnsSOARecordData soaData = PowerDnsSOARecordData.FromString(recordContent); soaData.PrimaryNameServer = primaryNsServer; soaData.HostMaster = primaryPerson; soaData.Refresh = SOARefreshInterval; soaData.Retry = SOARetryDelay; soaData.DefaultTTL = SOAMinimumTTL; soaData.Expire = SOAExpireLimit; soaData.IncrementSerial( GetDomainNotifiedSerial(zoneName) ); UpdateRecord(recordId, soaData.ToString()); } catch (Exception ex) { Log.WriteError(String.Format("Error updating SOA record for '{0}' Power DNS zone", zoneName), ex); } } //TESTED: partially /// /// The caller of this method is not waiting for SOA records. Assuming this, one should return all records except SOA. /// /// Corresponds to the Domain name in the Power DNS domains table. /// All DnsRecords except of SOA type. public DnsRecord[] GetZoneRecords(string zoneName) { List records = new List(); try { string domainId = GetDomainId(zoneName); if (string.IsNullOrEmpty(domainId)) throw new ArgumentOutOfRangeException("Power DNS zone '{0}' does not exist."); MySqlParameter DomainId = new MySqlParameter("?DomainId", MySqlDbType.Int32); DomainId.Value = domainId; IDataReader reader = ExecuteReader( "SELECT * FROM records WHERE domain_id = ?DomainId AND type != 'SOA'" , DomainId ); while (reader.Read()) { DnsRecord record = new DnsRecord(); record.RecordData = reader["content"].ToString(); record.RecordName = CorrectHost(zoneName, reader["name"].ToString()); record.RecordType = ConvertStringToDnsRecordType(reader["type"].ToString()); int mxPriority = 0; if (!string.IsNullOrEmpty(reader["prio"].ToString())) if (Int32.TryParse(reader["prio"].ToString(), out mxPriority)) { record.MxPriority = mxPriority; } records.Add(record); } reader.Close(); } catch (Exception ex) { Log.WriteError(String.Format("Error getting records for '{0}' Power DNS zone", zoneName), ex); } return records.ToArray(); } /// /// Adds zone record into Power DNS database /// /// Domain name in Power DNS database. /// Record in Power DNS database public void AddZoneRecord(string zoneName, DnsRecord record) { PDNSAddZoneRecord(zoneName, record, true); } public void AddZoneRecords(string zoneName, DnsRecord[] records) { foreach (DnsRecord record in records) { PDNSAddZoneRecord(zoneName, record, false); } PDNSUpdateSoaRecord(zoneName); } /// /// Delete zone record from Power DNS database. /// /// Domain name from Power DNS database /// Record from Power DNS database public void DeleteZoneRecord(string zoneName, DnsRecord record) { PDNSDeleteZoneRecord(zoneName, record, true); } public void DeleteZoneRecords(string zoneName, DnsRecord[] records) { foreach (DnsRecord record in records) { PDNSDeleteZoneRecord(zoneName, record, false); } PDNSUpdateSoaRecord(zoneName); } #endregion #region Zone /// /// Adds zone in Power DNS domains table and creates a SOA record for it. /// /// Domain name in Power DNS database. /// /// protected void PDNSAddZone(string zoneName, string zoneType, string[] nameServers) { string domainId = AddDomainAndReturnDomainId(zoneName, zoneType); if (string.IsNullOrEmpty(domainId)) throw new ArgumentOutOfRangeException(string.Format("Unable to add Power DNS zone '{0}'.", zoneName)); //create SOA record PowerDnsSOARecordData data = new PowerDnsSOARecordData(); data.DefaultTTL = SOAMinimumTTL; data.Expire = SOAExpireLimit; data.Refresh = SOARefreshInterval; data.Retry = SOARetryDelay; data.Serial = DateTime.Now.ToString("yyyyMMdd") + "01"; //add SOA record AddRecord( domainId , zoneName , data.ToString() , ConvertDnsRecordTypeToString(DnsRecordType.SOA) , GetDefaultRecordTTL(DnsRecordType.SOA) , "0" ); //add NS records for secondary servers foreach (string server in nameServers) { AddRecord( domainId , zoneName , server , ConvertDnsRecordTypeToString(DnsRecordType.NS) , GetDefaultRecordTTL(DnsRecordType.NS) , "0" ); } } #endregion #region Zone Record protected void PDNSAddZoneRecord(string zoneName, DnsRecord record, bool isNeedToUpdateSOA) { string domainId = GetDomainId(zoneName); if (domainId == string.Empty) throw new ArgumentOutOfRangeException("DomainId not found. Zone does not exist."); string recordType = ConvertDnsRecordTypeToString(record.RecordType); string ttl = GetDefaultRecordTTL(record.RecordType); //NS record if (record.RecordType == DnsRecordType.NS) { if (string.IsNullOrEmpty(record.RecordName)) record.RecordName = zoneName; } //widen record name for Power DNS if (!string.IsNullOrEmpty(record.RecordName)) { if (!record.RecordName.Contains(zoneName)) { record.RecordName = string.Format("{0}.{1}", record.RecordName, zoneName); } } else { record.RecordName = zoneName; } AddRecord( domainId , record.RecordName , record.RecordData , recordType , ttl , record.MxPriority.ToString() ); if (isNeedToUpdateSOA) { PDNSUpdateSoaRecord(zoneName); } } protected void PDNSDeleteZoneRecord(string zoneName, DnsRecord record, bool isNeedToUpdateSOA) { string recordName = zoneName; if (!String.IsNullOrEmpty(record.RecordName)) { recordName = string.Format("{0}.{1}", record.RecordName, recordName); } RemoveRecord( recordName , ConvertDnsRecordTypeToString(record.RecordType) , record.RecordData , record.MxPriority ); if (isNeedToUpdateSOA) { PDNSUpdateSoaRecord(zoneName); } } #endregion #region SOA Record /// /// Updates SOA record of the corresponding zone /// /// Domain name in Power DNS database protected void PDNSUpdateSoaRecord(string zoneName) { try { string domainId = GetDomainId(zoneName); if (string.IsNullOrEmpty(domainId)) throw new ArgumentOutOfRangeException(string.Format("Power DNS zone '{0}' does not exist.", domainId)); MySqlParameter DomainId = new MySqlParameter("?DomainId", MySqlDbType.Int32); DomainId.Value = domainId; IDataReader reader = ExecuteReader( "SELECT id, content FROM records WHERE domain_id = ?DomainId AND type='SOA' LIMIT 1" , DomainId ); string recordId = string.Empty, recordContent = string.Empty; if (reader.Read()) { recordId = reader["id"].ToString(); recordContent = reader["content"].ToString(); } if (string.IsNullOrEmpty(recordId)) throw new ArgumentOutOfRangeException(string.Format("SOA record for Power DNS zone '{0}' not found", zoneName)); PowerDnsSOARecordData data = PowerDnsSOARecordData.FromString(recordContent); data.Refresh = SOARefreshInterval; data.Retry = SOARetryDelay; data.DefaultTTL = SOAMinimumTTL; data.Expire = SOAExpireLimit; data.IncrementSerial(GetDomainNotifiedSerial(zoneName)); UpdateRecord(recordId, data.ToString()); } catch (Exception ex) { Log.WriteError(String.Format("Error updating SOA record for '{0}' Power DNS zone", zoneName), ex); } } #endregion #region Database Helper Methods protected string GetConnectionString() { return string.Format( "server={0};port={1};database={2};uid={3};password={4}" , DbServer , DbPort , DbName , DbUser , DbPassword ); } public IDataReader ExecuteReader(string mySqlStatement, params MySqlParameter[] parameters) { MySqlConnection mysqlConnection = new MySqlConnection(GetConnectionString()); mysqlConnection.Open(); MySqlCommand command = new MySqlCommand( mySqlStatement , mysqlConnection ); foreach (MySqlParameter param in parameters) { command.Parameters.Add(param); } return command.ExecuteReader(CommandBehavior.CloseConnection); } public int ExecuteNonQuery(string mySqlStatement, params MySqlParameter[] parameters) { MySqlConnection mysqlConnection = new MySqlConnection(GetConnectionString()); mysqlConnection.Open(); MySqlCommand command = new MySqlCommand( mySqlStatement , mysqlConnection ); foreach (MySqlParameter param in parameters) { command.Parameters.Add(param); } int returnValue = command.ExecuteNonQuery(); mysqlConnection.Close(); return returnValue; } #endregion #region Record Helper Methods /// /// Removes record by it's name and type. /// /// /// void RemoveRecord(string name, string type, string content, int mxPriority) { try { MySqlParameter RecordName = new MySqlParameter("?RecordName", MySqlDbType.VarString); RecordName.Value = name; MySqlParameter RecordType = new MySqlParameter("?RecordType", MySqlDbType.VarString); RecordType.Value = type; MySqlParameter RecordContent = new MySqlParameter("?RecordContent", MySqlDbType.VarString); RecordContent.Value = "%" + content.Trim() + "%"; MySqlParameter RecordPriority = new MySqlParameter("?RecordPriority", MySqlDbType.Int32); RecordPriority.Value = mxPriority; ExecuteNonQuery( "DELETE FROM records WHERE name = ?RecordName AND type = ?RecordType AND prio = ?RecordPriority AND content like ?RecordContent " , RecordName , RecordType , RecordContent , RecordPriority ); } catch (Exception ex) { Log.WriteError(String.Format("Error removing record '{0}' of type '{1}' from Power DNS", name, type), ex); } } /// /// Add record to Power DNS database /// /// /// /// /// /// /// protected void AddRecord(string domainId, string name, string content, string type, string ttl, string prio) { try { MySqlParameter DomainId = new MySqlParameter("?DomainId", MySqlDbType.Int32); DomainId.Value = domainId; MySqlParameter RecordName = new MySqlParameter("?RecordName", MySqlDbType.VarString); RecordName.Value = name; MySqlParameter RecordContent = new MySqlParameter("?RecordContent", MySqlDbType.VarString); RecordContent.Value = content; MySqlParameter RecordType = new MySqlParameter("?RecordType", MySqlDbType.VarString); RecordType.Value = type; MySqlParameter RecordTtl = new MySqlParameter("?RecordTtl", MySqlDbType.Int32); RecordTtl.Value = ttl; MySqlParameter RecordPriority = new MySqlParameter("?RecordPriority", MySqlDbType.Int32); RecordPriority.Value = prio; ExecuteNonQuery( "INSERT INTO records (domain_id, name, content, type, ttl, prio) " + "VALUES (?DomainId, ?RecordName, ?RecordContent, ?RecordType, ?RecordTtl, ?RecordPriority)" , DomainId , RecordName , RecordContent , RecordType , RecordTtl , RecordPriority ); } catch (Exception ex) { Log.WriteError(String.Format("Error adding record '{0}' of type '{1}' in Power DNS", name, type), ex); } } /// /// Updates record's content field /// /// /// protected void UpdateRecord(string recordId, string content) { try { MySqlParameter RecordContent = new MySqlParameter("?RecordContent", MySqlDbType.VarString); RecordContent.Value = content; MySqlParameter RecordId = new MySqlParameter("?RecordId", MySqlDbType.Int32); RecordId.Value = recordId; ExecuteNonQuery( "UPDATE records SET content = ?RecordContent " + "WHERE id = ?RecordId LIMIT 1" , RecordContent , RecordId ); } catch (Exception ex) { Log.WriteError(String.Format("Error updating record with id '{0}' in Power DNS", recordId), ex); } } /// /// Provides a default TTLs for records. /// /// /// public string GetDefaultRecordTTL(DnsRecordType recordType) { string ttl = string.Empty; switch (recordType) { case DnsRecordType.SOA: ttl = SOAMinimumTTL; break; case DnsRecordType.NS: ttl = "3600"; break; default: ttl = "120"; break; } return ttl; } /// /// Represents SOA record contents in Power DNS database. /// Allows to perform Increment operation. /// internal class PowerDnsSOARecordData { public string PrimaryNameServer = "localhost"; public string HostMaster = "hostmaster.yourdomain.com"; public string Serial = "1"; public string Refresh = "10800"; public string Retry = "3600"; public string Expire = "84600"; public string DefaultTTL = "3600"; /// /// Converts class instance to string representation. /// /// SOA record content according to the Power DNS SOA record content format public override string ToString() { return string.Format( "{0} {1} {2} {3} {4} {5} {6}" , PrimaryNameServer , HostMaster , Serial , Refresh , Retry , Expire , DefaultTTL ).Trim(); } /// /// Creates class instance from string. /// /// Record content from Power DNS database. /// Instance of class. public static PowerDnsSOARecordData FromString(string content) { PowerDnsSOARecordData data = new PowerDnsSOARecordData(); string[] contentParts = content .Trim() .Split(' '); for (int i = 0; i < contentParts.Length; i++) { data.UpdateProperty(i, contentParts[i]); } return data; } /// /// Increments Serial number of SOA record according to RFC for DNS format. /// /// Is a serial number of SOA record notified by primary server. public void IncrementSerial(string notifiedSerial) { string todayDate = DateTime.Now.ToString("yyyyMMdd"); if (notifiedSerial.Contains(todayDate)) { Serial = notifiedSerial; } if (Serial.Length < 10 || !Serial.StartsWith(todayDate)) { Serial = todayDate + "01"; } else { Serial = (UInt32.Parse(Serial) + 1).ToString(); } } private void UpdateProperty(int index, string data) { switch (index) { case 0: PrimaryNameServer = data; break; case 1: HostMaster = data; break; case 2: Serial = data; break; case 3: Refresh = data; break; case 4: Retry = data; break; case 5: Expire = data; break; case 6: DefaultTTL = data; break; default: throw new ArgumentOutOfRangeException("Unknown index."); } } } #endregion #region Domain Record Helpers /// /// Determines domain id by its name. /// /// Domain name in Power DNS database. /// Domain Id protected string GetDomainId(string domainName) { string domainId = string.Empty; try { MySqlParameter DomainName = new MySqlParameter("?DomainName", MySqlDbType.VarString); DomainName.Value = domainName; IDataReader reader = ExecuteReader( "SELECT id FROM domains WHERE name = ?DomainName LIMIT 1" , DomainName ); if (reader.Read()) { domainId = reader["id"].ToString(); } reader.Close(); } catch (Exception ex) { Log.WriteError(String.Format("Error getting domain '{0}' id from Power DNS.", domainName), ex); } return domainId; } /// /// Determines notified_serial value from Domains table in Power DNS database. /// /// Domain name in Power DNS database. /// string represeting notified_serial field. protected string GetDomainNotifiedSerial(string domainName) { string domainId = string.Empty; try { MySqlParameter DomainName = new MySqlParameter("?DomainName", MySqlDbType.VarString); DomainName.Value = domainName; IDataReader reader = ExecuteReader( "SELECT notified_serial FROM domains WHERE name = ?DomainName LIMIT 1" , DomainName ); if (reader.Read()) { domainId = reader["notified_serial"].ToString(); } reader.Close(); } catch (Exception ex) { Log.WriteError(String.Format("Error getting notofied serial for domain '{0}' from Power DNS.", domainName), ex); } return domainId; } /// /// Inserts domain into Power DNS database and returns it's id. /// /// Domain name in Power DNS database. /// Can be Native or Slave /// An id of the inserted domain protected string AddDomainAndReturnDomainId(string zoneName, string domainType) { AddDomain(zoneName, domainType); return GetDomainId(zoneName); } /// /// Add domain into Power DNS database. /// /// Domain name in Power DNS database. /// Can be Native or Slave protected void AddDomain(string zoneName, string domainType) { try { MySqlParameter DomainName = new MySqlParameter("?DomainName", MySqlDbType.VarString); DomainName.Value = zoneName; MySqlParameter DomainType = new MySqlParameter("?DomainType", MySqlDbType.VarString); DomainType.Value = domainType; ExecuteNonQuery( "INSERT INTO domains (name, type) VALUES (?DomainName, ?DomainType)" , DomainName , DomainType ); } catch (Exception ex) { Log.WriteError(String.Format("Error adding domain '{0}' of type '{1}' to Power DNS", zoneName, domainType), ex); } } #endregion #region Conversion Methods public DnsRecordType ConvertStringToDnsRecordType(string recordType) { DnsRecordType result = DnsRecordType.Other; switch (recordType) { case "A": result = DnsRecordType.A; break; case "CNAME": result = DnsRecordType.CNAME; break; case "MX": result = DnsRecordType.MX; break; case "NS": result = DnsRecordType.NS; break; case "TXT": result = DnsRecordType.TXT; break; case "SOA": result = DnsRecordType.SOA; break; default: result = DnsRecordType.Other; break; } return result; } public string ConvertDnsRecordTypeToString(DnsRecordType recordType) { string result = string.Empty; switch (recordType) { case DnsRecordType.A: result = "A"; break; case DnsRecordType.CNAME: result = "CNAME"; break; case DnsRecordType.MX: result = "MX"; break; case DnsRecordType.NS: result = "NS"; break; case DnsRecordType.SOA: result = "SOA"; break; case DnsRecordType.TXT: result = "TXT"; break; case DnsRecordType.Other: default: throw new NotSupportedException("Record type not supported."); } return result; } #endregion /// /// If zoneName stored in Power DNS is the same as record name (host) for this zone the the return value is string.Empty. /// If record name different, then we delete zone name from record name ans return the rest. /// /// Represents domain name in Power DNS database. /// FQDN, record name in Power DNS database. /// Third Level Domain name or empty string if zoneName == host. private string CorrectHost(string zoneName, string host) { if (host == String.Empty) return host; if (host.ToLower() == zoneName.ToLower()) return string.Empty; else return host.Substring(0, (host.Length - zoneName.Length - 1)); } public override void DeleteServiceItems(ServiceProviderItem[] items) { foreach (ServiceProviderItem item in items) { if (item is DnsZone) { try { // delete DNS zone DeleteZone(item.Name); } catch (Exception ex) { Log.WriteError(String.Format("Error deleting '{0}' Power DNS zone", item.Name), ex); } } } } public override bool IsInstalled() { return false; } } }