summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/high-availability/keepalived.conf.j22
-rw-r--r--interface-definitions/high-availability.xml.in3
-rw-r--r--interface-definitions/include/address-ipv4-ipv6-single.xml.i18
-rw-r--r--interface-definitions/include/version/vrrp-version.xml.i2
-rwxr-xr-xsmoketest/scripts/cli/test_ha_virtual_server.py38
-rwxr-xr-xsrc/conf_mode/high-availability.py5
-rwxr-xr-xsrc/migration-scripts/vrrp/3-to-451
7 files changed, 100 insertions, 19 deletions
diff --git a/data/templates/high-availability/keepalived.conf.j2 b/data/templates/high-availability/keepalived.conf.j2
index bcd92358f..47408e345 100644
--- a/data/templates/high-availability/keepalived.conf.j2
+++ b/data/templates/high-availability/keepalived.conf.j2
@@ -173,7 +173,7 @@ vrrp_sync_group {{ name }} {
{% for vserver, vserver_config in virtual_server.items() %}
# Vserver {{ vserver }}
{% if vserver_config.port is vyos_defined %}
-virtual_server {{ vserver }} {{ vserver_config.port }} {
+virtual_server {{ vserver_config.address }} {{ vserver_config.port }} {
{% else %}
virtual_server fwmark {{ vserver_config.fwmark }} {
{% endif %}
diff --git a/interface-definitions/high-availability.xml.in b/interface-definitions/high-availability.xml.in
index d1bbcc365..4f55916fa 100644
--- a/interface-definitions/high-availability.xml.in
+++ b/interface-definitions/high-availability.xml.in
@@ -336,9 +336,10 @@
</node>
<tagNode name="virtual-server">
<properties>
- <help>Load-balancing virtual server address</help>
+ <help>Load-balancing virtual server alias</help>
</properties>
<children>
+ #include <include/address-ipv4-ipv6-single.xml.i>
<leafNode name="algorithm">
<properties>
<help>Schedule algorithm (default - least-connection)</help>
diff --git a/interface-definitions/include/address-ipv4-ipv6-single.xml.i b/interface-definitions/include/address-ipv4-ipv6-single.xml.i
new file mode 100644
index 000000000..dc3d6fc1b
--- /dev/null
+++ b/interface-definitions/include/address-ipv4-ipv6-single.xml.i
@@ -0,0 +1,18 @@
+<!-- include start from interface/address-ipv4-ipv6.xml.i -->
+<leafNode name="address">
+ <properties>
+ <help>IP address</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>IPv4 address</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>IPv6 address</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ip-address"/>
+ </constraint>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/version/vrrp-version.xml.i b/interface-definitions/include/version/vrrp-version.xml.i
index 626dd6cbc..1514b19ab 100644
--- a/interface-definitions/include/version/vrrp-version.xml.i
+++ b/interface-definitions/include/version/vrrp-version.xml.i
@@ -1,3 +1,3 @@
<!-- include start from include/version/vrrp-version.xml.i -->
-<syntaxVersion component='vrrp' version='3'></syntaxVersion>
+<syntaxVersion component='vrrp' version='4'></syntaxVersion>
<!-- include end -->
diff --git a/smoketest/scripts/cli/test_ha_virtual_server.py b/smoketest/scripts/cli/test_ha_virtual_server.py
index e3a91283e..6327df9df 100755
--- a/smoketest/scripts/cli/test_ha_virtual_server.py
+++ b/smoketest/scripts/cli/test_ha_virtual_server.py
@@ -47,6 +47,7 @@ class TestHAVirtualServer(VyOSUnitTestSHIM.TestCase):
delay = '10'
method = 'nat'
persistence_timeout = '600'
+ vs = 'serv-one'
vip = '203.0.113.111'
vport = '2222'
rservers = ['192.0.2.21', '192.0.2.22', '192.0.2.23']
@@ -56,21 +57,23 @@ class TestHAVirtualServer(VyOSUnitTestSHIM.TestCase):
vserver_base = base_path + ['virtual-server']
- self.cli_set(vserver_base + [vip, 'algorithm', algo])
- self.cli_set(vserver_base + [vip, 'delay-loop', delay])
- self.cli_set(vserver_base + [vip, 'forward-method', method])
- self.cli_set(vserver_base + [vip, 'persistence-timeout', persistence_timeout])
- self.cli_set(vserver_base + [vip, 'port', vport])
- self.cli_set(vserver_base + [vip, 'protocol', proto])
+ self.cli_set(vserver_base + [vs, 'address', vip])
+ self.cli_set(vserver_base + [vs, 'algorithm', algo])
+ self.cli_set(vserver_base + [vs, 'delay-loop', delay])
+ self.cli_set(vserver_base + [vs, 'forward-method', method])
+ self.cli_set(vserver_base + [vs, 'persistence-timeout', persistence_timeout])
+ self.cli_set(vserver_base + [vs, 'port', vport])
+ self.cli_set(vserver_base + [vs, 'protocol', proto])
for rs in rservers:
- self.cli_set(vserver_base + [vip, 'real-server', rs, 'connection-timeout', connection_timeout])
- self.cli_set(vserver_base + [vip, 'real-server', rs, 'port', rport])
+ self.cli_set(vserver_base + [vs, 'real-server', rs, 'connection-timeout', connection_timeout])
+ self.cli_set(vserver_base + [vs, 'real-server', rs, 'port', rport])
# commit changes
self.cli_commit()
config = read_file(KEEPALIVED_CONF)
+ self.assertIn(f'virtual_server {vip} {vport}', config)
self.assertIn(f'delay_loop {delay}', config)
self.assertIn(f'lb_algo lc', config)
self.assertIn(f'lb_kind {method.upper()}', config)
@@ -86,6 +89,7 @@ class TestHAVirtualServer(VyOSUnitTestSHIM.TestCase):
delay = '15'
method = 'nat'
persistence_timeout = '300'
+ vs = 'serv-two'
vip = '203.0.113.222'
vport = '22322'
rservers = ['192.0.2.11', '192.0.2.12']
@@ -107,15 +111,16 @@ class TestHAVirtualServer(VyOSUnitTestSHIM.TestCase):
self.cli_set(vrrp_base + [group, 'vrid', vrid])
# Virtual-server config
- self.cli_set(vserver_base + [vip, 'algorithm', algo])
- self.cli_set(vserver_base + [vip, 'delay-loop', delay])
- self.cli_set(vserver_base + [vip, 'forward-method', method])
- self.cli_set(vserver_base + [vip, 'persistence-timeout', persistence_timeout])
- self.cli_set(vserver_base + [vip, 'port', vport])
- self.cli_set(vserver_base + [vip, 'protocol', proto])
+ self.cli_set(vserver_base + [vs, 'address', vip])
+ self.cli_set(vserver_base + [vs, 'algorithm', algo])
+ self.cli_set(vserver_base + [vs, 'delay-loop', delay])
+ self.cli_set(vserver_base + [vs, 'forward-method', method])
+ self.cli_set(vserver_base + [vs, 'persistence-timeout', persistence_timeout])
+ self.cli_set(vserver_base + [vs, 'port', vport])
+ self.cli_set(vserver_base + [vs, 'protocol', proto])
for rs in rservers:
- self.cli_set(vserver_base + [vip, 'real-server', rs, 'connection-timeout', connection_timeout])
- self.cli_set(vserver_base + [vip, 'real-server', rs, 'port', rport])
+ self.cli_set(vserver_base + [vs, 'real-server', rs, 'connection-timeout', connection_timeout])
+ self.cli_set(vserver_base + [vs, 'real-server', rs, 'port', rport])
# commit changes
self.cli_commit()
@@ -131,6 +136,7 @@ class TestHAVirtualServer(VyOSUnitTestSHIM.TestCase):
self.assertIn(f'preempt_delay 0', config) # default value
# Keepalived virtual-server
+ self.assertIn(f'virtual_server {vip} {vport}', config)
self.assertIn(f'delay_loop {delay}', config)
self.assertIn(f'lb_algo lc', config)
self.assertIn(f'lb_kind {method.upper()}', config)
diff --git a/src/conf_mode/high-availability.py b/src/conf_mode/high-availability.py
index e18b426b1..2b1cdbd23 100755
--- a/src/conf_mode/high-availability.py
+++ b/src/conf_mode/high-availability.py
@@ -175,6 +175,11 @@ def verify(ha):
# Virtual-server
if 'virtual_server' in ha:
for vs, vs_config in ha['virtual_server'].items():
+
+ if 'address' not in vs_config and 'fwmark' not in vs_config:
+ raise ConfigError('Either address or fwmark is required '
+ f'but not set for virtual-server "{vs}"')
+
if 'port' not in vs_config and 'fwmark' not in vs_config:
raise ConfigError(f'Port or fwmark is required but not set for virtual-server "{vs}"')
if 'port' in vs_config and 'fwmark' in vs_config:
diff --git a/src/migration-scripts/vrrp/3-to-4 b/src/migration-scripts/vrrp/3-to-4
new file mode 100755
index 000000000..b0a6975c2
--- /dev/null
+++ b/src/migration-scripts/vrrp/3-to-4
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2023 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from sys import argv
+from vyos.configtree import ConfigTree
+
+if (len(argv) < 1):
+ print('Must specify file name!')
+ exit(1)
+
+file_name = argv[1]
+
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+base = ['high-availability', 'virtual-server']
+config = ConfigTree(config_file)
+
+if not config.exists(base):
+ # Nothing to do
+ exit(0)
+
+if config.exists(base):
+ for vs in config.list_nodes(base):
+ vs_base = base + [vs]
+
+ # If the fwmark is used, the address is not required
+ if not config.exists(vs_base + ['fwmark']):
+ # add option: 'virtual-server <tag> address x.x.x.x'
+ config.set(vs_base + ['address'], value=vs)
+
+
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print(f'Failed to save the modified config: {e}')
+ exit(1)