summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authors-hamann <10639154+s-hamann@users.noreply.github.com>2019-05-16 17:41:08 +0000
committerNathaniel Case <ncase@redhat.com>2019-05-16 13:41:08 -0400
commit730456b402fb7cf4182938c41403214112c5933c (patch)
tree276bde67fe845c03e9df2c846d6eb981e289961a
parenta910d195339d2386829eb404c1df06ecb5ff1f1b (diff)
downloadansible-730456b402fb7cf4182938c41403214112c5933c.tar.gz
Add seed parameter to random_mac filter (#51841)
-rw-r--r--docs/docsite/rst/user_guide/playbooks_filters.rst4
-rw-r--r--lib/ansible/plugins/filter/core.py10
-rw-r--r--test/integration/targets/filters/tasks/main.yml6
3 files changed, 17 insertions, 3 deletions
diff --git a/docs/docsite/rst/user_guide/playbooks_filters.rst b/docs/docsite/rst/user_guide/playbooks_filters.rst
index 6b55c0d48f..f7af25c143 100644
--- a/docs/docsite/rst/user_guide/playbooks_filters.rst
+++ b/docs/docsite/rst/user_guide/playbooks_filters.rst
@@ -378,6 +378,10 @@ To get a random MAC address from a string prefix starting with '52:54:00'::
Note that if anything is wrong with the prefix string, the filter will issue an error.
+As of Ansible version 2.9, it's also possible to initialize the random number generator from a seed. This way, you can create random-but-idempotent MAC addresses::
+
+ "{{ '52:54:00' | random_mac(seed=inventory_hostname) }}"
+
.. _random_filter:
Random Number Filter
diff --git a/lib/ansible/plugins/filter/core.py b/lib/ansible/plugins/filter/core.py
index 4ceb4a6c81..dc19b2649f 100644
--- a/lib/ansible/plugins/filter/core.py
+++ b/lib/ansible/plugins/filter/core.py
@@ -36,7 +36,7 @@ import yaml
import datetime
from functools import partial
-from random import Random, SystemRandom, shuffle, randint
+from random import Random, SystemRandom, shuffle
from jinja2.filters import environmentfilter, do_groupby as _do_groupby
@@ -533,7 +533,7 @@ def list_of_dict_key_value_elements_to_dict(mylist, key_name='key', value_name='
return dict((item[key_name], item[value_name]) for item in mylist)
-def random_mac(value):
+def random_mac(value, seed=None):
''' takes string prefix, and return it completed with random bytes
to get a complete 6 bytes MAC address '''
@@ -558,8 +558,12 @@ def random_mac(value):
if len(err):
raise AnsibleFilterError('Invalid value (%s) for random_mac: %s' % (value, err))
+ if seed is None:
+ r = SystemRandom()
+ else:
+ r = Random(seed)
# Generate random int between x1000000000 and xFFFFFFFFFF
- v = randint(68719476736, 1099511627775)
+ v = r.randint(68719476736, 1099511627775)
# Select first n chars to complement input prefix
remain = 2 * (6 - len(mac_items))
rnd = ('%x' % v)[:remain]
diff --git a/test/integration/targets/filters/tasks/main.yml b/test/integration/targets/filters/tasks/main.yml
index b5b59a7691..e6a37a2b1e 100644
--- a/test/integration/targets/filters/tasks/main.yml
+++ b/test/integration/targets/filters/tasks/main.yml
@@ -242,6 +242,12 @@
- "'00:00:00:00:00' | random_mac is match('^00:00:00:00:00:[a-f0-9][a-f0-9]$')"
- "'00:00:00' | random_mac != '00:00:00' | random_mac"
+- name: Verify random_mac filter with seed
+ assert:
+ that:
+ - "'00:00:00' | random_mac(seed='test') == '00:00:00' | random_mac(seed='test')"
+ - "'00:00:00' | random_mac(seed='test') != '00:00:00' | random_mac(seed='another_test')"
+
- name: Verify that union can be chained
vars:
unions: '{{ [1,2,3]|union([4,5])|union([6,7]) }}'