From d8118cdd8c47357c493dfe1b07ee83776a7d5853 Mon Sep 17 00:00:00 2001 From: Sergey Malyuk Date: Thu, 11 Dec 2025 10:27:01 +0300 Subject: [PATCH] add dnsmasq role --- .ansible-lint | 1 + roles/dnsmasq/.ansible-lint | 16 +++++++++ roles/dnsmasq/.gitignore | 2 ++ roles/dnsmasq/.yamllint | 8 +++++ roles/dnsmasq/README.md | 37 ++++++++++++++++++++ roles/dnsmasq/conda.dev.yml | 11 ++++++ roles/dnsmasq/conda.prod.yml | 9 +++++ roles/dnsmasq/defaults/main.yml | 3 ++ roles/dnsmasq/handlers/main.yml | 7 ++++ roles/dnsmasq/meta/main.yml | 17 +++++++++ roles/dnsmasq/molecule/default/converge.yml | 21 ++++++++++++ roles/dnsmasq/molecule/default/molecule.yml | 27 +++++++++++++++ roles/dnsmasq/molecule/default/verify.yml | 19 +++++++++++ roles/dnsmasq/renovate.json | 6 ++++ roles/dnsmasq/requirements.ci.txt | 6 ++++ roles/dnsmasq/requirements.txt | 1 + roles/dnsmasq/requirements.yml | 5 +++ roles/dnsmasq/tasks/main.yml | 38 +++++++++++++++++++++ roles/dnsmasq/vars/main.yml | 1 + 19 files changed, 235 insertions(+) create mode 100644 roles/dnsmasq/.ansible-lint create mode 100644 roles/dnsmasq/.gitignore create mode 100644 roles/dnsmasq/.yamllint create mode 100644 roles/dnsmasq/README.md create mode 100644 roles/dnsmasq/conda.dev.yml create mode 100644 roles/dnsmasq/conda.prod.yml create mode 100644 roles/dnsmasq/defaults/main.yml create mode 100644 roles/dnsmasq/handlers/main.yml create mode 100644 roles/dnsmasq/meta/main.yml create mode 100644 roles/dnsmasq/molecule/default/converge.yml create mode 100644 roles/dnsmasq/molecule/default/molecule.yml create mode 100644 roles/dnsmasq/molecule/default/verify.yml create mode 100644 roles/dnsmasq/renovate.json create mode 100644 roles/dnsmasq/requirements.ci.txt create mode 100644 roles/dnsmasq/requirements.txt create mode 100644 roles/dnsmasq/requirements.yml create mode 100644 roles/dnsmasq/tasks/main.yml create mode 100644 roles/dnsmasq/vars/main.yml diff --git a/.ansible-lint b/.ansible-lint index 43cae14..38f5606 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -7,3 +7,4 @@ loop_var_prefix: "^(__|{role}_)" exclude_paths: - .github/ + - .ansible/ diff --git a/roles/dnsmasq/.ansible-lint b/roles/dnsmasq/.ansible-lint new file mode 100644 index 0000000..f865478 --- /dev/null +++ b/roles/dnsmasq/.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/dnsmasq/.gitignore b/roles/dnsmasq/.gitignore new file mode 100644 index 0000000..8cd0df3 --- /dev/null +++ b/roles/dnsmasq/.gitignore @@ -0,0 +1,2 @@ +.vscode +.idea \ No newline at end of file diff --git a/roles/dnsmasq/.yamllint b/roles/dnsmasq/.yamllint new file mode 100644 index 0000000..611db54 --- /dev/null +++ b/roles/dnsmasq/.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/dnsmasq/README.md b/roles/dnsmasq/README.md new file mode 100644 index 0000000..2e1d6b4 --- /dev/null +++ b/roles/dnsmasq/README.md @@ -0,0 +1,37 @@ +ansible-dnsmasq +========= + +Deploy dnsmasq on the target node. For now, supports only DNS functionality (DHCP and TFTP are not configuratble). + +Requirements +------------ + +Take care to open the port you choose for dnsmasq to serve queries on. This role does not handle firewall configuration. + +Role Variables +-------------- + +None + +Dependencies +------------ + +None + +Example Playbook +---------------- + +```yaml +roles: + - role: genlab.dnsmasq +``` + +License +------- + +BSD + +Author Information +------------------ + +corvus-migratorius@proton.me diff --git a/roles/dnsmasq/conda.dev.yml b/roles/dnsmasq/conda.dev.yml new file mode 100644 index 0000000..d8f50de --- /dev/null +++ b/roles/dnsmasq/conda.dev.yml @@ -0,0 +1,11 @@ +--- +name: ansible-dnsmasq +channels: + - conda-forge +dependencies: + - python~=3.12.0 + - pip>=24.2 + - actionlint + - pip: + - -r requirements.txt + - -r requirements.ci.txt diff --git a/roles/dnsmasq/conda.prod.yml b/roles/dnsmasq/conda.prod.yml new file mode 100644 index 0000000..51dcb83 --- /dev/null +++ b/roles/dnsmasq/conda.prod.yml @@ -0,0 +1,9 @@ +--- +name: ansible-dnsmasq +channels: + - conda-forge +dependencies: + - python~=3.12.0 + - pip>=24.2 + - pip: + - -r requirements.txt diff --git a/roles/dnsmasq/defaults/main.yml b/roles/dnsmasq/defaults/main.yml new file mode 100644 index 0000000..0788c90 --- /dev/null +++ b/roles/dnsmasq/defaults/main.yml @@ -0,0 +1,3 @@ +--- +cache_size: 100 +dns_port: 5300 diff --git a/roles/dnsmasq/handlers/main.yml b/roles/dnsmasq/handlers/main.yml new file mode 100644 index 0000000..c30be1c --- /dev/null +++ b/roles/dnsmasq/handlers/main.yml @@ -0,0 +1,7 @@ +--- +- name: "Restart dnsmasq" + ansible.builtin.systemd_service: + name: dnsmasq + state: restarted + daemon_reload: true + enabled: true diff --git a/roles/dnsmasq/meta/main.yml b/roles/dnsmasq/meta/main.yml new file mode 100644 index 0000000..414d68d --- /dev/null +++ b/roles/dnsmasq/meta/main.yml @@ -0,0 +1,17 @@ +--- +galaxy_info: + role_name: dnsmasq + namespace: genlab + author: "Alexander Gorelyshev" + company: "Genlab, LLC" + description: "" + license: "MIT" + min_ansible_version: "2.1" + + platforms: + - name: "Ubuntu" + versions: [ "focal", "jammy" ] + + galaxy_tags: [ ] + +dependencies: [] diff --git a/roles/dnsmasq/molecule/default/converge.yml b/roles/dnsmasq/molecule/default/converge.yml new file mode 100644 index 0000000..f41738d --- /dev/null +++ b/roles/dnsmasq/molecule/default/converge.yml @@ -0,0 +1,21 @@ +--- +- name: Converge + hosts: all + roles: + - role: genlab.ufw + disable_ipv6: true + rules: + - rule: allow + # proto: udp + port: 5300 + interface: lo + direction: in + comment: "Allow dnsmasq to serve DNS queries on the given interface" + + - role: genlab.dnsmasq + iface: lo + domain: adm.local + dns_port: 5300 + nodes: + - name: hub + ip: 127.0.0.1 diff --git a/roles/dnsmasq/molecule/default/molecule.yml b/roles/dnsmasq/molecule/default/molecule.yml new file mode 100644 index 0000000..fd2f06d --- /dev/null +++ b/roles/dnsmasq/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/dnsmasq/molecule/default/verify.yml b/roles/dnsmasq/molecule/default/verify.yml new file mode 100644 index 0000000..3a4ca5f --- /dev/null +++ b/roles/dnsmasq/molecule/default/verify.yml @@ -0,0 +1,19 @@ +--- +- name: Verify + hosts: all + gather_facts: false + any_errors_fatal: true + + pre_tasks: + - name: "Install a package providing the `dig` tool" + ansible.builtin.apt: + name: dnsutils + state: present + + tasks: + - name: "Test the output of the `dig` command" + changed_when: false + register: dig + failed_when: 'dig.stdout != "127.0.0.1"' + ansible.builtin.command: + cmd: "dig @127.0.0.1 -p 5353 hub.adm.vpn +short" diff --git a/roles/dnsmasq/renovate.json b/roles/dnsmasq/renovate.json new file mode 100644 index 0000000..5db72dd --- /dev/null +++ b/roles/dnsmasq/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ] +} diff --git a/roles/dnsmasq/requirements.ci.txt b/roles/dnsmasq/requirements.ci.txt new file mode 100644 index 0000000..f99c76a --- /dev/null +++ b/roles/dnsmasq/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/dnsmasq/requirements.txt b/roles/dnsmasq/requirements.txt new file mode 100644 index 0000000..cd252b9 --- /dev/null +++ b/roles/dnsmasq/requirements.txt @@ -0,0 +1 @@ +ansible~=11.1.0 diff --git a/roles/dnsmasq/requirements.yml b/roles/dnsmasq/requirements.yml new file mode 100644 index 0000000..cf52e39 --- /dev/null +++ b/roles/dnsmasq/requirements.yml @@ -0,0 +1,5 @@ +# requirements file +--- +roles: + - name: genlab.ufw + src: https://github.com/corvus-migratorius/ansible-ufw.git diff --git a/roles/dnsmasq/tasks/main.yml b/roles/dnsmasq/tasks/main.yml new file mode 100644 index 0000000..6f7d0ec --- /dev/null +++ b/roles/dnsmasq/tasks/main.yml @@ -0,0 +1,38 @@ +--- +- name: "Install dnsmasq" + ansible.builtin.apt: + name: dnsmasq + state: present + update_cache: true + + +- name: "Create interface-specific configuration file" + notify: "Restart dnsmasq" + ansible.builtin.blockinfile: + path: /etc/dnsmasq.d/{{ domain }}.conf + create: true + owner: root + group: root + mode: "0660" + block: | + interface="{{ iface }}" + port="{{ dns_port }}" + cache-size="{{ cache_size }}" + log-queries + server=1.1.1.1 # Cloudflare DNS + server=8.8.8.8 # Google DNS + server=8.8.4.4 # Google DNS (secondary) + + +- name: "Add nodes to the configuration file" + notify: "Restart dnsmasq" + loop: "{{ nodes }}" + ansible.builtin.blockinfile: + path: /etc/dnsmasq.d/{{ domain }}.conf + marker: "# {mark} ANSIBLE MANAGED: {{ item.name }}.{{ domain }}" + block: | + address=/{{ item.name }}.{{ domain }}/{{ item.ip }} + + +- name: "Flush handlers" + ansible.builtin.meta: flush_handlers diff --git a/roles/dnsmasq/vars/main.yml b/roles/dnsmasq/vars/main.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/roles/dnsmasq/vars/main.yml @@ -0,0 +1 @@ +---