diff --git a/certbot_dns_openstack/dns_openstack.py b/certbot_dns_openstack/dns_openstack.py new file mode 100644 index 0000000..b7831d8 --- /dev/null +++ b/certbot_dns_openstack/dns_openstack.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- + +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +import logging + +import zope.interface + +from certbot import interfaces +from certbot.plugins import dns_common + +from openstack.config import loader +from openstack import connection + +LOG = logging.getLogger(__name__) + + +@zope.interface.implementer(interfaces.IAuthenticator) +@zope.interface.provider(interfaces.IPluginFactory) +class Authenticator(dns_common.DNSAuthenticator): + """DNS Authenticator for OpenStack + + This Authenticator uses the OpenStack v2 DNS API to fulfill a + dns-01 challenge. + """ + + description = 'Obtain certificates using a DNS TXT record.' + ttl = 60 + + @classmethod + def add_parser_arguments(cls, add): # pylint: disable=arguments-differ + super(Authenticator, cls).add_parser_arguments( + add, default_propagation_seconds=30) + add('client_config', help='OpenStack Client Config file.') + add('cloud', help='OpenStack to use.') + + def more_info(self): # pylint: disable=missing-docstring,no-self-use + return 'This plugin configures a DNS TXT record to respond to a ' + \ + 'dns-01 challenge using the OpenStack DNS API.' + + def _setup_credentials(self): + config_file = self.conf('client_config') or '' + config = loader.OpenStackConfig( + config_files=loader.CONFIG_FILES + [config_file]) + self.cloud = connection.Connection( + config=config.get_one( + self.conf('cloud') + ) + ) + + def _perform(self, domain, validation_name, validation): + self.zone = self.cloud.get_zone(domain + '.') + self.recordset = self.cloud.create_recordset( + self.zone['id'], validation_name + '.', "TXT", [validation]) + + def _cleanup(self, domain, validation_name, validation): + self.cloud.delete_recordset( + self.zone['id'], self.recordset['id']) diff --git a/requirements.txt b/requirements.txt index 1d18dd3..8cf2926 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,6 @@ # process, which may cause wedges in the gate later. pbr>=2.0 # Apache-2.0 +acme[dev] +certbot[dev] +openstacksdk \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index 9608cff..afbe639 100644 --- a/setup.cfg +++ b/setup.cfg @@ -13,8 +13,6 @@ classifier = License :: OSI Approved :: Apache Software License Operating System :: POSIX :: Linux Programming Language :: Python - Programming Language :: Python :: 2 - Programming Language :: Python :: 2.7 Programming Language :: Python :: 3 Programming Language :: Python :: 3.5 @@ -22,6 +20,10 @@ classifier = packages = certbot_dns_openstack +[entry_points] +certbot.plugins = + dns-openstack = certbot_dns_openstack.dns_openstack:Authenticator + [build_sphinx] all-files = 1 warning-is-error = 1 diff --git a/tox.ini b/tox.ini index c7b0d93..dda808b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] minversion = 2.0 -envlist = py35,py27,pep8 +envlist = py35,pep8 skipsdist = True [testenv]