示例#1
0
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)
示例#2
0
    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
示例#3
0
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)
示例#4
0
 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
示例#5
0
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()
示例#6
0
    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
示例#7
0
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)
示例#8
0
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()
示例#9
0
class LexiconClient:
    def __init__(self, provider_name, action, domain, name, type, content):

        self.lexicon_config = {
            "provider_name": provider_name,
            "action": action,
            "domain": domain,
            "name": name,
            "type": type,
            "content": content,
        }
        # print(self.lexicon_config)
        self.config = LexiconConfigResolver()
        self.config.with_env().with_dict(dict_object=self.lexicon_config)

        self.client = LexClient(self.config)

        self.auth_token = self.config.resolve("lexicon:{}:auth_token".format(
            self.lexicon_config["provider_name"]))

    def execute(self):
        # Check provider config before doing stuff
        results = ""
        if self.auth_token:
            results = self.client.execute()
            # print(results)
            if results:
                logger.info("✓ {}: {} Record {} -> {}".format(
                    self.config.resolve("lexicon:provider_name"),
                    self.config.resolve("lexicon:action").upper(),
                    self.config.resolve("lexicon:name") + "." +
                    self.config.resolve("lexicon:domain"),
                    self.config.resolve("lexicon:content"),
                ))
            else:
                logger.error("Couldn't create Record: {}".format(results))
        else:
            logger.error(
                "✗ {}: Missing auth_token. {} Record {} -> {} failed".format(
                    self.config.resolve("lexicon:provider_name"),
                    self.config.resolve("lexicon:action").upper(),
                    self.config.resolve("lexicon:name") + "." +
                    self.config.resolve("lexicon:domain"),
                    self.config.resolve("lexicon:content"),
                ))
            results = False
        return results
示例#10
0
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()
示例#11
0
    def __init__(self, provider_name, action, domain, name, type, content):

        self.lexicon_config = {
            "provider_name": provider_name,
            "action": action,
            "domain": domain,
            "name": name,
            "type": type,
            "content": content,
        }
        # print(self.lexicon_config)
        self.config = LexiconConfigResolver()
        self.config.with_env().with_dict(dict_object=self.lexicon_config)

        self.client = LexClient(self.config)

        self.auth_token = self.config.resolve("lexicon:{}:auth_token".format(
            self.lexicon_config["provider_name"]))
示例#12
0
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