Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions partition/roles/metal-core/test/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import os


def read_template_file(name):
with open(os.path.join(os.path.dirname(__file__), "..", "templates", name), 'r') as f:
return f.read()
159 changes: 159 additions & 0 deletions partition/roles/metal-core/test/template_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import unittest

import yaml
import os
from textwrap import dedent

from ansible.template import Templar

from test import read_template_file


def read_defaults():
with open(os.path.join(os.path.dirname(__file__), "..", "defaults", "main.yaml"), "r") as stream:
return yaml.safe_load(stream)


def read_partition_defaults():
with open(os.path.join(os.path.dirname(__file__), "..", "..", "defaults", "defaults", "main.yaml"), "r") as stream:
return yaml.safe_load(stream)


def base_vars():
return read_partition_defaults() | read_defaults() | dict(
metal_partition_timezone="Europe/Berlin",
metal_partition_id="fra-equ01",
metal_partition_metal_api_addr="api.metal-stack.dev",
lo="10.0.0.11",
asn=4200000011,
metal_core_cidr="10.255.255.2/24",
metal_core_rack_id="rack01",
)


class MetalCoreEnv(unittest.TestCase):
maxDiff = None

def test_env_template(self):
t = read_template_file("metal-core-env.j2")

templar = Templar(loader=None, variables=base_vars())

result = templar.template(t)

self.assertEqual(dedent("""\
TZ: "Europe/Berlin"
METAL_CORE_LOOPBACK_IP: "10.0.0.11"
METAL_CORE_ASN: "4200000011"
METAL_CORE_CIDR: "10.255.255.2/24"
METAL_CORE_PARTITION_ID: "fra-equ01"
METAL_CORE_RACK_ID: "rack01"
METAL_CORE_BIND_ADDRESS: 0.0.0.0
METAL_CORE_METAL_API_IP: "api.metal-stack.dev"
METAL_CORE_METAL_API_PORT: "443"
METAL_CORE_METAL_API_PROTOCOL: "https"
METAL_CORE_METAL_API_BASEPATH: "/"
METAL_CORE_HMAC_KEY: "change-me"
METAL_CORE_LOG_LEVEL: "warn"
METAL_CORE_RECONFIGURE_SWITCH: "True"
METAL_CORE_RECONFIGURE_SWITCH_INTERVAL: "10s"
METAL_CORE_TIMEOUT: "15s"
METAL_CORE_SET_SRC_LOOPBACK: "True"
METAL_CORE_GRPC_ADDRESS: "api.metal-stack.dev:50051"
METAL_CORE_GRPC_CA_CERT_FILE: "/certs/grpc/ca.pem"
METAL_CORE_GRPC_CLIENT_CERT_FILE: "/certs/grpc/client.pem"
METAL_CORE_GRPC_CLIENT_KEY_FILE: "/certs/grpc/client-key.pem"
METAL_CORE_ADDITIONAL_BRIDGE_VIDS: ""
METAL_CORE_ADDITIONAL_BRIDGE_PORTS: ""
METAL_CORE_INTERFACES_TPL_FILE: ""
METAL_CORE_FRR_TPL_FILE: ""
METAL_CORE_PXE_VLAN_ID: "4000"
"""), result)

def test_env_template_with_room_id_mgmt_gateway_and_spine_uplinks(self):
t = read_template_file("metal-core-env.j2")

templar = Templar(loader=None, variables=base_vars() | dict(
metal_core_room_id="room01",
metal_partition_mgmt_gateway="10.255.255.1",
metal_core_spine_uplinks=["Ethernet0", "Ethernet4"],
metal_core_additional_bridge_vids=["201-256"],
metal_core_additional_bridge_ports=["Ethernet96", "Ethernet100"],
))

result = templar.template(t)

