Пример #1
0
        public static Task UpdateDnsimpleRecord(Config config, KeyValuePair <string, DnsName> domain, IEnumerable <DnsimpleRecord> records, IEnumerable <IPAddress> addresses)
        {
            return(Task.Run(() =>
            {
                var token = UnprotectSecret(config.dnsimpleApiToken, config.randomString);
                var client = new DNSimpleRestClient(config.dnsimpleUsername, token: token);
                var fqDomainName = domain.Key;
                var domainName = DeriveBaseDomainName(domain.Key);
                var subName = DeriveSubDomainName(domain.Key);

                // It is possible for a computer to have multiple IP addresses (much more common with IPv6, but with multiple NICs, quite possible with IPv4 as well).
                // So we maintain them in multiple records.
                // When a record changes, a new record is added and the old one removed (no in-place updates).

                Log.Trace("Checking addresses for '{0}'...", fqDomainName);
                foreach (var addrGrp in addresses.GroupBy(x => x.AddressFamily))
                {
                    var v4orv6 = addrGrp.Key == System.Net.Sockets.AddressFamily.InterNetwork ? "IPv4" : "IPv6";
                    var recordType = addrGrp.Key == System.Net.Sockets.AddressFamily.InterNetwork ? "A" : "AAAA";
                    var ttl = addrGrp.Key == System.Net.Sockets.AddressFamily.InterNetwork ? domain.Value.ttl_ipv4.GetValueOrDefault(_DefaultTTL) : domain.Value.ttl_ipv6.GetValueOrDefault(_DefaultTTL);


                    Log.Trace("Checking {0} addresses to add for '{1}'...", v4orv6, fqDomainName);
                    foreach (var address in addrGrp)
                    {
                        // Check address.
                        var record = records.FirstOrDefault(x => x.record_type == recordType && x.ContentAsIpAddress().Equals(address) && String.Equals(x.name, subName, StringComparison.InvariantCultureIgnoreCase));

                        if (record == null)
                        {
                            // A new address.
                            Log.Debug("Adding '{0}' record for '{1}' (domain '{2}'): {3}.", recordType, fqDomainName, domainName, address);
                            client.AddRecord(domainName, subName, recordType, address.ToString(), ttl: ttl);
                            Log.Info("New {0} address detected for '{1}' - added '{2}' OK.", v4orv6, fqDomainName, address);
                        }
                        else
                        {
                            // Address has not changed: no action required.
                            Log.Trace("Address '{0}' is correct in DNS: unchanged.", address);
                        }
                    }


                    // Now, check for addresses which need to be removed.
                    Log.Trace("Checking for {0} addresses to remove for '{1}'...", v4orv6, fqDomainName);
                    foreach (var record in records.Where(x => x.record_type == recordType && String.Equals(x.name, subName, StringComparison.InvariantCultureIgnoreCase)))
                    {
                        if (!addrGrp.Contains(record.ContentAsIpAddress()))
                        {
                            // Address has changed / been released and needs to be removed.
                            Log.Debug("Deleting stale '{0}' record for '{1}' (domain '{2}'): {3}.", recordType, fqDomainName, domainName, record.ContentAsIpAddress());
                            client.DeleteRecord(domainName, record.id);
                            Log.Info("Stale {0} address detected for '{1}' - removed '{2}' OK.", v4orv6, fqDomainName, record.ContentAsIpAddress());
                        }
                        else
                        {
                            // Address remains: no action required.
                            Log.Trace("Address '{0}' is correct in DNS: unchanged.", record.ContentAsIpAddress());
                        }
                    }
                }
            }));
        }