Files
computer-playbook/plugins
kevinveenbirkenbachandClaude Opus 4.7 191bc1229a chore(ruff): enable S (bandit) rule family — 269 → 0
Adds ``S`` (flake8-bandit) to the strict ruleset. ``PTH`` was scoped
out: it surfaced 1000+ violations with no auto-fix support (most PTH
sub-rules are warning-only because each ``str`` ↔ ``Path`` conversion
is context-sensitive). Reserved for its own dedicated commit.

Config tuning
=============
Global ``ignore`` additions with rationale:
- ``S603`` (subprocess call without ``shell=False``) and ``S607`` (start
  process with partial path) are over-eager for a project whose CLI
  invokes ``make`` / ``git`` / ``docker`` / ``ansible-playbook`` from
  PATH using list-form args. The list-form already prevents shell
  injection (Python's ``subprocess`` does not parse argv[0] as a shell
  command), and resolving every binary's absolute path in the source
  would couple the code to the host filesystem layout. The genuinely
  dangerous shell-injection patterns (``shell=True``) are still caught
  by S602 / S605.

New ``[tool.ruff.lint.per-file-ignores]`` for ``tests/**``:
- ``S101``         — ``assert`` is the unittest idiom.
- ``S102``         — ``exec`` is used to load script-under-test by file path.
- ``S105`` / ``S106`` — hardcoded credentials in fixtures / dummy creds.
- ``S108``         — ``/tmp`` paths in tempdir fixtures.
- ``S110`` / ``S112`` — ``try``/``except``/``pass``/``continue`` in cleanup helpers.

Hand-fixes (38 across 23 files)
================================
S101 × 3
  Type-narrowing asserts (``cli/deploy/development/proc.py`` —
  ``p.stdout is not None`` after ``stdout=PIPE``) and an upstream-Odoo
  invariant assert in ``roles/web-app-odoo/.../res_users.py``.

S105 × 1
  ``cli/core/app.py`` argv parser comparing ``token == "--log"`` —
  ``token`` is a CLI argv element, not a credential. Inline noqa.

S106 × 1
  ``utils/cache/users.py`` Jinja template string ``"{{ 42 |
  strong_password }}"`` rendered to a real password at runtime; not a
  literal credential. Inline noqa.

S108 × 6
  Container-internal paths bind-mounted from the host:
  - ``/tmp/infinito/ca/root-ca.crt`` and ``/tmp/infinito/bin/with-ca-trust.sh``
    in ``roles/sys-svc-compose-ca/files/compose_ca.py`` and
    ``roles/sys-svc-container/files/container.py`` (CA-injection
    contract between role and wrapper).
  - ``/tmp/cache_nginx_general/`` and ``/tmp/cache_nginx_image/`` in
    ``plugins/lookup/nginx.py`` (well-known nginx cache dirs).

S110 × 1
  ``roles/web-app-bigbluebutton/filter_plugins/compose_mods.py``: filter
  intentionally swallows YAML parse errors and falls back to the
  unmodified text. Inline noqa.

S112 × 5
  Filter plugins / inventory builders iterating over role config files
  with skip-on-malformed semantics. The pattern is intentional
  throughout (CLI tools / Ansible plugins shouldn't crash on a single
  bad role file). Per-line noqa with rationale.

S324 × 2
  ``utils/cache/base.py`` uses md5 as a fast non-cryptographic
  fingerprint for cache keying; ``utils/manager/value_generator.py``
  uses sha1 when the caller selects ``algorithm == "sha1"`` for legacy
  app compatibility. Both gained ``usedforsecurity=False`` (Python 3.9+
  hashlib API) which silences the rule structurally; comments document
  the non-security purpose.

S310 × 8
  ``urlopen`` calls to fixed HTTPS registries (``api.github.com``,
  ``hub.docker.com``, ``ghcr.io``). URL prefix is a literal; only the
  ``namespace`` / ``image`` segment varies and comes from the project's
  own ``meta/services.yml``, never user input. No ``file://`` scheme
  exposure. Inline noqa per call site.

S602 / S605 / S606 × 8
  Role-deployed scripts that legitimately use ``shell=True`` /
  ``os.system`` for pipes/``&&``, or ``os.execvp`` in list-form (safe by
  construction — no shell parses argv). Each call site gained an inline
  noqa with a per-call rationale identifying where the command string
  is sourced (Ansible-templated config, host-trusted, never untrusted
  external input).

Verification
============
- ``ruff check .`` → All checks passed
- ``ruff format --check .`` → 894 files formatted
- 1621 unit tests → all pass
- Integration suite: 44 baseline failures (unchanged)

23 files changed, +97 / −38. Combined with the prior commits the
branch satisfies 21 ruff rule families end-to-end. ``PTH``
(modernise ``os.path`` to ``pathlib``) is the remaining big-impact
candidate, deferred to its own session.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:57:29 +02:00
..
…

🧩 Ansible Plugins (plugins/)

This document is the central reference for plugin types and plugin placement in Infinito.Nexus.

🗂️ Current Project Layout

plugins/
├── action/   # custom action plugins
├── filter/   # custom Jinja2 filters
└── lookup/   # custom lookup plugins

Configured plugin paths in this repository are defined in ansible.cfg:

  • action_plugins = ./plugins/action
  • filter_plugins = ./plugins/filter
  • lookup_plugins = ./plugins/lookup

📚 All Common Ansible Plugin Types

The table below summarizes common Ansible plugin types and their conventional directory names.

Emoji Plugin Type Conventional Directory Purpose
⚙️ action action_plugins/ or plugins/action/ Wrap/extend module execution behavior at task runtime.
🔐 become become_plugins/ Implement privilege escalation methods.
💾 cache cache_plugins/ Persist gathered facts and cached data between runs.
📣 callback callback_plugins/ React to play/task events (logging, reporting, notifications).
🖧 cliconf cliconf_plugins/ Define CLI command transport behavior (mainly network platforms).
🔌 connection connection_plugins/ Control how Ansible connects to targets (ssh, local, etc.).
🔍 filter filter_plugins/ or plugins/filter/ Add Jinja2 filters for data transformation.
🌐 httpapi httpapi_plugins/ API transport layer over HTTP(S), mainly for network devices.
🧭 inventory inventory_plugins/ Build dynamic inventories from APIs, services, or files.
👉 lookup lookup_plugins/ or plugins/lookup/ Resolve dynamic values during playbook processing.
🛰️ netconf netconf_plugins/ NETCONF transport integration for network automation.
🐚 shell shell_plugins/ Adjust shell command wrapping/execution behavior.
🧠 strategy strategy_plugins/ Customize task scheduling/execution strategy.
✅ test test_plugins/ Add Jinja2 tests used in conditions and templates.
📦 vars vars_plugins/ Load variables from custom sources.

🧭 Which Plugin Type to Use

⚙️ action

Use when task execution behavior itself must be changed or wrapped.

Examples:

  • centralized retry logic (uri_retry.py),
  • argument normalization before module dispatch,
  • pre/post task orchestration.

🔍 filter

Use for pure data transformation in Jinja2 expressions.

Examples:

  • mapping/normalizing dictionaries,
  • deriving computed fields for templates,
  • deterministic formatting helpers.

👉 lookup

Use when a value must be dynamically resolved at runtime.

Examples:

  • computing IDs from role metadata,
  • resolving paths/version data,
  • reading structured project data for templates/tasks.

📣 callback

Use to hook into execution events and shape output/reporting.

🧭 inventory

Use when host/group data should come from a dynamic source.

🧠 strategy

Use to alter how tasks are scheduled/executed across hosts.

📦 vars

Use to load variables from custom backends.

🔌🔐🐚 connection, become, shell

Use to customize low-level execution and privilege mechanics.

💾 cache

Use to persist facts/results across runs for performance and consistency.

🖧🌐🛰️ cliconf, httpapi, netconf

Use in network automation contexts requiring protocol-specific transport behavior.

✅ test

Use to add custom Jinja2 test operators for conditional logic.

🧪 Best Practices

  • Keep plugin interfaces explicit and stable.
  • Keep plugin logic focused; move shared logic to utils/.
  • Add unit tests for plugin behavior and integration tests for end-to-end flows.
  • Prefer deterministic outputs and avoid hidden global state.
  • Document any plugin-specific task arguments in the plugin docstring and README.

🔗 References