self.assertEqual(dedent("""\
TZ: "Europe/Berlin"
METAL_CORE_LOOPBACK_IP: "10.0.0.11"
METAL_CORE_ASN: "4200000011"
METAL_CORE_CIDR: "10.255.255.2/24"
METAL_CORE_PARTITION_ID: "fra-equ01"
METAL_CORE_RACK_ID: "rack01"
METAL_CORE_ROOM_ID: "room01"
METAL_CORE_BIND_ADDRESS: 0.0.0.0
METAL_CORE_METAL_API_IP: "api.metal-stack.dev"
METAL_CORE_METAL_API_PORT: "443"
METAL_CORE_METAL_API_PROTOCOL: "https"
METAL_CORE_METAL_API_BASEPATH: "/"
METAL_CORE_HMAC_KEY: "change-me"
METAL_CORE_LOG_LEVEL: "warn"
METAL_CORE_RECONFIGURE_SWITCH: "True"
METAL_CORE_RECONFIGURE_SWITCH_INTERVAL: "10s"
METAL_CORE_TIMEOUT: "15s"
METAL_CORE_SET_SRC_LOOPBACK: "True"
METAL_CORE_MANAGEMENT_GATEWAY: "10.255.255.1"
METAL_CORE_GRPC_ADDRESS: "api.metal-stack.dev:50051"
METAL_CORE_GRPC_CA_CERT_FILE: "/certs/grpc/ca.pem"
METAL_CORE_GRPC_CLIENT_CERT_FILE: "/certs/grpc/client.pem"
METAL_CORE_GRPC_CLIENT_KEY_FILE: "/certs/grpc/client-key.pem"
METAL_CORE_ADDITIONAL_BRIDGE_VIDS: "201-256"
METAL_CORE_ADDITIONAL_BRIDGE_PORTS: "Ethernet96,Ethernet100"
METAL_CORE_SPINE_UPLINKS: "Ethernet0,Ethernet4"
METAL_CORE_INTERFACES_TPL_FILE: ""
METAL_CORE_FRR_TPL_FILE: ""
METAL_CORE_PXE_VLAN_ID: "4000"
"""), result)


class MetalCoreVolumes(unittest.TestCase):
maxDiff = None

def test_volumes_template_sonic(self):
t = read_template_file("metal-core-volumes.j2")

templar = Templar(loader=None, variables=base_vars() | dict(
metal_stack_switch_os_is_sonic=True,
))

result = templar.template(t)

self.assertEqual(dedent("""\
- /etc/sonic/:/etc/sonic
- /var/run/redis/:/var/run/redis
- /var/run/dbus:/var/run/dbus
- /run/systemd/private:/run/systemd/private
- "/certs/grpc:/certs/grpc:ro"
- /var/run/bgp-neighbors:/var/run/bgp-neighbors"""), result)

def test_volumes_template_cumulus_with_hosts_file_resolution_and_additional_mounts(self):
t = read_template_file("metal-core-volumes.j2")

templar = Templar(loader=None, variables=base_vars() | dict(
metal_stack_switch_os_is_sonic=False,
metal_core_consider_hosts_file_resolution=True,
metal_core_additional_volume_mounts=["/etc/motd:/etc/motd:ro"],
))

result = templar.template(t)

self.assertEqual(dedent("""\
- /etc/network/:/etc/network
- /etc/frr/:/etc/frr
- /etc/lsb-release:/etc/lsb-release:ro
- /var/run/dbus:/var/run/dbus
- /run/systemd/private:/run/systemd/private
- /etc/nsswitch.conf:/etc/nsswitch.conf
- "/certs/grpc:/certs/grpc:ro"
- /etc/motd:/etc/motd:ro
- /var/run/bgp-neighbors:/var/run/bgp-neighbors"""), result)
6 changes: 6 additions & 0 deletions partition/roles/mgmt-server/test/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import os


def read_template_file(name):
with open(os.path.join(os.path.dirname(__file__), "..", "templates", name), 'r') as f:
return f.read()
208 changes: 208 additions & 0 deletions partition/roles/mgmt-server/test/template_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
import unittest

import yaml
import os
from textwrap import dedent

from ansible.template import Templar

from test import read_template_file


def read_defaults():
with open(os.path.join(os.path.dirname(__file__), "..", "defaults", "main.yaml"), "r") as stream:
return yaml.safe_load(stream)


class MgmtServerFrrConf(unittest.TestCase):
maxDiff = None

def test_frr_conf_template(self):
t = read_template_file("frr.conf.j2")

templar = Templar(loader=None, variables=read_defaults() | dict(
ansible_hostname="mgmt01",
mgmt_server_asn=4200000000,
mgmt_server_router_id="10.1.0.1",
mgmt_server_spine_facing_interface="lan0",
))

result = templar.template(t)

self.assertEqual(dedent("""\
frr defaults datacenter
hostname mgmt01
!
service integrated-vtysh-config
!
log syslog debugging
debug bgp updates
debug bgp nht
debug bgp update-groups
debug bgp zebra
!
interface lan0
ipv6 nd ra-interval 6
no ipv6 nd suppress-ra
!
router bgp 4200000000
bgp router-id 10.1.0.1
bgp bestpath as-path multipath-relax
bgp network import-check
neighbor FABRIC peer-group
neighbor FABRIC remote-as external
neighbor FABRIC timers 1 3
neighbor lan0 interface peer-group FABRIC
!
address-family ipv4 unicast
redistribute connected route-map LOCAL_INTERFACES
exit-address-family
!
route-map LOCAL_INTERFACES permit 10
match interface lo
!
line vty
!
"""), result)

