Add random_mac string filter (#39775)
Add new filter to generate random MAC addresses from string prefix. See docs/docsite/rst/user_guide/playbooks_filters.rst for more detailed infos.
This commit is contained in:
parent
5880404151
commit
06b73ff8f1
4 changed files with 102 additions and 2 deletions
6
changelogs/fragments/add_random_mac_filtter.yaml
Normal file
6
changelogs/fragments/add_random_mac_filtter.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
minor_changes:
|
||||
- Added new filter to generate random MAC addresses from a given
|
||||
string acting as a prefix. Refer to the appropriate entry
|
||||
which has been added to user_guide playbook_filters.rst
|
||||
document.
|
|
@ -243,6 +243,22 @@ An example of using this filter with ``loop``::
|
|||
key: "{{ lookup('file', item.1) }}"
|
||||
loop: "{{ users|subelements('authorized') }}"
|
||||
|
||||
.. _random_mac_filter:
|
||||
|
||||
Random Mac Address Filter
|
||||
`````````````````````````
|
||||
|
||||
.. versionadded:: 2.6
|
||||
|
||||
This filter can be used to generate a random MAC address from a string prefix.
|
||||
|
||||
To get a random MAC address from a string prefix starting with '52:54:00'::
|
||||
|
||||
"{{ '52:54:00'|random_mac }}"
|
||||
# => '52:54:00:ef:1c:03'
|
||||
|
||||
Note that if anything is wrong with the prefix string, the filter will issue an error.
|
||||
|
||||
.. _random_filter:
|
||||
|
||||
Random Number Filter
|
||||
|
|
|
@ -37,7 +37,7 @@ import yaml
|
|||
from collections import MutableMapping, MutableSequence
|
||||
import datetime
|
||||
from functools import partial
|
||||
from random import Random, SystemRandom, shuffle
|
||||
from random import Random, SystemRandom, shuffle, random
|
||||
|
||||
from jinja2.filters import environmentfilter, do_groupby as _do_groupby
|
||||
|
||||
|
@ -532,6 +532,39 @@ def dict_to_list_of_dict_key_value_elements(mydict):
|
|||
return ret
|
||||
|
||||
|
||||
def random_mac(value):
|
||||
''' takes string prefix, and return it completed with random bytes
|
||||
to get a complete 6 bytes MAC address '''
|
||||
|
||||
if not isinstance(value, string_types):
|
||||
raise AnsibleFilterError('Invalid value type (%s) for random_mac (%s)' % (type(value), value))
|
||||
|
||||
value = value.lower()
|
||||
mac_items = value.split(':')
|
||||
|
||||
if len(mac_items) > 5:
|
||||
raise AnsibleFilterError('Invalid value (%s) for random_mac: 5 colon(:) separated items max' % value)
|
||||
|
||||
err = ""
|
||||
for mac in mac_items:
|
||||
if len(mac) == 0:
|
||||
err += ",empty item"
|
||||
continue
|
||||
if not re.match('[a-f0-9]{2}', mac):
|
||||
err += ",%s not hexa byte" % mac
|
||||
err = err.strip(',')
|
||||
|
||||
if len(err):
|
||||
raise AnsibleFilterError('Invalid value (%s) for random_mac: %s' % (value, err))
|
||||
|
||||
# Generate random float and make it int
|
||||
v = int(random() * 10.0**10)
|
||||
# Select first n chars to complement input prefix
|
||||
remain = 2 * (6 - len(mac_items))
|
||||
rnd = ('%x' % v)[:remain]
|
||||
return value + re.sub(r'(..)', r':\1', rnd)
|
||||
|
||||
|
||||
class FilterModule(object):
|
||||
''' Ansible core jinja2 filters '''
|
||||
|
||||
|
@ -621,4 +654,7 @@ class FilterModule(object):
|
|||
'flatten': flatten,
|
||||
'dict2items': dict_to_list_of_dict_key_value_elements,
|
||||
'subelements': subelements,
|
||||
|
||||
# Misc
|
||||
'random_mac': random_mac,
|
||||
}
|
||||
|
|
|
@ -192,4 +192,46 @@
|
|||
- "'Ansible - くらとみ\n' | b64encode == 'QW5zaWJsZSAtIOOBj+OCieOBqOOBvwo='"
|
||||
- "'QW5zaWJsZSAtIOOBj+OCieOBqOOBvwo=' | b64decode == 'Ansible - くらとみ\n'"
|
||||
- "'Ansible - くらとみ\n' | b64encode(encoding='utf-16-le') == 'QQBuAHMAaQBiAGwAZQAgAC0AIABPMIkwaDB/MAoA'"
|
||||
- "'QQBuAHMAaQBiAGwAZQAgAC0AIABPMIkwaDB/MAoA' | b64decode(encoding='utf-16-le') == 'Ansible - くらとみ\n'"
|
||||
- "'QQBuAHMAaQBiAGwAZQAgAC0AIABPMIkwaDB/MAoA' | b64decode(encoding='utf-16-le') == 'Ansible - くらとみ\n'"
|
||||
|
||||
- name: Test random_mac filter bad argument type
|
||||
debug:
|
||||
var: "0 | random_mac"
|
||||
register: _bad_random_mac_filter
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Verify random_mac filter showed a bad argument type error message
|
||||
assert:
|
||||
that:
|
||||
- _bad_random_mac_filter is failed
|
||||
- "_bad_random_mac_filter.msg is match('Invalid value type (.*int.*) for random_mac .*')"
|
||||
|
||||
- name: Test random_mac filter bad argument value
|
||||
debug:
|
||||
var: "'dummy' | random_mac"
|
||||
register: _bad_random_mac_filter
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Verify random_mac filter showed a bad argument value error message
|
||||
assert:
|
||||
that:
|
||||
- _bad_random_mac_filter is failed
|
||||
- "_bad_random_mac_filter.msg is match('Invalid value (.*) for random_mac: .* not hexa byte')"
|
||||
|
||||
- name: Test random_mac filter prefix too big
|
||||
debug:
|
||||
var: "'00:00:00:00:00:00' | random_mac"
|
||||
register: _bad_random_mac_filter
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Verify random_mac filter showed a prefix too big error message
|
||||
assert:
|
||||
that:
|
||||
- _bad_random_mac_filter is failed
|
||||
- "_bad_random_mac_filter.msg is match('Invalid value (.*) for random_mac: 5 colon.* separated items max')"
|
||||
|
||||
- name: Verify random_mac filter
|
||||
assert:
|
||||
that:
|
||||
- "'00:00:00' | random_mac is match('^00:00:00:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]$')"
|
||||
- "'00:00:00' | random_mac != '00:00:00' | random_mac"
|
||||
|
|
Loading…
Reference in a new issue