Source code for dyndns.config

"""Load and validate the configuration."""

# standard imports
import os
import re
import yaml

# third party imports
from dyndns.names import Zones, validate_hostname
from dyndns.exceptions import ConfigurationError, NamesError, IpAddressesError
from dyndns.ipaddresses import validate as validate_ip


[docs]def load_config(config_file=None): config_files = [] if config_file: config_files.append(config_file) if 'dyndns_CONFIG_FILE' in os.environ: config_files.append(os.environ['dyndns_CONFIG_FILE']) config_files.append(os.path.join(os.getcwd(), '.dyndns.yml')) config_files.append('/etc/dyndns.yml') for _config_file in config_files: if os.path.exists(_config_file): config_file = _config_file break if not config_file: raise ConfigurationError('The configuration file could not be found.') stream = open(config_file, 'r') config = yaml.safe_load(stream) stream.close() return config
[docs]def validate_secret(secret): secret = str(secret) if re.match('^[a-zA-Z0-9]+$', secret) and len(secret) >= 8: return secret raise ConfigurationError('The secret must be at least 8 characters ' 'long and may not contain any ' 'non-alpha-numeric characters.')
[docs]def validate_config(config=None): if not config: try: config = load_config() except IOError: raise ConfigurationError('The configuration file could not be ' 'found.') except yaml.error.YAMLError: raise ConfigurationError('The configuration file is in a invalid ' 'YAML format.') if 'secret' not in config: raise ConfigurationError('Your configuration must have a "secret" ' 'key, for example: "secret: VDEdxeTKH"') config['secret'] = validate_secret(config['secret']) if 'nameserver' not in config: raise ConfigurationError('Your configuration must have a "nameserver" ' 'key, for example: "nameserver: 127.0.0.1"') try: validate_ip(config['nameserver']) except IpAddressesError: msg = 'The "nameserver" entry in your configuration is not a valid ' \ 'IP address: "{}".'.format(config['nameserver']) raise ConfigurationError(msg) if 'dyndns_domain' in config: try: validate_hostname(config['dyndns_domain']) except NamesError as error: raise ConfigurationError(str(error)) if 'zones' not in config: raise ConfigurationError('Your configuration must have a "zones" key.') if not isinstance(config['zones'], (list,)): raise ConfigurationError('Your "zones" key must contain a list of ' 'zones.') if not config['zones']: raise ConfigurationError('You must have at least one zone configured, ' 'for example: "- name: example.com" and ' '"tsig_key: tPyvZA=="') for zone in config['zones']: if 'name' not in zone: raise ConfigurationError('Your zone dictionary must contain a key ' '"name"') if 'tsig_key' not in zone: raise ConfigurationError('Your zone dictionary must contain a key ' '"tsig_key"') try: config['zones'] = Zones(config['zones']) except NamesError as error: raise ConfigurationError(str(error)) return config
[docs]def get_config(config_file=None): return validate_config(load_config(config_file))