Vendor Galaxy Roles and Collections
This commit is contained in:
parent
c1e1897cda
commit
2aed20393f
3553 changed files with 387444 additions and 2 deletions
20
ansible_collections/debops/debops/roles/dnsmasq/COPYRIGHT
Normal file
20
ansible_collections/debops/debops/roles/dnsmasq/COPYRIGHT
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
debops.dnsmasq - Install and configure dnsmasq
|
||||
|
||||
Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
|
||||
Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
|
||||
Copyright (C) 2014-2019 DebOps <https://debops.org/>
|
||||
SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
This Ansible role is part of DebOps.
|
||||
|
||||
DebOps is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 3, as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
DebOps is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DebOps. If not, see https://www.gnu.org/licenses/.
|
||||
|
|
@ -0,0 +1,669 @@
|
|||
---
|
||||
# .. vim: foldmarker=[[[,]]]:foldmethod=marker
|
||||
|
||||
# .. Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
|
||||
# .. Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
|
||||
# .. Copyright (C) 2014-2019 DebOps <https://debops.org/>
|
||||
# .. SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
# .. _dnsmasq__ref_defaults:
|
||||
|
||||
# debops.dnsmasq default variables
|
||||
# ================================
|
||||
|
||||
# .. contents:: Sections
|
||||
# :local:
|
||||
#
|
||||
# .. include:: ../../../../includes/global.rst
|
||||
|
||||
|
||||
# APT packages [[[
|
||||
# ----------------
|
||||
|
||||
# .. envvar:: dnsmasq__base_packages [[[
|
||||
#
|
||||
# List of APT packages to install for :command:`dnsmasq` support.
|
||||
dnsmasq__base_packages: [ 'dnsmasq' ]
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__packages [[[
|
||||
#
|
||||
# List of additional APT packages to install during :command:`dnsmasq`
|
||||
# configuration.
|
||||
dnsmasq__packages: []
|
||||
# ]]]
|
||||
# ]]]
|
||||
# Global options [[[
|
||||
# ------------------
|
||||
|
||||
# .. envvar:: dnsmasq__dhcpv4 [[[
|
||||
#
|
||||
# Enable or disable DHCPv4 support.
|
||||
dnsmasq__dhcpv4: True
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__dhcpv6 [[[
|
||||
#
|
||||
# Enable or disable DHCPv6 support (router support is required).
|
||||
dnsmasq__dhcpv6: True
|
||||
# ]]]
|
||||
# ]]]
|
||||
# Configuration specific to network interfaces [[[
|
||||
# ------------------------------------------------
|
||||
|
||||
# These variables define :command:`dnsmasq` configuration related to
|
||||
# a particular network interface. See :ref:`dnsmasq__ref_interfaces` for more
|
||||
# details.
|
||||
|
||||
# .. envvar:: dnsmasq__default_interfaces [[[
|
||||
#
|
||||
# List of network interfaces for which :command:`dnsmasq` configuration will be
|
||||
# generated by default.
|
||||
dnsmasq__default_interfaces:
|
||||
|
||||
# Name of the interface.
|
||||
- name: 'br2'
|
||||
state: '{{ "present"
|
||||
if (hostvars[inventory_hostname]["ansible_br2"] is defined)
|
||||
else "absent" }}'
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__interfaces [[[
|
||||
#
|
||||
# List of network interfaces for which :command:`dnsmasq` configuration will be
|
||||
# generated, defined by the user.
|
||||
dnsmasq__interfaces: []
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__combined_interfaces [[[
|
||||
#
|
||||
# Combined list of network interfaces for which :command:`dnsmasq`
|
||||
# configuration will be generated, used in role tasks and templates.
|
||||
dnsmasq__combined_interfaces: '{{ dnsmasq__default_interfaces
|
||||
+ dnsmasq__interfaces }}'
|
||||
# ]]]
|
||||
# ]]]
|
||||
# DNS options [[[
|
||||
# ---------------
|
||||
|
||||
# .. envvar:: dnsmasq__hostname [[[
|
||||
#
|
||||
# The router hostname used by :command:`dnsmasq`. It will be used to configure
|
||||
# DNS A and AAAA records pointing to the :command:`dnsmasq` server.
|
||||
dnsmasq__hostname: '{{ ansible_hostname }}'
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__base_domain [[[
|
||||
#
|
||||
# The DNS domain which will be used as a base for interface-based subdomains if
|
||||
# none are explicitly configured.
|
||||
dnsmasq__base_domain: '{{ ansible_domain }}'
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__base_domain_rebind_ok [[[
|
||||
#
|
||||
# When ``True``, :command:`dnsmasq` will accept DNS records for the base DNS
|
||||
# domain that specify IP addresses in private address ranges. This is needed
|
||||
# when another DHCP/DNS server is managing the IP address leases, otherwise
|
||||
# they will be unresolvable.
|
||||
dnsmasq__base_domain_rebind_ok: True
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__etc_hosts [[[
|
||||
#
|
||||
# List of absolute paths of the additional :man:`hosts(5)` database files to
|
||||
# read by :command:`dnsmasq`. This is useful if you don't want to keep the host
|
||||
# list in the system-wide :file:`/etc/hosts` database.
|
||||
#
|
||||
# You can provide the files using the :ref:`debops.resources` Ansible role,
|
||||
# non-existent files will be silently ignored by :command:`dnsmasq`.
|
||||
dnsmasq__etc_hosts: []
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__nameservers [[[
|
||||
#
|
||||
# List of upstream DNS nameservers where dnsmasq should forward its DNS queries
|
||||
# which it can not answer by itself. If empty, system nameservers (for example
|
||||
# received via DHCP) will be used by default.
|
||||
dnsmasq__nameservers: []
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__public_dns [[[
|
||||
#
|
||||
# Enable or disable access to the local DNS from upstream networks using the
|
||||
# firewall. You can publish your subdomain in the public DNS by delegating it
|
||||
# in your zone configuration. Be wary of the DNS reflection and amplification
|
||||
# attacks!
|
||||
dnsmasq__public_dns: False
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__public_dns_allow [[[
|
||||
#
|
||||
# List of IP addresses or CIDR subnets which are allowed to connect to
|
||||
# :command:`dnsmasq` DNS service in public DNS mode. If the list is empty, any
|
||||
# hosts can connect. The configuration will be set in the firewall.
|
||||
dnsmasq__public_dns_allow: []
|
||||
# ]]]
|
||||
# ]]]
|
||||
# TFTP options [[[
|
||||
# ----------------
|
||||
|
||||
# .. envvar:: dnsmasq__boot_enabled [[[
|
||||
#
|
||||
# Enable or disable support for BOOTP/PXE boot of remote hosts.
|
||||
dnsmasq__boot_enabled: True
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__boot_ipxe_enabled [[[
|
||||
#
|
||||
# Enable or disable support for iPXE boot menu. The iPXE configuration can be
|
||||
# done using the :ref:`debops.ipxe` Ansible role.
|
||||
dnsmasq__boot_ipxe_enabled: True
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__boot_server [[[
|
||||
#
|
||||
# Specify the IP address of the "next server" which provides a TFTP service
|
||||
# with boot files. If not specified, :command:`dnsmasq` server will be
|
||||
# contacted by the clients instead for the boot files.
|
||||
dnsmasq__boot_server: ''
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__boot_tftp_root [[[
|
||||
#
|
||||
# Absolute path of the TFTP root directory from which boot files will be
|
||||
# served. This path needs to exist, otherwise :command:`dnsmasq` service will
|
||||
# refuse to start.
|
||||
dnsmasq__boot_tftp_root: '/srv/tftp'
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__boot_filename [[[
|
||||
#
|
||||
# Name of the file located in the TFTP root directory which will be sent to
|
||||
# clients telling them which file to download and boot from.
|
||||
dnsmasq__boot_filename: '{{ "menu.ipxe" if dnsmasq__boot_ipxe_enabled | bool else "pxelinux.0" }}'
|
||||
# ]]]
|
||||
# ]]]
|
||||
# DHCP hosts, DNS resource records [[[
|
||||
# ------------------------------------
|
||||
|
||||
# The variables below can be used to configure DHCP client entries as well as
|
||||
# DNS resource records published by :command:`dnsmasq`; syntax for both of
|
||||
# these variables is the same. See :ref:`dnsmasq__ref_dhcp_dns_entries` for
|
||||
# more details.
|
||||
|
||||
# .. envvar:: dnsmasq__dhcp_hosts [[[
|
||||
#
|
||||
# List of DHCP clients that :command:`dnsmasq` knows about.
|
||||
dnsmasq__dhcp_hosts: []
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__dns_records [[[
|
||||
#
|
||||
# List of DNS resource records that :command:`dnsmasq` publishes.
|
||||
dnsmasq__dns_records: []
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__dhcp_dns_filename [[[
|
||||
#
|
||||
# Name of the configuration file that contains DHCP and DNS entries, located in
|
||||
# the :file:`/etc/dnsmasq.d/` directory.
|
||||
dnsmasq__dhcp_dns_filename: 'host-resource-records.conf'
|
||||
# ]]]
|
||||
# ]]]
|
||||
# The dnsmasq configuration files [[[
|
||||
# -----------------------------------
|
||||
|
||||
# These variables define the contents of the :command:`dnsmasq` configuration
|
||||
# files located in the :file:`/etc/dnsmasq.d/` directory.
|
||||
# See :ref:`dnsmasq__ref_configuration` for more details.
|
||||
|
||||
# .. envvar:: dnsmasq__default_configuration [[[
|
||||
#
|
||||
# The configuration defined by the role by default.
|
||||
dnsmasq__default_configuration:
|
||||
|
||||
# Remove the old default configuration file
|
||||
- name: '00_main.conf'
|
||||
state: 'absent'
|
||||
|
||||
- name: 'global.conf'
|
||||
options:
|
||||
|
||||
- name: 'conntrack'
|
||||
comment: 'Enable connection tracking support for firewalls'
|
||||
raw: |
|
||||
conntrack
|
||||
state: 'present'
|
||||
|
||||
- name: 'enable-ra'
|
||||
comment: 'Enable support for IPv6 Router Advertisements using dnsmasq'
|
||||
raw: |
|
||||
enable-ra
|
||||
state: 'present'
|
||||
|
||||
- name: 'bind-interfaces'
|
||||
comment: |
|
||||
Bind only to the network interfaces explicitly set in the
|
||||
configuration. This is required to allow additional dnsmasq instances
|
||||
managed by, for example, libvirt.
|
||||
raw: |
|
||||
bind-dynamic
|
||||
state: 'present'
|
||||
|
||||
- name: 'loopback-interface'
|
||||
comment: 'Bind to loopback interface for local DNS queries'
|
||||
raw: |
|
||||
interface = lo
|
||||
no-dhcp-interface = lo
|
||||
state: 'present'
|
||||
|
||||
- name: 'addn-hosts'
|
||||
comment: 'Read hosts information from additional files or directories'
|
||||
value: '{{ dnsmasq__etc_hosts }}'
|
||||
state: '{{ "present" if dnsmasq__etc_hosts | d() else "absent" }}'
|
||||
|
||||
- name: 'consul.conf'
|
||||
comment: |
|
||||
Support for Consul Agent DNS service on localhost
|
||||
Ref: https://www.consul.io/docs/agent/dns.html
|
||||
raw: |
|
||||
server = /consul/127.0.0.1#8600
|
||||
state: '{{ "present"
|
||||
if (ansible_local.consul.installed | d() | bool)
|
||||
else "init" }}'
|
||||
|
||||
- name: 'lxd-override'
|
||||
filename: 'lxd'
|
||||
comment: |
|
||||
Tell any system-wide dnsmasq instance to make sure to bind to interfaces
|
||||
instead of listening on 0.0.0.0
|
||||
raw: |
|
||||
bind-dynamic
|
||||
except-interface = lxdbr0
|
||||
state: '{{ "present" if (ansible_distribution == "Ubuntu") else "ignore" }}'
|
||||
|
||||
- name: 'reserved-domains.conf'
|
||||
options:
|
||||
|
||||
- name: 'reserved-domains'
|
||||
comment: |
|
||||
Do not forward the reserved top level domains to upstream nameservers
|
||||
raw: |
|
||||
# Ref: https://tools.ietf.org/html/rfc2606
|
||||
local = /test/example/invalid/
|
||||
|
||||
# Ref: https://tools.ietf.org/html/rfc6762
|
||||
local = /local/
|
||||
|
||||
# Ref: https://tools.ietf.org/html/rfc7686
|
||||
local = /onion/
|
||||
state: 'present'
|
||||
|
||||
- name: 'private-domains'
|
||||
comment: |
|
||||
Do not forward the following private top level DNS names to upstream
|
||||
DNS servers because RFC 6762 recommends not to use unregistered
|
||||
top-level domains (https://tools.ietf.org/html/rfc6762#appendix-G)
|
||||
raw: |
|
||||
local = /intranet/internal/private/corp/home/lan/
|
||||
state: 'present'
|
||||
|
||||
- name: 'block-dns-over-https'
|
||||
comment: |
|
||||
Blocking the 'use-application-dns.net' domain instructs the applications
|
||||
that support DNS over HTTPS to not use it and rely on the system resolver
|
||||
instead. This might be required for certain applications to support
|
||||
access to internal services, resolve split-DNS correctly, etc.
|
||||
|
||||
Ref: https://support.mozilla.org/en-US/kb/canary-domain-use-application-dnsnet
|
||||
raw: |
|
||||
server = /use-application-dns.net/
|
||||
state: 'present'
|
||||
|
||||
- name: 'dns-global.conf'
|
||||
options:
|
||||
|
||||
- name: 'localise-queries'
|
||||
comment: |
|
||||
Return localized answers to DNS queries from '/etc/hosts' depending
|
||||
on the originating network interface
|
||||
raw: |
|
||||
localise-queries
|
||||
state: 'present'
|
||||
|
||||
- name: 'domain-needed'
|
||||
comment: |
|
||||
Never forward plain hostname queries for A or AAAA records to
|
||||
upstream servers
|
||||
raw: |
|
||||
domain-needed
|
||||
state: 'present'
|
||||
|
||||
- name: 'expand-hosts'
|
||||
comment: |
|
||||
Expand short hostnames found in the '/etc/hosts' file to full FQDN
|
||||
addresses
|
||||
raw: |
|
||||
expand-hosts
|
||||
state: 'present'
|
||||
|
||||
- name: 'stop-dns-rebind'
|
||||
comment: |
|
||||
Reject addresses from the upstream DNS nameservers which are located
|
||||
in the private IP address ranges
|
||||
raw: |
|
||||
stop-dns-rebind
|
||||
state: 'present'
|
||||
|
||||
- name: 'rebind-localhost-ok'
|
||||
comment: |
|
||||
Skip rebinding checks for '127.0.0.0/8' IP address range. This range
|
||||
is used by the realtime black hole (RBL) servers.
|
||||
raw: |
|
||||
rebind-localhost-ok
|
||||
state: 'present'
|
||||
|
||||
- name: 'rebind-local-domain-ok'
|
||||
comment: |
|
||||
Skip rebinding checks for local domain, in case dnsmasq is used as
|
||||
a DNS cache and forwarder on a host that is a part of a network with
|
||||
private IP address ranges, with a different DHCP/DNS server
|
||||
maintaining the leases.
|
||||
option: 'rebind-domain-ok'
|
||||
value: '{{ dnsmasq__base_domain }}'
|
||||
state: '{{ "present"
|
||||
if (dnsmasq__base_domain_rebind_ok | bool and
|
||||
dnsmasq__base_domain | d())
|
||||
else "absent" }}'
|
||||
|
||||
- name: 'rebind-parent-domain-ok'
|
||||
comment: |
|
||||
Skip rebinding checks for the parent domain if it has 4 or more
|
||||
levels, which is most likely an internal domain on a network with
|
||||
private IP address ranges.
|
||||
option: 'rebind-domain-ok'
|
||||
value: '{{ dnsmasq__base_domain.split(".")[1:] | join(".") }}'
|
||||
state: '{{ "present"
|
||||
if (dnsmasq__base_domain_rebind_ok | bool and
|
||||
dnsmasq__base_domain | d() and
|
||||
(dnsmasq__base_domain.split(".") | length >= 4))
|
||||
else "absent" }}'
|
||||
|
||||
- name: 'bogus-priv'
|
||||
comment: |
|
||||
Do not forward reverse DNS queries for private IP addresses to
|
||||
upstream DNS servers.
|
||||
When an LXC network support is enabled, this parameter is commented
|
||||
out to allow revDNS queries. It will also be commented out when
|
||||
upstream nameservers are located in a private network to allow DNS
|
||||
queries to reach them. Ref: https://bugs.debian.org/461054
|
||||
raw: |
|
||||
bogus-priv
|
||||
state: '{{ "comment"
|
||||
if ((ansible_local.lxc.net_domain | d()) or
|
||||
(ansible_local.resolvconf.upstream_nameservers
|
||||
| d(ansible_dns.nameservers)
|
||||
| ansible.utils.ipaddr("private")))
|
||||
else "present" }}'
|
||||
|
||||
- name: 'resolv-file'
|
||||
comment: |
|
||||
Use custom list of nameservers instead of the system upstream
|
||||
nameservers
|
||||
value: '/etc/resolvconf/upstream.conf'
|
||||
state: '{{ "present" if dnsmasq__nameservers | d() else "absent" }}'
|
||||
|
||||
|
||||
- name: 'lxc-net.conf'
|
||||
comment: |
|
||||
Support for resolving LXC container hosts that use the 'lxc-net' bridge
|
||||
configuration
|
||||
options:
|
||||
|
||||
- name: 'local'
|
||||
value: '{{ "/" + (ansible_local.lxc.net_domain | d(""))
|
||||
+ "/" + ansible_local.lxc.net_address | d("") }}'
|
||||
|
||||
# Create a separate 'lxc' host record that points to the 'lxcbr0'
|
||||
# interface from the outside, if there's no external domain set.
|
||||
- name: 'host-record'
|
||||
value: '{{ ansible_local.lxc.net_domain | d("")
|
||||
+ "," + ansible_local.lxc.net_address | d("") }}'
|
||||
state: '{{ "present"
|
||||
if ("." not in ansible_local.lxc.net_domain | d())
|
||||
else "absent" }}'
|
||||
|
||||
- name: 'rev-server'
|
||||
value: '{{ ansible_local.lxc.net_subnet | d("")
|
||||
+ "," + ansible_local.lxc.net_address | d("") }}'
|
||||
|
||||
- name: 'rebind-domain-ok'
|
||||
value: '{{ ansible_local.lxc.net_domain | d("") }}'
|
||||
|
||||
state: '{{ "present"
|
||||
if (ansible_local.lxc.net_domain | d())
|
||||
else "init" }}'
|
||||
|
||||
- name: 'dhcp-boot.conf'
|
||||
comment: |
|
||||
This configuration file contains dnsmasq options related to booting
|
||||
remote hosts using iPXE boot menu
|
||||
options:
|
||||
|
||||
- name: 'dhcp-match-ipxe'
|
||||
comment: |
|
||||
Tag all DHCP requests with option 175 as coming from iPXE to avoid
|
||||
recursive loops
|
||||
option: 'dhcp-match'
|
||||
value: 'set:ipxe,175'
|
||||
|
||||
- name: 'dhcp-match-d-i'
|
||||
comment: |
|
||||
Tag all DHCP requests with 'd-i' vendor class as coming from the
|
||||
Debian Installer
|
||||
option: 'dhcp-match'
|
||||
value: 'set:debian-installer,option:vendor-class,"d-i"'
|
||||
|
||||
- name: 'vendor-match'
|
||||
comment: |
|
||||
Inspect the vendor class string and match the text to set the tag
|
||||
Ref: https://tools.ietf.org/html/rfc4578#section-2.1
|
||||
raw: |
|
||||
dhcp-vendorclass = BIOS,PXEClient:Arch:00000
|
||||
dhcp-vendorclass = UEFI32,PXEClient:Arch:00006
|
||||
dhcp-vendorclass = UEFI,PXEClient:Arch:00007
|
||||
dhcp-vendorclass = UEFI64,PXEClient:Arch:00009
|
||||
|
||||
- name: 'boot-ipxe-local'
|
||||
comment: 'Set the boot file name based on the matching tag from the vendor class (above)'
|
||||
raw: |
|
||||
{% if dnsmasq__boot_ipxe_enabled | bool %}
|
||||
# Redirect non-iPXE clients to iPXE
|
||||
dhcp-boot = tag:!ipxe,tag:BIOS,undionly.kpxe
|
||||
dhcp-boot = tag:!ipxe,tag:UEFI32,i386-efi/ipxe.efi
|
||||
dhcp-boot = tag:!ipxe,tag:UEFI,ipxe.efi
|
||||
dhcp-boot = tag:!ipxe,tag:UEFI64,ipxe.efi
|
||||
|
||||
# Load the main menu in iPXE clients
|
||||
{% endif %}
|
||||
dhcp-boot = {{ dnsmasq__boot_filename }}
|
||||
state: '{{ "absent" if dnsmasq__boot_server | d() else "present" }}'
|
||||
|
||||
- name: 'boot-ipxe-remote'
|
||||
comment: 'Set the boot file name based on the matching tag from the vendor class (above)'
|
||||
raw: |
|
||||
{% if dnsmasq__boot_ipxe_enabled | bool %}
|
||||
# Redirect non-iPXE clients to iPXE
|
||||
dhcp-boot = tag:!ipxe,tag:BIOS,undionly.kpxe,,{{ dnsmasq__boot_server }}
|
||||
dhcp-boot = tag:!ipxe,tag:UEFI32,i386-efi/ipxe.efi,,{{ dnsmasq__boot_server }}
|
||||
dhcp-boot = tag:!ipxe,tag:UEFI,ipxe.efi,,{{ dnsmasq__boot_server }}
|
||||
dhcp-boot = tag:!ipxe,tag:UEFI64,ipxe.efi,,{{ dnsmasq__boot_server }}
|
||||
|
||||
# Load the main menu in iPXE clients
|
||||
{% endif %}
|
||||
dhcp-boot = {{ dnsmasq__boot_filename }},,{{ dnsmasq__boot_server }}
|
||||
state: '{{ "present" if dnsmasq__boot_server | d() else "absent" }}'
|
||||
|
||||
state: '{{ "present" if dnsmasq__boot_enabled | bool else "init" }}'
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__interface_configuration [[[
|
||||
#
|
||||
# Automatically generated :command:`dnsmasq` configuration for each of the
|
||||
# network interfaces defined in the :envvar:`dnsmasq__combined_interfaces`
|
||||
# variable.
|
||||
dnsmasq__interface_configuration: '{{ lookup("template", "lookup/dnsmasq__interface_configuration.j2",
|
||||
convert_data=False) | from_yaml }}'
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__configuration [[[
|
||||
#
|
||||
# The configuration which should be present on all hosts in the Ansible
|
||||
# inventory.
|
||||
dnsmasq__configuration: []
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__group_configuration [[[
|
||||
#
|
||||
# The configuration which should be present on hosts in a specific Ansible
|
||||
# inventory group.
|
||||
dnsmasq__group_configuration: []
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__host_configuration [[[
|
||||
#
|
||||
# The configuration which should be present on specific hosts in the Ansible
|
||||
# inventory.
|
||||
dnsmasq__host_configuration: []
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__combined_configuration [[[
|
||||
#
|
||||
# The variable which combines all of the other configuration variables and is
|
||||
# used in the Ansible tasks.
|
||||
dnsmasq__combined_configuration: '{{ dnsmasq__default_configuration
|
||||
+ dnsmasq__interface_configuration
|
||||
+ dnsmasq__configuration
|
||||
+ dnsmasq__group_configuration
|
||||
+ dnsmasq__host_configuration }}'
|
||||
# ]]]
|
||||
# ]]]
|
||||
# Configuration for other Ansible roles [[[
|
||||
# -----------------------------------------
|
||||
|
||||
# .. envvar:: dnsmasq__ferm__dependent_rules [[[
|
||||
#
|
||||
# Configuration for the :ref:`debops.ferm` Ansible role.
|
||||
dnsmasq__ferm__dependent_rules:
|
||||
|
||||
- type: 'accept'
|
||||
by_role: 'debops.dnsmasq'
|
||||
name: 'dns'
|
||||
weight: '40'
|
||||
protocol: [ 'udp', 'tcp' ]
|
||||
saddr: '{{ dnsmasq__public_dns_allow }}'
|
||||
dport: [ 'domain' ]
|
||||
accept_any: True
|
||||
interface: '{{ []
|
||||
if (dnsmasq__public_dns | bool)
|
||||
else (dnsmasq__combined_interfaces | flatten | debops.debops.parse_kv_items
|
||||
| selectattr("state", "equalto", "present")
|
||||
| map(attribute="name") | list) }}'
|
||||
rule_state: '{{ "present"
|
||||
if ((dnsmasq__public_dns | bool) or
|
||||
(dnsmasq__combined_interfaces | flatten | debops.debops.parse_kv_items
|
||||
| selectattr("state", "equalto", "present")
|
||||
| map(attribute="name") | list))
|
||||
else "absent" }}'
|
||||
|
||||
- type: 'accept'
|
||||
by_role: 'debops.dnsmasq'
|
||||
name: 'dhcpv4'
|
||||
weight: '40'
|
||||
protocol: [ 'udp' ]
|
||||
dport: [ 'bootps' ]
|
||||
interface: '{{ dnsmasq__combined_interfaces | flatten | debops.debops.parse_kv_items
|
||||
| selectattr("state", "equalto", "present")
|
||||
| map(attribute="name") | list }}'
|
||||
rule_state: '{{ "present"
|
||||
if (dnsmasq__dhcpv4 | bool and
|
||||
(dnsmasq__combined_interfaces | flatten | debops.debops.parse_kv_items
|
||||
| selectattr("state", "equalto", "present")
|
||||
| map(attribute="name") | list))
|
||||
else "absent" }}'
|
||||
|
||||
- type: 'accept'
|
||||
by_role: 'debops.dnsmasq'
|
||||
name: 'dhcpv6'
|
||||
weight: '40'
|
||||
saddr: [ 'fe80::/10' ]
|
||||
daddr: [ 'ff02::1:2' ]
|
||||
# https://tools.ietf.org/html/rfc3315#section-13
|
||||
protocol: [ 'udp' ]
|
||||
sport: [ 'dhcpv6-client' ]
|
||||
dport: [ 'dhcpv6-server' ]
|
||||
interface: '{{ dnsmasq__combined_interfaces | flatten | debops.debops.parse_kv_items
|
||||
| selectattr("state", "equalto", "present")
|
||||
| map(attribute="name") | list }}'
|
||||
rule_state: '{{ "present"
|
||||
if (dnsmasq__dhcpv6 | bool and
|
||||
(dnsmasq__combined_interfaces | flatten | debops.debops.parse_kv_items
|
||||
| selectattr("state", "equalto", "present")
|
||||
| map(attribute="name") | list))
|
||||
else "absent" }}'
|
||||
|
||||
- type: 'accept'
|
||||
by_role: 'debops.dnsmasq'
|
||||
filename: 'tftp'
|
||||
weight: '40'
|
||||
dport: [ 'tftp' ]
|
||||
protocol: [ 'udp' ]
|
||||
interface: '{{ dnsmasq__combined_interfaces | flatten | debops.debops.parse_kv_items
|
||||
| selectattr("state", "equalto", "present")
|
||||
| map(attribute="name") | list }}'
|
||||
rule_state: '{{ "present"
|
||||
if (dnsmasq__boot_enabled | bool and
|
||||
(dnsmasq__combined_interfaces | flatten | debops.debops.parse_kv_items
|
||||
| selectattr("state", "equalto", "present")
|
||||
| map(attribute="name") | list))
|
||||
else "absent" }}'
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__tcpwrappers__dependent_allow [[[
|
||||
#
|
||||
# Configuration for the :ref:`debops.tcpwrappers` Ansible role.
|
||||
dnsmasq__tcpwrappers__dependent_allow: '{{ lookup("template", "lookup/dnsmasq__tcpwrappers__dependent_allow.j2",
|
||||
convert_data=False) | from_yaml }}'
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__apparmor__local_dependent_config [[[
|
||||
#
|
||||
# Configuration for the ``debops-contrib.apparmor`` Ansible role.
|
||||
dnsmasq__apparmor__local_dependent_config:
|
||||
|
||||
'usr.sbin.dnsmasq':
|
||||
- comment: 'Allow dnsmasq to read upstream DNS servers'
|
||||
rules:
|
||||
- '/etc/resolvconf/upstream.conf r'
|
||||
- '/etc/hosts.dnsmasq r'
|
||||
- comment: 'Allow dnsmasq to read /usr/share/dnsmasq-base/trust-anchors.conf provided by dnsmasq-base'
|
||||
rules:
|
||||
- '/usr/share/dnsmasq-base/* r'
|
||||
|
||||
# ]]]
|
||||
# .. envvar:: dnsmasq__persistent_paths__dependent_paths [[[
|
||||
#
|
||||
# Configuration for the :ref:`debops.persistent_paths` Ansible role.
|
||||
dnsmasq__persistent_paths__dependent_paths:
|
||||
|
||||
'50_debops_dnsmasq':
|
||||
by_role: 'debops.dnsmasq'
|
||||
paths:
|
||||
- '/etc/ansible'
|
||||
- '/etc/dnsmasq.d'
|
||||
- '/etc/default/dnsmasq'
|
||||
- '/etc/resolvconf/upstream.conf'
|
||||
- '/etc/hosts.dnsmasq'
|
||||
# ]]]
|
||||
# ]]]
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
|
||||
# Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
|
||||
# Copyright (C) 2014-2022 DebOps <https://debops.org/>
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
# Ensure that custom Ansible plugins and modules included in the main DebOps
|
||||
# collection are available to roles in other collections.
|
||||
collections: [ 'debops.debops' ]
|
||||
|
||||
dependencies: []
|
||||
|
||||
galaxy_info:
|
||||
|
||||
author: 'Maciej Delmanowski, Robin Schneider'
|
||||
description: 'Install and configure dnsmasq'
|
||||
company: 'DebOps'
|
||||
license: 'GPL-3.0-only'
|
||||
min_ansible_version: '2.6.0'
|
||||
|
||||
platforms:
|
||||
|
||||
- name: 'Ubuntu'
|
||||
versions: [ 'all' ]
|
||||
|
||||
- name: 'Debian'
|
||||
versions: [ 'all' ]
|
||||
|
||||
galaxy_tags:
|
||||
- dhcp
|
||||
- dns
|
||||
- pxe
|
||||
- tftp
|
||||
115
ansible_collections/debops/debops/roles/dnsmasq/tasks/main.yml
Normal file
115
ansible_collections/debops/debops/roles/dnsmasq/tasks/main.yml
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
---
|
||||
# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
|
||||
# Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
|
||||
# Copyright (C) 2014-2019 DebOps <https://debops.org/>
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
- name: Import custom Ansible plugins
|
||||
ansible.builtin.import_role:
|
||||
name: 'ansible_plugins'
|
||||
|
||||
- name: Import DebOps global handlers
|
||||
ansible.builtin.import_role:
|
||||
name: 'global_handlers'
|
||||
|
||||
- name: Install required packages
|
||||
ansible.builtin.package:
|
||||
name: '{{ q("flattened", (dnsmasq__base_packages + dnsmasq__packages)) }}'
|
||||
state: 'present'
|
||||
register: dnsmasq__register_packages
|
||||
until: dnsmasq__register_packages is succeeded
|
||||
|
||||
- name: Make sure Ansible fact directory exists
|
||||
ansible.builtin.file:
|
||||
path: '/etc/ansible/facts.d'
|
||||
state: 'directory'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0755'
|
||||
|
||||
- name: Generate dnsmasq Ansible local facts
|
||||
ansible.builtin.template:
|
||||
src: 'etc/ansible/facts.d/dnsmasq.fact.j2'
|
||||
dest: '/etc/ansible/facts.d/dnsmasq.fact'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0755'
|
||||
unsafe_writes: '{{ True if (core__unsafe_writes | d(ansible_local.core.unsafe_writes | d()) | bool) else omit }}'
|
||||
notify: [ 'Refresh host facts' ]
|
||||
tags: [ 'meta::facts' ]
|
||||
|
||||
- name: Reload facts if they were modified
|
||||
ansible.builtin.meta: 'flush_handlers'
|
||||
|
||||
# This directory is required, otherwise dnsmasq won't start when TFTP support
|
||||
# is enabled
|
||||
- name: Make sure TFTP root directory exists
|
||||
ansible.builtin.file:
|
||||
path: '{{ dnsmasq__boot_tftp_root }}'
|
||||
state: 'directory'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0755'
|
||||
when: dnsmasq__boot_enabled | bool
|
||||
|
||||
- name: Remove dnsmasq configuration if requested
|
||||
ansible.builtin.file:
|
||||
path: '/etc/dnsmasq.d/{{ item.filename | d(item.name | regex_replace("\.conf$", "") + ".conf") }}'
|
||||
state: 'absent'
|
||||
with_items: '{{ dnsmasq__combined_configuration | debops.debops.parse_kv_items }}'
|
||||
notify: [ 'Test and restart dnsmasq' ]
|
||||
when: (item.name | d() and item.state | d('present') == 'absent')
|
||||
|
||||
- name: Generate dnsmasq configuration
|
||||
ansible.builtin.template:
|
||||
src: 'etc/dnsmasq.d/template.conf.j2'
|
||||
dest: '/etc/dnsmasq.d/{{ item.filename | d(item.name | regex_replace(".conf$", "") + ".conf") }}'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0644'
|
||||
with_items: '{{ dnsmasq__combined_configuration | debops.debops.parse_kv_items }}'
|
||||
notify: [ 'Test and restart dnsmasq' ]
|
||||
when: (item.name | d() and item.state | d('present') not in ['absent', 'ignore', 'init'])
|
||||
|
||||
- name: Remove DHCP host configuration and DNS records if requested
|
||||
ansible.builtin.file:
|
||||
path: '/etc/dnsmasq.d/{{ dnsmasq__dhcp_dns_filename }}'
|
||||
state: 'absent'
|
||||
notify: [ 'Test and restart dnsmasq' ]
|
||||
when: not dnsmasq__dhcp_hosts | d() and not dnsmasq__dns_records | d()
|
||||
|
||||
- name: Generate DHCP host configuration and DNS records
|
||||
ansible.builtin.template:
|
||||
src: 'etc/dnsmasq.d/dhcp-dns-options.conf.j2'
|
||||
dest: '/etc/dnsmasq.d/{{ dnsmasq__dhcp_dns_filename }}'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0644'
|
||||
notify: [ 'Test and restart dnsmasq' ]
|
||||
when: dnsmasq__dhcp_hosts | d() or dnsmasq__dns_records | d()
|
||||
|
||||
- name: Divert original dnsmasq environment file
|
||||
debops.debops.dpkg_divert:
|
||||
path: '/etc/default/dnsmasq'
|
||||
notify: [ 'Test and restart dnsmasq' ]
|
||||
|
||||
- name: Configure dnsmasq environment file
|
||||
ansible.builtin.template:
|
||||
src: 'etc/default/dnsmasq.j2'
|
||||
dest: '/etc/default/dnsmasq'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0644'
|
||||
unsafe_writes: '{{ True if (core__unsafe_writes | d(ansible_local.core.unsafe_writes | d()) | bool) else omit }}'
|
||||
notify: [ 'Test and restart dnsmasq' ]
|
||||
|
||||
- name: Configure custom nameservers in resolvconf
|
||||
ansible.builtin.template:
|
||||
src: 'etc/resolvconf/upstream.conf.j2'
|
||||
dest: '/etc/resolvconf/upstream.conf'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0644'
|
||||
unsafe_writes: '{{ True if (core__unsafe_writes | d(ansible_local.core.unsafe_writes | d()) | bool) else omit }}'
|
||||
notify: [ 'Test and restart dnsmasq' ]
|
||||
when: dnsmasq__nameservers | d()
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
|
||||
# Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
|
||||
# Copyright (C) 2014-2019 DebOps <https://debops.org/>
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
- name: Prepare environment for dependent Ansible roles
|
||||
ansible.builtin.set_fact:
|
||||
dnsmasq__env_tcpwrappers__dependent_allow: '{{ dnsmasq__tcpwrappers__dependent_allow }}'
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#!{{ ansible_python['executable'] }}
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
|
||||
# Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
|
||||
# Copyright (C) 2014-2019 DebOps <https://debops.org/>
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
# {{ ansible_managed }}
|
||||
|
||||
from __future__ import print_function
|
||||
from json import dumps, loads
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
|
||||
def cmd_exists(cmd):
|
||||
return any(
|
||||
os.access(os.path.join(path, cmd), os.X_OK)
|
||||
for path in os.environ["PATH"].split(os.pathsep)
|
||||
)
|
||||
|
||||
|
||||
output = loads('''{{ {"boot_tftp_root": dnsmasq__boot_tftp_root}
|
||||
| to_nice_json }}''')
|
||||
|
||||
output['installed'] = cmd_exists('dnsmasq')
|
||||
|
||||
try:
|
||||
version_stdout = subprocess.check_output(
|
||||
["dpkg-query", "-W", "-f=${Version}",
|
||||
"dnsmasq"]).decode('utf-8').split('-')[0]
|
||||
output['version'] = version_stdout
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
print(dumps(output, sort_keys=True, indent=4))
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
{# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
|
||||
# Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
|
||||
# Copyright (C) 2014-2019 DebOps <https://debops.org/>
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
#}
|
||||
# {{ ansible_managed }}
|
||||
|
||||
# This file has five functions:
|
||||
# 1) to completely disable starting dnsmasq,
|
||||
# 2) to set DOMAIN_SUFFIX by running `dnsdomainname`
|
||||
# 3) to select an alternative config file
|
||||
# by setting DNSMASQ_OPTS to --conf-file=<file>
|
||||
# 4) to tell dnsmasq to read the files in /etc/dnsmasq.d for
|
||||
# more configuration variables.
|
||||
# 5) to stop the resolvconf package from controlling dnsmasq's
|
||||
# idea of which upstream nameservers to use.
|
||||
# For upgraders from very old versions, all the shell variables set
|
||||
# here in previous versions are still honored by the init script
|
||||
# so if you just keep your old version of this file nothing will break.
|
||||
|
||||
#DOMAIN_SUFFIX=`dnsdomainname`
|
||||
#DNSMASQ_OPTS="--conf-file=/etc/dnsmasq.alt"
|
||||
|
||||
# Whether or not to run the dnsmasq daemon; set to 0 to disable.
|
||||
ENABLED=1
|
||||
|
||||
# By default search this drop directory for configuration options.
|
||||
# Libvirt leaves a file here to make the system dnsmasq play nice.
|
||||
# Comment out this line if you don't want this. The dpkg-* are file
|
||||
# endings which cause dnsmasq to skip that file. This avoids pulling
|
||||
# in backups made by dpkg.
|
||||
CONFIG_DIR=/etc/dnsmasq.d,.dpkg-dist,.dpkg-old,.dpkg-new
|
||||
|
||||
# If the resolvconf package is installed, dnsmasq will use its output
|
||||
# rather than the contents of /etc/resolv.conf to find upstream
|
||||
# nameservers. Uncommenting this line inhibits this behaviour.
|
||||
# Note that including a "resolv-file=<filename>" line in
|
||||
# /etc/dnsmasq.conf is not enough to override resolvconf if it is
|
||||
# installed: the line below must be uncommented.
|
||||
{% if dnsmasq__nameservers | d() %}
|
||||
IGNORE_RESOLVCONF=yes
|
||||
{% else %}
|
||||
#IGNORE_RESOLVCONF=yes
|
||||
{% endif %}
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
{# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
|
||||
# Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
|
||||
# Copyright (C) 2014-2019 DebOps <https://debops.org/>
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
#}
|
||||
# {{ ansible_managed }}
|
||||
|
||||
# DHCP host configuration and DNS records
|
||||
|
||||
{% for element in (dnsmasq__dhcp_hosts + dnsmasq__dns_records) %}
|
||||
{% set entry = {} %}
|
||||
{% for k, v in element.items() %}
|
||||
{% set _ = entry.update({k.lower(): v}) %}
|
||||
{% endfor %}
|
||||
{% if entry.state | d('present') != 'absent' %}
|
||||
{% set dhcp_host = [] %}
|
||||
{% set host_record = [] %}
|
||||
{% set cname = [] %}
|
||||
{% set record_command = '' %}
|
||||
{% set record_content = [] %}
|
||||
{% if entry.hwaddr | d() %}
|
||||
{% set _ = dhcp_host.extend( ([ entry.hwaddr ] if (entry.hwaddr is string) else entry.hwaddr) ) %}
|
||||
{% elif entry.mac | d() %}
|
||||
{% set _ = dhcp_host.extend( ([ entry.mac ] if (entry.mac is string) else entry.mac) ) %}
|
||||
{% endif %}
|
||||
{% if entry.id | d() %}
|
||||
{% set _ = dhcp_host.append('id:' + entry.id) %}
|
||||
{% endif %}
|
||||
{% if entry.tag | d() %}
|
||||
{% set _ = dhcp_host.append('set:' + entry.tag) %}
|
||||
{% endif %}
|
||||
{% if entry.ip | d() and (entry.host is undefined and entry.a is undefined and entry.aaaa is undefined) %}
|
||||
{% set _ = dhcp_host.extend( ([ entry.ip ] if (entry.ip is string) else entry.ip) | ansible.utils.ipwrap ) %}
|
||||
{% elif entry.ipaddr | d() and (entry.host is undefined and entry.a is undefined and entry.aaaa is undefined) %}
|
||||
{% set _ = dhcp_host.extend( ([ entry.ipaddr ] if (entry.ipaddr is string) else entry.ipaddr) | ansible.utils.ipwrap ) %}
|
||||
{% elif entry.address | d() and (entry.host is undefined and entry.a is undefined and entry.aaaa is undefined) %}
|
||||
{% set _ = dhcp_host.extend( ([ entry.address ] if (entry.address is string) else entry.address) | ansible.utils.ipwrap ) %}
|
||||
{% endif %}
|
||||
{% if entry.name | d() %}
|
||||
{% set _ = dhcp_host.append(entry.name) %}
|
||||
{% elif entry.hostname | d() %}
|
||||
{% set _ = dhcp_host.append(entry.hostname) %}
|
||||
{% endif %}
|
||||
{% if entry.lease | d() %}
|
||||
{% set _ = dhcp_host.append(entry.lease) %}
|
||||
{% elif entry.lease_time | d() %}
|
||||
{% set _ = dhcp_host.append(entry.lease_time) %}
|
||||
{% endif %}
|
||||
{% if (entry.ignore | d()) | bool %}
|
||||
{% set _ = dhcp_host.append('ignore') %}
|
||||
{% endif %}
|
||||
{% if entry.domain | d() and (entry.ip | d() or entry.ipaddr | d() or entry.address | d()) %}
|
||||
{% if entry.name | d() %}
|
||||
{% set host_name = entry.name %}
|
||||
{% elif entry.hostname | d() %}
|
||||
{% set host_name = entry.hostname %}
|
||||
{% endif %}
|
||||
{% set _ = host_record.append(host_name + '.' + entry.domain) %}
|
||||
{% if entry.ip | d() %}
|
||||
{% set _ = host_record.extend( ([ entry.ip ] if (entry.ip is string) else entry.ip) | ansible.utils.ipwrap ) %}
|
||||
{% elif entry.ipaddr | d() %}
|
||||
{% set _ = host_record.extend( ([ entry.ipaddr ] if (entry.ipaddr is string) else entry.ipaddr) | ansible.utils.ipwrap ) %}
|
||||
{% elif entry.address | d() %}
|
||||
{% set _ = host_record.extend( ([ entry.address ] if (entry.address is string) else entry.address) | ansible.utils.ipwrap ) %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if (entry.host | d() or entry.a | d() or entry.aaaa | d()) and (entry.ip | d() or entry.ipaddr | d() or entry.address | d() or entry.target | d()) %}
|
||||
{% set record_command = 'host-record' %}
|
||||
{% if entry.host | d() %}
|
||||
{% set _ = record_content.extend( ([ entry.host ] if (entry.host is string) else entry.host) ) %}
|
||||
{% elif entry.a | d() %}
|
||||
{% set _ = record_content.extend( ([ entry.a ] if (entry.a is string) else entry.a) ) %}
|
||||
{% elif entry.aaaa | d() %}
|
||||
{% set _ = record_content.extend( ([ entry.aaaa ] if (entry.aaaa is string) else entry.aaaa) ) %}
|
||||
{% endif %}
|
||||
{% if entry.ip | d() %}
|
||||
{% set _ = record_content.extend( ([ entry.ip ] if (entry.ip is string) else entry.ip) ) %}
|
||||
{% elif entry.ipaddr | d() %}
|
||||
{% set _ = record_content.extend( ([ entry.ipaddr ] if (entry.ipaddr is string) else entry.ipaddr) ) %}
|
||||
{% elif entry.address | d() %}
|
||||
{% set _ = record_content.extend( ([ entry.address ] if (entry.address is string) else entry.address) ) %}
|
||||
{% elif entry.target | d() %}
|
||||
{% set _ = record_content.extend( ([ entry.target ] if (entry.target is string) else entry.target) ) %}
|
||||
{% endif %}
|
||||
{% elif entry.txt | d() and (entry.value | d() or entry.target | d()) %}
|
||||
{% set record_command = 'txt-record' %}
|
||||
{% set _ = record_content.extend( [ entry.txt ] ) %}
|
||||
{% if entry.value | d() %}
|
||||
{% set _ = record_content.extend( ([ entry.value ] if (entry.value is string) else entry.value) ) %}
|
||||
{% elif entry.target | d() %}
|
||||
{% set _ = record_content.extend( ([ entry.target ] if (entry.target is string) else entry.target) ) %}
|
||||
{% endif %}
|
||||
{% elif entry.cname | d() and entry.target | d() %}
|
||||
{% set record_command = 'cname' %}
|
||||
{% set _ = record_content.extend( [ entry.cname ] ) %}
|
||||
{% set _ = record_content.extend( [ entry.target ] ) %}
|
||||
{% elif entry.ptr | d() and entry.target | d() %}
|
||||
{% set record_command = 'ptr-record' %}
|
||||
{% set _ = record_content.extend( [ entry.ptr ] ) %}
|
||||
{% set _ = record_content.extend( [ entry.target ] ) %}
|
||||
{% elif entry.mx | d() %}
|
||||
{% set record_command = 'mx-host' %}
|
||||
{% set _ = record_content.extend( [ entry.mx ] ) %}
|
||||
{% if entry.target | d() %}
|
||||
{% set _ = record_content.extend( [ entry.target ] ) %}
|
||||
{% endif %}
|
||||
{% if entry.preference | d() %}
|
||||
{% set _ = record_content.extend( [ entry.preference ] ) %}
|
||||
{% elif entry.priority | d() %}
|
||||
{% set _ = record_content.extend( [ entry.priority ] ) %}
|
||||
{% endif %}
|
||||
{% elif entry.srv | d() and entry.target | d() %}
|
||||
{% set record_command = 'srv-host' %}
|
||||
{% set _ = record_content.extend( [ entry.srv ] ) %}
|
||||
{% set _ = record_content.extend( [ entry.target ] ) %}
|
||||
{% if entry.port | d() %}
|
||||
{% set _ = record_content.extend( [ entry.port ] ) %}
|
||||
{% endif %}
|
||||
{% if entry.preference | d() %}
|
||||
{% set _ = record_content.extend( [ entry.preference ] ) %}
|
||||
{% elif entry.priority | d() %}
|
||||
{% set _ = record_content.extend( [ entry.priority ] ) %}
|
||||
{% endif %}
|
||||
{% if entry.weight | d() %}
|
||||
{% set _ = record_content.extend( [ entry.weight ] ) %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if (dhcp_host | d() or (record_command | d() and record_content | d()) or entry.raw | d()) %}
|
||||
{% if not loop.first %}
|
||||
|
||||
{% endif %}
|
||||
{% if entry.comment | d() %}
|
||||
{{ entry.comment | regex_replace('\n$','') | comment(prefix='', postfix='') -}}
|
||||
{% endif %}
|
||||
{% if entry.raw | d() %}
|
||||
{% if entry.state | d('present') == 'comment' %}
|
||||
{{ "{}".format(entry.raw | regex_replace('\n$','')) | comment(decoration='#', prefix='', postfix='') }}
|
||||
{% else %}
|
||||
{{ "{}".format(entry.raw | regex_replace('\n$','')) }}
|
||||
{% endif %}
|
||||
{% elif dhcp_host | d() %}
|
||||
{{ '{}dhcp-host = {}'.format(('#' if (entry.state | d('present') == 'comment') else ''), dhcp_host | join(',')) }}
|
||||
{% if host_record | d() %}
|
||||
{{ '{}host-record = {}'.format(('#' if (entry.state | d('present') == 'comment') else ''), host_record | join(',')) }}
|
||||
{% if entry.cname | d() %}
|
||||
{% for cname in ([ entry.cname ] if entry.cname is string else entry.cname) %}
|
||||
{{ '{}cname = {},{}'.format(('#' if (entry.state | d('present') == 'comment') else ''), cname + '.' + entry.domain, host_name + '.' + entry.domain) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% elif (record_command | d() and record_content | d()) %}
|
||||
{{ '{}{} = {}'.format(('#' if (entry.state | d('present') == 'comment') else ''), record_command, record_content | join(',')) }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
{# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
|
||||
# Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
|
||||
# Copyright (C) 2014-2019 DebOps <https://debops.org/>
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
#}
|
||||
# {{ ansible_managed }}
|
||||
|
||||
{% if item.comment | d() %}
|
||||
{{ item.comment | regex_replace('\n$','') | comment(prefix='', postfix='') -}}
|
||||
{% endif %}
|
||||
{% if item.options | d() %}
|
||||
{% for element in item.options %}
|
||||
{% if element is string %}
|
||||
{% if not loop.first %}
|
||||
|
||||
{% endif %}
|
||||
{{ "{}".format(element) }}
|
||||
{% elif element is mapping %}
|
||||
{% if element.name | d() %}
|
||||
{% if element.state | d('present') not in [ 'absent', 'ignore' ] %}
|
||||
{% if (loop.first and item.comment | d() and element.comment | d()) or (not loop.first and (element.comment | d() or (element.separator | d()) | bool)) %}
|
||||
|
||||
{% endif %}
|
||||
{% if element.comment | d() %}
|
||||
{{ element.comment | regex_replace('\n$','') | comment(prefix='', postfix='') -}}
|
||||
{% endif %}
|
||||
{% if element.value | d() %}
|
||||
{% if element.value is string %}
|
||||
{{ "{}{} = {}".format(('#' if (element.state | d('present') == 'comment') else ''), element.option | d(element.name), element.value) }}
|
||||
{% else %}
|
||||
{% for thing in (element.value | selectattr('state', 'equalto', 'present') | map(attribute='name') | list) %}
|
||||
{{ "{}{} = {}".format(('#' if (element.state | d('present') == 'comment') else ''), element.option | d(element.name), thing) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% elif element.raw | d() %}
|
||||
{% if element.state | d('present') == 'comment' %}
|
||||
{{ "{}".format(element.raw | regex_replace('\n$','')) | comment(decoration='#', prefix='', postfix='') -}}
|
||||
{% else %}
|
||||
{{ "{}".format(element.raw | regex_replace('\n$','')) }}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{{ "{}{}".format(('#' if (element.state | d('present') == 'comment') else ''), element.option | d(element.name)) }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% for key, value in element.items() %}
|
||||
{{ "{} = {}".format(key, value) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if item.raw | d() %}
|
||||
{{ item.raw | regex_replace('\n$','') }}
|
||||
{% endif %}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
|
||||
# Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
|
||||
# Copyright (C) 2014-2019 DebOps <https://debops.org/>
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
#}
|
||||
# {{ ansible_managed }}
|
||||
|
||||
{% if dnsmasq__nameservers | d() and dnsmasq__nameservers is iterable %}
|
||||
{% for nameserver in dnsmasq__nameservers %}
|
||||
nameserver {{ nameserver }}
|
||||
{% endfor %}
|
||||
{% elif dnsmasq__nameservers | d() and dnsmasq__nameservers is string %}
|
||||
nameserver {{ dnsmasq__nameservers }}
|
||||
{% endif %}
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
{# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
|
||||
# Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
|
||||
# Copyright (C) 2014-2019 DebOps <https://debops.org/>
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
#}
|
||||
{% set dnsmasq__tpl_interface_configuration = [] %}
|
||||
{% for interface in (dnsmasq__combined_interfaces | flatten | debops.debops.parse_kv_items) %}
|
||||
{% set dnsmasq__tpl_ipv4 = [] %}
|
||||
{% set dnsmasq__tpl_ipv6 = [] %}
|
||||
{% if not interface.ignore_interface_addresses|d(False) and hostvars[inventory_hostname]["ansible_" + interface.name] | d() %}
|
||||
{% if hostvars[inventory_hostname]["ansible_" + interface.name].ipv4 | d() %}
|
||||
{% set _ = dnsmasq__tpl_ipv4.append(hostvars[inventory_hostname]["ansible_" + interface.name].ipv4.address + '/'
|
||||
+ (hostvars[inventory_hostname]["ansible_" + interface.name].ipv4.address + '/'
|
||||
+ hostvars[inventory_hostname]["ansible_" + interface.name].ipv4.netmask) | ansible.utils.ipaddr('prefix') | string) %}
|
||||
{% if hostvars[inventory_hostname]["ansible_" + interface.name].ipv4_secondaries | d() %}
|
||||
{% for element in hostvars[inventory_hostname]["ansible_" + interface.name].ipv4_secondaries %}
|
||||
{% set _ = dnsmasq__tpl_ipv4.append(element.address + '/' + (element.address + '/' + element.netmask) | ansible.utils.ipaddr('prefix') | string) %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if hostvars[inventory_hostname]["ansible_" + interface.name].ipv6 | d() %}
|
||||
{% for element in hostvars[inventory_hostname]["ansible_" + interface.name].ipv6 %}
|
||||
{% if not element.address | ansible.utils.ipv6('link-local') %}
|
||||
{% set _ = dnsmasq__tpl_ipv6.append(element.address + '/' + element.prefix) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if interface.address | d() %}
|
||||
{% for element in ([ interface.address ] if interface.address is string else interface.address) %}
|
||||
{% if element | ansible.utils.ipv4('host/prefix') %}
|
||||
{% set _ = dnsmasq__tpl_ipv4.append(element) %}
|
||||
{% elif element | ansible.utils.ipv6('host/prefix') and not element | ansible.utils.ipv6('link-local') %}
|
||||
{% set _ = dnsmasq__tpl_ipv6.append(element) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if interface.addresses | d() %}
|
||||
{% for element in ([ interface.addresses ] if interface.addresses is string else interface.addresses) %}
|
||||
{% if element | ansible.utils.ipv4('host/prefix') %}
|
||||
{% set _ = dnsmasq__tpl_ipv4.append(element) %}
|
||||
{% elif element | ansible.utils.ipv6('host/prefix') and not element | ansible.utils.ipv6('link-local') %}
|
||||
{% set _ = dnsmasq__tpl_ipv6.append(element) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% set interface_hostname = (interface.hostname | d(dnsmasq__hostname)) %}
|
||||
{% set interface_domain = (interface.domain | d(interface.name + "." + dnsmasq__base_domain)) %}
|
||||
{% set interface_tag = (interface.tag | d(interface.name)) %}
|
||||
{% set interface_base = {"name": (interface.filename | d("interface-" + interface.name + ".conf")), "state": (interface.state | d("present"))} %}
|
||||
{% set interface_search = [] %}
|
||||
{% if interface.search | d() %}
|
||||
{% set _ = interface_search.extend([ interface.search ] if interface.search is string else interface.search) %}
|
||||
{% endif %}
|
||||
{% if (interface_domain.endswith(dnsmasq__base_domain) and interface_domain.split(".") | length >= 3 and dnsmasq__base_domain.split(".") | length >= 2) %}
|
||||
{% set _ = interface_search.append(dnsmasq__base_domain) %}
|
||||
{% endif %}
|
||||
{% set interface_options = [] %}
|
||||
{% set _ = interface_options.append({
|
||||
"name": "interface",
|
||||
"value": interface.name
|
||||
}) %}
|
||||
{% set _ = interface_options.append({
|
||||
"name": "interface-name_domain",
|
||||
"option": "interface-name",
|
||||
"value": (interface_hostname + "." + interface_domain + "," + interface.name)
|
||||
}) %}
|
||||
{% if (not interface.dhcp_enabled | d(True)) | bool %}
|
||||
{% set _ = interface_options.append({
|
||||
"name": "no-dhcp-interface",
|
||||
"value": interface.name
|
||||
}) %}
|
||||
{% else %}
|
||||
{% if interface.dhcp_range_state | d('present') == 'present' %}
|
||||
{% for host_address in dnsmasq__tpl_ipv4 %}
|
||||
{% set _ = interface_options.append({
|
||||
"name": ("dhcp_range_" + (host_address | replace('.','_') | replace('/','_'))),
|
||||
"option": "dhcp-range",
|
||||
"separator": True,
|
||||
"value": ("set:" + interface_tag + "," + host_address | ansible.utils.ipv4(interface.dhcp_range_start | d(10) | int) | ansible.utils.ipv4('address') + ',' + host_address | ansible.utils.ipv4(interface.dhcp_range_end | d(-10) | int) | ansible.utils.ipv4('address') + ',' + host_address | ansible.utils.ipv4('netmask') + ',' + interface.dhcp_lease | d('24h'))
|
||||
}) %}
|
||||
{% endfor %}
|
||||
{% for host_address in dnsmasq__tpl_ipv6 %}
|
||||
{% if (interface.dhcp_ipv6_mode is string and interface.dhcp_ipv6_mode == '') %}
|
||||
{% set ra_separator = '' %}
|
||||
{% else %}
|
||||
{% set ra_separator = ',' %}
|
||||
{% endif %}
|
||||
{% set _ = interface_options.append({
|
||||
"name": ("dhcp_range_" + (host_address | replace(':','_') | replace('/','_'))),
|
||||
"option": "dhcp-range",
|
||||
"value": ("set:" + interface_tag + "," + host_address | ansible.utils.ipv6(interface.dhcp_range_start | d(10) | int) | ansible.utils.ipv6('address') + ',' + host_address | ansible.utils.ipv6(interface.dhcp_range_end | d(-10) | int) | ansible.utils.ipv6('address') + ',' + interface.dhcp_ipv6_mode | d("ra-names,ra-stateless,slaac") + ra_separator + host_address | ansible.utils.ipv6('prefix') | string + ',' + interface.dhcp_lease | d('24h'))
|
||||
}) %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if (interface.router_state | d('present')) in [ 'present', 'enabled' ] %}
|
||||
{% if interface.router_gateway | d() %}
|
||||
{% set _ = interface_options.append({
|
||||
"name": "dhcp_option_ipv4_router",
|
||||
"option": "dhcp-option",
|
||||
"value": ("tag:" + interface_tag + ",option:router," + interface.router_gateway)
|
||||
}) %}
|
||||
{% else %}
|
||||
{% set _ = interface_options.append({
|
||||
"name": "dhcp_option_ipv4_router",
|
||||
"option": "dhcp-option",
|
||||
"value": ("tag:" + interface_tag + ",option:router,0.0.0.0")
|
||||
}) %}
|
||||
{% endif %}
|
||||
{% elif (interface.router_state | d('present')) in [ 'disabled' ] %}
|
||||
{% set _ = interface_options.append({
|
||||
"name": "dhcp_option_ipv4_router",
|
||||
"option": "dhcp-option",
|
||||
"comment": "IPv4 router is not advertised",
|
||||
"value": ("tag:" + interface_tag + ",option:router")
|
||||
}) %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if dnsmasq__tpl_ipv6 | d() %}
|
||||
{% set _ = interface_options.append({
|
||||
"name": "dhcp_option6_dns_server",
|
||||
"option": "dhcp-option",
|
||||
"comment": "Advertise RDNSS servers for local IPv6 network",
|
||||
"value": ("tag:" + interface_tag + ",option6:dns-server," + dnsmasq__tpl_ipv6 | ansible.utils.ipv6("address") | ansible.utils.ipwrap | join(","))
|
||||
}) %}
|
||||
{% endif %}
|
||||
{% set _ = interface_options.append({
|
||||
"name": "dhcp_option_search",
|
||||
"option": "dhcp-option",
|
||||
"value": ("tag:" + interface_tag + ",option:domain-search," + ([ interface_domain ] + ([ interface_search ] if interface_search is string else interface_search)) | unique | join(","))
|
||||
}) %}
|
||||
{% set _ = interface_options.append({
|
||||
"name": "dhcp_option6_search",
|
||||
"option": "dhcp-option",
|
||||
"value": ("tag:" + interface_tag + ",option6:domain-search," + ([ interface_domain ] + ([ interface_search ] if interface_search is string else interface_search)) | unique | join(","))
|
||||
}) %}
|
||||
{% for host_address in (dnsmasq__tpl_ipv4 + dnsmasq__tpl_ipv6) %}
|
||||
{% set _ = interface_options.append({
|
||||
"name": ("domain_" + (host_address | replace('.','_') | replace('/','_'))),
|
||||
"option": "domain",
|
||||
"value": (interface_domain + "," + host_address | ansible.utils.ipaddr('subnet') + (",local" if (host_address | ansible.utils.ipaddr('prefix') in [ 8, 16, 24 ]) else ""))
|
||||
}) %}
|
||||
{% endfor %}
|
||||
{% if (interface.boot_enabled | d(dnsmasq__boot_enabled)) | bool %}
|
||||
{% set _ = interface_options.extend([{
|
||||
"name": "enable-tftp",
|
||||
"comment": "Enable TFTP support",
|
||||
"value": interface.name
|
||||
}, {
|
||||
"name": "tftp-root",
|
||||
"value": (interface.boot_tftp_root | d(dnsmasq__boot_tftp_root)) + "," + interface.name
|
||||
}]) %}
|
||||
{% if not dnsmasq__boot_ipxe_enabled | bool %}
|
||||
{% set _ = interface_options.append({
|
||||
"name": "dhcp-boot",
|
||||
"value": ("tag:" + interface_tag + "," + interface.boot_filename | d("pxelinux.0") + ((",," + interface.boot_server) if interface.boot_server | d() else ""))
|
||||
}) %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if interface.raw | d() %}
|
||||
{% set _ = interface_options.append({
|
||||
"name": "interface_raw",
|
||||
"comment": "Additional interface options",
|
||||
"raw": interface.raw
|
||||
}) %}
|
||||
{% endif %}
|
||||
{% set _ = interface_base.update({"options": interface_options}) %}
|
||||
{% set _ = dnsmasq__tpl_interface_configuration.append(interface_base) %}
|
||||
{% endfor %}
|
||||
{{ dnsmasq__tpl_interface_configuration | to_nice_yaml }}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
{# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
|
||||
# Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
|
||||
# Copyright (C) 2014-2019 DebOps <https://debops.org/>
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
#}
|
||||
{% set dnsmasq__tpl_subnets = [] %}
|
||||
{% set dnsmasq__tpl_tcpwrappers__dependent_allow = [] %}
|
||||
{% for interface in (dnsmasq__combined_interfaces | flatten | debops.debops.parse_kv_items) %}
|
||||
{% set dnsmasq__tpl_ipv4 = [] %}
|
||||
{% set dnsmasq__tpl_ipv6 = [] %}
|
||||
{% if hostvars[inventory_hostname]["ansible_" + interface.name] | d() %}
|
||||
{% if hostvars[inventory_hostname]["ansible_" + interface.name].ipv4 | d() %}
|
||||
{% set _ = dnsmasq__tpl_ipv4.append(hostvars[inventory_hostname]["ansible_" + interface.name].ipv4.address + '/'
|
||||
+ (hostvars[inventory_hostname]["ansible_" + interface.name].ipv4.address + '/'
|
||||
+ hostvars[inventory_hostname]["ansible_" + interface.name].ipv4.netmask) | ansible.utils.ipaddr('prefix') | string) %}
|
||||
{% if hostvars[inventory_hostname]["ansible_" + interface.name].ipv4_secondaries | d() %}
|
||||
{% for element in hostvars[inventory_hostname]["ansible_" + interface.name].ipv4_secondaries %}
|
||||
{% set _ = dnsmasq__tpl_ipv4.append(element.address + '/' + (element.address + '/' + element.netmask) | ansible.utils.ipaddr('prefix') | string) %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if hostvars[inventory_hostname]["ansible_" + interface.name].ipv6 | d() %}
|
||||
{% for element in hostvars[inventory_hostname]["ansible_" + interface.name].ipv6 %}
|
||||
{% if not element.address | ansible.utils.ipv6('link-local') %}
|
||||
{% set _ = dnsmasq__tpl_ipv6.append(element.address + '/' + element.prefix) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if interface.address | d() %}
|
||||
{% for element in ([ interface.address ] if interface.address is string else interface.address) %}
|
||||
{% if element | ansible.utils.ipv4('host/prefix') %}
|
||||
{% set _ = dnsmasq__tpl_ipv4.append(element) %}
|
||||
{% elif element | ansible.utils.ipv6('host/prefix') and not element | ansible.utils.ipv6('link-local') %}
|
||||
{% set _ = dnsmasq__tpl_ipv6.append(element) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if interface.addresses | d() %}
|
||||
{% for element in ([ interface.addresses ] if interface.addresses is string else interface.addresses) %}
|
||||
{% if element | ansible.utils.ipv4('host/prefix') %}
|
||||
{% set _ = dnsmasq__tpl_ipv4.append(element) %}
|
||||
{% elif element | ansible.utils.ipv6('host/prefix') and not element | ansible.utils.ipv6('link-local') %}
|
||||
{% set _ = dnsmasq__tpl_ipv6.append(element) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if (interface.state | d('present') != 'absent' and (interface.boot_enabled | d(dnsmasq__boot_enabled)) | bool) %}
|
||||
{% set _ = dnsmasq__tpl_subnets.extend(dnsmasq__tpl_ipv4 + dnsmasq__tpl_ipv6) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% set _ = dnsmasq__tpl_tcpwrappers__dependent_allow.append({
|
||||
"daemon": "in.tftpd",
|
||||
"client": (dnsmasq__tpl_subnets | ansible.utils.ipaddr('subnet')),
|
||||
"weight": 50,
|
||||
"filename": "dnsmasq_dependent_allow",
|
||||
"comment": "Allow remote connections to TFTP server",
|
||||
"state": ("present" if (dnsmasq__boot_enabled | bool and dnsmasq__tpl_subnets | d()) else "absent")
|
||||
}) %}
|
||||
{{ dnsmasq__tpl_tcpwrappers__dependent_allow | to_nice_yaml }}
|
||||
Loading…
Add table
Add a link
Reference in a new issue