<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:

def gen_key(minion_id, dns_name=None, zone='default', password=None):
    '''
    Generate and return an private_key. If a ``dns_name`` is passed in, the
    private_key will be cached under that name. The type of key and the
    parameters used to generate the key are based on the default certificate
    use policy associated with the specified zone.

    CLI Example:

    .. code-block:: bash

        salt-run venafi.gen_key <minion_id> [dns_name] [zone] [password]
    '''
    # Get the default certificate use policy associated with the zone
    # so we can generate keys that conform with policy

    # The /v1/zones/tag/{name} API call is a shortcut to get the zoneID
    # directly from the name

    qdata = __utils__['http.query'](
        '{0}/zones/tag/{1}'.format(_base_url(), zone),
        method='GET',
        decode=True,
        decode_type='json',
        header_dict={
            'tppl-api-key': _api_key(),
            'Content-Type': 'application/json',
        },
    )

    zone_id = qdata['dict']['id']

    # the /v1/certificatepolicies?zoneId API call returns the default
    # certificate use and certificate identity policies

    qdata = __utils__['http.query'](
        '{0}/certificatepolicies?zoneId={1}'.format(_base_url(), zone_id),
        method='GET',
        decode=True,
        decode_type='json',
        header_dict={
            'tppl-api-key': _api_key(),
            'Content-Type': 'application/json',
        },
    )

    policies = qdata['dict']['certificatePolicies']

    # Extract the key length and key type from the certificate use policy
    # and generate the private key accordingly

    for policy in policies:
        if policy['certificatePolicyType'] == "CERTIFICATE_USE":
            keyTypes = policy['keyTypes']
            # in case multiple keytypes and key lengths are supported
            # always use the first key type and key length
            keygen_type = keyTypes[0]['keyType']
            key_len = keyTypes[0]['keyLengths'][0]

    if int(key_len) < 2048:
        key_len = 2048

    if keygen_type == "RSA":
        if HAS_M2:
            gen = RSA.gen_key(key_len, 65537)
            private_key = gen.as_pem(cipher='des_ede3_cbc', callback=lambda x: six.b(password))
        else:
            gen = RSA.generate(bits=key_len)
            private_key = gen.exportKey('PEM', password)
        if dns_name is not None:
            bank = 'venafi/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