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
|
||||
$lookups/random_string.py:
|
||||
maintainers: Akasurde
|
||||
$lookups/random_words.py:
|
||||
maintainers: konstruktoid
|
||||
$lookups/redis.py:
|
||||
maintainers: $team_ansible_core jpmens
|
||||
$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