class LetsencryptDynectUpdater (object):

    customer_name = os.environ['CERTBOT_CUSTOMER_NAME']
    api_key = os.environ['CERTBOT_API_KEY']
    api_pass = os.environ['CERTBOT_API_PASS']
    challengeSubdomain = '_acme-challenge'
    rest_client = DynectRest()
    fqdn = None
    domain = None
    validation = None

    def __init__(self, domain, validation):
        self.domain = self.parseTld(domain)

        self.validation = validation
        # use the passed domain param here, self.domain only contains the main domain at this point
        self.fqdn = '{}.{}'.format(self.challengeSubdomain, domain)

    def parseTld(self, domain):
        splitted = domain.split('.')
        return '.'.join(splitted[-2:])

    def login(self):
        arguments = {
            'customer_name': self.customer_name,
            'user_name': self.api_key,
            'password': self.api_pass,
        }

        response = self.rest_client.execute('/Session/', 'POST', arguments)
        if response['status'] != 'success':
            print("Incorrect credentials")
            sys.exit(1)

    def deleteValidationRecord(self):
        response = self.rest_client.execute(
            '/TXTRecord/{}/{}/'.format(
                self.domain,
                self.fqdn
            ), 'DELETE'
        )
        if response['status'] != 'success':
            print('No entries found to delete')
            return True

        records = response['data']
        for record in records:
            record_id = record.split('/').pop()
        return True

    def addValidationRecord(self):
        arguments = {
            'rdata': {'txtdata': self.validation},
            'ttl': 5
        }
        response = self.rest_client.execute(
            '/TXTRecord/{}/{}/'.format(
                self.domain,
                self.fqdn
            ), 'POST', arguments)
        if response['status'] != 'success':
            print('Adding txt record failed')
            sys.exit(1)

    def publish(self):
        arguments = {
            'publish': 1
        }
        response = self.rest_client.execute(
            '/Zone/{}/'.format(
                self.domain
            ), 'PUT', arguments)
        if response['status'] != 'success':
            print('Adding txt record failed')
            sys.exit(1)

    def logout(self):
        self.rest_client.execute('/Session/', 'DELETE')
Example #2
0
def point_dns_to_stack(region, stack_type, name):
    import sys
    import os
    import json
    import boto.ec2.elb

    from dynect.DynectDNS import DynectRest  # sudo pip install https://github.com/dyninc/Dynect-API-Python-Library/zipball/master

    if stack_type == 'stage':
        elbs = {
            'firefoxos.anosrep.org': 'w-anosrep-org',
            'login.anosrep.org': 'w-anosrep-org',
            'www.anosrep.org': 'w-anosrep-org',
            'static.login.anosrep.org': 'w-login-anosrep-org',
            'verifier.login.anosrep.org': 'w-login-anosrep-org',
            'gmail.login.anosrep.org': 'gmail-login-anosrep-org',
            'yahoo.login.anosrep.org': 'yahoo-login-anosrep-org'
        }
        zone = 'anosrep.org'
    elif stack_type == 'prod':
        elbs = {
            'login.persona.org': 'persona-org',
            'www.persona.org': 'persona-org',
            'gmail.login.persona.org': 'gmail-login-persona-org',
            'yahoo.login.persona.org': 'yahoo-login-persona-org'
        }
        zone = 'persona.org'
    new_names = {}

    # TODO : This doesn't work for prod because we need to inject multiple regions into traffic mangement

    conn_elb = boto.ec2.elb.connect_to_region(region)
    load_balancers = conn_elb.get_all_load_balancers(
        load_balancer_names=['%s-%s' % (x, name) for x in set(elbs.values())])
    for load_balancer in load_balancers:
        new_names['-'.join(
            load_balancer.name.split('-')[:-1])] = load_balancer.dns_name

    rest_iface = DynectRest()
    if 'AWS_CONFIG_DIR' in os.environ:
        user_data_filename = os.path.join(os.environ['AWS_CONFIG_DIR'],
                                          'dynect.json')
    else:
        user_data_filename = 'config/dynect.json'

    with open(user_data_filename, 'r') as f:
        dynect_credentials = json.load(f)

    # Log in
    response = rest_iface.execute('/Session/', 'POST', dynect_credentials)

    if response['status'] != 'success':
        sys.exit("Incorrect credentials")

    for record in elbs.keys():
        # Get record_id
        uri = '/CNAMERecord/%s/%s/' % (zone, record)
        response = rest_iface.execute(uri, 'GET')
        record_id = response['data'][0].split('/')[-1]
        uri = uri + record_id + '/'

        # Get current record
        response = rest_iface.execute(uri, 'GET')
        old_name = response['data']['rdata']['cname']

        # Set new record
        new_name = new_names[elbs[record]] + '.'
        arguments = {'rdata': {'cname': new_name}}
        logging.info('calling "%s" to change the record from "%s" to "%s"' %
                     (uri, old_name, new_name))
        response = rest_iface.execute(uri, 'PUT', arguments)
        logging.info(json.dumps(response['msgs']))

    # Publish the new zone
    response = rest_iface.execute('/Zone/%s' % zone, 'PUT', {'publish': 1})
    logging.info('new zone published with updates at serial number %s' %
                 response['data']['serial'])

    # Log out, to be polite
    rest_iface.execute('/Session/', 'DELETE')
