From b53a4f4ae26e78d60a9e2f0e07267935d12f7c80 Mon Sep 17 00:00:00 2001 From: jcmdln Date: Fri, 22 Mar 2024 23:32:50 -0400 Subject: [PATCH] Bundle playbooks in collection --- .ansible-lint | 6 +- .editorconfig | 6 +- .github/workflows/galaxy.yml | 8 +- .github/workflows/lint.yml | 16 +- .gitignore | 44 +++--- .prettierrc.yml | 5 +- .vscode/extensions.json | 5 +- .vscode/settings.json | 62 +++++--- .yamllint | 21 +-- LICENSE | 2 +- README.md | 42 ++--- galaxy.yml | 2 +- inventory/localhost.yml | 9 +- meta/runtime.yml | 4 +- playbooks/mail.yml | 12 ++ site-pkg.yml => playbooks/pkg.yml | 7 +- site-check.yml => playbooks/python.yml | 16 +- site-syspatch.yml => playbooks/syspatch.yml | 9 +- .../sysupgrade.yml | 9 +- playbooks/update.yml | 12 ++ plugins/modules/pkg.py | 36 ++++- plugins/modules/syspatch.py | 30 +++- plugins/modules/sysupgrade.py | 143 +++++++++--------- pyproject.toml | 14 +- roles/mail/README.md | 2 +- roles/mail/defaults/main.yml | 2 +- roles/mail/handlers/main.yml | 2 +- roles/mail/tasks/main.yml | 20 +-- .../mail/templates/etc/dovecot/local.conf.j2 | 35 +---- roles/mail/templates/etc/mail/smtpd.conf.j2 | 6 +- site-mail.yml | 9 -- tox.ini | 11 +- 32 files changed, 316 insertions(+), 291 deletions(-) create mode 100644 playbooks/mail.yml rename site-pkg.yml => playbooks/pkg.yml (50%) rename site-check.yml => playbooks/python.yml (59%) rename site-syspatch.yml => playbooks/syspatch.yml (63%) rename site-sysupgrade.yml => playbooks/sysupgrade.yml (65%) create mode 100644 playbooks/update.yml delete mode 100644 site-mail.yml diff --git a/.ansible-lint b/.ansible-lint index e559d58..ebe5732 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -1,10 +1,12 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin --- exclude_paths: - - .github + - .github/ + - .vscode/ skip_list: + - meta-runtime[unsupported-version] - no-changed-when - no-handler - no-tabs diff --git a/.editorconfig b/.editorconfig index 0d49243..f2d5e9a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,6 +1,6 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin root = true @@ -21,7 +21,3 @@ tab_width = 2 [*.{ansible-,yaml}lint] indent_size = 2 tab_width = 2 - -[Vagrantfile] -indent_size = 2 -tab_width = 2 diff --git a/.github/workflows/galaxy.yml b/.github/workflows/galaxy.yml index b8ff536..65d81f3 100644 --- a/.github/workflows/galaxy.yml +++ b/.github/workflows/galaxy.yml @@ -1,13 +1,12 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin --- name: Release on: push: - tags: - - "*" + tags: ["*"] jobs: release: @@ -17,8 +16,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 - with: - python-version: "3.11" + with: { python-version: "3.11" } - name: Install Ansible run: pip install ansible-core diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index eed9fba..6c1b649 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,20 +1,16 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin --- name: lint on: pull_request: - branches: - - "**" - paths-ignore: - - "**.md" + branches: ["**"] + paths-ignore: ["**.md"] push: - branches: - - "**" - paths-ignore: - - "**.md" + branches: ["**"] + paths-ignore: ["**.md"] workflow_dispatch: jobs: @@ -27,7 +23,7 @@ jobs: matrix: linter: [ansible-lint, mypy, ruff] os: [ubuntu-latest] - python: ["3.9", "3.10", "3.11"] + python: ["3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v3 diff --git a/.gitignore b/.gitignore index cc48f6f..0c1747b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,49 +1,41 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin # Ignore everything * -# Include specific files -!.ansible-lint -!.editorconfig -!.gitignore -!.prettierrc.yml -!.yamllint -!CHANGELOG.md -!galaxy.yml -!LICENSE -!pyproject.toml -!README.md -!site-check.yml -!site-mail.yml -!site-pkg.yml -!site-syspatch.yml -!site-sysupgrade.yml -!tox.ini - -# Include files from subdirectories +# Include directories !.github/ !.github/workflows/ !.github/workflows/*.yml - !.vscode/ !.vscode/extensions.json !.vscode/settings.json - !inventory/ !inventory/localhost.yml - !meta/ !meta/runtime.yml - +!playbooks/ +!playbooks/*.yml !plugins/ !plugins/modules/ !plugins/modules/*.py - !roles/ !roles/**/ -!roles/**/*.j2 !roles/**/*.md !roles/**/*.yml +!roles/**/templates/**/*.j2 + +# Include files +!.ansible-lint +!.editorconfig +!.gitignore +!.prettierrc.yml +!.yamllint +!CHANGELOG.md +!galaxy.yml +!LICENSE +!pyproject.toml +!README.md +!tox.ini diff --git a/.prettierrc.yml b/.prettierrc.yml index 09fa552..ab35350 100644 --- a/.prettierrc.yml +++ b/.prettierrc.yml @@ -1,11 +1,10 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin --- options: editorconfig: true overrides: - files: "*.md" - options: - tabWidth: 2 + options: { tabWidth: 2 } diff --git a/.vscode/extensions.json b/.vscode/extensions.json index fd5f010..1933efb 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,18 +1,17 @@ // SPDX-License-Identifier: ISC // -// Copyright (c) 2023 Johnathan C. Maudlin +// Copyright (c) 2024 Johnathan C. Maudlin { "recommendations": [ "charliermarsh.ruff", "editorconfig.editorconfig", "esbenp.prettier-vscode", + "ms-python.mypy-type-checker", "ms-python.python", "ms-python.vscode-pylance", "redhat.ansible", "redhat.vscode-yaml", "samuelcolvin.jinjahtml", - "wayou.vscode-todo-highlight", - "github.vscode-github-actions", "tamasfe.even-better-toml" ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index c02c9b1..e8857e2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,15 +1,11 @@ // SPDX-License-Identifier: ISC // -// Copyright (c) 2023 Johnathan C. Maudlin +// Copyright (c) 2024 Johnathan C. Maudlin { "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, "editor.wordWrap": "on", - "evenBetterToml.formatter.columnWidth": 100, - "evenBetterToml.formatter.reorderKeys": true, - "evenBetterToml.schema.enabled": false, - "files.associations": { ".ansible-lint": "yaml", "**/.github/workflows/galaxy.yml": "yaml", @@ -19,6 +15,7 @@ "**/meta/**/*.yml": "ansible", "**/tasks/**/*.yml": "ansible", "**/vars/**/*.yml": "ansible", + "**/roles/*/templates/**/*.conf.j2": "jinja-properties", "galaxy.yml": "ansible", "site-*.yml": "ansible" }, @@ -26,28 +23,30 @@ "**/__pycache__/**": true, "**/.mypy_cache/**": true, "**/.ruff_cache/**": true, + "**/.pytest_cache/**": true, "**/.tox/**": true, - "**/.venv/**": true, - "**/*.egg-info/**": true + "**/.venv/**": true }, + "files.insertFinalNewline": true, + "files.trimFinalNewlines": true, + "files.trimTrailingWhitespace": true, - "[json]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" - }, - "[jsonc]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" - }, + // + // Extensions + // + + "ansible.python.interpreterPath": "/bin/python", - "python.formatting.provider": "black", - "python.linting.enabled": true, - "python.linting.mypyEnabled": true, + "evenBetterToml.formatter.columnWidth": 100, + "evenBetterToml.formatter.reorderKeys": true, + "evenBetterToml.schema.enabled": false, + + "python.testing.pytestArgs": ["test"], + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true, + + "ruff.enable": true, "ruff.organizeImports": true, - "[python]": { - "editor.codeActionsOnSave": { - "source.organizeImports": true - }, - "editor.defaultFormatter": "ms-python.python" - }, "yaml.schemas": { "https://raw.githubusercontent.com/ansible/schemas/main/f/ansible.json": [ @@ -59,5 +58,22 @@ "https://json.schemastore.org/github-workflow.json": [ "{workspaceFolder}/.github/workflows/*.yml" ] - } + }, + + // + // Languages + // + + "[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, + "[jsonc]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, + "[markdown]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, + + "[python]": { + "editor.codeActionsOnSave": { + "source.organizeImports": "explicit" + }, + "editor.defaultFormatter": "charliermarsh.ruff" + }, + + "[yaml]": { "editor.defaultFormatter": "esbenp.prettier-vscode" } } diff --git a/.yamllint b/.yamllint index 9979a06..222a0dd 100644 --- a/.yamllint +++ b/.yamllint @@ -1,27 +1,16 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin --- -ignore: | - .mypy_cache/ - .tox/ - .vagrant/ - .venv/ - .vscode/ - rules: - braces: - max-spaces-inside: 1 + braces: { max-spaces-inside: 1 } brackets: enable colons: enable commas: enable - comments: - level: warning - comments-indentation: - level: warning + comments: { level: warning } + comments-indentation: { level: warning } document-end: disable - document-start: - level: warning + document-start: { level: warning } empty-lines: enable empty-values: disable hyphens: enable diff --git a/LICENSE b/LICENSE index 3be6cb7..25f7ed9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ ISC License -Copyright (c) 2023 Johnathan C. Maudlin +Copyright (c) 2024 Johnathan C. Maudlin Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/README.md b/README.md index 1519ac9..266d5f6 100644 --- a/README.md +++ b/README.md @@ -7,43 +7,27 @@ If you are looking for a hosting provider that offers OpenBSD, consider using # Using -## Collection - ```sh +# Install the collection ansible-galaxy collection install git+https://github.com/jcmdln/ansible-collection-openbsd -``` - -Ansible allows running modules in an adhoc fashion for one-off tasks: -```sh +# Adhoc use of a module ansible -i all -m jcmdln.openbsd.pkg -a "name=htop state=present" -``` - -For more info, see the following: -- https://docs.ansible.com/ansible/latest/command_guide/intro_adhoc.html +# Use a provided playbook to ensure Python is installed +ansible-playbook -i jcmdln.openbsd.python -## Playbook - -```sh -# Install this collection and its dependencies -ansible-galaxy collection install . - -# Create a symlink to this collection so changes don't require reinstalling -rm -fr ~/.ansible/collections/ansible_collections/jcmdln/openbsd -ln -fs $PWD ~/.ansible/collections/ansible_collections/jcmdln/openbsd - -# Create an inventory -cp inventory/localhost.yml inventory/example.yml -vi inventory/example.yml - -# Run a playbook -ansible-playbook -i inventory/example.yml site-check.yml +# Chain playbooks to patch hosts and update packages +ansible-playbook -i jcmdln.openbsd.{syspatch,pkg} ``` -In this example we chain playbooks to patch/upgrade hosts and update packages: +# Developing + +To avoid reinstalling the collection during each change, create a symbolic link +to your user's collections path instead of installing the collection: ```sh -ansible-playbook -i inventory/example.yml \ - site-check.yml site-syspatch.yml site-sysupgrade.yml site-pkg.yml +mkdir -pv $HOME/.ansible/collections/ansible_collections/jcmdln && +rm -frv $HOME/.ansible/collections/ansible_collections/jcmdln/openbsd && +ln -fs $PWD $HOME/.ansible/collections/ansible_collections/jcmdln/openbsd ``` diff --git a/galaxy.yml b/galaxy.yml index fb8bc42..f8198db 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,6 +1,6 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin --- namespace: jcmdln name: openbsd diff --git a/inventory/localhost.yml b/inventory/localhost.yml index 9d5008c..7ded1bb 100644 --- a/inventory/localhost.yml +++ b/inventory/localhost.yml @@ -1,14 +1,13 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin --- all: + hosts: + localhost: + ansible_connection: local vars: ansible_python_interpreter: "/usr/bin/env python3" mail: hosts: - openbsd: - mail_aliases_root: example - mail_dkim_selector: openbsd - mail_domain: openbsd.localhost diff --git a/meta/runtime.yml b/meta/runtime.yml index d6ec8cb..7b16324 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin --- -requires_ansible: ">=2.9.10" +requires_ansible: ">=2.11.0" diff --git a/playbooks/mail.yml b/playbooks/mail.yml new file mode 100644 index 0000000..e142001 --- /dev/null +++ b/playbooks/mail.yml @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: ISC +# +# Copyright (c) 2024 Johnathan C. Maudlin +--- +- name: Mail + hosts: "{{ target | default('mail') }}" + + any_errors_fatal: true + gather_facts: false + + roles: + - role: jcmdln.openbsd.mail diff --git a/site-pkg.yml b/playbooks/pkg.yml similarity index 50% rename from site-pkg.yml rename to playbooks/pkg.yml index bffdfd9..68b22ea 100644 --- a/site-pkg.yml +++ b/playbooks/pkg.yml @@ -1,9 +1,12 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin --- - name: Pkg - hosts: all + hosts: "{{ target | default('all') }}" + + any_errors_fatal: true + gather_facts: false tasks: - name: Update packages diff --git a/site-check.yml b/playbooks/python.yml similarity index 59% rename from site-check.yml rename to playbooks/python.yml index bc87eaa..349e9f0 100644 --- a/site-check.yml +++ b/playbooks/python.yml @@ -1,25 +1,21 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin --- -- name: Check +- name: Python + hosts: "{{ target | default('all') }}" + + any_errors_fatal: true gather_facts: false - hosts: all handlers: - name: Install Python ansible.builtin.raw: pkg_add python3 tasks: - - name: Confirm host is running OpenBSD - ansible.builtin.raw: uname - changed_when: false - failed_when: ("OpenBSD" not in uname.stdout) - register: uname - - name: Check if Python 3.x is present - ansible.builtin.raw: command -v python3 changed_when: not python_check or python_check.rc > 0 failed_when: false notify: Install Python register: python_check + ansible.builtin.raw: command -v python3 diff --git a/site-syspatch.yml b/playbooks/syspatch.yml similarity index 63% rename from site-syspatch.yml rename to playbooks/syspatch.yml index 99e7a7c..db36646 100644 --- a/site-syspatch.yml +++ b/playbooks/syspatch.yml @@ -1,9 +1,12 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin --- - name: Syspatch - hosts: all + hosts: "{{ target | default('all') }}" + + any_errors_fatal: true + gather_facts: false handlers: - name: Reboot @@ -12,6 +15,6 @@ tasks: - name: Apply all available patches + notify: Reboot jcmdln.openbsd.syspatch: apply: true - notify: Reboot diff --git a/site-sysupgrade.yml b/playbooks/sysupgrade.yml similarity index 65% rename from site-sysupgrade.yml rename to playbooks/sysupgrade.yml index 1b30788..4d71425 100644 --- a/site-sysupgrade.yml +++ b/playbooks/sysupgrade.yml @@ -1,9 +1,12 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin --- - name: Sysupgrade - hosts: all + hosts: "{{ target | default('all') }}" + + any_errors_fatal: true + gather_facts: false handlers: - name: Reboot @@ -12,6 +15,6 @@ tasks: - name: Upgrade to latest release or snapshot + notify: Reboot jcmdln.openbsd.sysupgrade: branch: auto - notify: Reboot diff --git a/playbooks/update.yml b/playbooks/update.yml new file mode 100644 index 0000000..58b7eca --- /dev/null +++ b/playbooks/update.yml @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: ISC +# +# Copyright (c) 2024 Johnathan C. Maudlin +--- +- name: Python + import_playbook: jcmdln.openbsd.python + +- name: Pkg + import_playbook: jcmdln.openbsd.pkg + +- name: Syspatch + import_playbook: jcmdln.openbsd.syspatch diff --git a/plugins/modules/pkg.py b/plugins/modules/pkg.py index e9c9b48..99072d4 100644 --- a/plugins/modules/pkg.py +++ b/plugins/modules/pkg.py @@ -2,12 +2,36 @@ # # Copyright (c) 2023 Johnathan C. Maudlin -from __future__ import annotations +from __future__ import absolute_import, annotations, division, print_function + +__metaclass__ = type import re from ansible.module_utils.basic import AnsibleModule +DOCUMENTATION = r""" +--- +module: pkg +short_description: Manage packages using pkg_* suite +version_added: "1.2.0" + +author: Johnathan Craig Maudlin (@jcmdln) +description: [] + +options: + delete_unused: + description: thing + force: + description: thing + name: + description: thing + replace_existing: + description: thing + state: + description: thing +""" + class Pkg: def __init__(self, module: AnsibleModule) -> None: @@ -69,7 +93,7 @@ def add(self) -> None: self.command = f"{self.command} -D {self.force}".format() for pkg in self.packages: - package = self.packages[pkg]["name"] + package: str = self.packages[pkg]["name"] if pkg in pkgs or package in pkgs: to_update[package] = None pkgs = list(set(pkgs) - {pkg} - {package}) @@ -140,7 +164,7 @@ def delete(self) -> None: return for pkg in self.packages: - package = self.packages[pkg]["name"] + package: str = self.packages[pkg]["name"] if pkg in self.name: to_delete[pkg] = None elif package in self.name: @@ -151,8 +175,8 @@ def delete(self) -> None: self.msg = "no action performed" return - for package in to_delete: - self.command = f"{self.command} {package}" + for pkg in to_delete: + self.command = f"{self.command} {pkg}" self.rc, self.stdout, self.stderr = self.module.run_command(self.command, check_rc=False) @@ -178,7 +202,7 @@ def info(self) -> None: name = re.sub(r"-[0-9].*$", "", pkg) _version = re.search(r"-([\d.]+.*$)", pkg) if _version: - version = _version.group(1) + version: str = _version.group(1) self.packages[pkg] = {"name": name, "version": f"{version}"} diff --git a/plugins/modules/syspatch.py b/plugins/modules/syspatch.py index ce2e94b..7e155bf 100644 --- a/plugins/modules/syspatch.py +++ b/plugins/modules/syspatch.py @@ -1,11 +1,37 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin -from __future__ import annotations +from __future__ import absolute_import, annotations, division, print_function + +__metaclass__ = type from ansible.module_utils.basic import AnsibleModule +DOCUMENTATION = r""" +--- +module: syspatch +short_description: Apply patches using syspatch +version_added: "1.2.0" + +author: Johnathan Craig Maudlin (@jcmdln) +description: [] + +options: + apply: + description: + default: + list: + description: + default: + reboot: + description: + default: + revert: + description: + default: +""" + class Syspatch: def __init__(self, module: AnsibleModule) -> None: diff --git a/plugins/modules/sysupgrade.py b/plugins/modules/sysupgrade.py index b2da4d8..f550a50 100644 --- a/plugins/modules/sysupgrade.py +++ b/plugins/modules/sysupgrade.py @@ -1,60 +1,80 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin -from __future__ import annotations +from __future__ import absolute_import, annotations, division, print_function -from ansible.module_utils.basic import AnsibleModule - - -class Sysupgrade: - def __init__(self, module: AnsibleModule) -> None: - self.module: AnsibleModule = module - - # Return values - self.changed: bool = False - self.command: str = "/usr/sbin/sysupgrade -n" - self.msg: str = "" - self.rc: int = 0 - self.reboot: bool = False - self.stdout: str = "" - self.stderr: str = "" - - def update(self) -> None: - if self.module.params["branch"] == "release": - self.command = f"{self.command} -r" - elif self.module.params["branch"] == "snapshot": - self.command = f"{self.command} -s" - - if self.module.params["force"]: - self.command = f"{self.command} -f" - - self.rc, self.stdout, self.stderr = self.module.run_command(self.command, check_rc=False) +__metaclass__ = type - if not self.stdout and not self.stderr: - self.msg = "no actions performed" - return - - if "already on latest" in self.stdout.lower(): - self.msg = self.stdout.split("\n")[-1].strip(".").lower() - return - - if "404 not found" in self.stderr.lower(): - self.msg = "no newer {} available".format(self.module.params["branch"]) - self.rc = 0 - return - - if self.rc != 0 or "failed" in [ - self.stderr.lower(), - self.stdout.lower(), - ]: - self.msg = "failed to upgrade host" - self.rc = 1 if self.rc == 0 else self.rc - return +from ansible.module_utils.basic import AnsibleModule - self.changed = True - self.msg = "upgrade performed successfully" - self.reboot = True +DOCUMENTATION = r""" +--- +module: sysupgrade +short_description: Update to the next release or snapshot with sysupgrade +version_added: "1.2.0" + +author: Johnathan Craig Maudlin (@jcmdln) +description: [] + +options: + branch: + description: + default: + force: + description: + default: + keep: + description: + default: +""" + + +class Result: + changed: bool = False + command: str = "/usr/sbin/sysupgrade -n" + msg: str = "" + rc: int = 0 + reboot: bool = False + stdout: str = "" + stderr: str = "" + + +def sysupgrade(module: AnsibleModule) -> Result: + r: Result = Result() + + if module.params["branch"] == "release": + r.command = f"{r.command} -r" + elif module.params["branch"] == "snapshot": + r.command = f"{r.command} -s" + + if module.params["force"]: + r.command = f"{r.command} -f" + + r.rc, r.stdout, r.stderr = module.run_command(r.command, check_rc=False) + + if not r.stdout and not r.stderr: + r.msg = "no actions performed" + return r + if "already on latest" in r.stdout.lower(): + r.msg = r.stdout.split("\n")[-1].strip(".").lower() + return r + if "404 not found" in r.stderr.lower(): + r.msg = "no newer {} available".format(module.params["branch"]) + r.rc = 0 + return r + if r.rc != 0 or "failed" in [ + r.stderr.lower(), + r.stdout.lower(), + ]: + r.msg = "failed to upgrade host" + r.rc = 1 if r.rc == 0 else r.rc + return r + + r.changed = True + r.msg = "upgrade performed successfully" + r.reboot = True + return r def main() -> None: @@ -71,23 +91,10 @@ def main() -> None: supports_check_mode=False, ) - sysupgrade: Sysupgrade = Sysupgrade(module) - sysupgrade.update() - - result: dict[str, bool | int | str] = { - "changed": sysupgrade.changed, - "command": sysupgrade.command, - "msg": sysupgrade.msg, - "reboot": sysupgrade.reboot, - "rc": sysupgrade.rc, - "stdout": sysupgrade.stdout, - "stderr": sysupgrade.stderr, - } - - if sysupgrade.rc > 0: - module.fail_json(**result) - - module.exit_json(**result) + result: Result = sysupgrade(module) + if result.rc > 0: + module.fail_json(**result.__dict__) + module.exit_json(**result.__dict__) if __name__ == "__main__": diff --git a/pyproject.toml b/pyproject.toml index 5f7e6e1..7500282 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,12 +1,12 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin [tool.black] line-length = 100 [tool.mypy] -exclude = [".git/", ".github/", ".mypy_cache/", ".ruff_cache/", ".tox/", ".venv/", ".vscode/"] +mypy_path = ["plugins/modules/"] ignore_missing_imports = true show_error_context = true strict = true @@ -15,6 +15,14 @@ strict_optional = true disallow_any_generics = false [tool.ruff] +line-length = 100 +src = ["plugins/modules/"] + +[tool.ruff.format] +docstring-code-format = true +docstring-code-line-length = 80 + +[tool.ruff.lint] ignore = [ "D", # Ignore all documentation lints "ANN101", # Missing type annotation for `self` in method @@ -24,5 +32,3 @@ ignore = [ "PLR0912", # Too many branches "PLR2004", # Magic value used in comparison, consider replacing with a constant variable ] -line-length = 100 -select = ["ALL"] diff --git a/roles/mail/README.md b/roles/mail/README.md index e94d9b0..a4e8cbd 100644 --- a/roles/mail/README.md +++ b/roles/mail/README.md @@ -73,7 +73,7 @@ Consider enabling DNSSEC: ### Examples -```ruby +```perl # ~/Mail/dovecot.sieve require ["fileinto", "mailbox"]; diff --git a/roles/mail/defaults/main.yml b/roles/mail/defaults/main.yml index d01d992..53f1998 100644 --- a/roles/mail/defaults/main.yml +++ b/roles/mail/defaults/main.yml @@ -1,6 +1,6 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin --- mail_aliases_root: root mail_dkim_selector: domain diff --git a/roles/mail/handlers/main.yml b/roles/mail/handlers/main.yml index 08ce8a6..c3bcea8 100644 --- a/roles/mail/handlers/main.yml +++ b/roles/mail/handlers/main.yml @@ -1,6 +1,6 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin --- - name: Restart dovecot ansible.builtin.service: diff --git a/roles/mail/tasks/main.yml b/roles/mail/tasks/main.yml index 8f34eb7..485b0d9 100644 --- a/roles/mail/tasks/main.yml +++ b/roles/mail/tasks/main.yml @@ -1,6 +1,6 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin --- - name: Install required packages jcmdln.openbsd.pkg: @@ -53,7 +53,7 @@ - name: Generate RSA2048 dkim private key community.crypto.openssl_privatekey: - path: /etc/mail/dkim/{{ mail_dkim_selector }}.private.key + path: "/etc/mail/dkim/{{ mail_dkim_selector }}.private.key" size: 2048 type: RSA owner: _dkimsign @@ -62,8 +62,8 @@ - name: Generate RSA2048 dkim public key community.crypto.openssl_publickey: - path: /etc/mail/dkim/{{ mail_dkim_selector }}.public.key - privatekey_path: /etc/mail/dkim/{{ mail_dkim_selector }}.private.key + path: "/etc/mail/dkim/{{ mail_dkim_selector }}.public.key" + privatekey_path: "/etc/mail/dkim/{{ mail_dkim_selector }}.private.key" owner: _dkimsign group: _dkimsign mode: 0600 @@ -88,6 +88,7 @@ path: "/etc/login.conf" - name: Configure Dovecot + notify: Restart dovecot ansible.builtin.template: backup: true dest: /etc/dovecot/local.conf @@ -95,7 +96,6 @@ mode: 0644 owner: root src: etc/dovecot/local.conf.j2 - notify: Restart dovecot - name: Comment out ssl_cert from /etc/dovecot/conf.d/10-ssl.conf ansible.builtin.replace: @@ -124,6 +124,7 @@ name: smtpd - name: Configure smtpd + notify: Restart smtpd ansible.builtin.template: backup: true dest: /etc/mail/smtpd.conf @@ -131,18 +132,20 @@ mode: 0644 owner: root src: etc/mail/smtpd.conf.j2 - notify: Restart smtpd - name: Define well-known mail aliases for root@ + when: + - mail_aliases_root is defined + - mail_aliases_root != "root" ansible.builtin.blockinfile: block: | # Well-known aliases - root: {{ mail_aliases_root }} contact: root dumper: root info: root manager: root privacy: root + root: {{ mail_aliases_root }} # RFC 2142 abuse: root @@ -151,9 +154,6 @@ webmaster: root marker: "# {mark} ANSIBLE MANAGED BLOCK: jcmdln.openbsd.mail" path: "/etc/mail/aliases" - when: - - mail_aliases_root is defined - - mail_aliases_root != "root" - name: Start smtpd ansible.builtin.service: diff --git a/roles/mail/templates/etc/dovecot/local.conf.j2 b/roles/mail/templates/etc/dovecot/local.conf.j2 index 574b83d..32408d5 100644 --- a/roles/mail/templates/etc/dovecot/local.conf.j2 +++ b/roles/mail/templates/etc/dovecot/local.conf.j2 @@ -1,10 +1,6 @@ # {{ template_destpath }} # {{ ansible_managed }} -# -# Authentication -# - auth_username_format = %Ln hostname = {{ mail_domain }} lda_mailbox_autocreate = yes @@ -18,19 +14,6 @@ ssl_cert = ---- -- name: Mail - hosts: mail - - roles: - - role: jcmdln.openbsd.mail diff --git a/tox.ini b/tox.ini index ecdb3c2..78c1001 100644 --- a/tox.ini +++ b/tox.ini @@ -1,12 +1,9 @@ # SPDX-License-Identifier: ISC # -# Copyright (c) 2023 Johnathan C. Maudlin +# Copyright (c) 2024 Johnathan C. Maudlin [tox] -envlist = - mypy - ruff - ansible-lint +envlist = mypy,ruff,ansible-lint ignore_basepython_conflict = true isolated_build = true minversion = 3.20 @@ -34,6 +31,4 @@ deps = mypy commands = ruff --version ruff check --diff {toxinidir}/plugins/modules/ -deps = - black - ruff +deps = ruff