From db55cb16eb86004c170e2c4fa784ad4410ac2b22 Mon Sep 17 00:00:00 2001 From: Sergey Malyuk Date: Fri, 12 Dec 2025 14:17:20 +0300 Subject: [PATCH 1/2] fix linter errors --- roles/wg_spoke/.ansible-lint | 16 +++++++ roles/wg_spoke/.gitignore | 2 + roles/wg_spoke/.yamllint | 8 ++++ roles/wg_spoke/README.md | 46 ++++++++++++++++++++ roles/wg_spoke/conda.dev.yml | 11 +++++ roles/wg_spoke/conda.prod.yml | 9 ++++ roles/wg_spoke/defaults/main.yml | 3 ++ roles/wg_spoke/handlers/main.yml | 7 +++ roles/wg_spoke/meta/main.yml | 17 ++++++++ roles/wg_spoke/molecule/default/converge.yml | 20 +++++++++ roles/wg_spoke/molecule/default/molecule.yml | 27 ++++++++++++ roles/wg_spoke/molecule/default/verify.yml | 13 ++++++ roles/wg_spoke/renovate.json | 6 +++ roles/wg_spoke/requirements.ci.txt | 6 +++ roles/wg_spoke/requirements.txt | 1 + roles/wg_spoke/requirements.yml | 3 ++ roles/wg_spoke/tasks/deploy.yml | 41 +++++++++++++++++ roles/wg_spoke/tasks/logging.yml | 11 +++++ roles/wg_spoke/tasks/main.yml | 9 ++++ roles/wg_spoke/vars/main.yml | 1 + 20 files changed, 257 insertions(+) create mode 100644 roles/wg_spoke/.ansible-lint create mode 100644 roles/wg_spoke/.gitignore create mode 100644 roles/wg_spoke/.yamllint create mode 100644 roles/wg_spoke/README.md create mode 100644 roles/wg_spoke/conda.dev.yml create mode 100644 roles/wg_spoke/conda.prod.yml create mode 100644 roles/wg_spoke/defaults/main.yml create mode 100644 roles/wg_spoke/handlers/main.yml create mode 100644 roles/wg_spoke/meta/main.yml create mode 100644 roles/wg_spoke/molecule/default/converge.yml create mode 100644 roles/wg_spoke/molecule/default/molecule.yml create mode 100644 roles/wg_spoke/molecule/default/verify.yml create mode 100644 roles/wg_spoke/renovate.json create mode 100644 roles/wg_spoke/requirements.ci.txt create mode 100644 roles/wg_spoke/requirements.txt create mode 100644 roles/wg_spoke/requirements.yml create mode 100644 roles/wg_spoke/tasks/deploy.yml create mode 100644 roles/wg_spoke/tasks/logging.yml create mode 100644 roles/wg_spoke/tasks/main.yml create mode 100644 roles/wg_spoke/vars/main.yml diff --git a/roles/wg_spoke/.ansible-lint b/roles/wg_spoke/.ansible-lint new file mode 100644 index 0000000..f865478 --- /dev/null +++ b/roles/wg_spoke/.ansible-lint @@ -0,0 +1,16 @@ +--- +profile: production +strict: true + +# Enable checking of loop variable prefixes in roles +loop_var_prefix: "^(__|{role}_)" + +skip_list: + - var-naming[no-role-prefix] + +warn_list: + - role-name[path] + - var-naming[no-role-prefix] + +exclude_paths: + - .github/ diff --git a/roles/wg_spoke/.gitignore b/roles/wg_spoke/.gitignore new file mode 100644 index 0000000..8cd0df3 --- /dev/null +++ b/roles/wg_spoke/.gitignore @@ -0,0 +1,2 @@ +.vscode +.idea \ No newline at end of file diff --git a/roles/wg_spoke/.yamllint b/roles/wg_spoke/.yamllint new file mode 100644 index 0000000..611db54 --- /dev/null +++ b/roles/wg_spoke/.yamllint @@ -0,0 +1,8 @@ +--- +rules: + brackets: + forbid: false + min-spaces-inside: 0 + max-spaces-inside: 2 + min-spaces-inside-empty: -1 + max-spaces-inside-empty: 2 diff --git a/roles/wg_spoke/README.md b/roles/wg_spoke/README.md new file mode 100644 index 0000000..c0ba380 --- /dev/null +++ b/roles/wg_spoke/README.md @@ -0,0 +1,46 @@ +wg_spoke +========= + +Configure the host as a Spoke in Wireguard Spoke&Hub topology. + +Requirements +------------ + +Ubuntu 20.04, 22.04 or 24.04. + +Role Variables +-------------- + +```yaml +iface_name: name of the Wireguard interface (network), config file is named after it; WARNING, dashes are not supported +spoke_ipv4_vpn: IPv4 address that this Spoke should expect on the VPN +subnet: something like "10.0.0.0" +netmask: CIDR-style netmask without a slash, e.g. "24" +spoke_pkey: Spoke private key (Wireguard-generated, base64) +hub_pubkey: Hub public key (Wireguard-generated, base64) +hub_ipv4_wan: WAN (Internet) IPv4 address of the Hub +hub_ipv4_vpn: IPv4 address of the Hub on the VPN +hub_port: Hub should be listening on this port +wg_spoke_hide_secrets: whether or not prevent Ansible from logging tasks that handle sensitive info like keys (default is `true`) +wg_spoke_logging: whether or not to send Wireguard dyndbg logs to the kernel buffer accesible via journalctl -ek (default is `true`) +``` + +Dependencies +------------ + +None + +Example Playbook +---------------- + +See `molecule/default/converge.yml`. + +License +------- + +BSD + +Author Information +------------------ + +corvus-migratorius@proton.me diff --git a/roles/wg_spoke/conda.dev.yml b/roles/wg_spoke/conda.dev.yml new file mode 100644 index 0000000..93ca437 --- /dev/null +++ b/roles/wg_spoke/conda.dev.yml @@ -0,0 +1,11 @@ +--- +name: ansible-wg-spoke +channels: + - conda-forge +dependencies: + - python~=3.12.0 + - pip>=24.2 + - actionlint + - pip: + - -r requirements.txt + - -r requirements.ci.txt diff --git a/roles/wg_spoke/conda.prod.yml b/roles/wg_spoke/conda.prod.yml new file mode 100644 index 0000000..239f515 --- /dev/null +++ b/roles/wg_spoke/conda.prod.yml @@ -0,0 +1,9 @@ +--- +name: ansible-wg-spoke +channels: + - conda-forge +dependencies: + - python~=3.12.0 + - pip>=24.2 + - pip: + - -r requirements.txt diff --git a/roles/wg_spoke/defaults/main.yml b/roles/wg_spoke/defaults/main.yml new file mode 100644 index 0000000..3cb9c8b --- /dev/null +++ b/roles/wg_spoke/defaults/main.yml @@ -0,0 +1,3 @@ +--- +wg_spoke_hide_secrets: true +wg_spoke_logging: true diff --git a/roles/wg_spoke/handlers/main.yml b/roles/wg_spoke/handlers/main.yml new file mode 100644 index 0000000..7372f6c --- /dev/null +++ b/roles/wg_spoke/handlers/main.yml @@ -0,0 +1,7 @@ +--- +- name: "Run the Wireguard service" + ansible.builtin.systemd_service: + name: wg-quick@{{ iface_name }} + state: restarted + enabled: true + daemon_reload: true diff --git a/roles/wg_spoke/meta/main.yml b/roles/wg_spoke/meta/main.yml new file mode 100644 index 0000000..396d62a --- /dev/null +++ b/roles/wg_spoke/meta/main.yml @@ -0,0 +1,17 @@ +--- +galaxy_info: + role_name: "wg_spoke" + namespace: genlab + author: "Alexander Gorelyshev" + company: "Genlab, LLC" + description: "" + license: "MIT" + min_ansible_version: "2.1" + + platforms: + - name: "Ubuntu" + versions: ["focal", "jammy", "noble"] + + galaxy_tags: [] + +dependencies: [] diff --git a/roles/wg_spoke/molecule/default/converge.yml b/roles/wg_spoke/molecule/default/converge.yml new file mode 100644 index 0000000..cc5f583 --- /dev/null +++ b/roles/wg_spoke/molecule/default/converge.yml @@ -0,0 +1,20 @@ +--- +- name: Converge + hosts: all + roles: + - role: genlab.common.wg_spoke + iface_name: adm + subnet: "10.0.0.0" + netmask: "24" + spoke_ipv4_vpn: "10.0.0.1" + spoke_port: "51820" + spoke_pkey: eGqGx4A5ufFKatLflPFKNuzFgGuospIe08iPbTlEhm0= + hub_pubkey: EvcoZ21/p0AHz5y95jwjVIR9puljc2kXqh/f3U1A4nk= + # hub_psk: 5qmMuLuGQT7w8VnHPsZDO4vRF5wEKcpEtaCQW1BLmbg= + hub_ipv4_wan: "1.2.3.4" + hub_ipv4_vpn: "10.0.0.254" + hub_port: "51820" + dns_server: "10.0.0.254:5300" + domain: "adm.local" + wg_spoke_hide_secrets: false + wg_spoke_logging: false # doesn't work in Github Actions environment diff --git a/roles/wg_spoke/molecule/default/molecule.yml b/roles/wg_spoke/molecule/default/molecule.yml new file mode 100644 index 0000000..fd2f06d --- /dev/null +++ b/roles/wg_spoke/molecule/default/molecule.yml @@ -0,0 +1,27 @@ +--- +dependency: + name: galaxy + +driver: + name: docker + +platforms: + - name: ubuntu + image: geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2204}-ansible:latest + pre_build_image: true + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + +provisioner: + name: ansible + +verifier: + name: ansible + +lint: | + set -e + yamllint . + ansible-lint . diff --git a/roles/wg_spoke/molecule/default/verify.yml b/roles/wg_spoke/molecule/default/verify.yml new file mode 100644 index 0000000..38f93ff --- /dev/null +++ b/roles/wg_spoke/molecule/default/verify.yml @@ -0,0 +1,13 @@ +--- +- name: Verify + hosts: all + gather_facts: false + any_errors_fatal: true + vars: + iface_name: adm + + tasks: + - name: "Check that the Wireguard service is running" + ansible.builtin.service: + name: wg-quick@{{ iface_name }} + state: started diff --git a/roles/wg_spoke/renovate.json b/roles/wg_spoke/renovate.json new file mode 100644 index 0000000..5db72dd --- /dev/null +++ b/roles/wg_spoke/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ] +} diff --git a/roles/wg_spoke/requirements.ci.txt b/roles/wg_spoke/requirements.ci.txt new file mode 100644 index 0000000..f99c76a --- /dev/null +++ b/roles/wg_spoke/requirements.ci.txt @@ -0,0 +1,6 @@ +ansible-lint +molecule==24.12.0 +molecule-plugins[docker] +docker~=7.1.0 +requests==2.31.0 # pinned to the latest version not breaking Docker SDK +yamllint diff --git a/roles/wg_spoke/requirements.txt b/roles/wg_spoke/requirements.txt new file mode 100644 index 0000000..cd252b9 --- /dev/null +++ b/roles/wg_spoke/requirements.txt @@ -0,0 +1 @@ +ansible~=11.1.0 diff --git a/roles/wg_spoke/requirements.yml b/roles/wg_spoke/requirements.yml new file mode 100644 index 0000000..3d5f1cd --- /dev/null +++ b/roles/wg_spoke/requirements.yml @@ -0,0 +1,3 @@ +# requirements file +--- +collections: [] diff --git a/roles/wg_spoke/tasks/deploy.yml b/roles/wg_spoke/tasks/deploy.yml new file mode 100644 index 0000000..faa60ad --- /dev/null +++ b/roles/wg_spoke/tasks/deploy.yml @@ -0,0 +1,41 @@ +--- +- name: "Install Wireguard system-wide" + ansible.builtin.apt: + name: wireguard + state: present + update_cache: true + cache_valid_time: 3600 + +- name: "Ensure no dashes in the interface name" + when: "'-' in iface_name" + ansible.builtin.fail: + msg: "The interface name must not contain dashes, got: '{{ iface_name }}'" + +- name: "Create a Spoke configuration file" + no_log: "{{ wg_spoke_hide_secrets }}" + notify: "Run the Wireguard service" + ansible.builtin.blockinfile: + path: "/etc/wireguard/{{ iface_name }}.conf" + create: true + owner: root + group: root + mode: "0600" + state: present + block: | + [Interface] # Local settings for this node + Address = {{ spoke_ipv4_vpn }}/32 + ListenPort = {{ spoke_port }} + PrivateKey = {{ spoke_pkey }} + + {% if dns_server is defined and domain is defined %} + PostUp = resolvectl dns %i {{ dns_server }}; resolvectl domain %i {{ domain }} + {% endif %} + + [Peer] # Settings for the Hub peer + PublicKey = {{ hub_pubkey }} + {% if spoke_psk is defined %} + PresharedKey = {{ spoke_psk }} + {% endif %} + AllowedIPs = {{ subnet }}/{{ netmask }} + Endpoint = {{ hub_ipv4_wan }}:{{ hub_port }} + PersistentKeepalive = 20 diff --git a/roles/wg_spoke/tasks/logging.yml b/roles/wg_spoke/tasks/logging.yml new file mode 100644 index 0000000..8989ae4 --- /dev/null +++ b/roles/wg_spoke/tasks/logging.yml @@ -0,0 +1,11 @@ +--- +# SRC https://www.procustodibus.com/blog/2021/03/wireguard-logs/ +- name: "Add wireguard module" + community.general.modprobe: + name: wireguard + state: present + +- name: "Turn on Wireguard dyndbg logging into kernel message buffer" + changed_when: false + ansible.builtin.shell: + cmd: echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control diff --git a/roles/wg_spoke/tasks/main.yml b/roles/wg_spoke/tasks/main.yml new file mode 100644 index 0000000..d25fec3 --- /dev/null +++ b/roles/wg_spoke/tasks/main.yml @@ -0,0 +1,9 @@ +--- +- name: "Include Wireguard deployment tasks" + ansible.builtin.include_tasks: + file: "tasks/deploy.yml" + +- name: "Include Wireguard logging configuration tasks" + when: wg_spoke_logging is true + ansible.builtin.include_tasks: + file: "tasks/logging.yml" diff --git a/roles/wg_spoke/vars/main.yml b/roles/wg_spoke/vars/main.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/roles/wg_spoke/vars/main.yml @@ -0,0 +1 @@ +--- From 4503751e8718393fe21fbd0ee566de776a455f3a Mon Sep 17 00:00:00 2001 From: Sergey Malyuk Date: Fri, 12 Dec 2025 14:18:07 +0300 Subject: [PATCH 2/2] remove garbage --- roles/wg_spoke/.ansible-lint | 16 ---------------- roles/wg_spoke/.gitignore | 2 -- roles/wg_spoke/.yamllint | 8 -------- roles/wg_spoke/conda.dev.yml | 11 ----------- roles/wg_spoke/conda.prod.yml | 9 --------- roles/wg_spoke/renovate.json | 6 ------ roles/wg_spoke/requirements.ci.txt | 6 ------ roles/wg_spoke/requirements.txt | 1 - roles/wg_spoke/requirements.yml | 3 --- 9 files changed, 62 deletions(-) delete mode 100644 roles/wg_spoke/.ansible-lint delete mode 100644 roles/wg_spoke/.gitignore delete mode 100644 roles/wg_spoke/.yamllint delete mode 100644 roles/wg_spoke/conda.dev.yml delete mode 100644 roles/wg_spoke/conda.prod.yml delete mode 100644 roles/wg_spoke/renovate.json delete mode 100644 roles/wg_spoke/requirements.ci.txt delete mode 100644 roles/wg_spoke/requirements.txt delete mode 100644 roles/wg_spoke/requirements.yml diff --git a/roles/wg_spoke/.ansible-lint b/roles/wg_spoke/.ansible-lint deleted file mode 100644 index f865478..0000000 --- a/roles/wg_spoke/.ansible-lint +++ /dev/null @@ -1,16 +0,0 @@ ---- -profile: production -strict: true - -# Enable checking of loop variable prefixes in roles -loop_var_prefix: "^(__|{role}_)" - -skip_list: - - var-naming[no-role-prefix] - -warn_list: - - role-name[path] - - var-naming[no-role-prefix] - -exclude_paths: - - .github/ diff --git a/roles/wg_spoke/.gitignore b/roles/wg_spoke/.gitignore deleted file mode 100644 index 8cd0df3..0000000 --- a/roles/wg_spoke/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.vscode -.idea \ No newline at end of file diff --git a/roles/wg_spoke/.yamllint b/roles/wg_spoke/.yamllint deleted file mode 100644 index 611db54..0000000 --- a/roles/wg_spoke/.yamllint +++ /dev/null @@ -1,8 +0,0 @@ ---- -rules: - brackets: - forbid: false - min-spaces-inside: 0 - max-spaces-inside: 2 - min-spaces-inside-empty: -1 - max-spaces-inside-empty: 2 diff --git a/roles/wg_spoke/conda.dev.yml b/roles/wg_spoke/conda.dev.yml deleted file mode 100644 index 93ca437..0000000 --- a/roles/wg_spoke/conda.dev.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: ansible-wg-spoke -channels: - - conda-forge -dependencies: - - python~=3.12.0 - - pip>=24.2 - - actionlint - - pip: - - -r requirements.txt - - -r requirements.ci.txt diff --git a/roles/wg_spoke/conda.prod.yml b/roles/wg_spoke/conda.prod.yml deleted file mode 100644 index 239f515..0000000 --- a/roles/wg_spoke/conda.prod.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -name: ansible-wg-spoke -channels: - - conda-forge -dependencies: - - python~=3.12.0 - - pip>=24.2 - - pip: - - -r requirements.txt diff --git a/roles/wg_spoke/renovate.json b/roles/wg_spoke/renovate.json deleted file mode 100644 index 5db72dd..0000000 --- a/roles/wg_spoke/renovate.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended" - ] -} diff --git a/roles/wg_spoke/requirements.ci.txt b/roles/wg_spoke/requirements.ci.txt deleted file mode 100644 index f99c76a..0000000 --- a/roles/wg_spoke/requirements.ci.txt +++ /dev/null @@ -1,6 +0,0 @@ -ansible-lint -molecule==24.12.0 -molecule-plugins[docker] -docker~=7.1.0 -requests==2.31.0 # pinned to the latest version not breaking Docker SDK -yamllint diff --git a/roles/wg_spoke/requirements.txt b/roles/wg_spoke/requirements.txt deleted file mode 100644 index cd252b9..0000000 --- a/roles/wg_spoke/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -ansible~=11.1.0 diff --git a/roles/wg_spoke/requirements.yml b/roles/wg_spoke/requirements.yml deleted file mode 100644 index 3d5f1cd..0000000 --- a/roles/wg_spoke/requirements.yml +++ /dev/null @@ -1,3 +0,0 @@ -# requirements file ---- -collections: []