def test_frr_conf_template_with_firewall_static_routes_and_default_route(self):
t = read_template_file("frr.conf.j2")

templar = Templar(loader=None, variables=read_defaults() | dict(
ansible_hostname="mgmt01",
mgmt_server_asn=4200000000,
mgmt_server_router_id="10.1.0.1",
mgmt_server_spine_facing_interface="lan0",
mgmt_server_firewall_ip="10.1.0.2",
mgmt_server_provide_default_route=True,
mgmt_server_frr_static_routes=[
"10.100.0.0/22 10.1.0.254",
"192.168.0.0/16 10.1.0.253",
],
))

result = templar.template(t)

self.assertEqual(dedent("""\
frr defaults datacenter
hostname mgmt01
!
service integrated-vtysh-config
!
log syslog debugging
debug bgp updates
debug bgp nht
debug bgp update-groups
debug bgp zebra
!
ip route 10.100.0.0/22 10.1.0.254
ip route 192.168.0.0/16 10.1.0.253
!
interface lan0
ipv6 nd ra-interval 6
no ipv6 nd suppress-ra
!
router bgp 4200000000
bgp router-id 10.1.0.1
bgp bestpath as-path multipath-relax
bgp network import-check
neighbor FABRIC peer-group
neighbor FABRIC remote-as external
neighbor FABRIC timers 1 3
neighbor lan0 interface peer-group FABRIC
neighbor 10.1.0.2 peer-group FABRIC
neighbor 10.1.0.2 disable-connected-check
!
address-family ipv4 unicast
redistribute connected route-map LOCAL_INTERFACES
network 0.0.0.0/0
exit-address-family
!
route-map LOCAL_INTERFACES permit 10
match interface lo
!
line vty
!
"""), result)


class MgmtServerSSHConfig(unittest.TestCase):
maxDiff = None

def test_ssh_config_template(self):
t = read_template_file("ssh_config.j2")

# leaf02 comes before leaf01 to prove hosts are rendered in sorted
# order, mgmt01 has no ansible_user and must be skipped entirely
templar = Templar(loader=None, variables=read_defaults() | dict(
mgmt_server_metal_ssh_options=["StrictHostKeyChecking no"],
mgmt_server_metal_ssh_groups=["leaf02", "mgmt01", "leaf01"],
hostvars=dict(
leaf01=dict(ansible_host="10.1.0.10", ansible_user="admin", host_alias="exit01"),
leaf02=dict(ansible_host="10.1.0.11", ansible_user="admin"),
mgmt01=dict(ansible_host="10.1.0.1"),
),
))

result = templar.template(t)

self.assertEqual(dedent("""\
StrictHostKeyChecking no
Host leaf01 exit01
User admin
Host leaf02{trailing_space}
User admin
""").format(trailing_space=" "), result)


class MgmtServerResolvedConf(unittest.TestCase):
maxDiff = None

def test_resolved_conf_template_with_defaults(self):
t = read_template_file("resolved.conf.j2")

templar = Templar(loader=None, variables=read_defaults())

result = templar.template(t)

self.assertEqual(dedent("""\
[Resolve]
DNS=193.110.81.0#dns0.eu
DNS=2a0f:fc80::#dns0.eu
DNS=185.253.5.0#dns0.eu
DNS=2a0f:fc81::#dns0.eu

DNSOverTLS=yes
"""), result)

def test_resolved_conf_template_without_dns_over_tls(self):
t = read_template_file("resolved.conf.j2")

templar = Templar(loader=None, variables=read_defaults() | dict(
mgmt_server_nameservers=["10.1.0.53"],
mgmt_server_dns_over_tls=False,
))

result = templar.template(t)

self.assertEqual(dedent("""\
[Resolve]
DNS=10.1.0.53

"""), result)


class MgmtServerDockerDaemonJson(unittest.TestCase):
maxDiff = None

def test_daemon_json_template(self):
t = read_template_file("daemon.json.j2")

templar = Templar(loader=None, variables=read_defaults())

result = templar.template(t, convert_data=False)

self.assertEqual(dedent("""\
{
"registry-mirrors": ["https://mirror.gcr.io"]
}"""), result)
Loading