Esempio n. 1
0
def do_unvault(vault, secret, vaultid='filter_default'):

    if not isinstance(secret, (string_types, binary_type, Undefined)):
        raise AnsibleFilterTypeError(
            "Secret passed is required to be as string, instead we got: %s" %
            type(secret))

    if not isinstance(
            vault,
        (string_types, binary_type, AnsibleVaultEncryptedUnicode, Undefined)):
        raise AnsibleFilterTypeError(
            "Vault should be in the form of a string, instead we got: %s" %
            type(vault))

    data = ''
    vs = VaultSecret(to_bytes(secret))
    vl = VaultLib([(vaultid, vs)])
    if isinstance(vault, AnsibleVaultEncryptedUnicode):
        vault.vault = vl
        data = vault.data
    elif is_encrypted(vault):
        try:
            data = vl.decrypt(vault)
        except UndefinedError:
            raise
        except Exception as e:
            raise AnsibleFilterError("Unable to decrypt: %s" % to_native(e),
                                     orig_exc=e)
    else:
        data = vault

    return to_native(data)
Esempio n. 2
0
def do_vault(data,
             secret,
             salt=None,
             vaultid='filter_default',
             wrap_object=False):

    if not isinstance(secret, (string_types, binary_type, Undefined)):
        raise AnsibleFilterTypeError(
            "Secret passed is required to be a string, instead we got: %s" %
            type(secret))

    if not isinstance(data, (string_types, binary_type, Undefined)):
        raise AnsibleFilterTypeError(
            "Can only vault strings, instead we got: %s" % type(data))

    vault = ''
    vs = VaultSecret(to_bytes(secret))
    vl = VaultLib()
    try:
        vault = vl.encrypt(to_bytes(data), vs, vaultid, salt)
    except UndefinedError:
        raise
    except Exception as e:
        raise AnsibleFilterError("Unable to encrypt: %s" % to_native(e),
                                 orig_exc=e)

    if wrap_object:
        vault = AnsibleVaultEncryptedUnicode(vault)
    else:
        vault = to_native(vault)

    return vault
Esempio n. 3
0
def rekey_on_member(data, key, duplicates='error'):
    """
    Rekey a dict of dicts on another member

    May also create a dict from a list of dicts.

    duplicates can be one of ``error`` or ``overwrite`` to specify whether to error out if the key
    value would be duplicated or to overwrite previous entries if that's the case.
    """
    if duplicates not in ('error', 'overwrite'):
        raise AnsibleFilterError(
            "duplicates parameter to rekey_on_member has unknown value: {0}".
            format(duplicates))

    new_obj = {}

    # Ensure the positional args are defined - raise jinja2.exceptions.UndefinedError if not
    bool(data) and bool(key)

    if isinstance(data, Mapping):
        iterate_over = data.values()
    elif isinstance(
            data, Iterable) and not isinstance(data, (text_type, binary_type)):
        iterate_over = data
    else:
        raise AnsibleFilterTypeError("Type is not a valid list, set, or dict")

    for item in iterate_over:
        if not isinstance(item, Mapping):
            raise AnsibleFilterTypeError("List item is not a valid dict")

        try:
            key_elem = item[key]
        except KeyError:
            raise AnsibleFilterError("Key {0} was not found".format(key))
        except TypeError as e:
            raise AnsibleFilterTypeError(to_native(e))
        except Exception as e:
            raise AnsibleFilterError(to_native(e))

        # Note: if new_obj[key_elem] exists it will always be a non-empty dict (it will at
        # minimum contain {key: key_elem}
        if new_obj.get(key_elem, None):
            if duplicates == 'error':
                raise AnsibleFilterError(
                    "Key {0} is not unique, cannot correctly turn into dict".
                    format(key_elem))
            elif duplicates == 'overwrite':
                new_obj[key_elem] = item
        else:
            new_obj[key_elem] = item

    return new_obj
