mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
add random_words lookup plugin, based on the xkcdpass module (#3588)
* add random_words lookup plugin, based on the xkcdpass module Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com> * add maintainer in BOTMETA Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com> * Update plugins/lookup/random_words.py Co-authored-by: Felix Fontein <felix@fontein.de> * Update plugins/lookup/random_words.py Co-authored-by: Felix Fontein <felix@fontein.de> * Update plugins/lookup/random_words.py Co-authored-by: Felix Fontein <felix@fontein.de> * Update plugins/lookup/random_words.py Co-authored-by: Felix Fontein <felix@fontein.de> * Update plugins/lookup/random_words.py Co-authored-by: Felix Fontein <felix@fontein.de> * Update tests/integration/targets/lookup_random_words/test.yml Co-authored-by: Felix Fontein <felix@fontein.de> * Update tests/integration/targets/lookup_random_words/test.yml Co-authored-by: Felix Fontein <felix@fontein.de> * ignore E402, place imports below documentation Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com> Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
parent
73acdaa489
commit
c40db6789a
6 changed files with 167 additions and 0 deletions
2
.github/BOTMETA.yml
vendored
2
.github/BOTMETA.yml
vendored
|
@ -217,6 +217,8 @@ files:
|
||||||
maintainers: Akasurde
|
maintainers: Akasurde
|
||||||
$lookups/random_string.py:
|
$lookups/random_string.py:
|
||||||
maintainers: Akasurde
|
maintainers: Akasurde
|
||||||
|
$lookups/random_words.py:
|
||||||
|
maintainers: konstruktoid
|
||||||
$lookups/redis.py:
|
$lookups/redis.py:
|
||||||
maintainers: $team_ansible_core jpmens
|
maintainers: $team_ansible_core jpmens
|
||||||
$lookups/shelvefile.py: {}
|
$lookups/shelvefile.py: {}
|
||||||
|
|
119
plugins/lookup/random_words.py
Normal file
119
plugins/lookup/random_words.py
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
"""The community.general.random_words Ansible lookup plugin."""
|
||||||
|
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
DOCUMENTATION = r"""
|
||||||
|
name: random_words
|
||||||
|
author:
|
||||||
|
- Thomas Sjögren (@konstruktoid)
|
||||||
|
short_description: Return a number of random words
|
||||||
|
version_added: "4.0.0"
|
||||||
|
requirements:
|
||||||
|
- xkcdpass U(https://github.com/redacted/XKCD-password-generator)
|
||||||
|
description:
|
||||||
|
- Returns a number of random words. The output can for example be used for
|
||||||
|
passwords.
|
||||||
|
- See U(https://xkcd.com/936/) for background.
|
||||||
|
options:
|
||||||
|
numwords:
|
||||||
|
description:
|
||||||
|
- The number of words.
|
||||||
|
default: 6
|
||||||
|
type: int
|
||||||
|
min_length:
|
||||||
|
description:
|
||||||
|
- Minimum length of words to make password.
|
||||||
|
default: 5
|
||||||
|
type: int
|
||||||
|
max_length:
|
||||||
|
description:
|
||||||
|
- Maximum length of words to make password.
|
||||||
|
default: 9
|
||||||
|
type: int
|
||||||
|
delimiter:
|
||||||
|
description:
|
||||||
|
- The delimiter character between words.
|
||||||
|
default: " "
|
||||||
|
type: str
|
||||||
|
case:
|
||||||
|
description:
|
||||||
|
- The method for setting the case of each word in the passphrase.
|
||||||
|
choices: ["alternating", "upper", "lower", "random", "capitalize"]
|
||||||
|
default: "lower"
|
||||||
|
type: str
|
||||||
|
"""
|
||||||
|
|
||||||
|
EXAMPLES = r"""
|
||||||
|
- name: Generate password with default settings
|
||||||
|
ansible.builtin.debug:
|
||||||
|
var: lookup('community.general.random_words')
|
||||||
|
# Example result: 'traitor gigabyte cesarean unless aspect clear'
|
||||||
|
|
||||||
|
- name: Generate password with six, five character, words
|
||||||
|
ansible.builtin.debug:
|
||||||
|
var: lookup('community.general.random_words', min_length=5, max_length=5)
|
||||||
|
# Example result: 'brink banjo getup staff trump comfy'
|
||||||
|
|
||||||
|
- name: Generate password with three capitalized words and the '-' delimiter
|
||||||
|
ansible.builtin.debug:
|
||||||
|
var: lookup('community.general.random_words', numwords=3, delimiter='-', case='capitalize')
|
||||||
|
# Example result: 'Overlabor-Faucet-Coastline'
|
||||||
|
|
||||||
|
- name: Generate password with three words without any delimiter
|
||||||
|
ansible.builtin.debug:
|
||||||
|
var: lookup('community.general.random_words', numwords=3, delimiter='')
|
||||||
|
# Example result: 'deskworkmonopolystriking'
|
||||||
|
# https://www.ncsc.gov.uk/blog-post/the-logic-behind-three-random-words
|
||||||
|
"""
|
||||||
|
|
||||||
|
RETURN = r"""
|
||||||
|
_raw:
|
||||||
|
description: A single-element list containing random words.
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
|
"""
|
||||||
|
|
||||||
|
from ansible.errors import AnsibleLookupError
|
||||||
|
from ansible.plugins.lookup import LookupBase
|
||||||
|
|
||||||
|
try:
|
||||||
|
from xkcdpass import xkcd_password as xp
|
||||||
|
|
||||||
|
HAS_XKCDPASS = True
|
||||||
|
except ImportError:
|
||||||
|
HAS_XKCDPASS = False
|
||||||
|
|
||||||
|
|
||||||
|
class LookupModule(LookupBase):
|
||||||
|
"""The random_words Ansible lookup class."""
|
||||||
|
|
||||||
|
def run(self, terms, variables=None, **kwargs):
|
||||||
|
|
||||||
|
if not HAS_XKCDPASS:
|
||||||
|
raise AnsibleLookupError(
|
||||||
|
"Python xkcdpass library is required. "
|
||||||
|
'Please install using "pip install xkcdpass"'
|
||||||
|
)
|
||||||
|
|
||||||
|
self.set_options(var_options=variables, direct=kwargs)
|
||||||
|
method = self.get_option("case")
|
||||||
|
delimiter = self.get_option("delimiter")
|
||||||
|
max_length = self.get_option("max_length")
|
||||||
|
min_length = self.get_option("min_length")
|
||||||
|
numwords = self.get_option("numwords")
|
||||||
|
|
||||||
|
words = xp.locate_wordfile()
|
||||||
|
wordlist = xp.generate_wordlist(
|
||||||
|
max_length=max_length, min_length=min_length, wordfile=words
|
||||||
|
)
|
||||||
|
|
||||||
|
values = xp.generate_xkcdpassword(
|
||||||
|
wordlist, case=method, delimiter=delimiter, numwords=numwords
|
||||||
|
)
|
||||||
|
|
||||||
|
return [values]
|
3
tests/integration/targets/lookup_random_words/aliases
Normal file
3
tests/integration/targets/lookup_random_words/aliases
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
shippable/posix/group2
|
||||||
|
skip/aix
|
||||||
|
skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
- hosts: localhost
|
||||||
|
tasks:
|
||||||
|
- name: Install xkcdpass Python package
|
||||||
|
pip:
|
||||||
|
name: xkcdpass
|
9
tests/integration/targets/lookup_random_words/runme.sh
Executable file
9
tests/integration/targets/lookup_random_words/runme.sh
Executable file
|
@ -0,0 +1,9 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
ANSIBLE_ROLES_PATH=../ \
|
||||||
|
ansible-playbook dependencies.yml -v "$@"
|
||||||
|
|
||||||
|
ANSIBLE_ROLES_PATH=../ \
|
||||||
|
ansible-playbook test.yml -v "$@"
|
28
tests/integration/targets/lookup_random_words/test.yml
Normal file
28
tests/integration/targets/lookup_random_words/test.yml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
---
|
||||||
|
- hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
tasks:
|
||||||
|
- name: Call random_words plugin
|
||||||
|
set_fact:
|
||||||
|
result1: "{{ query('community.general.random_words') }}"
|
||||||
|
result2: "{{ query('community.general.random_words', min_length=5, max_length=5) }}"
|
||||||
|
result3: "{{ query('community.general.random_words', delimiter='!') }}"
|
||||||
|
result4: "{{ query('community.general.random_words', numwords=3, delimiter='-', case='capitalize') }}"
|
||||||
|
result5: "{{ query('community.general.random_words', numwords=3, delimiter='') }}"
|
||||||
|
|
||||||
|
- name: Check results
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result1 | length == 1
|
||||||
|
- result1[0] | length >= 35
|
||||||
|
- result2 | length == 1
|
||||||
|
- result2[0] | length == 35
|
||||||
|
- result3 | length == 1
|
||||||
|
- result3[0].count("!") == 5
|
||||||
|
- result4 | length == 1
|
||||||
|
- result4[0] | length >= 17
|
||||||
|
- result4[0] | length <= 29
|
||||||
|
- result4[0] | regex_findall("[A-Z]") | length == 3
|
||||||
|
- result4[0].count("-") == 2
|
||||||
|
- result5 | length == 1
|
||||||
|
- result5[0] | length >= 18
|
Loading…
Reference in a new issue