def main() -> None: """Main function of Lexicon.""" # Dynamically determine all the providers available and gather command line arguments. parsed_args = generate_cli_main_parser().parse_args() log_level = logging.getLevelName(parsed_args.log_level) logging.basicConfig(stream=sys.stdout, level=log_level, format="%(message)s") logger.debug("Arguments: %s", parsed_args) # In the CLI context, will get configuration interactively: # * from the command line # * from the environment variables # * from lexicon configuration files found in given --config-dir (default is current dir) config = ConfigResolver() config.with_args(parsed_args).with_env().with_config_dir(parsed_args.config_dir) client = Client(config) results = client.execute() action = config.resolve("lexicon:action") if not action: raise ValueError("Parameter action is not set.") handle_output(results, parsed_args.output, action)
def _txt_challenge( profile: Dict[str, Any], token: str, domain: str, action: str = "create", ): profile_name = profile["name"] provider_name = profile["provider"] provider_options = profile.get("provider_options", {}) if not provider_options: print(f"No provider_options are defined for profile {profile_name}, " "any call to the provider API is likely to fail.") config_dict = { "action": action, "domain": domain, "type": "TXT", "name": "_acme-challenge.{0}.".format(domain), "content": token, "delegated": profile.get("delegated_subdomain"), "provider_name": provider_name, provider_name: provider_options, } ttl = profile.get("ttl") if ttl: config_dict["ttl"] = ttl lexicon_config = ConfigResolver() lexicon_config.with_dict(config_dict) Client(lexicon_config).execute()
def delete_dns_record(self, record): """ Delete a record from the domain. """ lexicon_config = self._get_base_config() lexicon_config['domain'] = record['domain'] lexicon_config['action'] = 'delete' lexicon_config['name'] = record['name'] lexicon_config['type'] = record['type'] config = ConfigResolver() config.with_dict(dict_object=lexicon_config) client = Client(config) result = False try: result = client.execute() # Invalidate cache for the domain-cname pair cache.delete(f"{record['domain']}-{record['type']}") except Exception as e: # pylint: disable=broad-except # This ugly checking of the exception message is needed # as the library only throws an instance of the Exception class. if 'Record identifier could not be found' in str(e): result = True else: raise return result
def main(): parsed_args = MainParser().parse_args() log_level = logging.getLevelName(parsed_args.log_level) logging.basicConfig(stream=sys.stdout, level=log_level, format='%(message)s') logger.debug('Arguments: %s', parsed_args) client = Client(vars(parsed_args)) results = client.execute() handle_output(results, parsed_args.output)
def txt_challenge( certificate: Dict[str, Any], profile: Dict[str, Any], token: str, domain: str, action: str = "create", ): profile_name = profile["name"] provider_name = profile["provider"] provider_options = profile.get("provider_options", {}) if not provider_options: print(f"No provider_options are defined for profile {profile_name}, " "any call to the provider API is likely to fail.") challenge_name = f"_acme-challenge.{domain}." if certificate.get("follow_cnames"): print( f"Trying to resolve the canonical challenge name for {challenge_name}" ) canonical_challenge_name = resolve_canonical_challenge_name( challenge_name) print( f"Canonical challenge name found for {challenge_name}: {canonical_challenge_name}" ) challenge_name = canonical_challenge_name extracted = tldextract.extract(challenge_name) domain = ".".join([extracted.domain, extracted.suffix]) config_dict = { "action": action, "domain": domain, "type": "TXT", "name": challenge_name, "content": token, "delegated": profile.get("delegated_subdomain"), "provider_name": provider_name, provider_name: provider_options, } ttl = profile.get("ttl") if ttl: config_dict["ttl"] = ttl lexicon_config = ConfigResolver() lexicon_config.with_dict(config_dict) Client(lexicon_config).execute()
def add_dns_record(self, record): """ Add a DNS record to the domain. """ lexicon_config = self._get_base_config() lexicon_config['domain'] = record['domain'] lexicon_config['action'] = 'create' lexicon_config['type'] = record['type'] lexicon_config['name'] = record['name'] lexicon_config['content'] = record['value'] lexicon_config['ttl'] = record['ttl'] config = ConfigResolver() config.with_dict(dict_object=lexicon_config) client = Client(config) result = client.execute() return result
def main(): module = AnsibleModule( argument_spec={ "provider_name": { "type": "str", "required": True }, "action": { "type": "str", "required": True }, "domain": { "type": "str", "required": True }, "type": { "type": "str", "choices": SUPPORTED_RECORDS }, "name": { "type": "str" }, "content": { "type": "str" }, "delegated": { "type": "str", "default": None }, "provider_options": { "type": "dict", "required": True }, }) action = { "provider_name": module.params["provider_name"], "action": module.params["action"], "delegated": module.params["delegated"], "domain": module.params["domain"], "type": module.params["type"], "name": module.params["name"], "content": module.params["content"], module.params["provider_name"]: module.params["provider_options"], } config = ConfigResolver().with_dict(action) Client(config).execute() module.exit_json()
def list_dns_records(self, record): """ List all records of a domain name for a given type. """ cached_result = cache.get(f"{record['domain']}-{record['type']}") if cached_result: return cached_result lexicon_config = self._get_base_config() lexicon_config['domain'] = record['domain'] lexicon_config['action'] = 'list' lexicon_config['type'] = record['type'] config = ConfigResolver() config.with_dict(dict_object=lexicon_config) client = Client(config) result = client.execute() cache.set(f"{record['domain']}-{record['type']}", result) return result
def main(): """Main function of Lexicon.""" # Dynamically determine all the providers available and gather command line arguments. parsed_args = generate_cli_main_parser().parse_args() log_level = logging.getLevelName(parsed_args.log_level) logging.basicConfig(stream=sys.stdout, level=log_level, format='%(message)s') logger.debug('Arguments: %s', parsed_args) # In the CLI context, will get configuration interactively: # * from the command line # * from the environment variables # * from lexicon configuration files in working directory config = ConfigResolver() config.with_args(parsed_args).with_env().with_config_dir(os.getcwd()) client = Client(config) results = client.execute() handle_output(results, parsed_args.output)
from lexicon.config import ConfigResolver from lexicon.client import Client lexicon_config = { "provider_name" : "cloudflare", # lexicon shortname for provider, see providers directory for available proviers "action": "list", # create, list, update, delete "domain": "capsulecd.com", # domain name "type": "CNAME", # specify a type for record filtering, case sensitive in some cases. "cloudflare": { # cloudflare(provider) specific configuration goes here. # if .with_env() is not used, all credentials required for authention must be specified here. } } config = ConfigResolver() config.with_env().with_dict(dict_object=lexicon_config) client = Client(config) results = client.execute() print results