|
15 | 15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 |
|
17 | 17 | import os |
| 18 | +import re |
18 | 19 | import unittest |
19 | 20 |
|
20 | 21 | from json import loads |
21 | 22 |
|
22 | 23 | from base_vyostest_shim import VyOSUnitTestSHIM |
| 24 | +from time import sleep |
23 | 25 |
|
24 | 26 | from vyos.configsession import ConfigSessionError |
| 27 | +from vyos.kea import kea_add_lease |
| 28 | +from vyos.kea import kea_delete_lease |
| 29 | +from vyos.utils.process import cmd |
25 | 30 | from vyos.utils.process import process_named_running |
26 | 31 | from vyos.utils.file import read_file |
27 | 32 | from vyos.template import inc_ip |
|
31 | 36 | CTRL_PROCESS_NAME = 'kea-ctrl-agent' |
32 | 37 | KEA4_CONF = '/run/kea/kea-dhcp4.conf' |
33 | 38 | KEA4_CTRL = '/run/kea/dhcp4-ctrl-socket' |
| 39 | +HOSTSD_CLIENT = '/usr/bin/vyos-hostsd-client' |
34 | 40 | base_path = ['service', 'dhcp-server'] |
35 | 41 | interface = 'dum8765' |
36 | 42 | subnet = '192.0.2.0/25' |
@@ -842,6 +848,79 @@ def test_dhcp_on_interface_with_vrf(self): |
842 | 848 | self.cli_delete(['vrf', 'name', 'SMOKE-DHCP']) |
843 | 849 | self.cli_commit() |
844 | 850 |
|
| 851 | + def test_dhcp_hostsd_lease_sync(self): |
| 852 | + shared_net_name = 'SMOKE-LEASE-SYNC' |
| 853 | + domain_name = 'sync.private' |
| 854 | + |
| 855 | + client_range = range(1, 4) |
| 856 | + subnet_range_start = inc_ip(subnet, 10) |
| 857 | + subnet_range_stop = inc_ip(subnet, 20) |
| 858 | + |
| 859 | + def internal_cleanup(): |
| 860 | + for seq in client_range: |
| 861 | + ip_addr = inc_ip(subnet, seq) |
| 862 | + kea_delete_lease(4, ip_addr) |
| 863 | + cmd(f'{HOSTSD_CLIENT} --delete-hosts --tag dhcp-server-{ip_addr} --apply') |
| 864 | + |
| 865 | + self.addClassCleanup(internal_cleanup) |
| 866 | + |
| 867 | + pool = base_path + ['shared-network-name', shared_net_name, 'subnet', subnet] |
| 868 | + self.cli_set(pool + ['subnet-id', '1']) |
| 869 | + self.cli_set(pool + ['option', 'domain-name', domain_name]) |
| 870 | + self.cli_set(pool + ['range', '0', 'start', subnet_range_start]) |
| 871 | + self.cli_set(pool + ['range', '0', 'stop', subnet_range_stop]) |
| 872 | + |
| 873 | + # commit changes |
| 874 | + self.cli_commit() |
| 875 | + |
| 876 | + config = read_file(KEA4_CONF) |
| 877 | + obj = loads(config) |
| 878 | + |
| 879 | + self.verify_config_value(obj, ['Dhcp4', 'shared-networks'], 'name', shared_net_name) |
| 880 | + self.verify_config_value(obj, ['Dhcp4', 'shared-networks', 0, 'subnet4'], 'subnet', subnet) |
| 881 | + self.verify_config_value(obj, ['Dhcp4', 'shared-networks', 0, 'subnet4'], 'id', 1) |
| 882 | + |
| 883 | + # Verify options |
| 884 | + self.verify_config_object( |
| 885 | + obj, |
| 886 | + ['Dhcp4', 'shared-networks', 0, 'subnet4', 0, 'option-data'], |
| 887 | + {'name': 'domain-name', 'data': domain_name}) |
| 888 | + self.verify_config_object( |
| 889 | + obj, |
| 890 | + ['Dhcp4', 'shared-networks', 0, 'subnet4', 0, 'pools'], |
| 891 | + {'pool': f'{subnet_range_start} - {subnet_range_stop}'}) |
| 892 | + |
| 893 | + # Check for running process |
| 894 | + self.assertTrue(process_named_running(PROCESS_NAME)) |
| 895 | + |
| 896 | + # All up and running, now test vyos-hostsd store |
| 897 | + |
| 898 | + # 1. Inject leases into kea |
| 899 | + for seq in client_range: |
| 900 | + client = f'client{seq}' |
| 901 | + mac = f'00:50:00:00:00:{seq:02}' |
| 902 | + ip = inc_ip(subnet, seq) |
| 903 | + kea_add_lease(4, ip, host_name=client, mac_address=mac) |
| 904 | + |
| 905 | + # 2. Verify that leases are not available in vyos-hostsd |
| 906 | + tag_regex = re.escape(f'dhcp-server-{subnet.rsplit(".", 1)[0]}') |
| 907 | + host_json = cmd(f'{HOSTSD_CLIENT} --get-hosts {tag_regex}') |
| 908 | + self.assertFalse(host_json.strip('{}')) |
| 909 | + |
| 910 | + # 3. Restart the service to trigger vyos-hostsd sync and wait for it to start |
| 911 | + self.op_mode(['restart', 'dhcp', 'server']) |
| 912 | + count = 0 |
| 913 | + while count < 30: |
| 914 | + is_running = process_named_running(PROCESS_NAME) |
| 915 | + if is_running: |
| 916 | + break |
| 917 | + count += 1 |
| 918 | + sleep(1) |
| 919 | + |
| 920 | + # 4. Verify that leases are synced and available in vyos-hostsd |
| 921 | + tag_regex = re.escape(f'dhcp-server-{subnet.rsplit(".", 1)[0]}') |
| 922 | + host_json = cmd(f'{HOSTSD_CLIENT} --get-hosts {tag_regex}') |
| 923 | + self.assertTrue(host_json) |
845 | 924 |
|
846 | 925 | if __name__ == '__main__': |
847 | 926 | unittest.main(verbosity=2) |
0 commit comments