random_string: Specify seed while generating random string (#10710)

* random_string: Specify seed while generating random string

* Allow user to specify seed to generate random string

Fixes: #5362

Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>

* Apply suggestions from code review

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
Abhijeet Kasurde 2025-08-27 13:00:44 -07:00 committed by GitHub
commit b5a2c5812c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 33 additions and 4 deletions

View file

@ -0,0 +1,3 @@
---
minor_changes:
- random_string lookup plugin - allow to specify seed while generating random string (https://github.com/ansible-collections/community.general/issues/5362, https://github.com/ansible-collections/community.general/pull/10710).

View file

@ -101,6 +101,14 @@ options:
- Returns base64 encoded string.
type: bool
default: false
seed:
description:
- Seed for random string generator.
- B(Note) that this drastically reduces the security of this plugin. First, when O(seed) is provided, a non-cryptographic random number generator is used.
Second, if the seed does not contain enough entropy, the generated string is weak.
B(Do not use the generated string as a password or a secure token when using this option!)
type: str
version_added: 11.3.0
"""
EXAMPLES = r"""
@ -109,6 +117,14 @@ EXAMPLES = r"""
var: lookup('community.general.random_string')
# Example result: 'DeadBeeF'
- name: Generate random string with seed
ansible.builtin.debug:
var: lookup('community.general.random_string', seed=12345)
# Example result: '6[~(2q5O'
# NOTE: Do **not** use this string as a password or a secure token,
# unless you know exactly what you are doing!
# Specifying seed uses a non-secure random number generator.
- name: Generate random string with length 12
ansible.builtin.debug:
var: lookup('community.general.random_string', length=12)
@ -182,7 +198,6 @@ class LookupModule(LookupBase):
lower_chars = string.ascii_lowercase
upper_chars = string.ascii_uppercase
special_chars = string.punctuation
random_generator = random.SystemRandom()
self.set_options(var_options=variables, direct=kwargs)
@ -191,6 +206,13 @@ class LookupModule(LookupBase):
override_all = self.get_option("override_all")
ignore_similar_chars = self.get_option("ignore_similar_chars")
similar_chars = self.get_option("similar_chars")
seed = self.get_option("seed")
if seed is None:
random_generator = random.SystemRandom()
else:
random_generator = random.Random(seed)
values = ""
available_chars_set = ""
@ -236,10 +258,11 @@ class LookupModule(LookupBase):
remaining_pass_len = length - len(values)
values += self.get_random(random_generator, available_chars_set, remaining_pass_len)
# Get pseudo randomization
shuffled_values = list(values)
# Randomize the order
random.shuffle(shuffled_values)
if seed is None:
# Get pseudo randomization
# Randomize the order
random.shuffle(shuffled_values)
if base64_flag:
return [self.b64encode("".join(shuffled_values))]

View file

@ -21,6 +21,8 @@
result11: "{{ query('community.general.random_string', base64=true, length=8) }}"
result12: "{{ query('community.general.random_string', upper=false, numbers=false, special=false) }}" # all lower case
result13: "{{ query('community.general.random_string', override_all='0', length=2) }}"
result14: "{{ query('community.general.random_string', seed='1234') }}"
result15: "{{ query('community.general.random_string', seed='1234') }}"
- name: Raise error when impossible constraints are provided
set_fact:
@ -51,3 +53,4 @@
- result13[0] == '00'
- impossible_result is failed
- "'Available characters cannot' in impossible_result.msg"
- result15[0] == result14[0]