mirror of https://github.com/sipwise/ngcpcfg.git
Since we manage this as a template, the configuration is getting more and more complex and it's important to have comprehensive tests that help us to detect problems when we add options and change templates. Change-Id: Ieff8449f3d6d1cd74a9b44d49e1642a1bf02efc2changes/70/24770/6
parent
43ac83d1d6
commit
f6596cc9cf
@ -0,0 +1,37 @@
|
||||
# directory name where ngcpcfg is managed through git
|
||||
[ -n "${NGCPCTL_BASE:-}" ] || NGCPCTL_BASE="$(pwd)/"
|
||||
[ -n "${NGCPCTL_MAIN:-}" ] || NGCPCTL_MAIN="${NGCPCTL_BASE}/fixtures/repos/"
|
||||
[ -n "${NGCPCTL_CONFIG:-}" ] || NGCPCTL_CONFIG="${NGCPCTL_MAIN}/config.yml"
|
||||
[ -n "${HOST_CONFIG:-}" ] || HOST_CONFIG="${NGCPCTL_MAIN}/config.$(hostname).yml"
|
||||
[ -n "${LOCAL_CONFIG:-}" ] || LOCAL_CONFIG="${NGCPCTL_MAIN}/config.local.yml"
|
||||
[ -n "${CONSTANTS_CONFIG:-}" ] || CONSTANTS_CONFIG="${NGCPCTL_MAIN}/constants.yml"
|
||||
[ -n "${NETWORK_CONFIG:-}" ] || NETWORK_CONFIG="${NGCPCTL_MAIN}/network_network_interfaces.yml"
|
||||
[ -n "${RTP_INTERFACES_CONFIG:-}" ] || RTP_INTERFACES_CONFIG="/etc/ngcp-rtpengine-daemon/interfaces.yml"
|
||||
[ -n "${EXTRA_CONFIG_DIR:-}" ] || EXTRA_CONFIG_DIR="${NGCPCTL_MAIN}/config.d/"
|
||||
|
||||
# configuration dirs that should be managed
|
||||
[ -n "${CONFIG_POOL:-}" ] || CONFIG_POOL='/etc /var'
|
||||
|
||||
# location of templates
|
||||
[ -n "${TEMPLATE_POOL_BASE:-}" ] || TEMPLATE_POOL_BASE="${NGCPCTL_MAIN}/templates"
|
||||
|
||||
# location of service definitions
|
||||
[ -n "${SERVICES_POOL_BASE:-}" ] || SERVICES_POOL_BASE="${NGCPCTL_MAIN}/templates"
|
||||
|
||||
# Backward compatibility config for upgrade mr3.4*->mr3.5*
|
||||
# it can be removed when the next LTS is released:
|
||||
[ -n "${TEMPLATE_POOL:-}" ] || TEMPLATE_POOL="${TEMPLATE_POOL_BASE}/etc"
|
||||
[ -n "${SERVICES_POOL:-}" ] || SERVICES_POOL="${SERVICES_POOL_BASE}/etc"
|
||||
|
||||
# timestamp format for console output
|
||||
[ -n "${TIME_FORMAT:-}" ] || TIME_FORMAT="+%F %T"
|
||||
|
||||
# Run-time state directory
|
||||
[ -n "${RUN_DIR:-}" ] || RUN_DIR='/var/run'
|
||||
|
||||
# directory holding files for internal state of ngcpcfg
|
||||
[ -n "${STATE_FILES_DIR:-}" ] || STATE_FILES_DIR='/var/lib/ngcpcfg/state/'
|
||||
|
||||
# validate configs using kwalify schema
|
||||
[ -n "${VALIDATE_SCHEMA:-}" ] || VALIDATE_SCHEMA="false"
|
||||
## END OF FILE #################################################################
|
||||
@ -0,0 +1,74 @@
|
||||
# File autogenerated by ngcpcfg
|
||||
|
||||
# eth11 ----------------------
|
||||
auto eth11
|
||||
iface eth11 inet manual
|
||||
pre-up ethtool -K eth11 sg off
|
||||
# --------------------------------------------
|
||||
|
||||
# eth22 ----------------------
|
||||
auto eth22
|
||||
iface eth22 inet manual
|
||||
pre-up ethtool -K eth22 sg off
|
||||
# --------------------------------------------
|
||||
|
||||
# bond0 ----------------------
|
||||
auto bond0
|
||||
iface bond0 inet static
|
||||
address 10.10.10.2
|
||||
netmask 255.0.0.0
|
||||
gateway 10.10.10.254
|
||||
bond-slaves eth11 eth22
|
||||
bond-mode active-backup
|
||||
bond-miimon 100
|
||||
# --------------------------------------------
|
||||
|
||||
# lo ----------------------
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
iface lo inet6 loopback
|
||||
# --------------------------------------------
|
||||
|
||||
# eth46 ----------------------
|
||||
auto eth46
|
||||
iface eth46 inet static
|
||||
address 127.11.22.33
|
||||
netmask 255.0.0.0
|
||||
gateway 127.11.22.254
|
||||
hwaddress c0:ff:ee:15:90:0d
|
||||
dns-nameservers 127.0.0.1 1.1.1.1
|
||||
iface eth46 inet6 static
|
||||
address 2001:aaaa:1111:bbbb:2222:cccc:3333:dddd
|
||||
netmask 64
|
||||
gateway 2001:aaaa:1111:bbbb:2222:cccc:3333:0001
|
||||
hwaddress c0:ff:ee:15:90:0d
|
||||
dns-nameservers ::1 2606:4700:4700::1111
|
||||
# --------------------------------------------
|
||||
|
||||
# vlan1111 ----------------------
|
||||
auto vlan1111
|
||||
iface vlan1111 inet static
|
||||
address 10.11.11.11
|
||||
netmask 255.0.0.0
|
||||
gateway 10.11.11.254
|
||||
vlan-raw-device bond0
|
||||
# --------------------------------------------
|
||||
|
||||
# vlan2222 ----------------------
|
||||
auto vlan2222
|
||||
iface vlan2222 inet static
|
||||
address 10.22.22.22
|
||||
netmask 255.0.0.0
|
||||
gateway 10.22.22.254
|
||||
vlan-raw-device bond0
|
||||
# --------------------------------------------
|
||||
|
||||
# vlan3333 ----------------------
|
||||
auto vlan3333
|
||||
iface vlan3333 inet static
|
||||
address 10.33.33.33
|
||||
netmask 255.0.0.0
|
||||
gateway 10.33.33.254
|
||||
vlan-raw-device bond0
|
||||
# --------------------------------------------
|
||||
|
||||
@ -0,0 +1,83 @@
|
||||
---
|
||||
hosts:
|
||||
self:
|
||||
bond0:
|
||||
bond_miimon: '100'
|
||||
bond_mode: active-backup
|
||||
bond_slaves: eth11 eth22
|
||||
gateway: 10.10.10.254
|
||||
ip: 10.10.10.2
|
||||
netmask: 255.0.0.0
|
||||
dbnode: '1'
|
||||
eth11:
|
||||
dhcp: yes
|
||||
hwaddr: 11:11:11:11:11:11
|
||||
mtu: '1111'
|
||||
eth22:
|
||||
dhcp: yes
|
||||
hwaddr: 22:22:22:22:22:22
|
||||
mtu: '2222'
|
||||
eth46:
|
||||
dns_nameservers:
|
||||
- 127.0.0.1
|
||||
- 1.1.1.1
|
||||
- ::1
|
||||
- 2606:4700:4700::1111
|
||||
gateway: 127.11.22.254
|
||||
hwaddr: c0:ff:ee:15:90:0d
|
||||
ip: 127.11.22.33
|
||||
netmask: 255.0.0.0
|
||||
v6gateway: 2001:aaaa:1111:bbbb:2222:cccc:3333:0001
|
||||
v6ip: 2001:aaaa:1111:bbbb:2222:cccc:3333:dddd
|
||||
v6netmask: '64'
|
||||
interfaces:
|
||||
- lo
|
||||
- eth46
|
||||
- bond0
|
||||
- eth11
|
||||
- eth22
|
||||
- vlan1111
|
||||
- vlan2222
|
||||
- vlan3333
|
||||
lo:
|
||||
ip: 127.0.0.1
|
||||
netmask: 255.255.255.0
|
||||
type:
|
||||
- sip_int
|
||||
- ha_int
|
||||
- web_ext
|
||||
- sip_ext
|
||||
- rtp_ext
|
||||
- ssh_ext
|
||||
- mon_ext
|
||||
role:
|
||||
- proxy
|
||||
- lb
|
||||
- mgmt
|
||||
vlan1111:
|
||||
gateway: 10.11.11.254
|
||||
ip: 10.11.11.11
|
||||
netmask: 255.0.0.0
|
||||
type:
|
||||
- ha_int
|
||||
- ssh_ext
|
||||
- stor_int
|
||||
vlan_raw_device: bond0
|
||||
vlan2222:
|
||||
gateway: 10.22.22.254
|
||||
ip: 10.22.22.22
|
||||
netmask: 255.0.0.0
|
||||
type:
|
||||
- mon_ext
|
||||
- ssh_ext
|
||||
vlan_raw_device: bond0
|
||||
vlan3333:
|
||||
gateway: 10.33.33.254
|
||||
ip: 10.33.33.33
|
||||
netmask: 255.0.0.0
|
||||
type:
|
||||
- web_ext
|
||||
- web_int
|
||||
vlan_raw_device: bond0
|
||||
status: online
|
||||
swraiddevices: []
|
||||
@ -0,0 +1,322 @@
|
||||
# File autogenerated by ngcpcfg
|
||||
|
||||
[%
|
||||
hostname = ngcp.get_hostname();
|
||||
|
||||
# in SPCE there's no proper hostname, but "self", default to it
|
||||
UNLESS hosts.${hostname};
|
||||
hostname = 'self';
|
||||
END;
|
||||
|
||||
MACRO print_start_interface BLOCK;
|
||||
"# ${interface} ----------------------\n";
|
||||
"auto ${interface}\n";
|
||||
END;
|
||||
|
||||
MACRO print_end_interface BLOCK;
|
||||
"# --------------------------------------------\n\n";
|
||||
END;
|
||||
|
||||
MACRO print_bond_fields BLOCK;
|
||||
IF iface.bond_slaves;
|
||||
bslaves = iface.bond_slaves.join(" ").trim();
|
||||
" bond-slaves ${bslaves}\n";
|
||||
END;
|
||||
IF iface.bond_mode;
|
||||
" bond-mode ${iface.bond_mode}\n";
|
||||
END;
|
||||
IF iface.bond_miimon;
|
||||
" bond-miimon ${iface.bond_miimon}\n";
|
||||
END;
|
||||
IF iface.bond_primary;
|
||||
" bond-primary ${iface.bond_primary}\n";
|
||||
END;
|
||||
IF iface.bond_updelay;
|
||||
" bond-updelay ${iface.bond_updelay}\n";
|
||||
END;
|
||||
IF iface.bond_downdelay;
|
||||
" bond-downdelay ${iface.bond_downdelay}\n";
|
||||
END;
|
||||
IF iface.bond_xmit_hash_policy;
|
||||
" bond-xmit-hash-policy ${iface.bond_xmit_hash_policy}\n";
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_hwaddress BLOCK;
|
||||
IF iface.hwaddr;
|
||||
" hwaddress ${iface.hwaddr}\n";
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_mtu BLOCK;
|
||||
IF iface.mtu;
|
||||
IF (iface.ip or iface.v6ip or iface.dhcp == 'yes' or iface.v6dhcp == 'yes');
|
||||
" mtu ${iface.mtu}\n";
|
||||
ELSE;
|
||||
" pre-up ip link set dev ${iface.name} mtu ${iface.mtu}\n";
|
||||
END;
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_hardware_options BLOCK;
|
||||
print_hwaddress;
|
||||
print_mtu;
|
||||
END;
|
||||
|
||||
MACRO print_address_v4 BLOCK;
|
||||
IF iface.ip;
|
||||
" address ${iface.ip}\n";
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_address_v6 BLOCK;
|
||||
IF iface.v6ip;
|
||||
" address ${iface.v6ip}\n";
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_netmask_v4 BLOCK;
|
||||
IF iface.netmask;
|
||||
" netmask ${iface.netmask}\n";
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_netmask_v6 BLOCK;
|
||||
IF iface.v6netmask;
|
||||
" netmask ${iface.v6netmask}\n";
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_gateway_v4 BLOCK;
|
||||
gateway = iface.gateway.trim();
|
||||
IF gateway;
|
||||
" gateway ${gateway}\n";
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_gateway_v6 BLOCK;
|
||||
gateway = iface.v6gateway.trim();
|
||||
IF gateway;
|
||||
" gateway ${gateway}\n";
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_dns_nameservers_v4 BLOCK;
|
||||
nservers = iface.dns_nameservers.grep('\.').join(" ").trim();
|
||||
IF nservers;
|
||||
" dns-nameservers ${nservers}\n";
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_dns_nameservers_v6 BLOCK;
|
||||
nservers = iface.dns_nameservers.grep(':').join(" ").trim();
|
||||
IF nservers;
|
||||
" dns-nameservers ${nservers}\n";
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_vlan_raw_device BLOCK;
|
||||
IF iface.vlan_raw_device;
|
||||
devs = iface.vlan_raw_device.join(" ").trim();
|
||||
" vlan-raw-device ${devs}\n";
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_pre_up_v4 BLOCK;
|
||||
IF iface.pre_up;
|
||||
FOREACH rule IN iface.pre_up;
|
||||
" pre-up ${rule}\n";
|
||||
END;
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_pre_up_v6 BLOCK;
|
||||
IF iface.v6pre_up;
|
||||
FOREACH rule IN iface.v6pre_up;
|
||||
" pre-up ${rule}\n";
|
||||
END;
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_post_up_v4 BLOCK;
|
||||
IF iface.post_up;
|
||||
FOREACH rule IN iface.post_up;
|
||||
" post-up ${rule}\n";
|
||||
END;
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_post_up_v6 BLOCK;
|
||||
IF iface.v6post_up;
|
||||
FOREACH rule IN iface.v6post_up;
|
||||
" post-up ${rule}\n";
|
||||
END;
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_pre_down_v4 BLOCK;
|
||||
IF iface.pre_down;
|
||||
FOREACH rule IN iface.pre_down;
|
||||
" pre-down ${rule}\n";
|
||||
END;
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_pre_down_v6 BLOCK;
|
||||
IF iface.v6pre_down;
|
||||
FOREACH rule IN iface.v6pre_down;
|
||||
" pre-down ${rule}\n";
|
||||
END;
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_post_down_v4 BLOCK;
|
||||
IF iface.post_down;
|
||||
FOREACH rule IN iface.post_down;
|
||||
" post-down ${rule}\n";
|
||||
END;
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_post_down_v6 BLOCK;
|
||||
IF iface.v6post_down;
|
||||
FOREACH rule IN iface.v6post_down;
|
||||
" post-down ${rule}\n";
|
||||
END;
|
||||
END;
|
||||
END;
|
||||
|
||||
MACRO print_up_down_v4 BLOCK;
|
||||
print_pre_up_v4;
|
||||
print_post_up_v4;
|
||||
print_pre_down_v4;
|
||||
print_post_down_v4;
|
||||
END;
|
||||
|
||||
MACRO print_up_down_v6 BLOCK;
|
||||
print_pre_up_v6;
|
||||
print_post_up_v6;
|
||||
print_pre_down_v6;
|
||||
print_post_down_v6;
|
||||
END;
|
||||
|
||||
MACRO print_interface BLOCK;
|
||||
iface = hosts.${hostname}.${interface};
|
||||
|
||||
print_start_interface(interface=interface);
|
||||
|
||||
IF interface == 'lo';
|
||||
"iface ${interface} inet loopback\n";
|
||||
"iface ${interface} inet6 loopback\n";
|
||||
ELSE;
|
||||
|
||||
# ipv4
|
||||
IF iface.manual == 'yes';
|
||||
"iface ${interface} inet manual\n";
|
||||
print_hardware_options(iface=iface);
|
||||
print_up_down_v4(iface=iface);
|
||||
ELSIF iface.dhcp == 'yes';
|
||||
"iface ${interface} inet dhcp\n";
|
||||
ELSIF iface.ip;
|
||||
"iface ${interface} inet static\n";
|
||||
print_address_v4(iface=iface);
|
||||
print_netmask_v4(iface=iface);
|
||||
print_gateway_v4(iface=iface);
|
||||
ELSE;
|
||||
ipv4=no;
|
||||
END;
|
||||
|
||||
# ipv4-related fields
|
||||
IF iface.ip or iface.dhcp == 'yes';
|
||||
# common, they can be attached to any protocol of the interface
|
||||
print_hardware_options(iface=iface);
|
||||
print_bond_fields(iface=iface);
|
||||
print_vlan_raw_device(iface=iface);
|
||||
|
||||
print_dns_nameservers_v4(iface=iface);
|
||||
print_up_down_v4(iface=iface);
|
||||
END;
|
||||
|
||||
# ipv6
|
||||
IF iface.v6manual == 'yes';
|
||||
"iface ${interface} inet6 manual\n";
|
||||
print_hardware_options(iface=iface);
|
||||
print_up_down_v6(iface=iface);
|
||||
ELSIF iface.v6dhcp == 'yes';
|
||||
"iface ${interface} inet6 dhcp\n";
|
||||
ELSIF iface.v6ip;
|
||||
"iface ${interface} inet6 static\n";
|
||||
print_address_v6(iface=iface);
|
||||
print_netmask_v6(iface=iface);
|
||||
print_gateway_v6(iface=iface);
|
||||
ELSE;
|
||||
ipv6=no;
|
||||
END;
|
||||
|
||||
# ipv6-related fields
|
||||
IF iface.v6ip or iface.v6dhcp == 'yes';
|
||||
# common, they can be attached to any protocol of the interface
|
||||
print_hardware_options(iface=iface);
|
||||
print_bond_fields(iface=iface);
|
||||
print_vlan_raw_device(iface=iface);
|
||||
|
||||
print_dns_nameservers_v6(iface=iface);
|
||||
print_up_down_v6(iface=iface);
|
||||
END;
|
||||
|
||||
# disable "Duplicate Address Detection", it creates problems with HA resource transfer
|
||||
IF iface.shared_v6ip;
|
||||
" dad-attempts 0\n";
|
||||
" pre-up echo 0 > /proc/sys/net/ipv6/conf/${interface}/accept_dad\n";
|
||||
END;
|
||||
|
||||
IF ipv4 == 'no' and ipv6 == 'no';
|
||||
"# ERROR, neither IPv4 nor IPv6 present in network configuration\n";
|
||||
END;
|
||||
|
||||
END;
|
||||
|
||||
print_end_interface();
|
||||
END;
|
||||
|
||||
|
||||
all_interfaces = hosts.${hostname}.interfaces;
|
||||
|
||||
# print bond* interfaces in the beginning, needs to happen before vlan* start to
|
||||
# use them, otherwise "ifup -a" does not work
|
||||
FOREACH interface IN all_interfaces;
|
||||
# "# debug: host ${hostname}: processing interface ${interface}\n";
|
||||
|
||||
iface = hosts.${hostname}.${interface};
|
||||
|
||||
IF iface.bond_slaves;
|
||||
interfaces_in_bond = iface.bond_slaves.split(" ");
|
||||
FOREACH phys_interface IN interfaces_in_bond;
|
||||
|
||||
print_start_interface(interface=phys_interface);
|
||||
"iface ${phys_interface} inet manual\n";
|
||||
" pre-up ethtool -K ${phys_interface} sg off\n";
|
||||
print_hardware_options(iface=iface);
|
||||
print_up_down_v4(iface=iface);
|
||||
print_end_interface();
|
||||
|
||||
# remove now to not process again, but lists do not allow to remove
|
||||
# elements straight away
|
||||
all_interfaces = all_interfaces.join(" ").remove("${phys_interface}").split(" +");
|
||||
END;
|
||||
|
||||
print_interface(interface=interface);
|
||||
END;
|
||||
END;
|
||||
|
||||
# print non-bond* and non-tun* interfaces
|
||||
FOREACH interface IN all_interfaces;
|
||||
# "# debug: host ${hostname}: processing interface ${interface}\n";
|
||||
|
||||
iface = hosts.${hostname}.${interface};
|
||||
|
||||
UNLESS iface.bond_slaves or interface.match('^tun[0-9]+$');
|
||||
print_interface(interface=interface);
|
||||
END;
|
||||
END;
|
||||
-%]
|
||||
@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env py.test-3
|
||||
|
||||
import filecmp
|
||||
import os
|
||||
import pytest
|
||||
import re
|
||||
import tempfile
|
||||
import sys
|
||||
|
||||
|
||||
@pytest.mark.tt_47255
|
||||
def test_network_interfaces(ngcpcfgcli, tmpdir):
|
||||
tmpdir = tempfile.mkdtemp(prefix='ngcp-', suffix='-pytest-output')
|
||||
out = ngcpcfgcli("build", "--ignore-branch-check",
|
||||
"/etc/network/interfaces",
|
||||
env={
|
||||
'NGCP_BASE_TT2': os.getcwd(),
|
||||
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
|
||||
'OUTPUT_DIRECTORY': tmpdir,
|
||||
'NGCPCFG': 'fixtures/ngcpcfg_network_interfaces.cfg',
|
||||
})
|
||||
|
||||
# debug, only printed in logs in case of error
|
||||
print("stdout:")
|
||||
print(out.stdout.replace("\\n", "\n"))
|
||||
print("stderr:")
|
||||
print(out.stderr.replace("\\n", "\n"))
|
||||
|
||||
regex1 = re.compile(r"Generating .*/etc/network/interfaces: OK")
|
||||
assert re.search(regex1, out.stdout)
|
||||
|
||||
regex2 = re.compile(r"Error")
|
||||
assert not re.search(regex2, out.stdout)
|
||||
assert not re.search(regex2, out.stderr)
|
||||
|
||||
output_file = os.path.join(tmpdir, "etc/network/interfaces")
|
||||
test_file = "fixtures/output/network_interfaces"
|
||||
|
||||
assert os.path.exists(output_file)
|
||||
assert os.path.exists(test_file)
|
||||
|
||||
# debug
|
||||
if not filecmp.cmp(output_file, test_file):
|
||||
print("output_file:")
|
||||
print(open(output_file).read())
|
||||
print("test_file:")
|
||||
print(open(test_file).read())
|
||||
assert filecmp.cmp(output_file, test_file)
|
||||
Loading…
Reference in new issue