예제 #1
0
    def get_dns_ip(self, zone_uuid: str) -> str:
        """Get the DNS A @ record."""

        url = '{}/zones/{}/records'.format(self.api, zone_uuid)
        headers = {'X-Api-Key': self.api_secret}
        response = get(url, headers=headers)

        try:
            tld_a_record = [
                entry for entry in response
                if entry['rrset_type'] == 'A'
                and entry['rrset_name'] == '@'
            ]
            ip_record = tld_a_record[0]['rrset_values'][0]

            self.validate_subdomain_entries(response)

            message = 'Discovered IP address of {} for {} DNS A @ record'
            logger.info(message.format(ip_record, self.domain))

            return ip_record
        except (KeyError, IndexError):
            message = 'Could not find A record for {}'.format(self.domain)
            logger.critical(message)
            exit(EXIT_CODE_1_BAD)
예제 #2
0
def get_user() -> str:
    """Determine who the current user is."""
    try:
        return check_output('whoami', timeout=0.5).decode('utf-8').strip()
    except OSError as exception:
        message = 'Canot determine user. Raised {}'.format(str(exception))
        logger.critical(message)
        exit(EXIT_CODE_1_BAD)
예제 #3
0
 def validate_subdomain_entries(self, response):
     """Validate that user specified subdomain entries exist."""
     entries = set([entry['rrset_name'] for entry in response])
     entries_match = all((subd in entries for subd in self.subdomains))
     if not entries_match:
         message = 'Missing subdomain DNS record from {} under {}'
         subdomains = ','.join(self.subdomains)
         logger.critical(message.format(subdomains, self.domain))
         exit(EXIT_CODE_1_BAD)
예제 #4
0
def validate_api_secrets(config, sections) -> None:
    """Validate the DNS providers are actually supported."""
    for section in sections:
        try:
            config[section]['api_secret']
        except KeyError:
            message = 'No api_secret in {} config section'.format(section)
            logger.critical(message)
            exit(EXIT_CODE_1_BAD)
예제 #5
0
파일: requests.py 프로젝트: kay0u/hdyndns
def put(url, payload, headers=None):
    """Run a HTTP PUT on some web resource."""
    headers = headers or []
    try:
        request = Request(url, headers=headers, method='PUT')
        dumped = dumps(payload).encode('utf-8')
        return (urlopen(request, data=dumped,
                        timeout=REQUEST_TIMEOUT).read().decode('utf-8'))
    except (URLError, ValueError, timeout) as exception:
        print(exception.file.read())
        message = 'Unable to PUT against {}: {}'.format(url, str(exception))
        logger.critical(message)
        exit(EXIT_CODE_1_BAD)
예제 #6
0
def validate_dns_providers(config, sections) -> None:
    """Validate the DNS providers are actually supported."""
    for section in sections:
        try:
            provider = config[section]['provider']
            if provider not in SUPPORTED_DNS_PROVIDERS:
                message = 'Unsupported DNS provider {}'.format(provider)
                logger.critical(message)
                exit(EXIT_CODE_1_BAD)
        except KeyError:
            message = 'No provider in {} config section'.format(section)
            logger.critical(message)
            exit(EXIT_CODE_1_BAD)
예제 #7
0
def read_config(user: str, root: Union[str, None] = None) -> Any:
    """Read the INI configuration file."""
    cfg_path = '{root}/{user}/.hdyndns/hdyndns.ini'.format(
        root=root if root else '/home', user=user)

    config = ConfigParser()

    if not config.read(cfg_path):
        message = 'Missing configuration from {}'.format(cfg_path)
        logger.critical(message)
        exit(EXIT_CODE_1_BAD)

    return config
예제 #8
0
    def get_zone_uuid(self) -> List[str]:
        """Get the DNS zone UUID."""
        url = '{}/domains/{}'.format(self.api, self.domain)
        headers = {'X-Api-Key': self.api_secret}
        response = get(url, headers=headers)

        try:
            zone_uuid = response['zone_uuid']

            message = 'Discovered Gandi zone UUID of {} for {}'
            logger.info(message.format(zone_uuid, self.domain))

            return zone_uuid
        except KeyError as exception:
            message = 'Missing {} from {}'
            logger.critical(message.format(str(exception), dumps(response)))
            exit(EXIT_CODE_1_BAD)
예제 #9
0
def cli_entrypoint() -> None:
    """The command line entrypoint."""
    user = get_user()
    create_home(user)

    config = read_config(user)
    sections = [section for section in config.keys() if section != 'DEFAULT']

    validate_dns_providers(config, sections)
    validate_api_secrets(config, sections)

    for section in sections:
        if 'gandi' == config[section]['provider']:
            logger.info('Processing {} with provider Gandi'.format(section))
            GandiDynDNS(config[section]).update_dns()
            exit(EXIT_CODE_0_OK)
        else:
            logger.critical('No supported provider found')
            exit(EXIT_CODE_1_BAD)
예제 #10
0
파일: requests.py 프로젝트: kay0u/hdyndns
def get(url, headers=None, load_json=True):
    """Run a HTTP GET on some web resource."""
    headers = headers or {}
    try:
        request = Request(url, headers=headers, method='GET')
        response = (urlopen(request,
                            timeout=REQUEST_TIMEOUT).read().decode('utf-8'))
        if not load_json:
            return response
        try:
            return loads(response)
        except JSONDecodeError:
            message = 'Unable to JSON load {}'.format(response)
            logger.critical(message)
            exit(EXIT_CODE_1_BAD)
    except (URLError, ValueError, timeout) as exception:
        message = 'Unable to GET against {}: {}'.format(url, str(exception))
        logger.critical(message)
        exit(EXIT_CODE_1_BAD)