diff --git a/README.md b/README.md index ede080d..68f982e 100644 --- a/README.md +++ b/README.md @@ -13,15 +13,12 @@ customers to prove control of a domain name. 2. Install the plugin using `pip install certbot-plugin-gandi` 3. Create a `gandi.ini` config file with the following contents and apply `chmod 600 gandi.ini` on it: + ```conf + # Gandi personal access token + dns_gandi_token=PERSONAL_ACCESS_TOKEN ``` - # live dns v5 api key - dns_gandi_api_key=APIKEY - - # optional organization id, remove it if not used - dns_gandi_sharing_id=SHARINGID - ``` - Replace `APIKEY` with your Gandi API key and ensure permissions are set - to disallow access to other users. + Replace `PERSONAL_ACCESS_TOKEN` with your Gandi personal access token and ensure permissions are set + to disallow access to other users. You can also use a Gandi LiveDNS API Key instead, see FAQ below. 4. Run `certbot` and direct it to use the plugin for authentication and to use the config file previously created: @@ -70,6 +67,20 @@ You can setup automatic renewal using `crontab` with the following job for weekl ## FAQ +> I don't have a personal access token, only a Gandi LiveDNS API Key + +Use the following configuration in your `gandi.ini` file instead: + +```conf +# live dns v5 api key +dns_gandi_api_key=APIKEY + +# optional organization id, remove it if not used +dns_gandi_sharing_id=SHARINGID +``` +Replace `APIKEY` with your Gandi API key and ensure permissions are set +to disallow access to other users. + > I have a warning telling me `Plugin legacy name certbot-plugin-gandi:dns may be removed in a future version. Please use dns instead.` Certbot had moved to remove 3rd party plugins prefixes since v1.7.0. Please switch to the new configuration format and remove any used prefix-based configuration. diff --git a/certbot_plugin_gandi/gandi_api.py b/certbot_plugin_gandi/gandi_api.py index 3e1ef84..67c9908 100644 --- a/certbot_plugin_gandi/gandi_api.py +++ b/certbot_plugin_gandi/gandi_api.py @@ -4,11 +4,11 @@ from collections import namedtuple from certbot.plugins import dns_common -_GandiConfig = namedtuple('_GandiConfig', ('api_key', 'sharing_id',)) +_GandiConfig = namedtuple('_GandiConfig', ('api_key', 'sharing_id', 'personal_access_token',)) _BaseDomain = namedtuple('_BaseDomain', ('fqdn')) -def get_config(api_key, sharing_id): - return _GandiConfig(api_key=api_key, sharing_id=sharing_id) +def get_config(api_key, sharing_id, personal_access_token=None): + return _GandiConfig(api_key=api_key, sharing_id=sharing_id, personal_access_token=personal_access_token) def _get_json(response): @@ -24,9 +24,13 @@ def _get_response_message(response, default=''): def _headers(cfg): + if cfg.personal_access_token: + auth = 'Bearer ' + cfg.personal_access_token + else: + auth = 'Apikey ' + cfg.api_key return { 'Content-Type': 'application/json', - 'Authorization': 'Apikey ' + cfg.api_key + 'Authorization': auth, } diff --git a/certbot_plugin_gandi/main.py b/certbot_plugin_gandi/main.py index c547d1a..6930f0c 100644 --- a/certbot_plugin_gandi/main.py +++ b/certbot_plugin_gandi/main.py @@ -15,7 +15,7 @@ def register_authenticator(cls): import zope.interface zope.interface.implementer(interfaces.IAuthenticator)(cls) zope.interface.provider(interfaces.IPluginFactory)(cls) - return cls + return cls @register_authenticator class Authenticator(dns_common.DNSAuthenticator): @@ -47,14 +47,22 @@ def _validate_sharing_id(self, credentials): except ValueError: raise errors.PluginError("Invalid sharing_id: {0}.".format(sharing_id)) + def _validate(self, credentials): + self._validate_sharing_id(credentials) + + # Either api-key or token must be set + if not credentials.conf('api-key') and not credentials.conf('token'): + raise errors.PluginError( + 'Missing property in credentials configuration file {0}: {1}'.format( + credentials.confobj.filename, 'dns_gandi_api_key or dns_gandi_token must be set') + ) + def _setup_credentials(self): self.credentials = self._configure_credentials( 'credentials', 'Gandi credentials INI file', - { - 'api-key': 'API key for Gandi account', - }, - self._validate_sharing_id + {}, + self._validate ) @@ -71,4 +79,8 @@ def _cleanup(self, domain, validation_name, validation): def _get_gandi_config(self): - return gandi_api.get_config(api_key = self.credentials.conf('api-key'), sharing_id = self.credentials.conf('sharing-id')) + return gandi_api.get_config( + api_key = self.credentials.conf('api-key'), + sharing_id = self.credentials.conf('sharing-id'), + personal_access_token = self.credentials.conf('token'), + )