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.

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 = salt.utils.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']}