예제 #1
0
        /// <summary>
        /// Creates a record set if none exists, else updates an existing record set of type A, assigning the supplied public ip address to the supplied domain
        /// </summary>
        /// <param name="hostedZoneId">the hosted zone id to create or update a recordset for</param>
        /// <param name="domainName">the domain to assign the public ip to</param>
        /// <param name="publicIp">the public ip to assign to the supplied domain</param>
        /// <returns>the change request id and </returns>
        public async Task <(string, string)> UpsertRecordset(string hostedZoneId, string domainName, string publicIp)
        {
            // Create recordset change request
            var recordsetRequest = new ChangeResourceRecordSetsRequest(hostedZoneId, new ChangeBatch(new List <Change>()
            {
                new Change
                {
                    ResourceRecordSet = new ResourceRecordSet(domainName, RRType.A)
                    {
                        TTL             = 60,
                        ResourceRecords = new List <ResourceRecord>()
                        {
                            new ResourceRecord(publicIp)
                        }
                    },
                    Action = ChangeAction.UPSERT
                }
            }));

            // Reqeust change
            var recordsetResponse = await _route53Client.ChangeResourceRecordSetsAsync(recordsetRequest);

            if (recordsetResponse.HttpStatusCode == System.Net.HttpStatusCode.OK)
            {
                return(recordsetResponse.ChangeInfo.Id, recordsetResponse.ChangeInfo.Status);
            }

            else
            {
                throw new System.Exception($"Failed to Upsert recordset, ChangeResourceRecordSetsRequest status: {recordsetResponse.HttpStatusCode}");
            }
        }
예제 #2
0
        private async Task <ChangeResourceRecordSetsResponse> createAws_A_ResourceRecords(string hostedZoneId, string hostName)
        {
            ChangeBatch changes     = new ChangeBatch();
            string      newHostName = hostName.Substring(0, hostName.Length - 1);

            logger.LogInformation($"Creating Alias Record for hosted zone { newHostName }...");

            ResourceRecordSet aliasRs = new ResourceRecordSet()
            {
                AliasTarget = new AliasTarget()
                {
                    HostedZoneId         = "Z3AQBSTGFYJSTF", //use zone id from here: https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
                    DNSName              = "s3-website-us-east-1.amazonaws.com",
                    EvaluateTargetHealth = false
                },
                Type = RRType.A,
                Name = newHostName
            };
            Change AliasRecord = new Change(ChangeAction.CREATE, aliasRs);

            changes.Changes.Add(AliasRecord);

            ChangeResourceRecordSetsRequest request = new ChangeResourceRecordSetsRequest()
            {
                ChangeBatch  = changes,
                HostedZoneId = hostedZoneId
            };

            ChangeResourceRecordSetsResponse response = await TheRoute53Client().ChangeResourceRecordSetsAsync(request);

            return(response);
        }
예제 #3
0
        public async Task DeleteTxtRecordAsync(DnsZone zone, string relativeRecordName)
        {
            var recordName = $"{relativeRecordName}.{zone.Name}.";

            var listRequest = new ListResourceRecordSetsRequest(zone.Id)
            {
                StartRecordName = recordName,
                StartRecordType = RRType.TXT
            };

            var listResponse = await _amazonRoute53Client.ListResourceRecordSetsAsync(listRequest);

            if (listResponse.ResourceRecordSets.Count == 0)
            {
                return;
            }

            var changes = listResponse.ResourceRecordSets
                          .Select(x => new Change {
                Action = ChangeAction.DELETE, ResourceRecordSet = x
            })
                          .ToList();

            var request = new ChangeResourceRecordSetsRequest(zone.Id, new ChangeBatch(changes));

            await _amazonRoute53Client.ChangeResourceRecordSetsAsync(request);
        }
예제 #4
0
        private bool ApplyDnsChange(HostedZone zone, ResourceRecordSet recordSet, ChangeAction action)
        {
            // Prepare change as Batch
            Change changeDetails = new Change()
            {
                ResourceRecordSet = recordSet,
                Action            = action
            };

            ChangeBatch changeBatch = new ChangeBatch()
            {
                Changes = new List <Change> {
                    changeDetails
                }
            };

            // Prepare zone's resource record sets
            var recordsetRequest = new ChangeResourceRecordSetsRequest()
            {
                HostedZoneId = zone.Id,
                ChangeBatch  = changeBatch
            };

            logger.Debug($"Route53 :: ApplyDnsChange : ChangeResourceRecordSets: {recordsetRequest.ChangeBatch} ");

            var recordsetResponse = route53Client.ChangeResourceRecordSets(recordsetRequest);

            logger.Debug($"Route53 :: ApplyDnsChange : ChangeResourceRecordSets Response: {recordsetResponse} ");

            logger.Info("DNS change completed.");

            return(true);
        }
예제 #5
0
        private async Task UpdateRoute53(string instanceId, Instance instance, List <Amazon.EC2.Model.Tag> tags, string action)
        {
            log.LogLine($"Checking whether to update, delete or ignore");
            foreach (var tag in tags)
            {
                string key = tag.Key;
                if (key == PublicDNSTagKey || key == PrivateDNSTagKey)
                {
                    log.LogLine($"Got one! {key}");

                    bool isPublicDNS = key == PublicDNSTagKey;

                    UpdateDeleteIgnoreDecision decision = MakeDeleteUpdateOrIgnoreDecision(action, isPublicDNS);
                    if (decision == UpdateDeleteIgnoreDecision.Ignore)
                    {
                        log.LogLine($"Ignoring {action} for {instanceId}");
                        continue;
                    }

                    string dnsName = tag.Value;
                    string message = string.Empty;
                    if (decision == UpdateDeleteIgnoreDecision.Update)
                    {
                        message = "Creating / updating";
                    }
                    else if (decision == UpdateDeleteIgnoreDecision.Delete)
                    {
                        message = "Deleting";
                    }
                    log.LogLine($"{message} record set for {instanceId} - {dnsName}");
                    string id        = GetHostedZoneIdFor(dnsName);
                    string ipAddress = isPublicDNS ? instance.PublicIpAddress : instance.PrivateIpAddress;
                    ChangeResourceRecordSetsRequest rreq = await CreateChangeResourceRecordSetsRequest(id, dnsName, ipAddress, decision);

                    if (rreq == null)
                    {
                        log.LogLine("Couldn't update. Skipping this one.");
                        continue;
                    }
                    try
                    {
                        var rresp = await R53.ChangeResourceRecordSetsAsync(rreq);

                        log.LogLine($"Result: {rresp.ChangeInfo.Status}");
                    }
                    catch (AggregateException ex)
                    {
                        foreach (var exp in ex.InnerExceptions)
                        {
                            log.LogLine(exp.ToString());
                        }
                    }
                }
            }
        }
