mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 08:58:59 +00:00
commit
5bc2727d01
46
salt/pillar/digicert.py
Normal file
46
salt/pillar/digicert.py
Normal file
@ -0,0 +1,46 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Digicert Pillar Certificates
|
||||
|
||||
This module will only return pillar data if the ``digicert`` runner module has
|
||||
already been used to create certificates.
|
||||
|
||||
To configure this module, set ``digicert`` to ``True`` in the ``ext_pillar``
|
||||
section of your ``master`` configuration file:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ext_pillar:
|
||||
- digicert: True
|
||||
'''
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
import salt.utils
|
||||
import salt.cache
|
||||
import salt.syspaths as syspaths
|
||||
|
||||
__virtualname__ = 'digicert'
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
No special requirements outside of Salt itself
|
||||
'''
|
||||
return __virtualname__
|
||||
|
||||
|
||||
def ext_pillar(minion_id, pillar, conf):
|
||||
'''
|
||||
Return an existing set of certificates
|
||||
'''
|
||||
cache = salt.cache.Cache(__opts__, syspaths.CACHE_DIR)
|
||||
|
||||
ret = {}
|
||||
dns_names = cache.fetch('digicert/minions', minion_id)
|
||||
|
||||
for dns_name in dns_names:
|
||||
data = cache.fetch('digicert/domains', dns_name)
|
||||
ret[dns_name] = data
|
||||
del ret[dns_name]['csr']
|
||||
return {'digicert': ret}
|
738
salt/runners/digicertapi.py
Normal file
738
salt/runners/digicertapi.py
Normal file
@ -0,0 +1,738 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Support for Digicert. Heavily based on the Venafi runner by Joseph Hall (jphall@saltstack.com).
|
||||
|
||||
Before using this module you need to register an account with Digicert's CertCentral.
|
||||
|
||||
Login to CertCentral, ensure you have a payment method configured and/or there are adequate
|
||||
funds attached to your account. Click the ``Account`` item in the left sidebar, and select
|
||||
``Account Access``. The right hand pane should show "Account Access" and a link to create
|
||||
an API key. Create a new API key and assign it to the user that should be attached to requests
|
||||
coming from Salt.
|
||||
|
||||
NOTE CertCentral will not show the API key again after revealing it the first time. Make sure
|
||||
you copy it right away or you will have to revoke it and generate a new one.
|
||||
|
||||
Now open ``/etc/salt/master`` and add the API key as shown below.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
digicert:
|
||||
api_key: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABC
|
||||
|
||||
|
||||
Restart your Salt Master.
|
||||
|
||||
You can also include default values of the following variables to help with creating CSRs:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
digicert:
|
||||
api_key: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABC
|
||||
shatype: sha256
|
||||
|
||||
This API currently only supports RSA key types. Support for other key types will be added
|
||||
if interest warrants.
|
||||
|
||||
'''
|
||||
from __future__ import absolute_import
|
||||
import os
|
||||
import logging
|
||||
import tempfile
|
||||
import subprocess
|
||||
import collections
|
||||
import json
|
||||
import re
|
||||
import salt.syspaths as syspaths
|
||||
import salt.cache
|
||||
import salt.utils
|
||||
import salt.utils.http
|
||||
import salt.ext.six as six
|
||||
from salt.ext.six.moves import range
|
||||
from salt.exceptions import (CommandExecutionError, SaltRunnerError)
|
||||
from Crypto.PublicKey import RSA
|
||||
|
||||
__virtualname__ = 'digicert'
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
Only load the module if digicert has configuration in place
|
||||
'''
|
||||
if __opts__.get('digicert', {}).get('api_key'):
|
||||
return __virtualname__
|
||||
return False
|
||||
|
||||
|
||||
def _base_url():
|
||||
'''
|
||||
Return the base_url
|
||||
'''
|
||||
return __opts__.get('digicert', {}).get(
|
||||
'base_url', 'https://www.digicert.com/services/v2/'
|
||||
)
|
||||
|
||||
|
||||
def _api_key():
|
||||
'''
|
||||
Return the API key
|
||||
'''
|
||||
return __opts__.get('digicert', {}).get('api_key', '')
|
||||
|
||||
|
||||
def _paginate(url, topkey, *args, **kwargs):
|
||||
'''
|
||||
Wrapper to assist with paginated responses from Digicert's REST API.
|
||||
'''
|
||||
|
||||
ret = salt.utils.http.query(url, **kwargs)
|
||||
if 'errors' in ret['dict']:
|
||||
return ret['dict']
|
||||
|
||||
lim = int(ret['dict']['page']['limit'])
|
||||
total = int(ret['dict']['page']['total'])
|
||||
|
||||
if total == 0:
|
||||
return {}
|
||||
|
||||
numpages = (total / lim) + 1
|
||||
|
||||
# If the count returned is less than the page size, just return the dict
|
||||
if numpages == 1:
|
||||
return ret['dict'][topkey]
|
||||
|
||||
aggregate_ret = ret['dict'][topkey]
|
||||
url = args[0]
|
||||
for p in range(2, numpages):
|
||||
param_url = url + '?offset={0}'.format(lim * (p - 1))
|
||||
next_ret = salt.utils.http.query(param_url, kwargs)
|
||||
aggregate_ret[topkey].extend(next_ret['dict'][topkey])
|
||||
|
||||
return aggregate_ret
|
||||
|
||||
|
||||
def list_domains(container_id=None):
|
||||
'''
|
||||
List domains that CertCentral knows about. You can filter by
|
||||
container_id (also known as "Division") by passing a container_id.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-run digicert.list_domains
|
||||
'''
|
||||
if container_id:
|
||||
url = '{0}/domain?{1}'.format(_base_url(), container_id)
|
||||
else:
|
||||
url = '{0}/domain'.format(_base_url())
|
||||
|
||||
orgs = _paginate(url,
|
||||
"domains",
|
||||
method='GET',
|
||||
decode=True,
|
||||
decode_type='json',
|
||||
header_dict={
|
||||
'X-DC-DEVKEY': _api_key(),
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
)
|
||||
|
||||
ret = {'domains': orgs}
|
||||
return ret
|
||||
|
||||
|
||||
def list_requests(status=None):
|
||||
'''
|
||||
List certificate requests made to CertCentral. You can filter by
|
||||
status: ``pending``, ``approved``, ``rejected``
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-run digicert.list_requests pending
|
||||
'''
|
||||
if status:
|
||||
url = '{0}/request?status={1}'.format(_base_url(), status)
|
||||
else:
|
||||
url = '{0}/request'.format(_base_url())
|
||||
|
||||
reqs = _paginate(url,
|
||||
"requests",
|
||||
method='GET',
|
||||
decode=True,
|
||||
decode_type='json',
|
||||
raise_error=False,
|
||||
header_dict={
|
||||
'X-DC-DEVKEY': _api_key(),
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
)
|
||||
|
||||
ret = {'requests': reqs}
|
||||
return ret
|
||||
|
||||
|
||||
def list_orders(status=None):
|
||||
'''
|
||||
List certificate orders made to CertCentral.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-run digicert.list_orders
|
||||
'''
|
||||
url = '{0}/order/certificate'.format(_base_url())
|
||||
|
||||
reqs = _paginate(url,
|
||||
"orders",
|
||||
method='GET',
|
||||
decode=True,
|
||||
decode_type='json',
|
||||
raise_error=False,
|
||||
header_dict={
|
||||
'X-DC-DEVKEY': _api_key(),
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
)
|
||||
|
||||
ret = {'orders': reqs}
|
||||
return ret
|
||||
|
||||
|
||||
def get_certificate(order_id=None, certificate_id=None, minion_id=None, cert_format='pem_all', filename=None):
|
||||
'''
|
||||
Retrieve a certificate by order_id or certificate_id and write it to stdout or a filename.
|
||||
|
||||
A list of permissible cert_formats is here:
|
||||
https://www.digicert.com/services/v2/documentation/appendix-certificate-formats
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-run digicert.get_certificate order_id=48929454 cert_format=apache
|
||||
|
||||
Including a 'filename' will write the certificate to the desired file.
|
||||
Note that some cert formats are zipped files, and some are binary.
|
||||
|
||||
If the certificate has not been issued, this function will return the order details
|
||||
inside of which will be a status (one of pending, rejected, processing, issued,
|
||||
revoked, canceled, needs_csr, and needs_approval)
|
||||
|
||||
If for some reason you want to pipe the output of this command to a file or other
|
||||
command you will want to leave off the ``filename`` argument and make sure to include
|
||||
``--no-color`` so there will be no terminal ANSI escape sequences.
|
||||
|
||||
'''
|
||||
|
||||
if order_id:
|
||||
order_cert = salt.utils.http.query(
|
||||
'{0}/order/certificate/{1}'.format(_base_url(),
|
||||
order_id),
|
||||
method='GET',
|
||||
raise_error=False,
|
||||
decode=True,
|
||||
decode_type='json',
|
||||
header_dict={
|
||||
'X-DC-DEVKEY': _api_key(),
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
)
|
||||
if order_cert['dict'].get('status') != 'issued':
|
||||
return {'certificate': order_cert['dict']}
|
||||
|
||||
if order_cert['dict'].get('errors', False):
|
||||
return {'certificate': order_cert['dict']}
|
||||
|
||||
certificate_id = order_cert['dict'].get('certificate').get('id', None)
|
||||
common_name = order_cert['dict'].get('certificate').get('common_name')
|
||||
|
||||
if not certificate_id:
|
||||
return {'certificate':
|
||||
{'errors':
|
||||
{'code': 'unknown',
|
||||
'message': 'Unknown error, no certificate ID passed on command line or in body returned from API'}}}
|
||||
|
||||
if filename:
|
||||
ret_cert = salt.utils.http.query(
|
||||
'{0}/certificate/{1}/download/format/{2}'.format(_base_url(),
|
||||
certificate_id,
|
||||
cert_format),
|
||||
method='GET',
|
||||
decode=False,
|
||||
text=False,
|
||||
headers=True,
|
||||
text_out=filename,
|
||||
raise_error=False,
|
||||
header_dict={
|
||||
'X-DC-DEVKEY': _api_key(),
|
||||
}
|
||||
)
|
||||
else:
|
||||
ret_cert = salt.utils.http.query(
|
||||
'{0}/certificate/{1}/download/format/{2}'.format(_base_url(),
|
||||
certificate_id,
|
||||
cert_format),
|
||||
method='GET',
|
||||
text=False,
|
||||
decode=False,
|
||||
raise_error=False,
|
||||
header_dict={
|
||||
'X-DC-DEVKEY': _api_key(),
|
||||
}
|
||||
)
|
||||
if 'errors' in ret_cert:
|
||||
return {'certificate': ret_cert}
|
||||
|
||||
if 'body' not in ret_cert:
|
||||
ret = {'certificate': ret_cert}
|
||||
cert = ret_cert
|
||||
if isinstance(ret_cert, dict):
|
||||
ret = ret_cert['body']
|
||||
cert = ret
|
||||
else:
|
||||
ret = ret_cert
|
||||
cert = ret
|
||||
|
||||
tmpfilename = None
|
||||
if not filename:
|
||||
fd, tmpfilename = tempfile.mkstemp()
|
||||
filename = tmpfilename
|
||||
os.write(fd, cert)
|
||||
os.close(fd)
|
||||
|
||||
cmd = ['openssl', 'x509', '-noout', '-subject', '-nameopt', 'multiline', '-in', filename]
|
||||
out = subprocess.check_output(cmd)
|
||||
common_name = None
|
||||
for l in out.splitlines():
|
||||
common_name_match = re.search(' *commonName *= *(.*)', l)
|
||||
if common_name_match:
|
||||
common_name = common_name_match.group(1)
|
||||
break
|
||||
if tmpfilename:
|
||||
os.unlink(tmpfilename)
|
||||
|
||||
if common_name:
|
||||
bank = 'digicert/domains'
|
||||
cache = salt.cache.Cache(__opts__, syspaths.CACHE_DIR)
|
||||
try:
|
||||
data = cache.fetch(bank, common_name)
|
||||
except TypeError:
|
||||
data = {'certificate': cert}
|
||||
cache.store(bank, common_name, data)
|
||||
|
||||
if 'headers' in ret_cert:
|
||||
return {'certificate': {'filename': filename,
|
||||
'original_filename': ret_cert['headers'].get('Content-Disposition', 'Not provided'),
|
||||
'Content-Type': ret_cert['headers'].get('Content-Type', 'Not provided')
|
||||
}}
|
||||
|
||||
return {'certificate': cert}
|
||||
|
||||
|
||||
def list_organizations(container_id=None, include_validation=True):
|
||||
'''
|
||||
List organizations that CertCentral knows about. You can filter by
|
||||
container_id (also known as "Division") by passing a container_id.
|
||||
This function returns validation information by default; pass
|
||||
``include_validation=False`` to turn it off.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-run digicert.list_organizations
|
||||
'''
|
||||
|
||||
orgs = _paginate('{0}/organization'.format(_base_url()),
|
||||
"organizations",
|
||||
method='GET',
|
||||
decode=True,
|
||||
decode_type='json',
|
||||
header_dict={
|
||||
'X-DC-DEVKEY': _api_key(),
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
)
|
||||
|
||||
ret = {'organizations': orgs}
|
||||
return ret
|
||||
|
||||
|
||||
def order_certificate(minion_id, common_name, organization_id, validity_years,
|
||||
cert_key_passphrase=None, signature_hash=None, key_len=2048,
|
||||
dns_names=None, organization_units=None, server_platform=None,
|
||||
custom_expiration_date=None, comments=None, disable_renewal_notifications=False,
|
||||
product_type_hint=None, renewal_of_order_id=None):
|
||||
'''
|
||||
Order a certificate. Requires that an Organization has been created inside Digicert's CertCentral.
|
||||
|
||||
See here for API documentation:
|
||||
https://www.digicert.com/services/v2/documentation/order/order-ssl-determinator
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-run digicert.order_certificate my_minionid my.domain.com 10 \
|
||||
3 signature_hash=sha256 \
|
||||
dns_names=['this.domain.com', 'that.domain.com'] \
|
||||
organization_units='My Domain Org Unit' \
|
||||
comments='Comment goes here for the approver'
|
||||
|
||||
This runner can also be used to renew a certificate by passing `renewal_of_order_id`.
|
||||
Previous order details can be retrieved with digicertapi.list_orders.
|
||||
'''
|
||||
|
||||
if dns_names and isinstance(dns_names, six.string_types):
|
||||
dns_names = [dns_names]
|
||||
if dns_names and not isinstance(dns_names, collections.Sequence):
|
||||
raise SaltRunnerError('order_certificate needs a single dns_name, or an array of dns_names.')
|
||||
certificate = {'common_name': common_name}
|
||||
certificate['dns_names'] = dns_names
|
||||
|
||||
if signature_hash:
|
||||
certificate['signature_hash'] = signature_hash
|
||||
else:
|
||||
certificate['signature_hash'] = __opts__.get('digicert', {}).get('shatype', 'sha256')
|
||||
|
||||
body = {}
|
||||
|
||||
if organization_units and isinstance(organization_units, six.string_types):
|
||||
organization_units = [organization_units]
|
||||
if organization_units and not isinstance(organization_units, collections.Sequence):
|
||||
raise SaltRunnerError('Organization_units is not a valid data type.')
|
||||
if organization_units:
|
||||
certificate['organization_units'] = organization_units
|
||||
|
||||
if organization_units:
|
||||
# Currently the Digicert API requires organization units to be an array
|
||||
# but only pays attention to the first one.
|
||||
csr = gen_csr(minion_id, common_name, organization_id,
|
||||
ou_name=organization_units[0],
|
||||
shatype=certificate['signature_hash'], key_len=key_len,
|
||||
password=cert_key_passphrase)
|
||||
else:
|
||||
csr = gen_csr(minion_id, common_name, organization_id,
|
||||
shatype=certificate['signature_hash'], key_len=key_len,
|
||||
password=cert_key_passphrase)
|
||||
|
||||
certificate['csr'] = csr
|
||||
|
||||
if server_platform:
|
||||
certificate['server_platform']['id'] = server_platform
|
||||
|
||||
body['organization'] = {'id': organization_id}
|
||||
|
||||
if custom_expiration_date:
|
||||
body['custom_expiration_date'] = custom_expiration_date
|
||||
|
||||
if validity_years:
|
||||
body['validity_years'] = validity_years
|
||||
|
||||
if comments:
|
||||
body['comments'] = comments
|
||||
|
||||
body['disable_renewal_notifications'] = disable_renewal_notifications
|
||||
|
||||
if product_type_hint:
|
||||
body['product'] = {'type_hint': product_type_hint}
|
||||
if renewal_of_order_id:
|
||||
body['renewal_of_order_id'] = renewal_of_order_id
|
||||
|
||||
body['certificate'] = certificate
|
||||
encoded_body = json.dumps(body)
|
||||
|
||||
qdata = salt.utils.http.query(
|
||||
'{0}/order/certificate/ssl'.format(_base_url()),
|
||||
method='POST',
|
||||
data=encoded_body,
|
||||
decode=True,
|
||||
decode_type='json',
|
||||
header_dict={
|
||||
'X-DC-DEVKEY': _api_key(),
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
raise_error=False
|
||||
)
|
||||
if 'errors' not in qdata['dict']:
|
||||
bank = 'digicert/domains'
|
||||
cache = salt.cache.Cache(__opts__, syspaths.CACHE_DIR)
|
||||
data = cache.fetch(bank, common_name)
|
||||
if data is None:
|
||||
data = {}
|
||||
data.update({
|
||||
'minion_id': minion_id,
|
||||
'order_id': qdata['dict']['requests'][0]['id'],
|
||||
'csr': csr,
|
||||
})
|
||||
cache.store(bank, common_name, data)
|
||||
_id_map(minion_id, common_name)
|
||||
|
||||
return {'order': qdata['dict']}
|
||||
|
||||
|
||||
def gen_key(minion_id, dns_name=None, password=None, key_len=2048):
|
||||
'''
|
||||
Generate and return a private_key. If a ``dns_name`` is passed in, the
|
||||
private_key will be cached under that name.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-run digicert.gen_key <minion_id> [dns_name] [password]
|
||||
'''
|
||||
keygen_type = 'RSA'
|
||||
|
||||
if keygen_type == "RSA":
|
||||
gen = RSA.generate(bits=key_len)
|
||||
private_key = gen.exportKey('PEM', password)
|
||||
if dns_name is not None:
|
||||
bank = 'digicert/domains'
|
||||
cache = salt.cache.Cache(__opts__, syspaths.CACHE_DIR)
|
||||
try:
|
||||
data = cache.fetch(bank, dns_name)
|
||||
data['private_key'] = private_key
|
||||
data['minion_id'] = minion_id
|
||||
except TypeError:
|
||||
data = {'private_key': private_key,
|
||||
'minion_id': minion_id}
|
||||
cache.store(bank, dns_name, data)
|
||||
return private_key
|
||||
|
||||
|
||||
def get_org_details(organization_id):
|
||||
'''
|
||||
Return the details for an organization
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-run digicert.get_org_details 34
|
||||
|
||||
Returns a dictionary with the org details, or with 'error' and 'status' keys.
|
||||
'''
|
||||
|
||||
qdata = salt.utils.http.query(
|
||||
'{0}/organization/{1}'.format(_base_url(), organization_id),
|
||||
method='GET',
|
||||
decode=True,
|
||||
decode_type='json',
|
||||
header_dict={
|
||||
'X-DC-DEVKEY': _api_key(),
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
)
|
||||
return qdata
|
||||
|
||||
|
||||
def gen_csr(
|
||||
minion_id,
|
||||
dns_name,
|
||||
organization_id,
|
||||
ou_name=None,
|
||||
key_len=2048,
|
||||
shatype='sha256',
|
||||
password=None):
|
||||
'''
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-run digicert.gen_csr <minion_id> <dns_name>
|
||||
'''
|
||||
org_details = get_org_details(organization_id)
|
||||
|
||||
if 'error' in org_details:
|
||||
raise SaltRunnerError('Problem getting organization details for organization_id={0} ({1})'.format(organization_id, org_details['error']))
|
||||
if org_details['dict'].get('status', 'active') == 'inactive':
|
||||
raise SaltRunnerError('Organization with organization_id={0} is marked inactive'.format(organization_id))
|
||||
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
os.chmod(tmpdir, 0o700)
|
||||
|
||||
bank = 'digicert/domains'
|
||||
cache = salt.cache.Cache(__opts__, syspaths.CACHE_DIR)
|
||||
data = cache.fetch(bank, dns_name)
|
||||
if data is None:
|
||||
data = {}
|
||||
if 'private_key' not in data:
|
||||
data['private_key'] = gen_key(minion_id, dns_name, password, key_len=key_len)
|
||||
|
||||
tmppriv = '{0}/priv'.format(tmpdir)
|
||||
tmpcsr = '{0}/csr'.format(tmpdir)
|
||||
with salt.utils.fopen(tmppriv, 'w') as if_:
|
||||
if_.write(data['private_key'])
|
||||
|
||||
subject = '/C={0}/ST={1}/L={2}/O={3}'.format(
|
||||
org_details['dict']['country'],
|
||||
org_details['dict']['state'],
|
||||
org_details['dict']['city'],
|
||||
org_details['dict']['display_name'])
|
||||
|
||||
if ou_name:
|
||||
subject = subject + '/OU={0}'.format(ou_name)
|
||||
|
||||
subject = subject + '/CN={0}'.format(dns_name)
|
||||
|
||||
cmd = "openssl req -new -{0} -key {1} -out {2} -subj '{3}'".format(
|
||||
shatype,
|
||||
tmppriv,
|
||||
tmpcsr,
|
||||
subject
|
||||
)
|
||||
output = __salt__['salt.cmd']('cmd.run', cmd)
|
||||
|
||||
if 'problems making Certificate Request' in output:
|
||||
raise CommandExecutionError(
|
||||
'There was a problem generating the CSR. Please ensure that you '
|
||||
'have a valid Organization established inside CertCentral'
|
||||
)
|
||||
|
||||
with salt.utils.fopen(tmpcsr, 'r') as of_:
|
||||
csr = of_.read()
|
||||
|
||||
data['minion_id'] = minion_id
|
||||
data['csr'] = csr
|
||||
cache.store(bank, dns_name, data)
|
||||
return csr
|
||||
|
||||
|
||||
# Request and renew are the same, so far as this module is concerned
|
||||
#renew = request
|
||||
|
||||
|
||||
def _id_map(minion_id, dns_name):
|
||||
'''
|
||||
Maintain a relationship between a minion and a dns name
|
||||
'''
|
||||
bank = 'digicert/minions'
|
||||
cache = salt.cache.Cache(__opts__, syspaths.CACHE_DIR)
|
||||
dns_names = cache.fetch(bank, minion_id)
|
||||
if not isinstance(dns_names, list):
|
||||
dns_names = []
|
||||
if dns_name not in dns_names:
|
||||
dns_names.append(dns_name)
|
||||
cache.store(bank, minion_id, dns_names)
|
||||
|
||||
|
||||
def show_organization(domain):
|
||||
'''
|
||||
Show organization information, especially the company id
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-run digicert.show_company example.com
|
||||
'''
|
||||
data = salt.utils.http.query(
|
||||
'{0}/companies/domain/{1}'.format(_base_url(), domain),
|
||||
status=True,
|
||||
decode=True,
|
||||
decode_type='json',
|
||||
header_dict={
|
||||
'tppl-api-key': _api_key(),
|
||||
},
|
||||
)
|
||||
status = data['status']
|
||||
if str(status).startswith('4') or str(status).startswith('5'):
|
||||
raise CommandExecutionError(
|
||||
'There was an API error: {0}'.format(data['error'])
|
||||
)
|
||||
return data.get('dict', {})
|
||||
|
||||
|
||||
def show_csrs():
|
||||
'''
|
||||
Show certificate requests for this API key
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-run digicert.show_csrs
|
||||
'''
|
||||
data = salt.utils.http.query(
|
||||
'{0}/certificaterequests'.format(_base_url()),
|
||||
status=True,
|
||||
decode=True,
|
||||
decode_type='json',
|
||||
header_dict={
|
||||
'tppl-api-key': _api_key(),
|
||||
},
|
||||
)
|
||||
status = data['status']
|
||||
if str(status).startswith('4') or str(status).startswith('5'):
|
||||
raise CommandExecutionError(
|
||||
'There was an API error: {0}'.format(data['error'])
|
||||
)
|
||||
return data.get('dict', {})
|
||||
|
||||
|
||||
def show_rsa(minion_id, dns_name):
|
||||
'''
|
||||
Show a private RSA key
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-run digicert.show_rsa myminion domain.example.com
|
||||
'''
|
||||
cache = salt.cache.Cache(__opts__, syspaths.CACHE_DIR)
|
||||
bank = 'digicert/domains'
|
||||
data = cache.fetch(
|
||||
bank, dns_name
|
||||
)
|
||||
return data['private_key']
|
||||
|
||||
|
||||
def list_domain_cache():
|
||||
'''
|
||||
List domains that have been cached
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-run digicert.list_domain_cache
|
||||
'''
|
||||
cache = salt.cache.Cache(__opts__, syspaths.CACHE_DIR)
|
||||
return cache.list('digicert/domains')
|
||||
|
||||
|
||||
def del_cached_domain(domains):
|
||||
'''
|
||||
Delete cached domains from the master
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-run digicert.del_cached_domain domain1.example.com,domain2.example.com
|
||||
'''
|
||||
cache = salt.cache.Cache(__opts__, syspaths.CACHE_DIR)
|
||||
if isinstance(domains, six.string_types):
|
||||
domains = domains.split(',')
|
||||
if not isinstance(domains, list):
|
||||
raise CommandExecutionError(
|
||||
'You must pass in either a string containing one or more domains '
|
||||
'separated by commas, or a list of single domain strings'
|
||||
)
|
||||
success = []
|
||||
failed = []
|
||||
for domain in domains:
|
||||
try:
|
||||
cache.flush('digicert/domains', domain)
|
||||
success.append(domain)
|
||||
except CommandExecutionError:
|
||||
failed.append(domain)
|
||||
return {'Succeeded': success, 'Failed': failed}
|
Loading…
Reference in New Issue
Block a user