Esempio n. 1
0
 def test_remove_dns_entries(self, mock_client):
     ds = DomainService('sundayafternoon')
     ds.build_cookie = Mock(return_value={'cookie': 'value'})
     ds.update_cookie = Mock()
     getinfo_result = Mock()
     dns_entry1 = DnsEntry(
         'testentry1',
         86400,
         DnsEntry.TYPE_A,
         '127.0.0.1',
     )
     dns_entry2 = DnsEntry(
         'testentry2',
         86400,
         DnsEntry.TYPE_A,
         '127.0.0.1',
     )
     getinfo_result.dnsEntries = [
         dns_entry1,
         dns_entry2,
     ]
     mock_client.return_value.service.getInfo.return_value = getinfo_result
     ds.remove_dns_entries('domain1', [dns_entry1])
     mock_client.return_value.service.setDnsEntries.assert_called_with(
         'domain1',
         [dns_entry2],
     )
Esempio n. 2
0
    def testEquality(self):
        dns_entry_one = DnsEntry('@', 300, DnsEntry.TYPE_A, '8.8.8.8')
        dns_entry_two = DnsEntry('@', 300, DnsEntry.TYPE_A, '8.8.8.8')
        self.assertEqual(dns_entry_one, dns_entry_two)

        dns_entry_two.expire = 600
        self.assertEqual(dns_entry_one, dns_entry_two)

        dns_entry_two.content = '127.0.0.1'
        self.assertNotEqual(dns_entry_one, dns_entry_two)
Esempio n. 3
0
 def _to_dns_entry(self, _entry):
     return DnsEntry(
         self._relative_name(_entry["name"]),
         _entry["ttl"],
         _entry["type"],
         _entry["content"],
     )
Esempio n. 4
0
    def _entries_for_multiple(self, name, record):
        _entries = []

        for value in record.values:
            _entries.append(DnsEntry(name, record.ttl, record._type, value))

        return _entries
Esempio n. 5
0
    def _create_record(self, rtype, name, content):
        records = self.client.get_info(self.domain).dnsEntries

        if self._filter_records(records, rtype, name, content):
            # Nothing to do, record already exists
            LOGGER.debug("create_record: already exists")
            return True

        records.append(
            DnsEntry(
                **{
                    "name": self._relative_name(name),
                    "record_type": rtype,
                    "content": self._bind_format_target(rtype, content),
                    "expire": self._get_lexicon_option("ttl"),
                }
            )
        )

        self.client.set_dns_entries(self.domain, records)
        status = (
            len(self._list_records_internal(rtype, name, content, show_output=False))
            >= 1
        )
        LOGGER.debug("create_record: %s", status)
        return status
Esempio n. 6
0
    def test_set_dns_entries(self, mock_client):
        # SETUP
        ds = DomainService('sundayafternoon')
        ds.build_cookie = Mock(return_value={"cookie": "value"})
        ds.update_cookie = Mock()

        i = mock_client.return_value
        i.service.setDnsEntries.return_value = None

        dns_entry = DnsEntry('testentry', 86400, DnsEntry.TYPE_A, '127.0.0.1')

        # CALL
        result = ds.set_dns_entries('domain1', [
            dns_entry,
        ])

        # VERIFY
        ds.build_cookie.assert_called_with(mode=MODE_RW,
                                           method='setDnsEntries',
                                           parameters=('domain1', [
                                               dns_entry,
                                           ]))
        ds.update_cookie.assert_called_with({"cookie": "value"})
        i.service.setDnsEntries.assert_called_with('domain1', [
            dns_entry,
        ])
Esempio n. 7
0
    def _entries_for_TXT(self, name, record):
        _entries = []

        for value in record.values:
            value = value.replace('\\;', ';')
            _entries.append(DnsEntry(name, record.ttl, record._type, value))

        return _entries
Esempio n. 8
0
    def _entries_for_MX(self, name, record):
        _entries = []

        for value in record.values:
            content = "{} {}".format(value.preference, value.exchange)
            _entries.append(DnsEntry(name, record.ttl, record._type, content))

        return _entries
Esempio n. 9
0
    def _entries_for_CAA(self, name, record):
        _entries = []

        for value in record.values:
            content = "{} {} {}".format(value.flags, value.tag, value.value)
            _entries.append(DnsEntry(name, record.ttl, record._type, content))

        return _entries
Esempio n. 10
0
    def _entries_for_SRV(self, name, record):
        _entries = []

        for value in record.values:
            content = "{} {} {} {}".format(value.priority, value.weight,
                                           value.port, value.target)
            _entries.append(DnsEntry(name, record.ttl, record._type, content))

        return _entries