예제 #6
0
        private async Task UpdateRoute53(HostedZone zone, Instance instance, ILambdaContext context)
        {
            if (zone == null)
            {
                return;
            }

            string hostName = instance.Tags.GetTag("HostName");

            if (string.IsNullOrWhiteSpace(hostName))
            {
                context.Logger.LogLine($"Hostname missing!");
                return;
            }

            string ipAddress = instance.PublicIpAddress;

            if (string.IsNullOrWhiteSpace(ipAddress))
            {
                context.Logger.LogLine($"ipAddress missing!");
                return;
            }

            context.Logger.LogLine($"Update Zone: {zone.Name} host: {hostName} with IpAddress: {ipAddress}");

            ChangeResourceRecordSetsRequest request = new ChangeResourceRecordSetsRequest
            {
                HostedZoneId = zone.Id,
                ChangeBatch  = new ChangeBatch
                {
                    Changes = new List <Change>
                    {
                        new Change
                        {
                            Action            = ChangeAction.UPSERT,
                            ResourceRecordSet = new ResourceRecordSet
                            {
                                Name            = $"{hostName}.{zone.Name}",
                                Type            = "A",
                                ResourceRecords = new List <ResourceRecord>
                                {
                                    new ResourceRecord {
                                        Value = ipAddress
                                    }
                                },
                                TTL = 60,
                            }
                        }
                    }
                }
            };
            await _amazonRoute53Client.ChangeResourceRecordSetsAsync(request);
        }
예제 #7
0
        private static async Task UpdateResourceRecordSet(ResourceRecordSet resourceRecordSet, Domain domain)
        {
            var change = new Change(ChangeAction.UPSERT, resourceRecordSet);

            var changeBatch = new ChangeBatch(new List <Change> {
                change
            });

            var request = new ChangeResourceRecordSetsRequest(domain.HostedZoneID, changeBatch);

            //var response = await client.ChangeResourceRecordSetsAsync(request);
        }
예제 #8
0
        /// <summary>
        /// Create or change a DNS record for a hosted zone.
        /// </summary>
        /// <param name="hostedZoneId">The ID of the hosted zone that contains the resource record sets that you want to change</param>
        /// <param name="name">The name of the DNS record set.</param>
        /// <param name="type">The type of the DNS record set.</param>
        /// <param name="value">The value of the record set.</param>
        /// <param name="ttl">The time to live of the record set.</param>
        /// <param name="settings">The <see cref="Route53Settings"/> required to upload to Amazon S3.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        public async Task <string> CreateResourceRecordSet(string hostedZoneId, string name, RRType type, string value, long ttl, Route53Settings settings, CancellationToken cancellationToken = default(CancellationToken))
        {
            var recordSet = new ResourceRecordSet()
            {
                Name            = name,
                TTL             = ttl,
                Type            = type,
                ResourceRecords = new List <ResourceRecord>
                {
                    new ResourceRecord {
                        Value = value
                    }
                }
            };

            var change1 = new Change()
            {
                ResourceRecordSet = recordSet,
                Action            = ChangeAction.UPSERT
            };

            var changeBatch = new ChangeBatch()
            {
                Changes = new List <Change> {
                    change1
                }
            };

            var recordsetRequest = new ChangeResourceRecordSetsRequest()
            {
                HostedZoneId = hostedZoneId,
                ChangeBatch  = changeBatch
            };



            AmazonRoute53Client client = this.GetClient(settings);
            ChangeResourceRecordSetsResponse response = await client.ChangeResourceRecordSetsAsync(recordsetRequest);

            if (response.HttpStatusCode == HttpStatusCode.OK)
            {
                await this.WaitForChange(client, response.ChangeInfo.Id, 10000, 60);

                _Log.Verbose("Updated record set");
                return(response.ChangeInfo.Id);
            }
            else
            {
                _Log.Error("Could not change resource records");
                return("");
            }
        }
