[CORD-2270]
Support head node on Ubuntu 16.04 (Xenial)
Change-Id: Ic13ea784b8fa55a481f08d21f5187fd37d13499c
diff --git a/copy-profile-playbook.yml b/copy-profile-playbook.yml
index 9530fe0..a093527 100644
--- a/copy-profile-playbook.yml
+++ b/copy-profile-playbook.yml
@@ -1,4 +1,4 @@
-
+---
# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,8 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
----
# copy-profile-playbook.yml
# Copies the profile to the head node
@@ -32,7 +30,7 @@
roles:
- { role: copy-profile, become: yes }
- { role: ssh-install, become: yes }
- - { role: glance-images, become: yes, when: use_maas }
+ - { role: glance-images, become: yes, when: ( use_openstack | default(True) ) }
- { role: copy-credentials, become: yes, when: not ( frontend_only | default(False) ) }
- name: Install ssh keys when using MaaS
diff --git a/filter_plugins/genmac.py b/filter_plugins/genmac.py
deleted file mode 100644
index 02142ae..0000000
--- a/filter_plugins/genmac.py
+++ /dev/null
@@ -1,45 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# 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.
-
-
-import hashlib
-import netaddr
-
-def genmac(value, prefix='', length=12):
- '''
- deterministically generates a "random" MAC with a configurable prefix
- '''
-
- # from: http://serverfault.com/questions/40712/what-range-of-mac-addresses-can-i-safely-use-for-my-virtual-machines
- if prefix == '' :
- mac_prefix = "0ac04d" # random "cord"-esque
-
- # deterministically generate a value
- h = hashlib.new('sha1')
- h.update(value)
-
- # build/trim MAC
- mac_string = (mac_prefix + h.hexdigest())[0:length]
-
- return netaddr.EUI(mac_string)
-
-class FilterModule(object):
- ''' MAC generation filter '''
- filter_map = {
- 'genmac': genmac,
- }
-
- def filters(self):
- return self.filter_map
diff --git a/filter_plugins/unbound_revdns.py b/filter_plugins/unbound_revdns.py
new file mode 100644
index 0000000..a45e08e
--- /dev/null
+++ b/filter_plugins/unbound_revdns.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+
+# Copyright 2017-present Open Networking Foundation
+#
+# 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.
+
+# unbound_revdns - ansible filter - ipv4 address or cidr and generates a
+# reverse DNS string suitable for use with unbound, which requires them in a
+# slightly unusual format when a RFC1918 address is used with a local-zone
+# definition:
+# https://www.unbound.net/documentation/unbound.conf.html
+# https://www.claudiokuenzler.com/blog/699/unbound-dns-not-serving-reverse-lookup-for-internal-addresses-rfc1918
+
+import netaddr
+
+
+class FilterModule(object):
+
+ def filters(self):
+ return {
+ 'unbound_revdns': self.unbound_revdns,
+ }
+
+ def unbound_revdns(self, var):
+ (o1, o2, o3, o4) = netaddr.IPNetwork(var).network.words
+
+ revdns = "%d.%d.%d.%d.in-addr.arpa." % (o4, o3, o2, o1)
+
+ if (o2 == 0 or o1 == 10):
+ revdns = "%d.in-addr.arpa." % (o1)
+ elif (o3 == 0
+ or (o1 == 172 and o2 >= 16 and o2 <= 31)
+ or (o1 == 192 and o2 == 168)):
+ revdns = "%d.%d.in-addr.arpa." % (o2, o1)
+ elif(o4 == 0):
+ revdns = "%d.%d.%d.in-addr.arpa." % (o3, o2, o1)
+
+ return revdns
diff --git a/prep-headnode-playbook.yml b/prep-headnode-playbook.yml
index d9d64b3..9d89e50 100644
--- a/prep-headnode-playbook.yml
+++ b/prep-headnode-playbook.yml
@@ -1,4 +1,4 @@
-
+---
# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,8 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
----
# prep-headnode-playbook.yml
# Preps the head node of a CORD pod for thr est of the install
@@ -44,7 +42,7 @@
roles:
- docker-install
-- name: Configure management network
+- name: Configure network interfaces
hosts: head
become: yes
roles:
@@ -54,7 +52,6 @@
hosts: head
become: yes
roles:
- - { role: head-mgmtbr, when: not use_maas }
- { role: dns-nsd, when: not use_maas }
- { role: dns-unbound, when: not use_maas }
diff --git a/roles/dhcpd/defaults/main.yml b/roles/dhcpd/defaults/main.yml
index 66edc52..9772910 100644
--- a/roles/dhcpd/defaults/main.yml
+++ b/roles/dhcpd/defaults/main.yml
@@ -1,4 +1,4 @@
-
+---
# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,18 +13,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
----
# dhcpd/defaults/main.yml
-# http://serverfault.com/questions/40712/what-range-of-mac-addresses-can-i-safely-use-for-my-virtual-machines
-hwaddr_prefix: "c2a4"
-
site_name: placeholder-sitename
site_suffix: "{{ site_name }}.test"
-# Management IP range from DHCP settings
-mgmt_ipv4_first_octets: "192.168.200"
+management_net_cidr: "192.168.200.0/24"
+
+vtn_net_management_host_cidr: "{{ management_net_cidr }}"
+
+# http://serverfault.com/questions/40712/what-range-of-mac-addresses-can-i-safely-use-for-my-virtual-machines
+vtn_net_management_host_hwaddr_prefix: "06A6"
# node lists
head_lxd_list: []
@@ -33,13 +32,10 @@
dns_search:
- "{{ site_suffix }}"
-dns_servers:
- - "{{ mgmt_ipv4_first_octets }}.1"
-
dhcpd_subnets:
- - interface: mgmtbr
- cidr: "{{ mgmt_ipv4_first_octets }}.1/24"
- dhcp_first: 129
+ - interface: mgmtbridge
+ cidr: "{{ management_net_cidr }}"
+ dhcp_first: 193
dhcp_last: 254
other_static:
- physical_node_list
diff --git a/roles/dhcpd/templates/dhcpd.conf.j2 b/roles/dhcpd/templates/dhcpd.conf.j2
index 072d6d7..c54e578 100644
--- a/roles/dhcpd/templates/dhcpd.conf.j2
+++ b/roles/dhcpd/templates/dhcpd.conf.j2
@@ -1,4 +1,3 @@
-
{#
Copyright 2017-present Open Networking Foundation
@@ -15,7 +14,6 @@
limitations under the License.
#}
-
# dhcpd.conf
# Managed by Ansible!
@@ -52,7 +50,7 @@
option host-name "{{ node.name }}";
{% set host_ipaddr = (subnet.cidr | ipaddr(node.ipv4_last_octet) | ipaddr('address')) %}
fixed-address {{ host_ipaddr }};
- hardware ethernet {{ node.hwaddr | default(hwaddr_prefix ~ (host_ipaddr | ip4_hex)) | hwaddr('unix') }};
+ hardware ethernet {{ node.hwaddr | default(vtn_net_management_host_hwaddr_prefix ~ (host_ipaddr | ip4_hex)) | hwaddr('unix') }};
{% if node.pxe_filename is defined %}
filename "{{ node.pxe_filename }}";
next-server {{ subnet.tftp_server | default(subnet.cidr | ipaddr('1') | ipaddr('address')) }};
@@ -69,7 +67,7 @@
option host-name "{{ node.name }}";
{% set host_ipaddr = (subnet.cidr | ipaddr(node.ipv4_last_octet) | ipaddr('address')) %}
fixed-address {{ host_ipaddr }};
- hardware ethernet {{ node.hwaddr | default(hwaddr_prefix ~ (host_ipaddr | ip4_hex)) | hwaddr('unix') }};
+ hardware ethernet {{ node.hwaddr | default(vtn_net_management_host_hwaddr_prefix ~ (host_ipaddr | ip4_hex)) | hwaddr('unix') }};
{% if node.pxe_filename is defined %}
filename "{{ subnet.pxe_filename }}";
next-server {{ subnet.tftp_server | default(subnet.cidr | ipaddr('1') | ipaddr('address')) }};
diff --git a/roles/dns-configure/defaults/main.yml b/roles/dns-configure/defaults/main.yml
index 777b1e2..19cc84c 100644
--- a/roles/dns-configure/defaults/main.yml
+++ b/roles/dns-configure/defaults/main.yml
@@ -1,4 +1,4 @@
-
+---
# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,17 +13,58 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
----
# roles/dns-configure/defaults
+site_name: placeholder-sitename
+site_suffix: "{{ site_name }}.test"
+
+headnode_dns: head1
+
+management_net_cidr: "192.168.200.0/24"
+
+# node lists
+head_lxd_list: []
+physical_node_list: []
+
+# Set this to search domain suffixes
+dns_search:
+ - "{{ site_suffix }}"
+
+dns_servers:
+ - "{{ management_net_cidr | ipaddr('1') | ipaddr('address') }}"
+
+unbound_listen_on_default: False
+
# Define this to set dns servers manually
#dns_servers:
# - 8.8.8.8
# - 8.8.4.4
-# Set this to search domain suffixes
-# dns_search: {}
-
-unbound_listen_on_default: False
+# DNS settings for NSD/Unbound
+nsd_zones:
+ - name: "{{ site_suffix }}"
+ cidr: "{{ management_net_cidr }}"
+ soa: ns1
+ ns:
+ - { name: ns1 }
+ nodelists:
+ - head_lxd_list
+ - physical_node_list
+ aliases:
+ - { name: "apt-cache", dest: "{{ headnode_dns }}" }
+ - { name: "cordloghost", dest: "{{ headnode_dns }}" }
+ - { name: "consul", dest: "{{ headnode_dns }}" }
+ - { name: "docker", dest: "{{ headnode_dns }}" }
+ - { name: "mavenrepo", dest: "{{ headnode_dns }}" }
+ - { name: "ns", dest: "{{ headnode_dns }}" }
+ - { name: "ns1", dest: "{{ headnode_dns }}" }
+ - { name: "onos-cord", dest: "{{ headnode_dns }}" }
+ - { name: "onos-fabric", dest: "{{ headnode_dns }}" }
+ - { name: "xos", dest: "{{ headnode_dns }}" }
+ - { name: "xos-chameleon", dest: "{{ headnode_dns }}" }
+ - { name: "xos-consul", dest: "{{ headnode_dns }}" }
+ - { name: "xos-core", dest: "{{ headnode_dns }}" }
+ - { name: "xos-gui", dest: "{{ headnode_dns }}" }
+ - { name: "xos-tosca", dest: "{{ headnode_dns }}" }
+ - { name: "xos-ws", dest: "{{ headnode_dns }}" }
diff --git a/roles/dns-configure/tasks/main.yml b/roles/dns-configure/tasks/main.yml
index 83c3a6f..5ea0418 100644
--- a/roles/dns-configure/tasks/main.yml
+++ b/roles/dns-configure/tasks/main.yml
@@ -1,4 +1,4 @@
-
+---
# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,8 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
----
# roles/dns-configure/tasks.yml
- name: Make sure resolvconf is doing DNS resolver mangling
@@ -48,3 +46,12 @@
tags:
- skip_ansible_lint # purely a way to pass/fail config done so far. Ansible needs a "dns_query" module
+- name: Check that aliases can be found in DNS
+ when: not use_maas
+ shell: "dig +short {{ item.1.name }}.{{ site_suffix }} | grep {{ item.1.dest }}"
+ with_subelements:
+ - "{{ nsd_zones }}"
+ - aliases
+ tags:
+ - skip_ansible_lint # purely a way to pass/fail config done so far. Ansible needs a "dns_query" module
+
diff --git a/roles/dns-nsd/defaults/main.yml b/roles/dns-nsd/defaults/main.yml
index 4e80a0c..20f0fde 100644
--- a/roles/dns-nsd/defaults/main.yml
+++ b/roles/dns-nsd/defaults/main.yml
@@ -15,39 +15,34 @@
# dns-nsd/defaults/main.yml
-nsd_ip: 127.0.0.1
-
-nsd_conf: "/etc/nsd/nsd.conf"
-nsd_zonesdir: "/var/lib/nsd/zones"
-nsd_group: "nsd"
-
-# default DNS TTL
-dns_ttl: 3600
-
-# NOTE - many of the below settings are shared with the dns-nsd role, and you
-# may need to update them in the defaults of both.
-
-headnode_dns: head1
-
site_name: placeholder-sitename
site_suffix: "{{ site_name }}.test"
-# Management IP range from DHCP settings
-mgmt_ipv4_first_octets: "192.168.200"
-mgmt_name_reverse_unbound: "168.192.in-addr.arpa"
+headnode_dns: head1
-dns_servers:
- - "{{ mgmt_ipv4_first_octets }}.1"
+management_net_cidr: "192.168.200.0/24"
# node lists
head_lxd_list: []
physical_node_list: []
+# NOTE - many of the below settings are shared with the dns-nsd role, and you
+# may need to update them in the defaults of both.
+
+nsd_conf: "/etc/nsd/nsd.conf"
+nsd_zonesdir: "/var/lib/nsd/zones"
+
+nsd_group: "nsd"
+
+nsd_ip: 127.0.0.1
+nsd_port: 53
+
+dns_ttl: 3600
+
# DNS settings for NSD/Unbound
nsd_zones:
- name: "{{ site_suffix }}"
- ipv4_first_octets: "{{ mgmt_ipv4_first_octets }}"
- name_reverse_unbound: "{{ mgmt_name_reverse_unbound }}"
+ cidr: "{{ management_net_cidr }}"
soa: ns1
ns:
- { name: ns1 }
diff --git a/roles/dns-nsd/tasks/main.yml b/roles/dns-nsd/tasks/main.yml
index 91eeabd..83e35ab 100644
--- a/roles/dns-nsd/tasks/main.yml
+++ b/roles/dns-nsd/tasks/main.yml
@@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
# dns-nsd/tasks/main.yml
- name: Install nsd
@@ -24,8 +23,18 @@
cache_valid_time: 3600
with_items:
- nsd
+ register: nsd_install
-- name: Ensure that zones directory exists
+- name: Stop nsd until configured
+ when: nsd_install.changed
+ service:
+ name: nsd
+ enabled: no
+ state: stopped
+ tags:
+ - skip_ansible_lint # need to down service before configured
+
+- name: Create nsd zones directory
file:
name: "{{ nsd_zonesdir }}"
state: directory
@@ -43,7 +52,7 @@
notify:
- restart-nsd
-- name: create forward zonefiles from template
+- name: Create forward zonefiles from template
template:
src: zone.forward.j2
dest: "{{ nsd_zonesdir }}/{{ item.name }}.forward"
@@ -54,7 +63,7 @@
notify:
- reload-nsd
-- name: create reverse zonefiles from template
+- name: Create reverse zonefiles from template
template:
src: zone.reverse.j2
dest: "{{ nsd_zonesdir }}/{{ item.name }}.reverse"
diff --git a/roles/dns-nsd/templates/nsd.conf.j2 b/roles/dns-nsd/templates/nsd.conf.j2
index 4d5ead7..8e6c185 100644
--- a/roles/dns-nsd/templates/nsd.conf.j2
+++ b/roles/dns-nsd/templates/nsd.conf.j2
@@ -1,4 +1,3 @@
-
{#
Copyright 2017-present Open Networking Foundation
@@ -15,31 +14,30 @@
limitations under the License.
#}
-
# nsd.conf
-# configured by Ansible!
+# created by dns-nsd/templates/nsd.conf.j2
server:
hide-version: yes
## bind to a specific address/port
ip-address: {{ nsd_ip }}
## port number
- port: {{ nsd_port|default(53) }}
+ port: {{ nsd_port }}
server-count: 1
ip4-only: yes
zonesdir: {{ nsd_zonesdir }}
remote-control:
- control-enable: no
+ control-enable: yes
-# zones to load
+# zonefiles to load
{% for zone in nsd_zones %}
zone:
name: {{ zone.name }}
zonefile: {{ zone.name }}.forward
zone:
- name: {{ (zone.ipv4_first_octets ~ ".0") | ipaddr('revdns') | regex_replace('^0\.','') }}
+ name: {{ zone.cidr | unbound_revdns }}
zonefile: {{ zone.name }}.reverse
{% endfor %}
diff --git a/roles/dns-nsd/templates/zone.forward.j2 b/roles/dns-nsd/templates/zone.forward.j2
index 613576f..86eae0c 100644
--- a/roles/dns-nsd/templates/zone.forward.j2
+++ b/roles/dns-nsd/templates/zone.forward.j2
@@ -1,4 +1,3 @@
-
{#
Copyright 2017-present Open Networking Foundation
@@ -15,10 +14,9 @@
limitations under the License.
#}
-
;## NSD authoritative only DNS
;## FORWARD Zone
-;# created by ansible
+;# created by dns-nsd/templates/zone.forward.j2
$ORIGIN {{ item.name }}. ; default zone domain
$TTL {{ item.ttl | default(dns_ttl) }} ; default time to live
@@ -37,9 +35,6 @@
{% endfor %}
;A and CNAME records
-{% if name_on_public_interface is defined %}
-{{ name_on_public_interface }} IN A {{ ansible_default_ipv4.address }}
-{% endif %}
{% if item.aliases is defined %}
{% for alias in item.aliases %}
{{ alias.name }} IN CNAME {{ alias.dest }}
@@ -50,7 +45,7 @@
; Created from nodelist: {{ nodelist }}
{% set nodes = vars[nodelist] %}
{% for node in nodes %}
-{{ node.name }} IN A {{ item.ipv4_first_octets ~ "." ~ node.ipv4_last_octet }}
+{{ node.name }} IN A {{ item.cidr | ipaddr(node.ipv4_last_octet) | ipaddr('address') }}
{% if node.aliases is defined %}
{% for alias in node.aliases %}
{{ alias }} IN CNAME {{ node.name }}
diff --git a/roles/dns-nsd/templates/zone.reverse.j2 b/roles/dns-nsd/templates/zone.reverse.j2
index 1ddf7ba..fdfd73f 100644
--- a/roles/dns-nsd/templates/zone.reverse.j2
+++ b/roles/dns-nsd/templates/zone.reverse.j2
@@ -1,4 +1,3 @@
-
{#
Copyright 2017-present Open Networking Foundation
@@ -15,7 +14,6 @@
limitations under the License.
#}
-
;## NSD authoritative only DNS
;## REVERSE Zone for {{ item.name }}
;# created by ansible
@@ -23,7 +21,7 @@
$ORIGIN {{ item.name }}. ; default zone domain
$TTL {{ item.ttl | default(dns_ttl) }} ; default time to live
-{{ (item.ipv4_first_octets ~ ".0") | ipaddr('revdns') | regex_replace('^0\.','') }} IN SOA {{ item.soa }}.{{ item.name }}. admin.{{ item.name }}. (
+{{ item.cidr | unbound_revdns }} IN SOA {{ item.soa }}.{{ item.name }}. admin.{{ item.name }}. (
{{ item.serial | default(ansible_date_time.epoch) }} ; Serial, must be incremented every time you change this file
3600 ; Refresh [1hr]
600 ; Retry [10m]
@@ -37,7 +35,7 @@
; Created from nodelist: {{ nodelist }}
{% set nodes = vars[nodelist] %}
{% for node in nodes %}
-{{ (item.ipv4_first_octets ~ "." ~ node.ipv4_last_octet) | ipaddr('revdns') }} IN PTR {{ node.name }}
+{{ item.cidr | ipaddr(node.ipv4_last_octet) | ipaddr('revdns') }} IN PTR {{ node.name }}
{% endfor %}
{% endfor %}
diff --git a/roles/dns-unbound/defaults/main.yml b/roles/dns-unbound/defaults/main.yml
index a3f4aa7..6dec81b 100644
--- a/roles/dns-unbound/defaults/main.yml
+++ b/roles/dns-unbound/defaults/main.yml
@@ -15,37 +15,34 @@
# dns-unbound/defaults/main.yml
-unbound_conf: "/etc/unbound/unbound.conf"
-unbound_group: "unbound"
-
-unbound_listen_on_default: False
-
-unbound_listen_all: True
-
-# NOTE - many of the below settings are shared with the dns-nsd role, and you
-# may need to update them in the defaults of both.
-
+# Shared settings
site_name: placeholder-sitename
site_suffix: "{{ site_name }}.test"
headnode_dns: head1
-# Management IP range from DHCP settings
-mgmt_ipv4_first_octets: "192.168.200"
-mgmt_name_reverse_unbound: "168.192.in-addr.arpa"
-
-unbound_interfaces:
- - "{{ mgmt_ipv4_first_octets }}.1/24"
+management_net_cidr: "192.168.200.0/24"
# node lists
head_lxd_list: []
physical_node_list: []
+# NOTE - many of the below settings are shared with the dns-nsd role, and you
+# may need to update them in the defaults of both.
+
+nsd_ip: 127.0.0.1
+
+unbound_conf: "/etc/unbound/unbound.conf"
+unbound_group: "unbound"
+
+unbound_listen_on_default: False
+unbound_listen_all: True
+unbound_listen_zones: True
+
# DNS settings for NSD/Unbound
nsd_zones:
- name: "{{ site_suffix }}"
- ipv4_first_octets: "{{ mgmt_ipv4_first_octets }}"
- name_reverse_unbound: "{{ mgmt_name_reverse_unbound }}"
+ cidr: "{{ management_net_cidr }}"
soa: ns1
ns:
- { name: ns1 }
diff --git a/roles/dns-unbound/tasks/main.yml b/roles/dns-unbound/tasks/main.yml
index d2fe1a6..c4672d0 100644
--- a/roles/dns-unbound/tasks/main.yml
+++ b/roles/dns-unbound/tasks/main.yml
@@ -23,6 +23,16 @@
cache_valid_time: 3600
with_items:
- unbound
+ register: unbound_install
+
+- name: Stop unbound until configured
+ when: unbound_install.changed
+ service:
+ name: unbound
+ enabled: no
+ state: stopped
+ tags:
+ - skip_ansible_lint # need to down service before configured
- name: create unbound.conf from template
template:
@@ -33,7 +43,6 @@
group: "{{ unbound_group }}"
# validate='unbound-checkconf %s' - can't use, checks path, not just config.
notify:
- - start-unbound
- reload-unbound
- name: flush unbound handlers
diff --git a/roles/dns-unbound/templates/unbound.conf.j2 b/roles/dns-unbound/templates/unbound.conf.j2
index 59c44e9..121a706 100644
--- a/roles/dns-unbound/templates/unbound.conf.j2
+++ b/roles/dns-unbound/templates/unbound.conf.j2
@@ -1,4 +1,4 @@
-
+# created by dns-unbound/templates/unbound.conf.j2
{#
Copyright 2017-present Open Networking Foundation
@@ -15,21 +15,21 @@
limitations under the License.
#}
-
-# unbound.conf (configured by Ansible)
-
server:
{% if unbound_listen_on_default %}
- interface: {{ ansible_default_ipv4.address }}
+ # created by unbound_listen_on_default
+ interface: {{ ansible_default_ipv4.address }}
{% endif %}
-{% if unbound_interfaces is defined %}
-{% for cidr_ipv4 in unbound_interfaces %}
- interface: {{ cidr_ipv4 | ipaddr('address') }}
+{% if unbound_listen_zones %}
+{% for zone in nsd_zones %}
+ # created by nsd_zones: {{ zone.name }}
+ interface: {{ zone.cidr | ipaddr('1') | ipaddr('address') }}
{% endfor %}
{% endif %}
verbosity: 1
port: 53
do-ip4: yes
+ do-ip6: no
do-udp: yes
do-tcp: yes
@@ -41,36 +41,29 @@
access-control: 0.0.0.0/0 allow
{% endif %}
-{% if unbound_listen_on_default %}
- # allow from default interfaces
- access-control: {{ ansible_default_ipv4.address }}/{{ (ansible_default_ipv4.address ~ "/" ~ ansible_default_ipv4.netmask) | ipaddr('prefix') }} allow
-{% endif %}
-
-{% if unbound_interfaces is defined %}
- # allow from local networks
-{% for cidr_ipv4 in unbound_interfaces %}
- access-control: {{ cidr_ipv4 | ipaddr('0') }} allow
+{% if nsd_zones %}
+ # allow from networks defined in zones
+{% for zone in nsd_zones %}
+ access-control: {{ zone.cidr | ipaddr('0') }} allow
{% endfor %}
-{% endif %}
-{% if nsd_zones is defined %}
# allow unbound to query localhost, where nsd is listening
do-not-query-localhost: no
# allow reverse queries for RFC1918 addresses
{% for zone in nsd_zones %}
-local-zone: "{{ zone.name_reverse_unbound }}." nodefault
+local-zone: "{{ zone.cidr | unbound_revdns }}" nodefault
{% endfor %}
# stub-zones zones that nsd is serving
{% for zone in nsd_zones %}
stub-zone:
name: "{{ zone.name }}"
- stub-addr: {{ nsd_ip | default("127.0.0.1") }}
+ stub-addr: {{ nsd_ip }}
stub-zone:
- name: "{{ zone.name_reverse_unbound }}."
- stub-addr: {{ nsd_ip | default("127.0.0.1") }}
+ name: "{{ zone.cidr | unbound_revdns }}"
+ stub-addr: {{ nsd_ip }}
{% endfor %}
{% endif %}
diff --git a/roles/head-mgmtbr/defaults/main.yml b/roles/head-mgmtbr/defaults/main.yml
deleted file mode 100644
index 8bfb1a1..0000000
--- a/roles/head-mgmtbr/defaults/main.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# 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.
-
-
----
-# head-mgmtbr/defaults/main.yml
-
-# public internet facing NAT interface
-mgmtbr_nat_interface: eth0
-
-# management interface bridged to mgmtbr
-mgmtbr_ext_interface: eth1
diff --git a/roles/head-mgmtbr/tasks/main.yml b/roles/head-mgmtbr/tasks/main.yml
deleted file mode 100644
index 63314e4..0000000
--- a/roles/head-mgmtbr/tasks/main.yml
+++ /dev/null
@@ -1,52 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# 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.
-
-
----
-# head-mgmtbr/tasks/main.yml
-
-- name: Create mgmtbr bridge configuration
- template:
- src: "mgmtbr.cfg.j2"
- dest: /etc/network/interfaces.d/mgmtbr.cfg
- owner: root
- group: root
- mode: 0644
- register: mgmtbr_config
-
-- name: Bring up mgmtbr if reconfigured
- when: mgmtbr_config.changed and ansible_mgmtbr is not defined
- command: ifup mgmtbr
- tags:
- - skip_ansible_lint # needs to be run here or the next steps will fail
-
-- name: Default to accept forwarded traffic
- iptables:
- chain: FORWARD
- policy: ACCEPT
-
-- name: Configure NAT for mgmtbr
- iptables:
- table: nat
- chain: POSTROUTING
- out_interface: "{{ mgmtbr_nat_interface }}"
- jump: MASQUERADE
-
-- name: Configure forwarding for mgmtbr
- iptables:
- chain: FORWARD
- in_interface: mgmtbr
- jump: ACCEPT
-
diff --git a/roles/head-mgmtbr/templates/mgmtbr.cfg.j2 b/roles/head-mgmtbr/templates/mgmtbr.cfg.j2
deleted file mode 100644
index 374fefc..0000000
--- a/roles/head-mgmtbr/templates/mgmtbr.cfg.j2
+++ /dev/null
@@ -1,29 +0,0 @@
-
-{#
-Copyright 2017-present Open Networking Foundation
-
-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.
-#}
-
-
-auto mgmtbr
-iface mgmtbr inet static
- address {{ nsd_zones[0].ipv4_first_octets }}.1
- network {{ nsd_zones[0].ipv4_first_octets }}.0
- netmask 255.255.255.0
- broadcast {{ nsd_zones[0].ipv4_first_octets }}.255
- gateway {{ nsd_zones[0].ipv4_first_octets }}.1
- bridge_ports {{ mgmtbr_ext_interface }}
- dns-search {{ site_suffix }}
- dns-nameservers {{ dns_servers | join(" ") }}
-
diff --git a/roles/interface-config/defaults/main.yml b/roles/interface-config/defaults/main.yml
index e1039fd..8dcbf0e 100644
--- a/roles/interface-config/defaults/main.yml
+++ b/roles/interface-config/defaults/main.yml
@@ -1,4 +1,4 @@
-
+---
# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,14 +12,41 @@
# 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.
-
-
----
+#
# interface-config/defaults/main.yml
-mgmt_interface: eth1
-
-mgmt_ipv4_first_octets: "192.168.200"
-
+# list of physical nodes in the scenario
physical_node_list: []
+# headnode internet-facing interface to NAT mgmtbridge traffic out of
+headnode_nat_interface: eth0
+
+# network interfaces on physical nodes
+management_net_interfaces: []
+fabric_net_interfaces: []
+
+# management network configuration
+management_net_cidr: "192.168.200.0/24"
+dns_servers:
+ - "{{ management_net_cidr | ipaddr('1') | ipaddr('address') }}"
+
+# VTN MANAGEMENT_HOST network
+use_vtn_net_management_host: False
+vtn_net_management_host_cidr: "{{ management_net_cidr }}"
+vtn_net_management_host_hwaddr_prefix: "06A6"
+
+# VTN PUBLIC network, used with fabric
+use_vtn_net_fabric: False
+vtn_data_plane_interface: "vethfabric1"
+vtn_net_public_cidr: "10.6.1.0/24"
+vtn_net_public_hwaddr_prefix: "0242"
+
+# VSG and public address pools
+use_addresspool_vsg: False
+addresspool_vsg_cidr: "10.7.1.0/24"
+addresspool_vsg_hwaddr_prefix: "0ACA"
+
+use_addresspool_public: False
+addresspool_public_cidr: "10.8.1.0/24"
+addresspool_public_hwaddr_prefix: "0EFE"
+
diff --git a/roles/interface-config/handlers/main.yml b/roles/interface-config/handlers/main.yml
new file mode 100644
index 0000000..13b765b
--- /dev/null
+++ b/roles/interface-config/handlers/main.yml
@@ -0,0 +1,10 @@
+---
+# interface-config/handlers/main.yml
+
+# the next handler may need to change in 16.04 as iptables-persistent was split
+# and may need 'netfilter-persistent' installed as well
+- name: iptables-save
+ shell: iptables-save | grep -vi docker > /etc/iptables/rules.v4
+ tags:
+ - skip_ansible_lint
+
diff --git a/roles/interface-config/tasks/main.yml b/roles/interface-config/tasks/main.yml
index f768c38..44efe78 100644
--- a/roles/interface-config/tasks/main.yml
+++ b/roles/interface-config/tasks/main.yml
@@ -1,4 +1,4 @@
-
+---
# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,22 +13,90 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
----
# interface-config/tasks/main.yml
-- name: Create network interface for management network
+- name: Install bridging/bonding utilities
+ apt:
+ name: "{{ item }}"
+ update_cache: yes
+ cache_valid_time: 3600
+ with_items:
+ - bridge-utils
+ - ifenslave
+ - iptables-persistent
+
+- name: Create management network interfaces
template:
- src: eth.cfg.j2
- dest: "/etc/network/interfaces.d/{{ mgmt_interface }}.cfg"
+ src: management.cfg.j2
+ dest: "/etc/network/interfaces.d/management.cfg"
owner: root
group: root
mode: 0644
- register: mgmtint_config
+ register: management_net_config
-- name: Bring up management network if reconfigured
- when: mgmtint_config.changed
- command: "ifup {{ mgmt_interface }}"
+- name: Bring up management network interfaces, if reconfigured
+ when: management_net_config.changed
+ command: "ifup {{ item }}"
+ with_flattened:
+ - mgmtbridge
+ - mgmtbond
+ - "{{ management_net_interfaces }}"
+ - vethmgmt0
+ tags:
+ - skip_ansible_lint # needs to be run before next steps
+
+# NAT/forward management network traffic out the head node
+- name: Default to accept forwarded traffic
+ when: "'head' in group_names and management_net_config.changed"
+ iptables:
+ chain: FORWARD
+ policy: ACCEPT
+ notify:
+ - iptables-save
+ tags:
+ - skip_ansible_lint # need to save config in following steps
+
+- name: Configure forwarding for management bridge
+ when: "'head' in group_names and management_net_config.changed"
+ iptables:
+ chain: FORWARD
+ in_interface: mgmtbridge
+ jump: ACCEPT
+ notify:
+ - iptables-save
+ tags:
+ - skip_ansible_lint # need to save config in following steps
+
+- name: Configure NAT for management network
+ when: "'head' in group_names and management_net_config.changed"
+ iptables:
+ table: nat
+ chain: POSTROUTING
+ out_interface: "{{ headnode_nat_interface }}"
+ jump: MASQUERADE
+ notify:
+ - iptables-save
+ tags:
+ - skip_ansible_lint # need to save config in following steps
+
+# Create fabric bridge and veth pair
+- name: Create fabric network interfaces on compute nodes
+ template:
+ src: fabric.cfg.j2
+ dest: "/etc/network/interfaces.d/fabric.cfg"
+ owner: root
+ group: root
+ mode: 0644
+ register: compute_fabric_config
+
+- name: Bring up fabric interfaces, if reconfigured
+ when: compute_fabric_config.changed
+ command: "ifup {{ item }}"
+ with_flattened:
+ - fabricbridge
+ - fabricbond
+ - "{{ fabric_net_interfaces }}"
+ - vethfabric0
tags:
- skip_ansible_lint # needs to be run before next steps
diff --git a/roles/interface-config/templates/eth.cfg.j2 b/roles/interface-config/templates/eth.cfg.j2
deleted file mode 100644
index b9aa67d..0000000
--- a/roles/interface-config/templates/eth.cfg.j2
+++ /dev/null
@@ -1,30 +0,0 @@
-
-{#
-Copyright 2017-present Open Networking Foundation
-
-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.
-#}
-
-
-{% for node in physical_node_list if node.name == ansible_hostname %}
-auto {{ node.interface | default(mgmt_interface) }}
-
-iface {{ node.interface | default(mgmt_interface) }} inet static
- address {{ mgmt_ipv4_first_octets }}.{{ node.ipv4_last_octet }}
- network {{ mgmt_ipv4_first_octets }}.0
- netmask 255.255.255.0
- broadcast {{ mgmt_ipv4_first_octets }}.255
-{% if node.gateway_enabled is defined and node.gateway_enabled %}
- gateway {{ mgmt_ipv4_first_octets }}.1
-{% endif %}
-{% endfor %}
diff --git a/roles/interface-config/templates/fabric.cfg.j2 b/roles/interface-config/templates/fabric.cfg.j2
new file mode 100644
index 0000000..0547f6a
--- /dev/null
+++ b/roles/interface-config/templates/fabric.cfg.j2
@@ -0,0 +1,83 @@
+# Created by platform-install: interface-config/templates/fabric.cfg.j2
+{% for node in physical_node_list if node.name == ansible_hostname %}
+
+# fabricbridge between physical bond and virtual interfaces for VTN
+auto fabricbridge
+iface fabricbridge inet manual
+ pre-up ip link add fabricbridge type bridge
+ bridge_ports fabricbond vethfabric0
+
+# fabric bond of physical interfaces for VTN
+auto fabricbond
+iface fabricbond inet manual
+ pre-up ip link add fabricbond type bond
+ pre-up ip link set fabricbond up
+ bond-miimon 100
+ bond-slaves none
+ bond-mode active-backup
+ post-down ip link del fabricbond
+
+{% if fabric_net_interfaces %}
+# physical network members of fabricbond
+{% for fab_int in fabric_net_interfaces %}
+auto {{ fab_int }}
+iface {{ fab_int }} inet manual
+ pre-up ip link set {{ mgmt_int }} master fabricbond
+ bond-master fabricbond
+ bond-mode active-backup
+ bond-primary {{ management_net_interfaces | join(' ') }}
+ post-down ip link set dev {{ mgmt_int }} nomaster
+
+{% endfor %}
+{% endif %}
+
+# vethfabric0/vethfabric1 interfaces connect from VTN br-int to fabricbridge
+# vethfabric0: connected to fabricbridge
+auto vethfabric0
+iface vethfabric0 inet manual
+ pre-up ip link add vethfabric0 type veth peer name vethfabric1
+ pre-up ip link set vethfabric0 up
+ post-up ip link set dev vethfabric0 master fabricbridge
+ pre-down ip link set dev vethfabric0 nomaster
+ post-down ip link del vethfabric0
+
+# vethfabric1: becomes a part of br-int, which takes over the IP address
+{% set vtn_veth_ip = ( vtn_net_public_cidr | ipaddr(node.ipv4_last_octet) | ipaddr('address')) %}
+auto vethfabric1
+iface vethfabric1 inet static
+ address {{ vtn_veth_ip }}
+ network {{ vtn_net_public_cidr | ipaddr('network') }}
+ netmask {{ vtn_net_public_cidr | ipaddr('netmask') }}
+ gateway {{ vtn_net_public_cidr | ipaddr('1') | ipaddr('address') }}
+ broadcast {{ vtn_net_public_cidr | ipaddr('broadcast') }}
+ hwaddress ether {{ ( vtn_net_public_hwaddr_prefix ~ ( vtn_veth_ip | ip4_hex )) | hwaddr('unix') }}
+
+{% if use_addresspool_vsg %}
+# vSG public gateway
+{% set ap_vsg_veth_ip = ( addresspool_vsg_cidr | ipaddr(node.ipv4_last_octet) | ipaddr('address')) %}
+auto vethfabric1:0
+iface vethfabric1:0 inet static
+ address {{ ap_vsg_veth_ip }}
+ network {{ addresspool_vsg_cidr | ipaddr('network') }}
+ netmask {{ addresspool_vsg_cidr | ipaddr('netmask') }}
+ gateway {{ addresspool_vsg_cidr | ipaddr('1') | ipaddr('address') }}
+ broadcast {{ addresspool_vsg_cidr | ipaddr('broadcast') }}
+ hwaddress ether {{ ( addresspool_vsg_hwaddr_prefix ~ ( ap_vsg_eth_ip | ip4_hex )) | hwaddr('unix') }}
+
+{% endif %}
+
+{% if use_addresspool_public %}
+# public network gateway
+{% set ap_pub_veth_ip = ( addresspool_public_cidr | ipaddr(node.ipv4_last_octet) | ipaddr('address')) %}
+auto vethfabric1:1
+iface vethfabric1:1 inet static
+ address {{ ap_pub_veth_ip }}
+ network {{ addresspool_public_cidr | ipaddr('network') }}
+ netmask {{ addresspool_public_cidr | ipaddr('netmask') }}
+ gateway {{ addresspool_public_cidr | ipaddr('1') | ipaddr('address') }}
+ broadcast {{ addresspool_public_cidr | ipaddr('broadcast') }}
+ hwaddress ether {{ ( addresspool_public_hwaddr_prefix ~ ( ap_pub_veth_ip | ip4_hex )) | hwaddr('unix') }}
+
+{% endif %}
+{% endfor %}
+
diff --git a/roles/interface-config/templates/management.cfg.j2 b/roles/interface-config/templates/management.cfg.j2
new file mode 100644
index 0000000..bb3c1e6
--- /dev/null
+++ b/roles/interface-config/templates/management.cfg.j2
@@ -0,0 +1,57 @@
+# Created by platform-install: interface-config/templates/management.cfg.j2
+{% for node in physical_node_list if node.name == ansible_hostname %}
+
+# management bridge between physical and virtual interfaces for VTN
+{% set mgmtbr_ip = ( vtn_net_management_host_cidr | ipaddr(node.ipv4_last_octet) | ipaddr('address')) %}
+auto mgmtbridge
+iface mgmtbridge inet static
+ pre-up ip link add mgmtbridge type bridge
+ bridge_ports mgmtbond vethmgmt0
+ address {{ mgmtbr_ip }}
+ network {{ vtn_net_management_host_cidr | ipaddr('network') }}
+ netmask {{ vtn_net_management_host_cidr | ipaddr('netmask') }}
+ broadcast {{ vtn_net_management_host_cidr | ipaddr('broadcast') }}
+ hwaddress ether {{ ( vtn_net_management_host_hwaddr_prefix ~ ( mgmtbr_ip | ip4_hex )) | hwaddr('unix') }}
+ dns-search {{ site_suffix }}
+ dns-nameservers {{ dns_servers | join(" ") }}
+
+# management bond of physical interfaces
+auto mgmtbond
+iface mgmtbond inet manual
+ pre-up ip link add mgmtbond type bond
+ pre-up ip link set mgmtbond up
+ bond-slaves none
+ bond-mode active-backup
+ bond-miimon 100
+ post-down ip link del mgmtbond
+
+{% if management_net_interfaces %}
+# physical network members of mgmtbond
+{% for mgmt_int in management_net_interfaces %}
+auto {{ mgmt_int }}
+iface {{ mgmt_int }} inet manual
+ pre-up ip link set {{ mgmt_int }} master mgmtbond
+ bond-master mgmtbond
+ bond-mode active-backup
+ bond-primary {{ management_net_interfaces | join(' ') }}
+ post-down ip link set dev {{ mgmt_int }} nomaster
+
+{% endfor %}
+{% endif %}
+
+# veth interfaces for VTN MANAGEMENT_HOST
+# vethmgmt0: connected to mgmtbond
+auto vethmgmt0
+iface vethmgmt0 inet manual
+ pre-up ip link add vethmgmt0 type veth peer name vethmgmt1
+ pre-up ip link set vethmgmt0 up
+ pre-up ip link set vethmgmt1 up
+ post-up ip link set dev vethmgmt0 master mgmtbridge
+ pre-down ip link set dev vethmgmt0 nomaster
+ post-down ip link del vethmgmt0
+
+# vethmgmt1: connected to VTN as hostManagementIface, if enabled
+# Brought up by vethmgmt0
+
+{% endfor %}
+