Esempio n. 11
0
def update_a_records(config_domains, avail_domains, expire_time, domain_service):
    domain_records = defaultdict(set)

    # Create inventory of which records to update for each domain
    for fqdn in config_domains:
        parts = fqdn.strip().rsplit('.', 2)
        if len(parts) < 2:
            raise ConfigError("Invalid domain in configuration: '{}'".format(fqdn))
        elif len(parts) == 2:
            record, (domain, tld) = '@', parts
        else:
            record, domain, tld = parts
        domain = "{}.{}".format(domain, tld)
        if domain not in avail_domains:
            raise ConfigError("Configured domain '{}' does not belong to this account".format(domain))
        log.debug("A record to update: '{}' on domain '{}'".format(record, domain))
        domain_records[domain].add(record)

    if not domain_records:
        log.debug("No A records configured to update")
        return

    ipv4 = get_ipv4()
    log.debug("Found external IPv4 address {}".format(ipv4))

    updated = False

    # Update records
    for domain, records in domain_records.items():
        entries = domain_service.get_info(domain).dnsEntries

        # Update existing entries
        for entry in entries:
            if entry.type != 'A':
                continue
            if entry.name not in records:
                continue
            log.debug("Found relevant A record on {}: {}".format(domain, entry))
            records.remove(entry.name)
            if entry.content == ipv4:
                log.debug("A record for '{}' on domain '{}' is already up to date".format(entry.name, domain))
                continue
            else:
                log.info("Updating A record for '{}' on domain '{}' to '{}'".format(entry.name, domain, ipv4))
                entry.content = ipv4
                updated = True
        
        # Create new entries
        for new_record in records:
            log.info("Creating new A record for '{}' on domain '{}' with content '{}' and expiry {}".format(new_record, domain, ipv4, expire_time))
            entries.append(DnsEntry(new_record, expire_time, 'A', ipv4))
            updated = True

        # Set new entries via API if needed
        if updated:
            domain_service.set_dns_entries(domain, entries)
Esempio n. 12
0
    def _entries_for_SSHFP(self, name, record):
        _entries = []

        for value in record.values:
            content = "{} {} {}".format(value.algorithm,
                                        value.fingerprint_type,
                                        value.fingerprint)
            _entries.append(DnsEntry(name, record.ttl, record._type, content))

        return _entries
    def setUp(self):
        self.domain_service = mock.MagicMock()
        with open(KEY_FILE, 'w') as key_file:
            key_file.write('''-----BEGIN RSA PRIVATE KEY-----
foobar
-----END RSA PRIVATE KEY-----''')
        self.transip_client = _TransipClient(username=USERNAME,
                                             key_file=KEY_FILE)
        self.transip_client.domain_service = self.domain_service
        self.domain_service.get_domain_names.return_value = ['example.com']
        self.correct_entry1 = DnsEntry(name='record1',
                                       record_type='A',
                                       content='127.0.0.1',
                                       expire=1)
        self.correct_entry2 = DnsEntry(name='record2',
                                       record_type='TXT',
                                       content='f00b4r',
                                       expire=1)
        self.add_record = DnsEntry(name='test.test',
                                   record_type='TXT',
                                   content='new record',
                                   expire=1)
Esempio n. 14
0
def update_dns(domain_service, args):
    """
    Adds, updates or deletes a DNS entry through the API
    :param domain_service: an initialized DomainService object
    :param args: arguments object from argparse
    """

    try:
        dns_entries = domain_service.get_info(args.domain_name).dnsEntries
    except WebFault as err:
        print(err)
        sys.exit(1)

    number_of_entries = len(dns_entries)
    for entry in dns_entries:
        if args.add_dns_entry and entry.name == args.entry_name and entry.type == args.entry_type and \
                entry.content == args.entry_content:
            print('The DNS entry already exists.')
            sys.exit(1)

        elif args.update_dns_entry and entry.name == args.entry_name and entry.type == args.entry_type:
            dns_entries.remove(entry)

        elif args.delete_dns_entry and entry.name == args.entry_name and entry.type == args.entry_type and \
                entry.expire == args.entry_expire and entry.content == args.entry_content:
            dns_entries.remove(entry)

    if args.update_dns_entry or args.delete_dns_entry:
        if number_of_entries == len(dns_entries):
            print('The DNS entry was not found.')
            sys.exit(1)

    if args.add_dns_entry or args.update_dns_entry:
        dns_entries.append(
            DnsEntry(args.entry_name, args.entry_expire, args.entry_type,
                     args.entry_content))

    try:
        result = domain_service.set_dns_entries(args.domain_name, dns_entries)
    except WebFault as err:
        print(err)
        sys.exit(1)
    if result is None:
        print('Request finished successfully.')
    else:
        print(result)
