Package io.fathom.cloud.dns.backend.aws

Source Code of io.fathom.cloud.dns.backend.aws.AwsRoute53Client

package io.fathom.cloud.dns.backend.aws;

import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.route53.AmazonRoute53;
import com.amazonaws.services.route53.AmazonRoute53Client;
import com.amazonaws.services.route53.model.Change;
import com.amazonaws.services.route53.model.ChangeAction;
import com.amazonaws.services.route53.model.ChangeBatch;
import com.amazonaws.services.route53.model.ChangeResourceRecordSetsRequest;
import com.amazonaws.services.route53.model.ChangeResourceRecordSetsResult;
import com.amazonaws.services.route53.model.CreateHostedZoneRequest;
import com.amazonaws.services.route53.model.CreateHostedZoneResult;
import com.amazonaws.services.route53.model.HostedZone;
import com.amazonaws.services.route53.model.HostedZoneAlreadyExistsException;
import com.amazonaws.services.route53.model.ListHostedZonesRequest;
import com.amazonaws.services.route53.model.ListHostedZonesResult;
import com.amazonaws.services.route53.model.ListResourceRecordSetsRequest;
import com.amazonaws.services.route53.model.ListResourceRecordSetsResult;
import com.amazonaws.services.route53.model.ResourceRecordSet;
import com.fathomdb.Configuration;
import com.google.common.base.CharMatcher;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@Singleton
// If injected, a singleton
public class AwsRoute53Client {

    private static final Logger log = LoggerFactory.getLogger(AwsRoute53Client.class);

    final AmazonRoute53 restClient;

    Map<String, HostedZone> hostedZones;

    @Inject
    public AwsRoute53Client(Configuration config) {
        this(config.get("aws.route53.access"), config.get("aws.route53.secret"));
    }

    public AwsRoute53Client(String accessKey, String secretKey) {
        BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
        this.restClient = new AmazonRoute53Client(awsCredentials);
    }

    public List<ResourceRecordSet> getResourceRecords(String awsZoneId) {
        List<ResourceRecordSet> resourceRecords = Lists.newArrayList();

        ListResourceRecordSetsResult previous = null;
        while (true) {
            ListResourceRecordSetsRequest request = new ListResourceRecordSetsRequest(awsZoneId);
            if (previous != null) {
                request.setStartRecordIdentifier(previous.getNextRecordIdentifier());
                request.setStartRecordName(previous.getNextRecordName());
                request.setStartRecordType(previous.getNextRecordType());
            }

            ListResourceRecordSetsResult response = restClient.listResourceRecordSets(request);
            for (ResourceRecordSet resourceRecordSet : response.getResourceRecordSets()) {
                resourceRecords.add(resourceRecordSet);
            }
            if (!Objects.equal(response.isTruncated(), Boolean.TRUE)) {
                break;
            }
            previous = response;
        }
        return resourceRecords;
    }

    public synchronized Map<String, HostedZone> getHostedZones() {
        if (hostedZones == null) {
            refreshHostedZones();
        }
        return hostedZones;
    }

    private synchronized void refreshHostedZones() {
        hostedZones = getHostedZones0();
    }

    private synchronized Map<String, HostedZone> getHostedZones0() {
        Map<String, HostedZone> hostedZones = Maps.newHashMap();
        String marker = null;
        while (true) {
            ListHostedZonesRequest request = new ListHostedZonesRequest();
            if (marker != null) {
                request.withMarker(marker);
            }
            ListHostedZonesResult response = restClient.listHostedZones(request);
            for (HostedZone hostedZone : response.getHostedZones()) {
                String key = CharMatcher.is('.').trimTrailingFrom(hostedZone.getName());
                hostedZones.put(key, hostedZone);
            }
            if (!Objects.equal(response.isTruncated(), Boolean.TRUE)) {
                break;
            }
            marker = response.getMarker();
        }
        return hostedZones;
    }

    public HostedZone createHostedZone(String zoneName) {
        HostedZone zone = getHostedZones().get(zoneName);
        if (zone != null) {
            return zone;
        }

        log.info("Creating Route 53 zone: {}", zoneName);

        CreateHostedZoneRequest request = new CreateHostedZoneRequest();
        request.setName(zoneName);
        request.setCallerReference("CreateHostedZoneRequest:" + zoneName);

        // HostedZoneConfig hostedZoneConfig = new HostedZoneConfig();
        // hostedZoneConfig.setComment(comment);
        // request.setHostedZoneConfig(hostedZoneConfig);

        try {
            CreateHostedZoneResult result = restClient.createHostedZone(request);
            zone = result.getHostedZone();
        } catch (HostedZoneAlreadyExistsException e) {
            refreshHostedZones();
            zone = hostedZones.get(zoneName);
        }
        if (zone == null) {
            throw new IllegalStateException();
        }
        return zone;
    }

    public void changeRecords(String hostedZoneId, List<ResourceRecordSet> create, List<ResourceRecordSet> remove) {
        List<Change> changes = Lists.newArrayList();

        for (ResourceRecordSet r : remove) {
            Change change = new Change(ChangeAction.DELETE, r);
            changes.add(change);
        }

        for (ResourceRecordSet r : create) {
            Change change = new Change(ChangeAction.CREATE, r);
            changes.add(change);
        }

        if (changes.isEmpty()) {
            log.info("No DNS record changes");
            return;
        }

        ChangeBatch changeBatch = new ChangeBatch();
        changeBatch.setChanges(changes);
        ChangeResourceRecordSetsRequest request = new ChangeResourceRecordSetsRequest();
        request.setHostedZoneId(hostedZoneId);
        request.setChangeBatch(changeBatch);

        log.info("Changing DNS records: {}", request);

        ChangeResourceRecordSetsResult response = restClient.changeResourceRecordSets(request);

        log.info("Changed records: {}", response);
    }

    public String getAwsZoneName(String domainName) {
        domainName = CharMatcher.is('.').trimTrailingFrom(domainName);

        int lastDot = domainName.lastIndexOf('.');
        if (lastDot == -1) {
            return domainName;
        }
        String suffix = domainName.substring(lastDot + 1);
        // TODO: Check for compound suffixes?

        String prefix = domainName.substring(0, lastDot);
        int lastDotPrefix = prefix.lastIndexOf('.');
        if (lastDotPrefix != -1) {
            prefix = prefix.substring(lastDotPrefix + 1);
        }

        return prefix + "." + suffix;
    }

}
TOP

Related Classes of io.fathom.cloud.dns.backend.aws.AwsRoute53Client

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.