openstack-ansible-nspawn_hosts/tasks/nspawn_networking.yml

231 lines
11 KiB
YAML

---
# Copyright 2017, Rackspace US, 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.
- block:
- name: Create machined proxy override unit directories
file:
path: "/etc/systemd/system/{{ item }}"
owner: root
group: root
mode: '0755'
state: directory
with_items:
- systemd-machined.service.d
- systemd-importd.service.d
- name: Drop the machined proxy override units
template:
src: systemd-proxy-unit.conf.j2
dest: /etc/systemd/system/{{ item }}/proxy.conf
owner: root
group: root
mode: '0644'
with_items:
- systemd-machined.service.d
- systemd-importd.service.d
when:
- (deployment_environment_variables | default({})).keys() | length > 0
- name: Load override systemd-nspawn@
template:
src: systemd-nspawn@.service.j2
dest: /etc/systemd/system/systemd-nspawn@.service
notify:
- Reload systemd-daemon
- name: Run the systemd service role
include_role:
name: systemd_service
private: true
vars:
systemd_user_name: "root"
systemd_group_name: "root"
systemd_tempd_prefix: machine
systemd_slice_name: machine
systemd_lock_path: /var/lock/machine
systemd_services:
- service_name: "nspawn-macvlan"
program_sandboxing:
PrivateTmp: True
PrivateDevices: True
config_overrides:
Unit:
After: network-online.target
Before: systemd-networkd.service
PartOf: systemd-networkd.service
Description: nspawn host macvlan integrations
Wants: network-online.target
Service:
RemainAfterExit: yes
service_type: oneshot
execstarts: |-
{%- set start_commands = [] %}
{%- set seen_start_interfaces = [] %}
{%- for key, value in nspawn_combined_networks.items() %}
{%- set interface = value.bridge.split('br-')[-1] %}
{%- set mv_interface = 'mv-' + interface %}
{%- if value.bridge not in seen_start_interfaces %}
{%- if value.private_device | default(false) | bool %}
{%- set _ = start_commands.append('-/sbin/ip link add dev ' + value.bridge + ' type dummy') %}
{%- set _ = start_commands.append('-/sbin/ip link set dev ' + value.bridge + ' up') %}
{%- endif %}
{%- set interface_from_ansible = 'ansible_' + value.bridge | replace('-', '_') %}
{%- set interface_data = hostvars[inventory_hostname][interface_from_ansible] | default({'type': none}) %}
{%- if interface_data['type'] == 'bridge' %}
{%- set _ = start_commands.append('-/sbin/ip link add dev veth-' + interface + '1 type veth peer name veth-' + interface + '2') %}
{%- set _ = start_commands.append('-/sbin/ip link set dev veth-' + interface + '1 up') %}
{%- set _ = start_commands.append('-/sbin/ip link set dev veth-' + interface + '1 mtu ' ~ (interface_data["mtu"] | default(1500))) %}
{%- set _ = start_commands.append('-/sbin/ip link set dev veth-' + interface + '2 up') %}
{%- set _ = start_commands.append('-/sbin/ip link set dev veth-' + interface + '2 mtu ' ~ (interface_data["mtu"] | default(1500))) %}
{%- set _ = start_commands.append('-/sbin/ip link set dev veth-' + interface + '1 master ' + value.bridge) %}
{%- set _ = start_commands.append('-/sbin/ip link add ' + mv_interface + ' link veth-' + interface + '2 mtu ' ~ (interface_data["mtu"] | default(1500)) ~ ' type macvlan mode ' + value.macvlan_mode | default(nspawn_macvlan_mode)) %}
{%- set _ = start_commands.append('-/sbin/ip link set dev ' + mv_interface + ' up') %}
{%- else %}
{%- set _ = start_commands.append('-/sbin/ip link add ' + mv_interface + ' link ' + value.bridge + ' mtu ' ~ (interface_data["mtu"] | default(1500)) ~ ' type macvlan mode ' + value.macvlan_mode | default(nspawn_macvlan_mode)) %}
{%- set _ = start_commands.append('-/sbin/ip link set dev ' + mv_interface + ' up') %}
{% if not (value.enable_dhcp | default(false)) | bool %}
{% if hostvars[inventory_hostname][key.split('_')[0] + '_cidr'] is defined %}
{% set net_cidr = hostvars[inventory_hostname]['container_cidr'] %}
{%- set _ = start_commands.append('-/sbin/ip route add local ' + net_cidr + ' dev ' + mv_interface + ' metric 100 proto kernel scope host table local') %}
{% elif (value.address is defined) and (value.netmask is defined) %}
{% set prefix = (value.address ~ '/' ~ value.netmask) | ipaddr('prefix') %}
{% set _network = (value.address ~ '/' ~ prefix) | ipaddr('network') %}
{% set _net_addr_network = (_network ~ '/' ~ prefix) %}
{%- set _ = start_commands.append('-/sbin/ip route add local ' + _net_addr_network + ' dev ' + mv_interface + ' metric 100 proto kernel scope host table local') %}
{%- endif %}
{%- endif %}
{%- endif %}
{%- endif %}
{%- endfor %}
{{ start_commands }}
enabled: yes
state: started
tags:
- network-config
- systemd-networkd
- name: Run the systemd-networkd role
include_role:
name: systemd_networkd
private: true
vars:
systemd_networkd_prefix: "nspawn_host"
systemd_run_networkd: true
systemd_interface_cleanup: false
systemd_netdevs: |-
{% set seen_netdevs = [] %}
{% set _netdevs = [] %}
{% for _, value in (nspawn_networks | combine(container_extra_networks | default({}))).items() %}
{% set netname = value.interface | default('mv-' + value.bridge.split('br-')[-1]) %}
{% set _netdev = {'NetDev': {'Name': netname, 'Kind': 'macvlan'}, 'MACVLAN': {'Mode': 'bridge'}} %}
{% if netname not in seen_netdevs %}
{% set _ = _netdevs.append(_netdev) %}
{% set _ = seen_netdevs.append(netname) %}
{% endif %}
{% endfor %}
{{ _netdevs | sort(attribute='NetDev.Name') }}
systemd_networks: |-
{% set seen_networks = [] %}
{% set _networks = [] %}
{# All nspawn_networks and container_extra_networks will be iterated over. #}
{# If a device is found, a networkd config will be generated for it. #}
{% for _, value in (nspawn_networks | combine(container_extra_networks | default({}))).items() %}
{% set netname = value.interface | default('mv-' + value.bridge.split('br-')[-1]) %}
{% set _network = {'interface': netname} %}
{% if netname not in seen_networks %}
{% set _ = seen_networks.append(netname) %}
{% if value.address is defined %}
{% set _ = _network.__setitem__('address', value.address) %}
{% if (value.netmask is defined) and (_network.address != 'dhcp') %}
{% set _ = _network.__setitem__('netmask', value.netmask) %}
{% set prefix = (value.address + '/' + value.netmask) | ipaddr('prefix') %}
{% set _ = _network.__setitem__('address', [value.address + '/' + prefix | string]) %}
{% endif %}
{% endif %}
{% set _ = _network.__setitem__('usedns', (value.usedns | default(true) | bool) | ternary('yes', 'no')) %}
{% set _ = _network.__setitem__('static_routes', value.static_routes | default([])) %}
{% if value.gateway is defined %}
{% set _ = _network.__setitem__('gateway', value.gateway) %}
{% endif %}
{% set _ = _network.__setitem__('mtu', value.mtu | default(1500 | string)) %}
{% set _ = _network.__setitem__('config_overrides', {'Network': {'IPForward': 'yes', 'IPMasquerade': 'yes'}, 'Link': {'ARP': 'yes'}}) %}
{% set _ = _networks.append(_network) %}
{% endif %}
{% endfor %}
{{ _networks | sort(attribute='interface') }}
tags:
- network-config
- systemd-networkd
- name: Create dnsmasq config(s)
template:
src: "dnsmasq-config.conf.j2"
dest: "/etc/dnsmasq.d/dnsmasq-{{ 'mv-' + item.value.bridge.split('br-')[-1] }}.conf"
with_dict: "{{ nspawn_combined_networks }}"
when:
- item.value.enable_dhcp | default(false) | bool
notify:
- Enable network dnsmasq service
- name: Run the systemd service role
include_role:
name: systemd_service
private: true
vars:
systemd_user_name: "root"
systemd_group_name: "root"
systemd_tempd_prefix: machine
systemd_slice_name: machine
systemd_lock_path: /var/lock/machine
systemd_CPUAccounting: true
systemd_BlockIOAccounting: true
systemd_MemoryAccounting: true
systemd_TasksAccounting: true
systemd_services:
- service_name: "dnsmasq-{{ 'mv-' + dnsmasq_var.value.bridge.split('br-')[-1] }}"
program_sandboxing:
PrivateTmp: True
PrivateDevices: True
config_overrides:
Unit:
Description: networking-post-up
After:
? network-online.target
? systemd-networkd.service
? nspawn-macvlan.service
PartOf: systemd-networkd.service
Wants: network-online.target
Service:
RemainAfterExit: yes
ExecStartPre: "-/sbin/iptables -t nat -A POSTROUTING -s {{ dnsmasq_var.value.address }}/{{ (dnsmasq_var.value.address | string + '/' + dnsmasq_var.value.netmask | string) | ipaddr('prefix') }} ! -d {{ dnsmasq_var.value.address }}/{{ (dnsmasq_var.value.address | string + '/' + dnsmasq_var.value.netmask | string) | ipaddr('prefix') }} -j MASQUERADE"
ExecStopPost: "-/sbin/iptables -t nat -D POSTROUTING -s {{ dnsmasq_var.value.address }}/{{ (dnsmasq_var.value.address | string + '/' + dnsmasq_var.value.netmask | string) | ipaddr('prefix') }} ! -d {{ dnsmasq_var.value.address }}/{{ (dnsmasq_var.value.address | string + '/' + dnsmasq_var.value.netmask | string) | ipaddr('prefix') }} -j MASQUERADE"
PIDFile: /run/run/nspawn-{{ dnsmasq_var.value.bridge }}-dnsmasq.pid
execstarts:
- "/usr/sbin/dnsmasq --keep-in-foreground --conf-file=/etc/dnsmasq.d/dnsmasq-{{ 'mv-' + dnsmasq_var.value.bridge.split('br-')[-1] }}.conf"
execstops:
- "-/usr/bin/killall -u systemd-network --regexp ^dnsmasq"
enabled: yes
state: started
when:
- dnsmasq_var.value.enable_dhcp | default(false) | bool
- dnsmasq_var.value.address is defined
- dnsmasq_var.value.netmask is defined
with_dict: "{{ nspawn_combined_networks }}"
loop_control:
loop_var: dnsmasq_var
tags:
- network-config
- systemd-service