Esempio n. 15
0
    def add_txt_record(self, domain_name, record_name, record_content):
        """
        Add a TXT record using the supplied information.

        :param str domain_name: The domain to use to associate the record with.
        :param str record_name: The record name (typically beginning with '_acme-challenge.').
        :param str record_content: The record content (typically the challenge validation).
        :raises certbot.errors.PluginError: if an error occurs communicating with the Transip
                                            API
        """
        try:
            domain = self._find_domain(domain_name)
        except suds.WebFault as error:
            self.logger.error('Error finding domain using the Transip API: %s',
                              error)
            raise errors.PluginError(
                'Error finding domain using the Transip API: {0}'.format(
                    error))

        domain_records = self._get_dns_entries(domain)

        try:
            new_record = DnsEntry(
                name=self._compute_record_name(domain, record_name),
                record_type='TXT',
                content=record_content,
                expire=1,
            )
        except suds.WebFault as error:
            self.logger.error(
                'Error getting DNS records using the Transip API: %s', error)
            return

        domain_records.append(new_record)

        try:
            self.domain_service.set_dns_entries(domain_name=domain,
                                                dns_entries=domain_records)
            self.logger.info('Successfully added TXT record')
        except suds.WebFault as error:
            self.logger.error(
                'Error adding TXT record using the Transip API: %s', error)
            raise errors.PluginError(
                'Error adding TXT record using the Transip API: {0}'.format(
                    error))
Esempio n. 16
0
    def get_info(self, domain_name):
        """
        Retrieves information about the requested domain-name.
        :param domain_name: str
        :rtype: transip.service.objects.Domain
        """
        cookie = self.build_cookie(mode=MODE_RO, method='getInfo', parameters=[domain_name])
        self.update_cookie(cookie)

        # Perform the call
        result = self.soap_client.service.getInfo(domain_name)

        # Parse the result to well-known objects
        new_dns_entries = []
        for dnsentry in result.dnsEntries:
            if dnsentry.__class__.__name__ == 'DnsEntry':
                new_dns_entries.append(DnsEntry(dnsentry.name, dnsentry.expire, dnsentry.type, dnsentry.content))
        result.dnsEntries = new_dns_entries

        return result
Esempio n. 17
0
    def create_record(self, type, name, content):
        records = self.client.get_info(self.domain).dnsEntries

        if self._filter_records(records, type, name, content):
            # Nothing to do, record already exists
            LOGGER.debug('create_record: already exists')
            return True

        records.append(DnsEntry(**{
            "name": self._relative_name(name),
            "record_type": type,
            "content": self._bind_format_target(type, content),
            "expire": self._get_lexicon_option('ttl')
        }))

        self.client.set_dns_entries(self.domain, records)
        status = len(self.list_records(
            type, name, content, show_output=False)) >= 1
        LOGGER.debug('create_record: %s', status)
        return status
Esempio n. 18
0
    def mockup(self, records):

        provider = TransipProvider('', '', '')

        _dns_entries = []
        for record in records:
            if record._type in provider.SUPPORTS:
                entries_for = getattr(provider,
                                      '_entries_for_{}'.format(record._type))

                # Root records have '@' as name
                name = record.name
                if name == '':
                    name = provider.ROOT_RECORD

                _dns_entries.extend(entries_for(name, record))

                # NS is not supported as a DNS Entry,
                # so it should cover the if statement
                _dns_entries.append(
                    DnsEntry('@', '3600', 'NS', 'ns01.transip.nl.'))

        self.mockupEntries = _dns_entries
Esempio n. 19
0
    def test_get_info(self, mock_client):
        # SETUP
        ds = DomainService(login='******')
        ds.build_cookie = Mock(return_value={"cookie": "value"})
        ds.update_cookie = Mock()

        i = mock_client.return_value
        getinfo_result = Mock()
        getinfo_result.dnsEntries = [
            DnsEntry('testentry', 86400, DnsEntry.TYPE_A, '127.0.0.1')
        ]
        i.service.getInfo.return_value = getinfo_result

        # CALL
        result = ds.get_info('example.com')

        # VERIFY
        ds.build_cookie.assert_called_with(mode=MODE_RO,
                                           method='getInfo',
                                           parameters=['example.com'])
        ds.update_cookie.assert_called_with({"cookie": "value"})
        i.service.getInfo.assert_called_with('example.com')
        self.assertEqual(result, getinfo_result)
Esempio n. 20
0
    def mockup(self, records):

        provider = TransipProvider('', '', '')

        _dns_entries = []
        for record in records:
            if record._type in provider.SUPPORTS:
                entries_for = getattr(provider,
                                      '_entries_for_{}'.format(record._type))

                # Root records have '@' as name
                name = record.name
                if name == '':
                    name = provider.ROOT_RECORD

                _dns_entries.extend(entries_for(name, record))

                # Add a non-supported type
                # so it triggers the "is supported" (transip.py:115) check and
                # give 100% code coverage
                _dns_entries.append(
                    DnsEntry('@', '3600', 'BOGUS', 'ns01.transip.nl.'))

        self.mockupEntries = _dns_entries
Esempio n. 21
0
 def _to_dns_entry(self, _entry):
     return DnsEntry(self._relative_name(_entry['name']), _entry['ttl'],
                     _entry['type'], _entry['content'])
Esempio n. 22
0
    def _entries_for_single(self, name, record):

        return [DnsEntry(name, record.ttl, record._type, record.value)]
 def build_record(self, domain, name, challenge):
     return DnsEntry(name[:-(len(domain) + 1)], 1, DnsEntry.TYPE_TXT,
                     challenge)