create cisco type 5 filters (#39901)

This commit is contained in:
Ken Celenza 2018-05-22 08:35:54 -04:00 committed by John R Barker
commit dd02a4e943
2 changed files with 143 additions and 3 deletions

View file

@ -23,13 +23,17 @@ __metaclass__ = type
import re
import os
import traceback
import string
from collections import Mapping
from xml.etree.ElementTree import fromstring
from ansible.module_utils.network.common.utils import Template
from ansible.module_utils.six import iteritems, string_types
from ansible.errors import AnsibleError
from ansible.errors import AnsibleError, AnsibleFilterError
from ansible.utils.encrypt import random_password
from ansible.plugins.lookup import password as ansible_password
try:
import yaml
@ -50,6 +54,12 @@ except ImportError:
from ansible.utils.display import Display
display = Display()
try:
from passlib.hash import md5_crypt
HAS_PASSLIB = True
except ImportError:
HAS_PASSLIB = False
def re_matchall(regex, value):
objects = list()
@ -345,13 +355,56 @@ def parse_xml(output, tmpl):
return obj
def type5_pw(password, salt=None):
if not HAS_PASSLIB:
raise AnsibleFilterError('type5_pw filter requires PassLib library to be installed')
if not isinstance(password, string_types):
raise AnsibleFilterError("type5_pw password input should be a string, but was given a input of %s" % (type(password).__name__))
salt_chars = ansible_password._gen_candidate_chars(['ascii_letters', 'digits', './'])
if salt is not None and not isinstance(salt, string_types):
raise AnsibleFilterError("type5_pw salt input should be a string, but was given a input of %s" % (type(salt).__name__))
elif not salt:
salt = random_password(length=4, chars=salt_chars)
elif not set(salt) <= set(salt_chars):
raise AnsibleFilterError("type5_pw salt used inproper characters, must be one of %s" % (salt_chars))
encrypted_password = md5_crypt.encrypt(password, salt=salt)
return encrypted_password
def hash_salt(password):
split_password = password.split("$")
if len(split_password) != 4:
raise AnsibleFilterError('Could not parse salt out password correctly from {0}'.format(password))
else:
return split_password[2]
def comp_type5(unencrypted_password, encrypted_password, return_orginal=False):
salt = hash_salt(encrypted_password)
if type5_pw(unencrypted_password, salt) == encrypted_password:
if return_orginal is True:
return encrypted_password
else:
return True
return False
class FilterModule(object):
"""Filters for working with output from network devices"""
filter_map = {
'parse_cli': parse_cli,
'parse_cli_textfsm': parse_cli_textfsm,
'parse_xml': parse_xml
'parse_xml': parse_xml,
'type5_pw': type5_pw,
'hash_salt': hash_salt,
'comp_type5': comp_type5
}
def filters(self):