Esempio n. 4
0
def subelements(obj, subelements, skip_missing=False):
    '''Accepts a dict or list of dicts, and a dotted accessor and produces a product
    of the element and the results of the dotted accessor

    >>> obj = [{"name": "alice", "groups": ["wheel"], "authorized": ["/tmp/alice/onekey.pub"]}]
    >>> subelements(obj, 'groups')
    [({'name': 'alice', 'groups': ['wheel'], 'authorized': ['/tmp/alice/onekey.pub']}, 'wheel')]

    '''
    if isinstance(obj, dict):
        element_list = list(obj.values())
    elif isinstance(obj, list):
        element_list = obj[:]
    else:
        raise AnsibleFilterError(
            'obj must be a list of dicts or a nested dict')

    if isinstance(subelements, list):
        subelement_list = subelements[:]
    elif isinstance(subelements, string_types):
        subelement_list = subelements.split('.')
    else:
        raise AnsibleFilterTypeError('subelements must be a list or a string')

    results = []

    for element in element_list:
        values = element
        for subelement in subelement_list:
            try:
                values = values[subelement]
            except KeyError:
                if skip_missing:
                    values = []
                    break
                raise AnsibleFilterError(
                    "could not find %r key in iterated item %r" %
                    (subelement, values))
            except TypeError:
                raise AnsibleFilterTypeError(
                    "the key %s should point to a dictionary, got '%s'" %
                    (subelement, values))
        if not isinstance(values, list):
            raise AnsibleFilterTypeError(
                "the key %r should point to a list, got %r" %
                (subelement, values))

        for value in values:
            results.append((element, value))

    return results
Esempio n. 5
0
def hashids_encode(nums, salt=None, alphabet=None, min_length=None):
    """Generates a YouTube-like hash from a sequence of ints

       :nums: Sequence of one or more ints to hash
       :salt: String to use as salt when hashing
       :alphabet: String of 16 or more unique characters to produce a hash
       :min_length: Minimum length of hash produced
    """

    hashids = initialize_hashids(
        salt=salt,
        alphabet=alphabet,
        min_length=min_length
    )

    # Handles the case where a single int is not encapsulated in a list or tuple.
    # User convenience seems preferable to strict typing in this case
    # Also avoids obfuscated error messages related to single invalid inputs
    if not is_sequence(nums):
        nums = [nums]

    try:
        hashid = hashids.encode(*nums)
    except TypeError as e:
        raise AnsibleFilterTypeError(
            "Data to encode must by a tuple or list of ints: %s" % to_native(e)
        )

    return hashid
Esempio n. 6
0
def list_of_dict_key_value_elements_to_dict(mylist, key_name='key', value_name='value'):
    ''' takes a list of dicts with each having a 'key' and 'value' keys, and transforms the list into a dictionary,
        effectively as the reverse of dict2items '''

    if not is_sequence(mylist):
        raise AnsibleFilterTypeError("items2dict requires a list, got %s instead." % type(mylist))

    return dict((item[key_name], item[value_name]) for item in mylist)
Esempio n. 7
0
def path_join(paths):
    ''' takes a sequence or a string, and return a concatenation
        of the different members '''
    if isinstance(paths, string_types):
        return os.path.join(paths)
    elif is_sequence(paths):
        return os.path.join(*paths)
    else:
        raise AnsibleFilterTypeError("|path_join expects string or sequence, got %s instead." % type(paths))
def inversepower(x, base=2):
    try:
        if base == 2:
            return math.sqrt(x)
        else:
            return math.pow(x, 1.0 / float(base))
    except (ValueError, TypeError) as e:
        raise AnsibleFilterTypeError('root() can only be used on numbers: %s' %
                                     to_native(e))
def logarithm(x, base=math.e):
    try:
        if base == 10:
            return math.log10(x)
        else:
            return math.log(x, base)
    except TypeError as e:
        raise AnsibleFilterTypeError('log() can only be used on numbers: %s' %
                                     to_native(e))