예제 #9
0
        public void Serialize()
        {
            var request = new ChangeResourceRecordSetsRequest(new[] {
                new ResourceRecordSetChange
                {
                    Action            = ChangeAction.CREATE,
                    ResourceRecordSet = new ResourceRecordSet
                    {
                        Type        = ResourceRecordType.CNAME,
                        AliasTarget = new AliasTarget
                        {
                            DNSName = "bananas"
                        },
                        GeoLocation   = new GeoLocation("NA"),
                        HealthCheckId = "1",
                        Name          = "name",
                        TTL           = 600,
                        SetIdentifier = "set-id"
                    }
                }
            });

            byte[] bytes = Route53Serializer <ChangeResourceRecordSetsRequest> .SerializeToUtf8Bytes(request);

            Assert.Equal(@"<?xml version=""1.0"" encoding=""utf-8""?>
<ChangeResourceRecordSetsRequest xmlns=""https://route53.amazonaws.com/doc/2013-04-01/"">
  <ChangeBatch>
    <Changes>
      <Change>
        <Action>CREATE</Action>
        <ResourceRecordSet>
          <AliasTarget>
            <DNSName>bananas</DNSName>
            <EvaluateTargetHealth>false</EvaluateTargetHealth>
          </AliasTarget>
          <GeoLocation>
            <ContinentCode>NA</ContinentCode>
          </GeoLocation>
          <HealthCheckId>1</HealthCheckId>
          <Name>name</Name>
          <SetIdentifier>set-id</SetIdentifier>
          <TTL>600</TTL>
          <Type>CNAME</Type>
        </ResourceRecordSet>
      </Change>
    </Changes>
  </ChangeBatch>
</ChangeResourceRecordSetsRequest>", Encoding.UTF8.GetString(bytes));
        }
예제 #10
0
        private static void CreateHostedZone(IAmazonRoute53 r53Client, string domainName)
        {
            var zoneRequest = new CreateHostedZoneRequest
            {
                Name            = domainName,
                CallerReference = "testingss"
            };

            var zoneResponse = r53Client.CreateHostedZone(zoneRequest);
            var recordSet    = new ResourceRecordSet
            {
                Name            = domainName,
                TTL             = 60,
                Type            = RRType.A,
                ResourceRecords = new List <ResourceRecord> {
                    new ResourceRecord {
                        Value = IpAddress
                    }
                }
            };

            var change1 = new Change
            {
                ResourceRecordSet = recordSet,
                Action            = ChangeAction.CREATE
            };

            var changeBatch = new ChangeBatch
            {
                Changes = new List <Change> {
                    change1
                }
            };

            var recordsetRequest = new ChangeResourceRecordSetsRequest
            {
                HostedZoneId = zoneResponse.HostedZone.Id,
                ChangeBatch  = changeBatch
            };

            var recordsetResponse = r53Client.ChangeResourceRecordSets(recordsetRequest);
            var changeRequest     = new GetChangeRequest
            {
                Id = recordsetResponse.ChangeInfo.Id
            };

            Console.WriteLine(changeRequest);
        }
예제 #11
0
        private static void CreateDNSChangeAction(string domain, string hostName, string value, RRType type, ChangeAction action, int ttl)
        {
            string zoneId = FindHostedZoneID(domain);

            if (zoneId == null)
            {
                throw new Exception("Zone not found");
            }

            ResourceRecord resourceRecord = null;

            if (value != null)
            {
                resourceRecord = new ResourceRecord()
                {
                    Value = value
                };
            }

            var change = new Change
            {
                Action            = action,
                ResourceRecordSet = new ResourceRecordSet
                {
                    Name            = $"{hostName}.{domain}",
                    Type            = type,
                    TTL             = ttl,
                    ResourceRecords = resourceRecord != null ? new List <ResourceRecord>()
                    {
                        resourceRecord
                    } : null
                },
            };

            var changeBatch = new ChangeBatch();

            changeBatch.Changes.Add(change);
            var changeResourceRecordSetsRequest = new ChangeResourceRecordSetsRequest
            {
                ChangeBatch  = changeBatch,
                HostedZoneId = zoneId
            };

            var changeResourceResponse = c.ChangeResourceRecordSetsAsync(changeResourceRecordSetsRequest).Result;

            Console.WriteLine($"{changeResourceResponse.ChangeInfo.Status} {changeResourceResponse.ChangeInfo.Comment}");
        }
예제 #12
0
        private async Task <ChangeResourceRecordSetsRequest> CreateChangeResourceRecordSetsRequest(string id, string dnsName, string ipAddress, UpdateDeleteIgnoreDecision decision)
        {
            if (string.IsNullOrEmpty(ipAddress))
            {
                log.LogLine($"No ip address provided. Looking up by hosted zone / dnsname.");
                ipAddress = await LookupIpAddressByZoneIdAndDNSName(id, dnsName);

                if (string.IsNullOrEmpty(ipAddress))
                {
                    log.LogLine($"No record set found for {id} - {dnsName}. Looks like it's been deleted already.");
                    return(null);
                }
            }
            log.LogLine($"Creating {decision} change request for {dnsName} - {ipAddress} - {id}");
            ChangeAction action = (decision == UpdateDeleteIgnoreDecision.Delete) ? ChangeAction.DELETE : ChangeAction.UPSERT;

            var result = new ChangeResourceRecordSetsRequest
            {
                HostedZoneId = id,
                ChangeBatch  = new ChangeBatch
                {
                    Changes = new List <Change>
                    {
                        new Change
                        {
                            Action            = action,
                            ResourceRecordSet = new ResourceRecordSet
                            {
                                Name            = dnsName,
                                ResourceRecords = new List <ResourceRecord>
                                {
                                    new ResourceRecord {
                                        Value = ipAddress
                                    }
                                },
                                Type = RRType.A,
                                TTL  = 300
                            }
                        }
                    }
                }
            };

            log.LogLine("Returning:");
            log.LogLine(JsonConvert.SerializeObject(result));
            return(result);
        }
예제 #13
0
        private async Task <bool> ApplyDnsChange(HostedZone zone, ResourceRecordSet recordSet, ChangeAction action)
        {
            // prepare change
            var changeDetails = new Change()
            {
                ResourceRecordSet = recordSet,
                Action            = action
            };

            var changeBatch = new ChangeBatch()
            {
                Changes = new List <Change> {
                    changeDetails
                }
            };

            // Update the zone's resource record sets
            var recordsetRequest = new ChangeResourceRecordSetsRequest()
            {
                HostedZoneId = zone.Id,
                ChangeBatch  = changeBatch
            };

            _log?.Debug($"Route53 :: ApplyDnsChange : ChangeResourceRecordSetsAsync: {JsonConvert.SerializeObject(recordsetRequest.ChangeBatch)} ");

            var recordsetResponse = await _route53Client.ChangeResourceRecordSetsAsync(recordsetRequest);

            _log?.Debug($"Route53 :: ApplyDnsChange : ChangeResourceRecordSetsAsync Response: {JsonConvert.SerializeObject(recordsetResponse)} ");

            // Monitor the change status
            var changeRequest = new GetChangeRequest()
            {
                Id = recordsetResponse.ChangeInfo.Id
            };

            while (ChangeStatus.PENDING == (await _route53Client.GetChangeAsync(changeRequest)).ChangeInfo.Status)
            {
                System.Diagnostics.Debug.WriteLine("DNS change is pending.");
                await Task.Delay(1500);
            }

            _log?.Information("DNS change completed.");

            return(true);
        }
예제 #14
0
        public async Task HandleInitR53(Instance inst, Dictionary <string, string> tags)
        {
            _logger.LogInformation("Handling CREATING R53 records");

            var r53Spec    = ResolveR53Spec(inst, tags);
            var r53Routing = ResolveR53RoutingSpec(inst, tags);

            var rrset = new ResourceRecordSet
            {
                Name            = r53Spec.Name,
                Type            = RRType.FindValue(r53Spec.Type),
                TTL             = r53Spec.TTL,
                ResourceRecords = new List <ResourceRecord>
                {
                    new ResourceRecord(r53Spec.Value),
                },
            };

            // Optional routing policy configuration
            r53Routing?.Apply(rrset);

            var changeRequ = new ChangeResourceRecordSetsRequest
            {
                HostedZoneId = r53Spec.Zone,
                ChangeBatch  = new ChangeBatch
                {
                    Changes = new List <Change>
                    {
                        new Change
                        {
                            Action            = ChangeAction.UPSERT,
                            ResourceRecordSet = rrset,
                        }
                    }
                }
            };

            var changeResp = await _r53.ChangeResourceRecordSetsAsync(changeRequ);

            _logger.LogInformation("UPSERT request completed, response:");
            _logger.LogInformation(JsonSerializer.Serialize(changeResp));
        }
예제 #15
0
        private async Task <ChangeResourceRecordSetsResponse> createAws_NS_ResourceRecords(string hostedZoneId, string fullName, ResourceRecordSet NsRecord)
        {
            logger.LogInformation($"Creating NS record for hosted zone ID { hostedZoneId }, { fullName }...");

            ChangeBatch changes = new ChangeBatch();

            Change change = new Change(ChangeAction.CREATE, NsRecord);

            changes.Changes.Add(change);

            ChangeResourceRecordSetsRequest request = new ChangeResourceRecordSetsRequest()
            {
                ChangeBatch  = changes,
                HostedZoneId = hostedZoneId
            };

            ChangeResourceRecordSetsResponse response = await TheRoute53Client().ChangeResourceRecordSetsAsync(request);

            return(response);
        }
        internal void Update(string hostname, IPAddress ipAddress)
        {
            var lhzTask = route53Client.ListHostedZonesAsync();

            ResourceRecord    resourceRecord    = new ResourceRecord(ipAddress.ToString());
            ResourceRecordSet resourceRecordSet = new ResourceRecordSet
            {
                Name            = hostname,
                TTL             = 30,
                Type            = RRType.A,
                ResourceRecords = new List <ResourceRecord> {
                    resourceRecord
                }
            };
            Change change = new Change
            {
                Action            = ChangeAction.UPSERT,
                ResourceRecordSet = resourceRecordSet
            };
            ChangeBatch changeBatch = new ChangeBatch
            {
                Changes = new List <Change> {
                    change
                },
                Comment = DateTime.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture)
            };

            // This is wrong and does The Wrong Thing, I'm fairly certain
            string domain       = DomainName.Parse(hostname).Domain;
            var    zones        = lhzTask.Result.HostedZones;
            string hostedZoneId = zones.Single(z => z.Name.StartsWith(domain)).Id;

            ChangeResourceRecordSetsRequest request = new ChangeResourceRecordSetsRequest
            {
                ChangeBatch  = changeBatch,
                HostedZoneId = hostedZoneId
            };

            var crrsTask = route53Client.ChangeResourceRecordSetsAsync(request);
            var response = crrsTask.Result;
        }