from dynect.DynectDNS import DynectRest
from pprint import PrettyPrinter

# TODO Break ouf of two additional loops for the DR verification block
# TODO where it says saving back up file, add file name and path

zone_list = []
current_time = time.strftime("%d%m%Y-%H%M%S")

# parameter / file name configuration
args = sys.argv
help_list = ["/?", "?", "help", "-h", "-he4lp"]
print(args)

# Login to API
api = DynectRest()
print("Log in DYN API")

pargs = {
    'customer_name': 'Infinata',
    'user_name': input('Enter your Dynect username: '******'password': getpass.getpass(prompt='Password:'******'/REST/Session/', 'POST', pargs)

if response['status'] != 'success':
    pretty = PrettyPrinter()
    msg = "** Login to API failed: %s" % pretty.pformat(response)
    sys.exit(msg)
Example #4
0
    def queryDynect(self):

        LOG.info('Query DynECT to get the state of GSLBs')
        try:
            rest_iface = DynectRest()
            if CONF.debug and CONF.use_stderr:
                rest_iface.verbose = True

            # login
            credentials = {
                'customer_name': CONF.dynect_customer,
                'user_name': CONF.dynect_username,
                'password': CONF.dynect_password,
            }
            LOG.debug('credentials = %s', credentials)
            response = rest_iface.execute('/Session/', 'POST', credentials)

            if response['status'] != 'success':
                LOG.error('Failed to create API session: %s',
                          response['msgs'][0]['INFO'])
                self.updating = False
                return

            # Discover all the Zones in DynECT
            response = rest_iface.execute('/Zone/', 'GET')
            LOG.debug('/Zone/ => %s', json.dumps(response, indent=4))
            zone_resources = response['data']

            # Discover all the LoadBalancers
            for resource in zone_resources:
                zone = resource.split('/')[
                    3]  # eg. /REST/Zone/guardiannews.com/
                response = rest_iface.execute('/LoadBalance/' + zone + '/',
                                              'GET')
                LOG.debug('/LoadBalance/%s/ => %s', zone,
                          json.dumps(response, indent=4))
                gslb = response['data']

                # Discover LoadBalancer pool information.
                for lb in gslb:
                    fqdn = lb.split(
                        '/'
                    )[4]  # eg. /REST/LoadBalance/guardiannews.com/id.guardiannews.com/
                    response = rest_iface.execute(
                        '/LoadBalance/' + zone + '/' + fqdn + '/', 'GET')
                    LOG.debug('/LoadBalance/%s/%s/ => %s', zone, fqdn,
                              json.dumps(response, indent=4))
                    status = response['data']['status']
                    monitor = response['data']['monitor']
                    self.info['gslb-' + fqdn] = {
                        'status': status,
                        'gslb': fqdn,
                        'rawData': monitor
                    }

                    for pool in response['data']['pool']:
                        name = '%s-%s' % (fqdn, pool['label'].replace(
                            ' ', '-'))
                        status = '%s:%s:%s' % (
                            pool['status'], pool['serve_mode'], pool['weight'])
                        self.info['pool-' + name] = {
                            'status': status,
                            'gslb': fqdn,
                            'rawData': pool
                        }

            LOG.info('Finished object discovery query.')
            LOG.debug('GSLBs and Pools: %s', json.dumps(self.info, indent=4))

            # logout
            rest_iface.execute('/Session/', 'DELETE')

        except Exception, e:
            LOG.error('Failed to discover GSLBs: %s', e)
            self.updating = False