Esempio n. 10
0
def human_to_bytes(size, default_unit=None, isbits=False):
    ''' Return bytes count from a human readable string '''
    try:
        return formatters.human_to_bytes(size, default_unit, isbits)
    except TypeError as e:
        raise AnsibleFilterTypeError(
            "human_to_bytes() failed on bad input: %s" % to_native(e))
    except Exception:
        raise AnsibleFilterError(
            "human_to_bytes() can't interpret following string: %s" % size)
Esempio n. 11
0
def human_readable(size, isbits=False, unit=None):
    ''' Return a human readable string '''
    try:
        return formatters.bytes_to_human(size, isbits, unit)
    except TypeError as e:
        raise AnsibleFilterTypeError(
            "human_readable() failed on bad input: %s" % to_native(e))
    except Exception:
        raise AnsibleFilterError(
            "human_readable() can't interpret following string: %s" % size)
Esempio n. 12
0
def dict_to_list_of_dict_key_value_elements(mydict, key_name='key', value_name='value'):
    ''' takes a dictionary and transforms it into a list of dictionaries,
        with each having a 'key' and 'value' keys that correspond to the keys and values of the original '''

    if not isinstance(mydict, Mapping):
        raise AnsibleFilterTypeError("dict2items requires a dictionary, got %s instead." % type(mydict))

    ret = []
    for key in mydict:
        ret.append({key_name: key, value_name: mydict[key]})
    return ret
Esempio n. 13
0
def baremetal_driver(bmc_type, bmc_address, bmc_username, bmc_password):
    '''Return Openstack Ironic driver info'''
    if not isinstance(bmc_type, string_types):
        raise AnsibleFilterTypeError(
            "|baremetal_driver_info expects string got %s instead." %
            type(bmc_type))
    bmc_props = {
        "idrac": {
            "driver": "idrac",
            "driver_info/drac_address": bmc_address,
            "driver_info/drac_password": bmc_password,
            "driver_info/drac_username": bmc_username,
            "boot_interface": "ipxe",
            "bios_interface": "no-bios",
            "console_interface": "no-console",
            "deploy_interface": "iscsi",
            "inspect_interface": "idrac-wsman",
            "management_interface": "idrac-wsman",
            "network_interface": "neutron",
            "power_interface": "idrac-wsman",
            "raid_interface": "idrac-wsman",
            "rescue_interface": "agent",
            "storage_interface": "noop",
            "vendor_interface": "idrac-wsman",
        },
        "ipmi": {
            "driver": "ipmi",
            "driver_info/ipmi_address": bmc_address,
            "driver_info/ipmi_password": bmc_password,
            "driver_info/ipmi_username": bmc_username,
            "boot_interface": "ipxe",
            "bios_interface": "no-bios",
            "console_interface": "no-console",
            "deploy_interface": "iscsi",
            "inspect_interface": "inspector",
            "management_interface": "ipmitool",
            "network_interface": "neutron",
            "power_interface": "ipmitool",
            "raid_interface": "no-raid",
            "rescue_interface": "agent",
            "storage_interface": "noop",
            "vendor_interface": "no-vendor",
        }
    }
    props = bmc_props[bmc_type]
    return props
Esempio n. 14
0
def unicode_normalize(data, form='NFC'):
    """Applies normalization to 'unicode' strings.

    Args:
        data: A unicode string piped into the Jinja filter
        form: One of ('NFC', 'NFD', 'NFKC', 'NFKD').
              See https://docs.python.org/3/library/unicodedata.html#unicodedata.normalize for more information.

    Returns:
        A normalized unicode string of the specified 'form'.
    """

    if not isinstance(data, text_type):
        raise AnsibleFilterTypeError("%s is not a valid input type" %
                                     type(data))

    if form not in ('NFC', 'NFD', 'NFKC', 'NFKD'):
        raise AnsibleFilterError("%s is not a valid form" % form)

    return normalize(form, data)
Esempio n. 15
0
def power(x, y):
    try:
        return math.pow(x, y)
    except TypeError as e:
        raise AnsibleFilterTypeError('pow() can only be used on numbers: %s' %
                                     to_native(e))