예제 #17
0
        public static void UpdateRoute53Record(string hostname, IPAddress newIp)
        {
            var route53Client = new AmazonRoute53Client(
                Settings.AwsAccessKeyId,
                Settings.AwsSecretAccessKey,
                Amazon.RegionEndpoint.USEast1);

            var recordSet = new ResourceRecordSet
            {
                Name            = hostname,
                TTL             = 60,
                Type            = RRType.A,
                ResourceRecords = new List <ResourceRecord>
                {
                    new ResourceRecord {
                        Value = newIp.ToString()
                    }
                }
            };

            var changeBatch = new ChangeBatch
            {
                Changes = new List <Change>
                {
                    new Change
                    {
                        ResourceRecordSet = recordSet,
                        Action            = ChangeAction.UPSERT
                    }
                }
            };

            var recordsetRequest = new ChangeResourceRecordSetsRequest
            {
                HostedZoneId = Settings.HostedZoneId,
                ChangeBatch  = changeBatch
            };

            route53Client.ChangeResourceRecordSets(recordsetRequest);
        }
예제 #18
0
        private ChangeResourceRecordSetsRequest GetChangeResourceRecordSetsRequest(string hostname, string ipAddress, string action, List <HostedZone> zones)
        {
            string domain       = DomainName.Parse(hostname).Domain;
            string hostedZoneId = zones.Single(z => z.Name.StartsWith(domain)).Id;

            var record = new ResourceRecord()
            {
                Value = ipAddress
            };

            var recordSet = new ResourceRecordSet()
            {
                Name            = hostname,
                TTL             = 300,                             //5 min.
                Type            = DnsRecordType.A,
                ResourceRecords = new List <ResourceRecord> {
                    record
                }
            };

            var change = new Change()
            {
                Action = action, ResourceRecordSet = recordSet
            };

            var request = new ChangeResourceRecordSetsRequest()
            {
                ChangeBatch = new ChangeBatch()
                {
                    Changes = new List <Change> {
                        change
                    },
                    Comment = string.Format("Automatically updated by {0}", this.ToString())
                },
                HostedZoneId = hostedZoneId
            };

            return(request);
        }
