diff --git a/.zuul.yaml b/.zuul.yaml index f5310c422b..76baacc29f 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -206,14 +206,19 @@ label: ubuntu-bionic - name: adns1.opendev.org label: ubuntu-bionic + - name: ns1.opendev.org + label: ubuntu-bionic files: - .zuul.yaml - playbooks/group_vars/adns.yaml - playbooks/group_vars/dns.yaml - - playbooks/host_vars/adns1.opendev.org.yaml + - ^playbooks/host_vars/(ad)?ns\d+.opendev.org.yaml - playbooks/zuul/templates/group_vars/adns.yaml.j2 + - playbooks/zuul/templates/group_vars/ns.yaml.j2 - playbooks/roles/master-nameserver/ + - playbooks/roles/nameserver/ - testinfra/test_adns.py + - testinfra/test_ns.py - job: name: infra-prod-playbook diff --git a/playbooks/base.yaml b/playbooks/base.yaml index 10f416de21..4c9ee170e4 100644 --- a/playbooks/base.yaml +++ b/playbooks/base.yaml @@ -46,3 +46,8 @@ name: "Base: configure adns1.opendev.org" roles: - master-nameserver + +- hosts: "ns1.opendev.org:ns2.opendev.org:!disabled" + name: "Base: configure authoritative nameservers" + roles: + - nameserver diff --git a/playbooks/group_vars/dns.yaml b/playbooks/group_vars/dns.yaml index 8d8cccbe48..9dd73eee0d 100644 --- a/playbooks/group_vars/dns.yaml +++ b/playbooks/group_vars/dns.yaml @@ -13,3 +13,4 @@ dns_zones: dns_notify: - 104.239.140.165 - 162.253.55.16 +dns_master: 104.239.146.24 diff --git a/playbooks/roles/nameserver/README.rst b/playbooks/roles/nameserver/README.rst new file mode 100644 index 0000000000..353bfe6772 --- /dev/null +++ b/playbooks/roles/nameserver/README.rst @@ -0,0 +1,42 @@ +Configure an authoritative nameserver + +This role installs and configures nsd to be an authoritative +nameserver. + +**Role Variables** + +.. zuul:rolevar:: tsig_key + :type: dict + + The TSIG key used to authenticate connections between nameservers. + + .. zuul:rolevar:: algorithm + + The algorithm used by the key. + + .. zuul:rolevar:: secret + + The secret portion of the key. + +.. zuul:rolevar:: dns_zones + :type: list + + A list of zones that should be served by named. Each item in the + list is a dictionary with the following keys: + + .. zuul:rolevar:: name + + The name of the zone. + + .. zuul:rolevar:: source + + The repo name and path of the directory containing the zone + file. For example if a repo was provided to + :zuul:rolevar:`master-nameserver.dns_repos.name` with the name + ``example.com``, and within that repo, the ``zone.db`` file was + located at ``zones/example_com/zone.db``, then the value here + should be ``example.com/zones/example_com``. + +.. zuul:rolevar:: dns_master + + The IP addresses of the master nameserver. diff --git a/playbooks/roles/nameserver/handlers/main.yaml b/playbooks/roles/nameserver/handlers/main.yaml new file mode 100644 index 0000000000..e3fec10611 --- /dev/null +++ b/playbooks/roles/nameserver/handlers/main.yaml @@ -0,0 +1,2 @@ +- name: Reconfigure NSD + command: "nsd-control reconfig" diff --git a/playbooks/roles/nameserver/tasks/main.yaml b/playbooks/roles/nameserver/tasks/main.yaml new file mode 100644 index 0000000000..21a83de3f8 --- /dev/null +++ b/playbooks/roles/nameserver/tasks/main.yaml @@ -0,0 +1,23 @@ +# Install the NSD config before installing the package because the +# default packaged config listens on all addresses therefore will +# not start. +- name: Ensure NSD config directory exists + file: + path: /etc/nsd + state: directory +- name: Install NSD config + template: + src: templates/nsd.conf.j2 + dest: /etc/nsd/nsd.conf + owner: root + group: root + mode: 0444 + notify: Reconfigure NSD +- name: Install packages + package: + name: + - nsd +- name: Enable NSD + service: + name: nsd + enabled: true diff --git a/playbooks/roles/nameserver/templates/nsd.conf.j2 b/playbooks/roles/nameserver/templates/nsd.conf.j2 new file mode 100644 index 0000000000..4627273b11 --- /dev/null +++ b/playbooks/roles/nameserver/templates/nsd.conf.j2 @@ -0,0 +1,41 @@ +server: +{% if 'address' in ansible_facts.default_ipv4 %} + ip-address: {{ ansible_facts.default_ipv4.address }} +{% endif %} +{% if 'address' in ansible_facts.default_ipv6 %} + ip-address: {{ ansible_facts.default_ipv6.address }} +{% endif %} + ip-transparent: no + debug-mode: no + database: /var/lib/nsd/nsd.db + identity: {{ inventory_hostname }} + server-count: 1 + tcp-count: 250 + tcp-query-count: 0 + ipv4-edns-size: 4096 + ipv6-edns-size: 4096 + pidfile: /run/nsd/nsd.pid + port: 53 + username: nsd + zonesdir: /var/lib/nsd + xfrdfile: /var/lib/nsd/xfrd.state + xfrd-reload-timeout: 1 + verbosity: 0 + hide-version: no + rrl-size: 1000000 + rrl-ratelimit: 200 + rrl-slip: 2 + rrl-ipv4-prefix-length: 24 + rrl-ipv6-prefix-length: 64 + rrl-whitelist-ratelimit: 4000 +key: + name: tsig + algorithm: {{ tsig_key.algorithm }} + secret: {{ tsig_key.secret }} +{% for zone in dns_zones %} +zone: + name: {{ zone.name }} + zonefile: /var/lib/nsd/zone/{{ zone.name }} + allow-notify: {{ dns_master }} NOKEY + request-xfr: AXFR {{ dns_master }} tsig +{% endfor %} diff --git a/playbooks/zuul/run-base.yaml b/playbooks/zuul/run-base.yaml index ecb48e058e..0ff4c311a6 100644 --- a/playbooks/zuul/run-base.yaml +++ b/playbooks/zuul/run-base.yaml @@ -60,6 +60,7 @@ - group_vars/all.yaml - group_vars/adns.yaml - group_vars/nodepool.yaml + - group_vars/ns.yaml - host_vars/bridge.openstack.org.yaml - name: Display group membership command: ansible localhost -m debug -a 'var=groups' diff --git a/playbooks/zuul/templates/group_vars/ns.yaml.j2 b/playbooks/zuul/templates/group_vars/ns.yaml.j2 new file mode 100644 index 0000000000..1ad4df1c74 --- /dev/null +++ b/playbooks/zuul/templates/group_vars/ns.yaml.j2 @@ -0,0 +1,3 @@ +tsig_key: + algorithm: hmac-md5 + secret: 9zO/4WnUinnLHISPgDI5Aw== diff --git a/testinfra/test_ns.py b/testinfra/test_ns.py new file mode 100644 index 0000000000..09303d63c0 --- /dev/null +++ b/testinfra/test_ns.py @@ -0,0 +1,21 @@ +# Copyright 2018 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +testinfra_hosts = ['ns1.opendev.org'] + + +def test_nsd(host): + nsd = host.service('nsd') + assert nsd.is_running