From 9567684225ab2697bb6f9b2b6e63b724876c0256 Mon Sep 17 00:00:00 2001 From: Johannes Löthberg Date: Mon, 21 Nov 2016 11:52:12 +0000 Subject: Initial commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Johannes Löthberg --- _states/acme.py | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 _states/acme.py (limited to '_states/acme.py') diff --git a/_states/acme.py b/_states/acme.py new file mode 100644 index 0000000..4fcf09a --- /dev/null +++ b/_states/acme.py @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- +''' +ACME / Let's Encrypt certificate management state +================================================= + +.. versionadded: 2016.3 + +See also the module documentation + +.. code-block:: yaml + + reload-gitlab: + cmd.run: + - name: gitlab-ctl hup + + dev.example.com: + acme.cert: + - aliases: + - gitlab.example.com + - email: acmemaster@example.com + - webroot: /opt/gitlab/embedded/service/gitlab-rails/public + - renew: 14 + - fire_event: acme/dev.example.com + - onchanges_in: + - cmd: reload-gitlab + +''' +# Import python libs +from __future__ import absolute_import +import logging + +log = logging.getLogger(__name__) + + +def __virtual__(): + ''' + Only work when the ACME module agrees + ''' + return 'acme.cert' in __salt__ + + +def cert(name, + aliases=None, + email=None, + webroot=None, + test_cert=False, + renew=None, + keysize=None, + server=None, + owner='root', + group='root'): + ''' + Obtain/renew a certificate from an ACME CA, probably Let's Encrypt. + + :param name: Common Name of the certificate (DNS name of certificate) + :param aliases: subjectAltNames (Additional DNS names on certificate) + :param email: e-mail address for interaction with ACME provider + :param webroot: True or a full path to use to use webroot. Otherwise use standalone mode + :param test_cert: Request a certificate from the Happy Hacker Fake CA (mutually exclusive with 'server') + :param renew: True/'force' to force a renewal, or a window of renewal before expiry in days + :param keysize: RSA key bits + :param server: API endpoint to talk to + :param owner: owner of private key + :param group: group of private key + ''' + + if __opts__['test']: + ret = { + 'name': name, + 'changes': {}, + 'result': None + } + window = None + try: + window = int(renew) + except: # pylint: disable=bare-except + pass + + comment = 'Certificate {0} '.format(name) + if not __salt__['acme.has'](name): + comment += 'would have been obtained' + elif __salt__['acme.needs_renewal'](name, window): + comment += 'would have been renewed' + else: + comment += 'would not have been touched' + ret['comment'] = comment + return ret + + if not __salt__['acme.has'](name): + old = None + else: + old = __salt__['acme.info'](name) + + res = __salt__['acme.cert']( + name, + aliases=aliases, + email=email, + webroot=webroot, + test_cert=test_cert, + renew=renew, + keysize=keysize, + server=server, + owner=owner, + group=group + ) + + ret = { + 'name': name, + 'result': res['result'] is not False, + 'comment': res['comment'] + } + + if res['result'] is None: + ret['changes'] = {} + else: + ret['changes'] = { + 'old': old, + 'new': __salt__['acme.info'](name) + } + + return ret -- cgit v1.2.3-54-g00ecf