예제 #19
0
        public async Task CreateTxtRecordAsync(DnsZone zone, string relativeRecordName, IEnumerable <string> values)
        {
            var recordName = $"{relativeRecordName}.{zone.Name}.";

            var change = new Change
            {
                Action            = ChangeAction.CREATE,
                ResourceRecordSet = new ResourceRecordSet
                {
                    Name            = recordName,
                    Type            = RRType.TXT,
                    TTL             = 60,
                    ResourceRecords = values.Select(x => new ResourceRecord($"\"{x}\"")).ToList()
                }
            };

            var request = new ChangeResourceRecordSetsRequest(zone.Id, new ChangeBatch(new List <Change> {
                change
            }));

            await _amazonRoute53Client.ChangeResourceRecordSetsAsync(request);
        }
예제 #20
0
        public void Serialize2()
        {
            var request = new ChangeResourceRecordSetsRequest(new[]
            {
                new ResourceRecordSetChange
                {
                    Action = ChangeAction.CREATE,

                    ResourceRecordSet = new ResourceRecordSet
                    {
                        Failover = Failover.SECONDARY,
                        TTL      = 600,
                        Type     = ResourceRecordType.NS
                    }
                }
            }
                                                              );

            byte[] bytes = Route53Serializer <ChangeResourceRecordSetsRequest> .SerializeToUtf8Bytes(request);

            Assert.Equal("9d0d340e8a3623f88f2d9731e37f6f66f43073fb841ffc32a63ddbc237012266", SignerV4.ComputeSHA256(new ByteArrayContent(bytes)));

            Assert.Equal(@"<?xml version=""1.0"" encoding=""utf-8""?>
<ChangeResourceRecordSetsRequest xmlns=""https://route53.amazonaws.com/doc/2013-04-01/"">
  <ChangeBatch>
    <Changes>
      <Change>
        <Action>CREATE</Action>
        <ResourceRecordSet>
          <Failover>SECONDARY</Failover>
          <TTL>600</TTL>
          <Type>NS</Type>
        </ResourceRecordSet>
      </Change>
    </Changes>
  </ChangeBatch>
</ChangeResourceRecordSetsRequest>", Encoding.UTF8.GetString(bytes));
        }
예제 #21
0
        private static void CreateRecordSet(IAmazonRoute53 r53Client)
        {
            var objRecord = new ResourceRecord {
                Value = "Your IP Address"
            };

            var objRecordSet = new ResourceRecordSet
            {
                Name = Fqdn,
                Type = "A",
                TTL  = 300
            };

            objRecordSet.ResourceRecords.Add(objRecord);

            var objChange = new Change
            {
                Action            = ChangeAction.UPSERT,
                ResourceRecordSet = objRecordSet
            };

            var objChangeList = new List <Change> {
                objChange
            };

            var objChangeBatch = new ChangeBatch {
                Changes = objChangeList
            };

            var objRequest = new ChangeResourceRecordSetsRequest
            {
                HostedZoneId = Zoneid,
                ChangeBatch  = objChangeBatch
            };

            r53Client.ChangeResourceRecordSets(objRequest);
        }
예제 #22
0
        public static async Task Create(this HostedZone zone, Credentials credentials)
        {
            var client = credentials.CreateClient();

            //[3] Create a resource record set change batch
            var recordSet = new ResourceRecordSet {
                Name            = zone.Name,
                TTL             = 60,
                Type            = RRType.A,
                ResourceRecords = new List <ResourceRecord> {
                    new ResourceRecord {
                        Value = "192.0.2.235"
                    }
                }
            };

            var change1 = new Change {
                ResourceRecordSet = recordSet,
                Action            = ChangeAction.CREATE
            };

            var changeBatch = new ChangeBatch {
                Changes = new List <Change> {
                    change1
                }
            };

            //[4] Update the zone's resource record sets
            var recordsetRequest = new ChangeResourceRecordSetsRequest {
                HostedZoneId = zone.Id,
                ChangeBatch  = changeBatch
            };

            var recordsetResponse = client.ChangeResourceRecordSets(recordsetRequest);

            var status = await recordsetResponse.ChangeInfo.WaitForStatusAync(credentials);
        }
예제 #23
0
        public async Task <string> UpdateHostZoneRecordSetValue(string action, List <KeyValuePair <string, string> > recordsetChanges)
        {
            List <Change> changes = new List <Change>();

            foreach (var recordsetChange in recordsetChanges)
            {
                changes.Add(
                    new Change(
                        new ChangeAction(action),  //"UPSERT"
                        new ResourceRecordSet()
                {
                    Name            = recordsetChange.Key,
                    TTL             = 900,
                    Type            = RRType.CNAME,
                    ResourceRecords = new List <ResourceRecord>()
                    {
                        new ResourceRecord()
                        {
                            Value = recordsetChange.Value
                        }
                    }
                }
                        )
                    );
            }
            ;
            ChangeBatch batch   = new ChangeBatch(changes);
            var         request = new ChangeResourceRecordSetsRequest()
            {
                HostedZoneId = await GetHostZoneId(),
                ChangeBatch  = batch
            };
            var response = await client.ChangeResourceRecordSetsAsync(request);

            return(response.HttpStatusCode.ToString());
        }
        public void SaveClients()
        {
            //Output
            Output($"MCS: Starting Save Clients");

            string dataText = "";

            //Validate
            if (Clients == null || !Clients.Any())
            {
                //Output
                Output($"MCS: Had no Clients.");

                //Will update with an empty string - no clients
            }
            else
            {
                //Output
                Output($"MCS: Found {Clients.Count} Clients.");

                //1) Serialize to JSON text
                dataText = JsonConvert.SerializeObject(Clients);

                //2) Prepare the string (encrypt, compress)
                //Encrypt and Compress
                dataText = dataText.CompressThenEncrypt(Config.MultiClientSettings.Route53.EncryptionPassword);
            }

            //Add quotation marks
            dataText = "\"" + dataText + "\"";

            //3) Update to R53
            //New the Route 53 Client
            AmazonRoute53Client r53Client =
                new AmazonRoute53Client(
                    Config.BaseSettings.AWSAccessKeyID,
                    Config.BaseSettings.AWSSecretAccessKey,
                    new AmazonRoute53Config
            {
                RegionEndpoint = RegionEndpoint
            });

            //New the Change Record to push
            Change change =
                new Change
            {
                Action            = ChangeAction.UPSERT, //Insert or Update
                ResourceRecordSet =
                    new ResourceRecordSet
                {
                    Name            = Config.MultiClientSettings.Route53.Name,
                    TTL             = 300,
                    Type            = RRType.TXT,
                    ResourceRecords = new List <ResourceRecord> {
                        new ResourceRecord(dataText)
                    }
                }
            };

            //New the Change Request
            ChangeResourceRecordSetsRequest recordSetsRequest =
                new ChangeResourceRecordSetsRequest
            {
                HostedZoneId = Config.MultiClientSettings.Route53.R53ZoneId,
                ChangeBatch  = new ChangeBatch(new List <Change> {
                    change
                })
            };

            //Submitting the Change Request to the API and receiving back the ID
            ChangeResourceRecordSetsResponse recordSetResponse =
                r53Client
                .ChangeResourceRecordSetsAsync(recordSetsRequest)
                .GetAwaiter()
                .GetResult();

            //The ID of the response
            string changeId = recordSetResponse.ChangeInfo.Id;

            //Output
            Output($"MCS-R53: Change ID \"{changeId}\": ChangeRequest was submitted.");

            //Enquire with R53 the status of the change (R53 updates can be VERY slow business)
            GetChangeRequest changeRequest =
                new GetChangeRequest
            {
                Id = changeId
            };

            while (r53Client.GetChangeAsync(changeRequest).GetAwaiter().GetResult().ChangeInfo.Status == ChangeStatus.PENDING)
            {
                //Output
                Output($"MCS-R53: Change ID \"{changeId}\": Change is still pending. (Can take a while.)");

                //Wait
                Thread.Sleep(10 * 1000); //Wait ten seconds
            }

            //Output DONE
            Output($"MCS-R53: Change ID \"{changeId}\": Change IN SYNC. Done.");
            Output($"MCS: Completed Save of {Clients.Count} Clients");
        }
예제 #25
0
        public async Task HandleTermR53(Instance inst, Dictionary <string, string> tags)
        {
            _logger.LogInformation("Handling REMOVING R53 records");

            var r53Spec    = ResolveR53Spec(inst, tags);
            var r53Routing = ResolveR53RoutingSpec(inst, tags);

            var rrset = new ResourceRecordSet
            {
                Name            = r53Spec.Name,
                Type            = RRType.FindValue(r53Spec.Type),
                TTL             = r53Spec.TTL,
                ResourceRecords = new List <ResourceRecord>
                {
                    new ResourceRecord(r53Spec.Value),
                },
            };

            // Optional routing policy configuration
            r53Routing?.Apply(rrset);

            var listRequ = new ListResourceRecordSetsRequest
            {
                HostedZoneId          = r53Spec.Zone,
                StartRecordName       = r53Spec.Name,
                StartRecordType       = r53Spec.Type,
                StartRecordIdentifier = null,
            };

            var listResp = await _r53.ListResourceRecordSetsAsync(listRequ);

            var rr = listResp.ResourceRecordSets.FirstOrDefault();

            if (rr == null ||
                rr.Name != r53Spec.Name ||
                rr.Type != r53Spec.Type)
            {
                _logger.LogWarning("No existing resource records found; SKIPPING");
                _logger.LogInformation("First returned record for query:");
                _logger.LogInformation(JsonSerializer.Serialize(rr));
                return;
            }

            var changeRequ = new ChangeResourceRecordSetsRequest
            {
                HostedZoneId = r53Spec.Zone,
                ChangeBatch  = new ChangeBatch
                {
                    Changes = new List <Change>
                    {
                        new Change
                        {
                            Action            = ChangeAction.DELETE,
                            ResourceRecordSet = rrset,
                        }
                    }
                }
            };

            var changeResp = await _r53.ChangeResourceRecordSetsAsync(changeRequ);

            _logger.LogInformation("DELETE request completed, response:");
            _logger.LogInformation(JsonSerializer.Serialize(changeResp));
        }
        /// <summary>
        /// Run a single item
        /// </summary>
        /// <param name="item">The item to run</param>
        public void RunItem(Route53Host item)
        {
            //Output
            Output($"R53: Starting item: {item}, new IP address: {IpState.NewIP}");

            //New the Route 53 Client
            AmazonRoute53Client r53Client =
                new AmazonRoute53Client(
                    Config.BaseSettings.AWSAccessKeyID,
                    Config.BaseSettings.AWSSecretAccessKey,
                    new AmazonRoute53Config {
                RegionEndpoint = RegionEndpoint
            });

            //New the Change Record to push
            Change change =
                new Change
            {
                Action            = ChangeAction.UPSERT, //Insert or Update
                ResourceRecordSet =
                    new ResourceRecordSet
                {
                    Name            = item.Name,
                    TTL             = item.TTL,
                    Type            = RRType.A,
                    ResourceRecords = new List <ResourceRecord> {
                        new ResourceRecord(IpState.NewIP)
                    }
                }
            };

            //New the Change Request
            ChangeResourceRecordSetsRequest recordSetsRequest =
                new ChangeResourceRecordSetsRequest
            {
                HostedZoneId = item.ZoneId,
                ChangeBatch  = new ChangeBatch(new List <Change> {
                    change
                })
            };

            //Submitting the Change Request to the API and receiving back the ID
            ChangeResourceRecordSetsResponse recordSetResponse = r53Client.ChangeResourceRecordSetsAsync(recordSetsRequest).GetAwaiter().GetResult();

            //The ID of the response
            string changeId = recordSetResponse.ChangeInfo.Id;

            //Output
            Output($"R53: Change ID \"{changeId}\": ChangeRequest was submitted.");

            //Enquire with R53 the status of the change (R53 updates can be VERY slow business)
            GetChangeRequest changeRequest =
                new GetChangeRequest
            {
                Id = changeId
            };

            while (r53Client.GetChangeAsync(changeRequest).GetAwaiter().GetResult().ChangeInfo.Status == ChangeStatus.PENDING)
            {
                //Output
                Output($"R53: Change ID \"{changeId}\": Change is still pending. (Can take a while.)");

                //Wait
                Thread.Sleep(10 * 1000); //Wait ten seconds
            }

            //Output DONE
            Output($"R53: Change ID \"{changeId}\": Change IN SYNC. Done.");
        }
예제 #27
0
        public void Serialize3()
        {
            var request = new ChangeResourceRecordSetsRequest(new[] {
                new ResourceRecordSetChange
                {
                    Action = ChangeAction.CREATE,

                    ResourceRecordSet = new ResourceRecordSet
                    {
                        Failover = Failover.SECONDARY,
                        TTL      = 600,
                        Type     = ResourceRecordType.NS
                    }
                },
                new ResourceRecordSetChange(ChangeAction.DELETE, new ResourceRecordSet(ResourceRecordType.AAAA, "example.com.")),
                new ResourceRecordSetChange
                {
                    Action = ChangeAction.UPSERT,

                    ResourceRecordSet = new ResourceRecordSet
                    {
                        Failover        = Failover.SECONDARY,
                        TTL             = 30,
                        Weight          = 255,
                        Type            = ResourceRecordType.TXT,
                        ResourceRecords = new[]
                        {
                            new ResourceRecord("a"),
                            new ResourceRecord("b"),
                            new ResourceRecord("c")
                        }
                    }
                }
            });

            byte[] bytes = Route53Serializer <ChangeResourceRecordSetsRequest> .SerializeToUtf8Bytes(request);

            var text = Encoding.UTF8.GetString(bytes);

            Assert.Equal(@"<?xml version=""1.0"" encoding=""utf-8""?>
<ChangeResourceRecordSetsRequest xmlns=""https://route53.amazonaws.com/doc/2013-04-01/"">
  <ChangeBatch>
    <Changes>
      <Change>
        <Action>CREATE</Action>
        <ResourceRecordSet>
          <Failover>SECONDARY</Failover>
          <TTL>600</TTL>
          <Type>NS</Type>
        </ResourceRecordSet>
      </Change>
      <Change>
        <Action>DELETE</Action>
        <ResourceRecordSet>
          <Name>example.com.</Name>
          <ResourceRecords />
          <Type>AAAA</Type>
        </ResourceRecordSet>
      </Change>
      <Change>
        <Action>UPSERT</Action>
        <ResourceRecordSet>
          <Failover>SECONDARY</Failover>
          <ResourceRecords>
            <ResourceRecord>
              <Value>a</Value>
            </ResourceRecord>
            <ResourceRecord>
              <Value>b</Value>
            </ResourceRecord>
            <ResourceRecord>
              <Value>c</Value>
            </ResourceRecord>
          </ResourceRecords>
          <TTL>30</TTL>
          <Type>TXT</Type>
          <Weight>255</Weight>
        </ResourceRecordSet>
      </Change>
    </Changes>
  </ChangeBatch>
</ChangeResourceRecordSetsRequest>", Encoding.UTF8.GetString(bytes));
        }
예제 #28
0
        //https://docs.aws.amazon.com/sdk-for-net/v2/developer-guide/route53-apis-intro.html
        public static void UpdateRecord()
        {
            //TODO: Better exception handling overall in the method
            SimpleLogging.WriteToLog("Time to check for update to public IP", true);
            SimpleLogging.WriteToLog("Last public IP was " + lastIP, true);
            string publicIP = GetPublicIP(ServiceConfig.GetPublicIPTries);

            SimpleLogging.WriteToLog("Current public IP is " + publicIP, true);

            if (publicIP == "")
            {
                SimpleLogging.WriteToLog("Failed to check for new public IP");
                return;
            }

            if (publicIP == lastIP)
            {
                if (ServiceConfig.WriteLogsOnlyIfIPChanged)
                {
                    SimpleLogging.WipePendingLogData();
                }
                else
                {
                    SimpleLogging.WriteToLog("Public IP address has not changed" + Environment.NewLine);
                }
                return;
            }
            SimpleLogging.WriteToLog("Contacting AWS to update public IP");
            lastIP = publicIP;

            //TODO: Better exception handling when these values aren't working
            //TODO: Confirm all users can use the APSoutheast2 endpoint
            var route53Client = new AmazonRoute53Client(ServiceConfig.AwsAccessKeyId, ServiceConfig.AwsSecretAccessKey, RegionEndpoint.APSoutheast2);

            SimpleLogging.WriteToLog("Successfully authenticated to AWS");

            var recordSet = new ResourceRecordSet()
            {
                Name            = ServiceConfig.DomainName,
                TTL             = 60,
                Type            = RRType.A, //TODO: Update so can do IPv6 records also where required
                ResourceRecords = new List <ResourceRecord>
                {
                    new ResourceRecord {
                        Value = publicIP
                    }
                }
            };

            var changeBatch = new ChangeBatch()
            {
                Changes = new List <Change>
                {
                    new Change()
                    {
                        ResourceRecordSet = recordSet,
                        Action            = ChangeAction.UPSERT
                    }
                }
            };

            var recordsetRequest = new ChangeResourceRecordSetsRequest()
            {
                HostedZoneId = ServiceConfig.HostedZoneId,
                ChangeBatch  = changeBatch
            };

            var recordsetResponse = route53Client.ChangeResourceRecordSets(recordsetRequest);

            SimpleLogging.WriteToLog("Succesfully submitted update request to AWS");

            var changeRequest = new GetChangeRequest()
            {
                Id = recordsetResponse.ChangeInfo.Id
            };

            while (ChangeStatus.PENDING == route53Client.GetChange(changeRequest).ChangeInfo.Status)
            {
                SimpleLogging.WriteToLog("Waiting for change to be INSYNC");
                Thread.Sleep(ServiceConfig.AWSGetChangeSleepTime);
            }

            SimpleLogging.WriteToLog("Succesfully updated IP address to " + publicIP + Environment.NewLine);
        }
예제 #29
0
        static void Main(string[] args)
        {
            const string awsId  = "AKIAJBEJGQLMJAGQV6YQ";
            const string awsKey = "lzM+9nJXLTNauQgz15SIyQD1QzWe/4+UcPzOEEPw";

            const string domainName = "www.example.org";

            //[1] Create an Amazon Route 53 client object
            var route53Client = AWSClientFactory.CreateAmazonRoute53Client(awsId, awsKey);

            //[2] Create a hosted zone
            var zoneRequest = new CreateHostedZoneRequest {
                Name            = domainName,
                CallerReference = "my_change_request"
            };

            var zoneResponse = route53Client.CreateHostedZone(zoneRequest);

            //[3] Create a resource record set change batch
            var recordSet = new ResourceRecordSet {
                Name            = domainName,
                TTL             = 60,
                Type            = RRType.A,
                ResourceRecords = new List <ResourceRecord> {
                    new ResourceRecord {
                        Value = "192.0.2.235"
                    }
                }
            };

            var change1 = new Change {
                ResourceRecordSet = recordSet,
                Action            = ChangeAction.CREATE
            };

            var changeBatch = new ChangeBatch {
                Changes = new List <Change> {
                    change1
                }
            };

            //[4] Update the zone's resource record sets
            var recordsetRequest = new ChangeResourceRecordSetsRequest {
                HostedZoneId = zoneResponse.HostedZone.Id,
                ChangeBatch  = changeBatch
            };

            var recordsetResponse = route53Client.ChangeResourceRecordSets(recordsetRequest);

            //[5] Monitor the change status
            var changeRequest = new GetChangeRequest {
                Id = recordsetResponse.ChangeInfo.Id
            };

            while (route53Client.GetChange(changeRequest).ChangeInfo.Status == ChangeStatus.PENDING)
            {
                Console.WriteLine("Change is pending.");
                Thread.Sleep(15000);
            }

            Console.WriteLine("Change is complete.");
            Console.ReadKey();
        }
        protected override async Task PersistAsync(string recordName, string recordType, string recordValue)
        {
            _logger.LogDebug("Starting creation or update of {RecordType} {RecordName} with value {RecordValue}", recordType, recordName, recordValue);

            var zone = await FindHostedZoneAsync(recordName);

            if (zone == null)
            {
                _logger.LogDebug("No zone was found");
                return;
            }

            if (recordType == TxtRecordType)
            {
                recordValue = NormalizeTxtValue(recordValue);
            }

            var existingRecordSets = await FindRecordSetsAsync(zone, recordName, recordType);

            var existingRecordSet = existingRecordSets.FirstOrDefault();

            var recordSet = existingRecordSet ?? new ResourceRecordSet
            {
                Name            = recordName,
                TTL             = 60,
                Type            = RRType.FindValue(recordType),
                ResourceRecords = new List <ResourceRecord>()
            };

            if (recordSet.ResourceRecords.Any(x => x.Value == recordValue))
            {
                _logger.LogDebug("Record {RecordType} {RecordName} with value {RecordValue} already exists", recordType, recordName, recordValue);
                return;
            }

            recordSet.ResourceRecords.Add(new ResourceRecord {
                Value = recordValue
            });

            var change1 = new Change
            {
                ResourceRecordSet = recordSet,
                Action            = ChangeAction.UPSERT
            };

            var changeBatch = new ChangeBatch
            {
                Changes = new List <Change> {
                    change1
                }
            };

            var recordsetRequest = new ChangeResourceRecordSetsRequest
            {
                HostedZoneId = zone.Id,
                ChangeBatch  = changeBatch
            };

            _logger.LogInformation("Creating or updating DNS record {RecordType} {RecordName}", recordType, recordName);

            var upsertResponse = await _route53Client.ChangeResourceRecordSetsAsync(
                new ChangeResourceRecordSetsRequest()
            {
                ChangeBatch  = changeBatch,
                HostedZoneId = zone.Id
            });

            var changeRequest = new GetChangeRequest
            {
                Id = upsertResponse.ChangeInfo.Id
            };

            while (await IsChangePendingAsync(changeRequest))
            {
                _logger.LogDebug("Creation/update of {RecordType} {RecordName} with value {RecordValue} is pending. Checking for status update in {StatusPollIntervalSeconds} seconds.", recordType, recordName, recordValue, StatusPollIntervalSeconds);
                Thread.Sleep(TimeSpan.FromSeconds(StatusPollIntervalSeconds));
            }
        }