diff options
Diffstat (limited to 'certbot/interfaces.py')
-rw-r--r-- | certbot/interfaces.py | 621 |
1 files changed, 0 insertions, 621 deletions
diff --git a/certbot/interfaces.py b/certbot/interfaces.py deleted file mode 100644 index bb9a91b0f..000000000 --- a/certbot/interfaces.py +++ /dev/null @@ -1,621 +0,0 @@ -"""Certbot client interfaces.""" -import abc -import six -import zope.interface - -# pylint: disable=no-self-argument,no-method-argument,no-init,inherit-non-class -# pylint: disable=too-few-public-methods - - -@six.add_metaclass(abc.ABCMeta) -class AccountStorage(object): - """Accounts storage interface.""" - - @abc.abstractmethod - def find_all(self): # pragma: no cover - """Find all accounts. - - :returns: All found accounts. - :rtype: list - - """ - raise NotImplementedError() - - @abc.abstractmethod - def load(self, account_id): # pragma: no cover - """Load an account by its id. - - :raises .AccountNotFound: if account could not be found - :raises .AccountStorageError: if account could not be loaded - - """ - raise NotImplementedError() - - @abc.abstractmethod - def save(self, account, client): # pragma: no cover - """Save account. - - :raises .AccountStorageError: if account could not be saved - - """ - raise NotImplementedError() - - -class IPluginFactory(zope.interface.Interface): - """IPlugin factory. - - Objects providing this interface will be called without satisfying - any entry point "extras" (extra dependencies) you might have defined - for your plugin, e.g (excerpt from ``setup.py`` script):: - - setup( - ... - entry_points={ - 'certbot.plugins': [ - 'name=example_project.plugin[plugin_deps]', - ], - }, - extras_require={ - 'plugin_deps': ['dep1', 'dep2'], - } - ) - - Therefore, make sure such objects are importable and usable without - extras. This is necessary, because CLI does the following operations - (in order): - - - loads an entry point, - - calls `inject_parser_options`, - - requires an entry point, - - creates plugin instance (`__call__`). - - """ - - description = zope.interface.Attribute("Short plugin description") - - def __call__(config, name): - """Create new `IPlugin`. - - :param IConfig config: Configuration. - :param str name: Unique plugin name. - - """ - - def inject_parser_options(parser, name): - """Inject argument parser options (flags). - - 1. Be nice and prepend all options and destinations with - `~.common.option_namespace` and `~common.dest_namespace`. - - 2. Inject options (flags) only. Positional arguments are not - allowed, as this would break the CLI. - - :param ArgumentParser parser: (Almost) top-level CLI parser. - :param str name: Unique plugin name. - - """ - - -class IPlugin(zope.interface.Interface): - """Certbot plugin.""" - - def prepare(): # type: ignore - """Prepare the plugin. - - Finish up any additional initialization. - - :raises .PluginError: - when full initialization cannot be completed. - :raises .MisconfigurationError: - when full initialization cannot be completed. Plugin will - be displayed on a list of available plugins. - :raises .NoInstallationError: - when the necessary programs/files cannot be located. Plugin - will NOT be displayed on a list of available plugins. - :raises .NotSupportedError: - when the installation is recognized, but the version is not - currently supported. - - """ - - def more_info(): # type: ignore - """Human-readable string to help the user. - - Should describe the steps taken and any relevant info to help the user - decide which plugin to use. - - :rtype str: - - """ - - -class IAuthenticator(IPlugin): - """Generic Certbot Authenticator. - - Class represents all possible tools processes that have the - ability to perform challenges and attain a certificate. - - """ - - def get_chall_pref(domain): - """Return `collections.Iterable` of challenge preferences. - - :param str domain: Domain for which challenge preferences are sought. - - :returns: `collections.Iterable` of challenge types (subclasses of - :class:`acme.challenges.Challenge`) with the most - preferred challenges first. If a type is not specified, it means the - Authenticator cannot perform the challenge. - :rtype: `collections.Iterable` - - """ - - def perform(achalls): - """Perform the given challenge. - - :param list achalls: Non-empty (guaranteed) list of - :class:`~certbot.achallenges.AnnotatedChallenge` - instances, such that it contains types found within - :func:`get_chall_pref` only. - - :returns: `collections.Iterable` of ACME - :class:`~acme.challenges.ChallengeResponse` instances - or if the :class:`~acme.challenges.Challenge` cannot - be fulfilled then: - - ``None`` - Authenticator can perform challenge, but not at this time. - ``False`` - Authenticator will never be able to perform (error). - - :rtype: :class:`collections.Iterable` of - :class:`acme.challenges.ChallengeResponse`, - where responses are required to be returned in - the same order as corresponding input challenges - - :raises .PluginError: If challenges cannot be performed - - """ - - def cleanup(achalls): - """Revert changes and shutdown after challenges complete. - - This method should be able to revert all changes made by - perform, even if perform exited abnormally. - - :param list achalls: Non-empty (guaranteed) list of - :class:`~certbot.achallenges.AnnotatedChallenge` - instances, a subset of those previously passed to :func:`perform`. - - :raises PluginError: if original configuration cannot be restored - - """ - - -class IConfig(zope.interface.Interface): - """Certbot user-supplied configuration. - - .. warning:: The values stored in the configuration have not been - filtered, stripped or sanitized. - - """ - server = zope.interface.Attribute("ACME Directory Resource URI.") - email = zope.interface.Attribute( - "Email used for registration and recovery contact. Use comma to " - "register multiple emails, ex: u1@example.com,u2@example.com. " - "(default: Ask).") - rsa_key_size = zope.interface.Attribute("Size of the RSA key.") - must_staple = zope.interface.Attribute( - "Adds the OCSP Must Staple extension to the certificate. " - "Autoconfigures OCSP Stapling for supported setups " - "(Apache version >= 2.3.3 ).") - - config_dir = zope.interface.Attribute("Configuration directory.") - work_dir = zope.interface.Attribute("Working directory.") - - accounts_dir = zope.interface.Attribute( - "Directory where all account information is stored.") - backup_dir = zope.interface.Attribute("Configuration backups directory.") - csr_dir = zope.interface.Attribute( - "Directory where newly generated Certificate Signing Requests " - "(CSRs) are saved.") - in_progress_dir = zope.interface.Attribute( - "Directory used before a permanent checkpoint is finalized.") - key_dir = zope.interface.Attribute("Keys storage.") - temp_checkpoint_dir = zope.interface.Attribute( - "Temporary checkpoint directory.") - - no_verify_ssl = zope.interface.Attribute( - "Disable verification of the ACME server's certificate.") - tls_sni_01_port = zope.interface.Attribute( - "Port used during tls-sni-01 challenge. " - "This only affects the port Certbot listens on. " - "A conforming ACME server will still attempt to connect on port 443.") - tls_sni_01_address = zope.interface.Attribute( - "The address the server listens to during tls-sni-01 challenge.") - - http01_port = zope.interface.Attribute( - "Port used in the http-01 challenge. " - "This only affects the port Certbot listens on. " - "A conforming ACME server will still attempt to connect on port 80.") - - http01_address = zope.interface.Attribute( - "The address the server listens to during http-01 challenge.") - - pref_challs = zope.interface.Attribute( - "Sorted user specified preferred challenges" - "type strings with the most preferred challenge listed first") - - allow_subset_of_names = zope.interface.Attribute( - "When performing domain validation, do not consider it a failure " - "if authorizations can not be obtained for a strict subset of " - "the requested domains. This may be useful for allowing renewals for " - "multiple domains to succeed even if some domains no longer point " - "at this system. This is a boolean") - - strict_permissions = zope.interface.Attribute( - "Require that all configuration files are owned by the current " - "user; only needed if your config is somewhere unsafe like /tmp/." - "This is a boolean") - - disable_renew_updates = zope.interface.Attribute( - "If updates provided by installer enhancements when Certbot is being run" - " with \"renew\" verb should be disabled.") - -class IInstaller(IPlugin): - """Generic Certbot Installer Interface. - - Represents any server that an X509 certificate can be placed. - - It is assumed that :func:`save` is the only method that finalizes a - checkpoint. This is important to ensure that checkpoints are - restored in a consistent manner if requested by the user or in case - of an error. - - Using :class:`certbot.reverter.Reverter` to implement checkpoints, - rollback, and recovery can dramatically simplify plugin development. - - """ - - def get_all_names(): # type: ignore - """Returns all names that may be authenticated. - - :rtype: `collections.Iterable` of `str` - - """ - - def deploy_cert(domain, cert_path, key_path, chain_path, fullchain_path): - """Deploy certificate. - - :param str domain: domain to deploy certificate file - :param str cert_path: absolute path to the certificate file - :param str key_path: absolute path to the private key file - :param str chain_path: absolute path to the certificate chain file - :param str fullchain_path: absolute path to the certificate fullchain - file (cert plus chain) - - :raises .PluginError: when cert cannot be deployed - - """ - - def enhance(domain, enhancement, options=None): - """Perform a configuration enhancement. - - :param str domain: domain for which to provide enhancement - :param str enhancement: An enhancement as defined in - :const:`~certbot.constants.ENHANCEMENTS` - :param options: Flexible options parameter for enhancement. - Check documentation of - :const:`~certbot.constants.ENHANCEMENTS` - for expected options for each enhancement. - - :raises .PluginError: If Enhancement is not supported, or if - an error occurs during the enhancement. - - """ - - def supported_enhancements(): # type: ignore - """Returns a `collections.Iterable` of supported enhancements. - - :returns: supported enhancements which should be a subset of - :const:`~certbot.constants.ENHANCEMENTS` - :rtype: :class:`collections.Iterable` of :class:`str` - - """ - - def save(title=None, temporary=False): - """Saves all changes to the configuration files. - - Both title and temporary are needed because a save may be - intended to be permanent, but the save is not ready to be a full - checkpoint. - - It is assumed that at most one checkpoint is finalized by this - method. Additionally, if an exception is raised, it is assumed a - new checkpoint was not finalized. - - :param str title: The title of the save. If a title is given, the - configuration will be saved as a new checkpoint and put in a - timestamped directory. `title` has no effect if temporary is true. - - :param bool temporary: Indicates whether the changes made will - be quickly reversed in the future (challenges) - - :raises .PluginError: when save is unsuccessful - - """ - - def rollback_checkpoints(rollback=1): - """Revert `rollback` number of configuration checkpoints. - - :raises .PluginError: when configuration cannot be fully reverted - - """ - - def recovery_routine(): # type: ignore - """Revert configuration to most recent finalized checkpoint. - - Remove all changes (temporary and permanent) that have not been - finalized. This is useful to protect against crashes and other - execution interruptions. - - :raises .errors.PluginError: If unable to recover the configuration - - """ - - def view_config_changes(): # type: ignore - """Display all of the LE config changes. - - :raises .PluginError: when config changes cannot be parsed - - """ - - def config_test(): # type: ignore - """Make sure the configuration is valid. - - :raises .MisconfigurationError: when the config is not in a usable state - - """ - - def restart(): # type: ignore - """Restart or refresh the server content. - - :raises .PluginError: when server cannot be restarted - - """ - - -class IDisplay(zope.interface.Interface): - """Generic display.""" - # pylint: disable=too-many-arguments - # see https://github.com/certbot/certbot/issues/3915 - - def notification(message, pause, wrap=True, force_interactive=False): - """Displays a string message - - :param str message: Message to display - :param bool pause: Whether or not the application should pause for - confirmation (if available) - :param bool wrap: Whether or not the application should wrap text - :param bool force_interactive: True if it's safe to prompt the user - because it won't cause any workflow regressions - - """ - - def menu(message, choices, ok_label=None, - cancel_label=None, help_label=None, - default=None, cli_flag=None, force_interactive=False): - """Displays a generic menu. - - When not setting force_interactive=True, you must provide a - default value. - - :param str message: message to display - - :param choices: choices - :type choices: :class:`list` of :func:`tuple` or :class:`str` - - :param str ok_label: label for OK button (UNUSED) - :param str cancel_label: label for Cancel button (UNUSED) - :param str help_label: label for Help button (UNUSED) - :param int default: default (non-interactive) choice from the menu - :param str cli_flag: to automate choice from the menu, eg "--keep" - :param bool force_interactive: True if it's safe to prompt the user - because it won't cause any workflow regressions - - :returns: tuple of (`code`, `index`) where - `code` - str display exit code - `index` - int index of the user's selection - - :raises errors.MissingCommandlineFlag: if called in non-interactive - mode without a default set - - """ - - def input(message, default=None, cli_args=None, force_interactive=False): - """Accept input from the user. - - When not setting force_interactive=True, you must provide a - default value. - - :param str message: message to display to the user - :param str default: default (non-interactive) response to prompt - :param bool force_interactive: True if it's safe to prompt the user - because it won't cause any workflow regressions - - :returns: tuple of (`code`, `input`) where - `code` - str display exit code - `input` - str of the user's input - :rtype: tuple - - :raises errors.MissingCommandlineFlag: if called in non-interactive - mode without a default set - - """ - - def yesno(message, yes_label="Yes", no_label="No", default=None, - cli_args=None, force_interactive=False): - """Query the user with a yes/no question. - - Yes and No label must begin with different letters. - - When not setting force_interactive=True, you must provide a - default value. - - :param str message: question for the user - :param str default: default (non-interactive) choice from the menu - :param str cli_flag: to automate choice from the menu, eg "--redirect / --no-redirect" - :param bool force_interactive: True if it's safe to prompt the user - because it won't cause any workflow regressions - - :returns: True for "Yes", False for "No" - :rtype: bool - - :raises errors.MissingCommandlineFlag: if called in non-interactive - mode without a default set - - """ - - def checklist(message, tags, default=None, cli_args=None, force_interactive=False): - """Allow for multiple selections from a menu. - - When not setting force_interactive=True, you must provide a - default value. - - :param str message: message to display to the user - :param list tags: where each is of type :class:`str` len(tags) > 0 - :param str default: default (non-interactive) state of the checklist - :param str cli_flag: to automate choice from the menu, eg "--domains" - :param bool force_interactive: True if it's safe to prompt the user - because it won't cause any workflow regressions - - :returns: tuple of the form (code, list_tags) where - `code` - int display exit code - `list_tags` - list of str tags selected by the user - :rtype: tuple - - :raises errors.MissingCommandlineFlag: if called in non-interactive - mode without a default set - - """ - - def directory_select(self, message, default=None, - cli_flag=None, force_interactive=False): - """Display a directory selection screen. - - When not setting force_interactive=True, you must provide a - default value. - - :param str message: prompt to give the user - :param default: the default value to return, if one exists, when - using the NoninteractiveDisplay - :param str cli_flag: option used to set this value with the CLI, - if one exists, to be included in error messages given by - NoninteractiveDisplay - :param bool force_interactive: True if it's safe to prompt the user - because it won't cause any workflow regressions - - :returns: tuple of the form (`code`, `string`) where - `code` - int display exit code - `string` - input entered by the user - - """ - - -class IReporter(zope.interface.Interface): - """Interface to collect and display information to the user.""" - - HIGH_PRIORITY = zope.interface.Attribute( - "Used to denote high priority messages") - MEDIUM_PRIORITY = zope.interface.Attribute( - "Used to denote medium priority messages") - LOW_PRIORITY = zope.interface.Attribute( - "Used to denote low priority messages") - - def add_message(self, msg, priority, on_crash=True): - """Adds msg to the list of messages to be printed. - - :param str msg: Message to be displayed to the user. - - :param int priority: One of HIGH_PRIORITY, MEDIUM_PRIORITY, or - LOW_PRIORITY. - - :param bool on_crash: Whether or not the message should be printed if - the program exits abnormally. - - """ - - def print_messages(self): - """Prints messages to the user and clears the message queue.""" - - -# Updater interfaces -# -# When "certbot renew" is run, Certbot will iterate over each lineage and check -# if the selected installer for that lineage is a subclass of each updater -# class. If it is and the update of that type is configured to be run for that -# lineage, the relevant update function will be called for it. These functions -# are never called for other subcommands, so if an installer wants to perform -# an update during the run or install subcommand, it should do so when -# :func:`IInstaller.deploy_cert` is called. - -@six.add_metaclass(abc.ABCMeta) -class GenericUpdater(object): - """Interface for update types not currently specified by Certbot. - - This class allows plugins to perform types of updates that Certbot hasn't - defined (yet). - - To make use of this interface, the installer should implement the interface - methods, and interfaces.GenericUpdater.register(InstallerClass) should - be called from the installer code. - - The plugins implementing this enhancement are responsible of handling - the saving of configuration checkpoints as well as other calls to - interface methods of `interfaces.IInstaller` such as prepare() and restart() - """ - - @abc.abstractmethod - def generic_updates(self, lineage, *args, **kwargs): - """Perform any update types defined by the installer. - - If an installer is a subclass of the class containing this method, this - function will always be called when "certbot renew" is run. If the - update defined by the installer should be run conditionally, the - installer needs to handle checking the conditions itself. - - This method is called once for each lineage. - - :param lineage: Certificate lineage object - :type lineage: storage.RenewableCert - - """ - - -@six.add_metaclass(abc.ABCMeta) -class RenewDeployer(object): - """Interface for update types run when a lineage is renewed - - This class allows plugins to perform types of updates that need to run at - lineage renewal that Certbot hasn't defined (yet). - - To make use of this interface, the installer should implement the interface - methods, and interfaces.RenewDeployer.register(InstallerClass) should - be called from the installer code. - """ - - @abc.abstractmethod - def renew_deploy(self, lineage, *args, **kwargs): - """Perform updates defined by installer when a certificate has been renewed - - If an installer is a subclass of the class containing this method, this - function will always be called when a certficate has been renewed by - running "certbot renew". For example if a plugin needs to copy a - certificate over, or change configuration based on the new certificate. - - This method is called once for each lineage renewed - - :param lineage: Certificate lineage object - :type lineage: storage.RenewableCert - - """ |