summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/pr-auto-close.yml18
-rw-r--r--.github/workflows/trigger-rebuild-repo-package.yml32
-rw-r--r--Jenkinsfile2
-rw-r--r--data/templates/rsyslog/rsyslog.conf.j210
-rw-r--r--interface-definitions/policy.xml.in48
-rw-r--r--interface-definitions/service_lldp.xml.in4
-rw-r--r--interface-definitions/system_option.xml.in8
-rw-r--r--interface-definitions/system_syslog.xml.in6
-rw-r--r--op-mode-definitions/date.xml.in2
-rw-r--r--smoketest/scripts/cli/base_accel_ppp_test.py6
-rwxr-xr-xsmoketest/scripts/cli/test_service_snmp.py14
-rwxr-xr-xsmoketest/scripts/cli/test_system_syslog.py33
-rwxr-xr-xsrc/conf_mode/protocols_static.py2
-rwxr-xr-xsrc/conf_mode/service_snmp.py13
-rwxr-xr-xsrc/conf_mode/system_syslog.py20
-rw-r--r--src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper18
16 files changed, 220 insertions, 16 deletions
diff --git a/.github/workflows/pr-auto-close.yml b/.github/workflows/pr-auto-close.yml
new file mode 100644
index 000000000..947108805
--- /dev/null
+++ b/.github/workflows/pr-auto-close.yml
@@ -0,0 +1,18 @@
+name: Auto-Close Pull Requests Sagitta
+
+on:
+ pull_request_target:
+ types:
+ - opened
+ branches:
+ - sagitta
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ # Optional. Post a issue comment just before closing a pull request.
+ comment: "Pull requests to this branch are not accepted and have been closed automatically."
+ github_token: ${{ secrets.PAT }}
diff --git a/.github/workflows/trigger-rebuild-repo-package.yml b/.github/workflows/trigger-rebuild-repo-package.yml
new file mode 100644
index 000000000..f267a6316
--- /dev/null
+++ b/.github/workflows/trigger-rebuild-repo-package.yml
@@ -0,0 +1,32 @@
+name: Trigger to build a deb package from repo
+
+on:
+ pull_request_target:
+ types:
+ - closed
+ branches:
+ - sagitta
+ workflow_dispatch:
+
+jobs:
+ get_repo_name:
+ runs-on: ubuntu-latest
+ outputs:
+ PACKAGE_NAME: ${{ steps.package_name.outputs.PACKAGE_NAME }}
+ steps:
+ - name: Set variables
+ id: package_name
+ run: |
+ echo "PACKAGE_NAME=$(basename ${{ github.repository }})" >> $GITHUB_OUTPUT
+
+ trigger-build:
+ needs: get_repo_name
+ uses: vyos/.github/.github/workflows/trigger-rebuild-repo-package.yml@sagitta
+ with:
+ branch: ${{ github.ref_name }}
+ package_name: ${{ needs.get_repo_name.outputs.PACKAGE_NAME }}
+ secrets:
+ REMOTE_OWNER: ${{ secrets.REMOTE_OWNER }}
+ REMOTE_REUSE_REPO: ${{ secrets.REMOTE_REUSE_REPO }}
+ GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }}
+ PAT: ${{ secrets.PAT }}
diff --git a/Jenkinsfile b/Jenkinsfile
index 21a6829c0..50a97e688 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -17,7 +17,7 @@
// Using a version specifier library, use 'current' branch. The underscore (_)
// is not a typo! You need this underscore if the line immediately after the
// @Library annotation is not an import statement!
-@Library('vyos-build@current')_
+@Library('vyos-build@sagitta')_
// Start package build using library function from https://github.com/vyos/vyos-build
buildPackage(null, null, null, true)
diff --git a/data/templates/rsyslog/rsyslog.conf.j2 b/data/templates/rsyslog/rsyslog.conf.j2
index 97e0ee0b7..7fd592d1f 100644
--- a/data/templates/rsyslog/rsyslog.conf.j2
+++ b/data/templates/rsyslog/rsyslog.conf.j2
@@ -10,6 +10,10 @@ $MarkMessagePeriod {{ global.marker.interval }}
$PreserveFQDN on
{% endif %}
+{% if global.local_host_name is vyos_defined %}
+$LocalHostName {{ global.local_host_name }}
+{% endif %}
+
# We always log to /var/log/messages
$outchannel global,/var/log/messages,262144,/usr/sbin/logrotate {{ logrotate }}
{% if global.facility is vyos_defined %}
@@ -54,12 +58,10 @@ $outchannel {{ file_name }},/var/log/user/{{ file_name }},{{ file_options.archiv
{% endif %}
{% if host_options.protocol is vyos_defined('tcp') %}
{% if host_options.format.octet_counted is vyos_defined %}
-{{ tmp | join(';') }} @@(o){{ host_name | bracketize_ipv6 }}:{{ host_options.port }};RSYSLOG_SyslogProtocol23Format
-{% else %}
-{{ tmp | join(';') }} @@{{ host_name | bracketize_ipv6 }}:{{ host_options.port }}
+{{ tmp | join(';') }} @@{{ '(o)' if host_options.format.octet_counted is vyos_defined }}{{ host_name | bracketize_ipv6 }}:{{ host_options.port }}{{ ';RSYSLOG_SyslogProtocol23Format' if host_options.format.include_timezone is vyos_defined }}
{% endif %}
{% else %}
-{{ tmp | join(';') }} @{{ host_name | bracketize_ipv6 }}:{{ host_options.port }}{{ ';RSYSLOG_SyslogProtocol23Format' if host_options.format.octet_counted is vyos_defined }}
+{{ tmp | join(';') }} @{{ host_name | bracketize_ipv6 }}:{{ host_options.port }}{{ ';RSYSLOG_SyslogProtocol23Format' if host_options.format.include_timezone is vyos_defined }}
{% endif %}
{% endfor %}
{% endif %}
diff --git a/interface-definitions/policy.xml.in b/interface-definitions/policy.xml.in
index 791fa1d87..4b5b609c5 100644
--- a/interface-definitions/policy.xml.in
+++ b/interface-definitions/policy.xml.in
@@ -202,11 +202,11 @@
<properties>
<help>Regular expression to match against a community-list</help>
<completionHelp>
- <list>local-AS no-advertise no-export internet additive</list>
+ <list>local-AS no-advertise no-export internet graceful-shutdown accept-own-nexthop accept-own route-filter-translated-v4 route-filter-v4 route-filter-translated-v6 route-filter-v6 llgr-stale no-llgr blackhole no-peer additive</list>
</completionHelp>
<valueHelp>
<format>&lt;aa:nn&gt;</format>
- <description>Community number in AA:NN format</description>
+ <description>Community number in AA:NN format where AA and NN are (0-65535)</description>
</valueHelp>
<valueHelp>
<format>local-AS</format>
@@ -225,6 +225,50 @@
<description>Well-known communities value 0</description>
</valueHelp>
<valueHelp>
+ <format>graceful-shutdown</format>
+ <description>Well-known communities value GRACEFUL_SHUTDOWN 0xFFFF0000</description>
+ </valueHelp>
+ <valueHelp>
+ <format>accept-own-nexthop</format>
+ <description>Well-known communities value ACCEPT_OWN_NEXTHOP 0xFFFF0008</description>
+ </valueHelp>
+ <valueHelp>
+ <format>accept-own</format>
+ <description>Well-known communities value ACCEPT_OWN 0xFFFF0001 65535:1</description>
+ </valueHelp>
+ <valueHelp>
+ <format>route-filter-translated-v4</format>
+ <description>Well-known communities value ROUTE_FILTER_TRANSLATED_v4 0xFFFF0002 65535:2</description>
+ </valueHelp>
+ <valueHelp>
+ <format>route-filter-v4</format>
+ <description>Well-known communities value ROUTE_FILTER_v4 0xFFFF0003 65535:3</description>
+ </valueHelp>
+ <valueHelp>
+ <format>route-filter-translated-v6</format>
+ <description>Well-known communities value ROUTE_FILTER_TRANSLATED_v6 0xFFFF0004 65535:4</description>
+ </valueHelp>
+ <valueHelp>
+ <format>route-filter-v6</format>
+ <description>Well-known communities value ROUTE_FILTER_v6 0xFFFF0005 65535:5</description>
+ </valueHelp>
+ <valueHelp>
+ <format>llgr-stale</format>
+ <description>Well-known communities value LLGR_STALE 0xFFFF0006 65535:6</description>
+ </valueHelp>
+ <valueHelp>
+ <format>no-llgr</format>
+ <description>Well-known communities value NO_LLGR 0xFFFF0007 65535:7</description>
+ </valueHelp>
+ <valueHelp>
+ <format>blackhole</format>
+ <description>Well-known communities value BLACKHOLE 0xFFFF029A 65535:666</description>
+ </valueHelp>
+ <valueHelp>
+ <format>no-peer</format>
+ <description>Well-known communities value NOPEER 0xFFFFFF04 65535:65284</description>
+ </valueHelp>
+ <valueHelp>
<format>additive</format>
<description>New value is appended to the existing value</description>
</valueHelp>
diff --git a/interface-definitions/service_lldp.xml.in b/interface-definitions/service_lldp.xml.in
index 1a06e0cb3..51a9f9cce 100644
--- a/interface-definitions/service_lldp.xml.in
+++ b/interface-definitions/service_lldp.xml.in
@@ -23,6 +23,10 @@
<script>${vyos_completion_dir}/list_interfaces</script>
<list>all</list>
</completionHelp>
+ <constraint>
+ #include <include/constraint/interface-name.xml.i>
+ <regex>all</regex>
+ </constraint>
</properties>
<children>
#include <include/generic-disable-node.xml.i>
diff --git a/interface-definitions/system_option.xml.in b/interface-definitions/system_option.xml.in
index e78a53552..1d2e8c880 100644
--- a/interface-definitions/system_option.xml.in
+++ b/interface-definitions/system_option.xml.in
@@ -68,7 +68,7 @@
<properties>
<help>System keyboard layout, type ISO2</help>
<completionHelp>
- <list>us uk fr de es fi jp106 no dk se-latin1 dvorak</list>
+ <list>us uk fr de es fi it jp106 no dk se-latin1 dvorak</list>
</completionHelp>
<valueHelp>
<format>us</format>
@@ -95,6 +95,10 @@
<description>Finland</description>
</valueHelp>
<valueHelp>
+ <format>it</format>
+ <description>Italy</description>
+ </valueHelp>
+ <valueHelp>
<format>jp106</format>
<description>Japan</description>
</valueHelp>
@@ -115,7 +119,7 @@
<description>Dvorak</description>
</valueHelp>
<constraint>
- <regex>(us|uk|fr|de|es|fi|jp106|no|dk|se-latin1|dvorak)</regex>
+ <regex>(us|uk|fr|de|es|fi|it|jp106|no|dk|se-latin1|dvorak)</regex>
</constraint>
<constraintErrorMessage>Invalid keyboard layout</constraintErrorMessage>
</properties>
diff --git a/interface-definitions/system_syslog.xml.in b/interface-definitions/system_syslog.xml.in
index 3343e2c59..0a9a00572 100644
--- a/interface-definitions/system_syslog.xml.in
+++ b/interface-definitions/system_syslog.xml.in
@@ -66,6 +66,12 @@
<valueless/>
</properties>
</leafNode>
+ <leafNode name="include-timezone">
+ <properties>
+ <help>Include system timezone in syslog message</help>
+ <valueless/>
+ </properties>
+ </leafNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/date.xml.in b/op-mode-definitions/date.xml.in
index 6d8586025..4e62a8335 100644
--- a/op-mode-definitions/date.xml.in
+++ b/op-mode-definitions/date.xml.in
@@ -35,7 +35,7 @@
<list>&lt;MMDDhhmm&gt; &lt;MMDDhhmmYY&gt; &lt;MMDDhhmmCCYY&gt; &lt;MMDDhhmmCCYY.ss&gt;</list>
</completionHelp>
</properties>
- <command>/bin/date "$3"</command>
+ <command>sudo bash -c "/bin/date '$3' &amp;&amp; hwclock --systohc --localtime"</command>
</tagNode>
</children>
</node>
diff --git a/smoketest/scripts/cli/base_accel_ppp_test.py b/smoketest/scripts/cli/base_accel_ppp_test.py
index c6f6cb804..750702e98 100644
--- a/smoketest/scripts/cli/base_accel_ppp_test.py
+++ b/smoketest/scripts/cli/base_accel_ppp_test.py
@@ -14,6 +14,7 @@
import re
+from time import sleep
from base_vyostest_shim import VyOSUnitTestSHIM
from configparser import ConfigParser
@@ -641,6 +642,11 @@ delegate={delegate_2_prefix},{delegate_mask},name={pool_name}"""
for log_level in range(0, 5):
self.set(['log', 'level', str(log_level)])
self.cli_commit()
+
+ # Systemd comes with a default of 5 restarts in 10 seconds policy,
+ # this limit can be hit by this reastart sequence, slow down a bit
+ sleep(5)
+
# Validate configuration values
conf = ConfigParser(allow_no_value=True)
conf.read(self._config_file)
diff --git a/smoketest/scripts/cli/test_service_snmp.py b/smoketest/scripts/cli/test_service_snmp.py
index b3daa90d0..7d5eaa440 100755
--- a/smoketest/scripts/cli/test_service_snmp.py
+++ b/smoketest/scripts/cli/test_service_snmp.py
@@ -246,5 +246,19 @@ class TestSNMPService(VyOSUnitTestSHIM.TestCase):
for excluded in snmpv3_view_oid_exclude:
self.assertIn(f'view {snmpv3_view} excluded .{excluded}', tmp)
+ def test_snmp_script_extensions(self):
+ extensions = {
+ 'default': 'snmp_smoketest_extension_script.sh',
+ 'external': '/run/external_snmp_smoketest_extension_script.sh'
+ }
+
+ for key, val in extensions.items():
+ self.cli_set(base_path + ['script-extensions', 'extension-name', key, 'script', val])
+ self.cli_commit()
+
+ self.assertEqual(get_config_value('extend default'), f'/config/user-data/{extensions["default"]}')
+ self.assertEqual(get_config_value('extend external'), extensions["external"])
+
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_system_syslog.py b/smoketest/scripts/cli/test_system_syslog.py
index 45a5b4087..c802ceeeb 100755
--- a/smoketest/scripts/cli/test_system_syslog.py
+++ b/smoketest/scripts/cli/test_system_syslog.py
@@ -20,6 +20,7 @@ import unittest
from base_vyostest_shim import VyOSUnitTestSHIM
from vyos.utils.file import read_file
+from vyos.utils.process import cmd
from vyos.utils.process import process_named_running
PROCESS_NAME = 'rsyslogd'
@@ -61,19 +62,45 @@ class TestRSYSLOGService(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['host', host2, 'facility', 'kern', 'level', 'err'])
self.cli_set(base_path + ['console', 'facility', 'all', 'level', 'warning'])
-
self.cli_commit()
# verify log level and facilities in config file
# *.warning /dev/console
# *.* @198.51.100.1:999
# kern.err @192.0.2.1:514
- config = [get_config_value('\*.\*'), get_config_value('kern.err'), get_config_value('\*.warning')]
+ config = [
+ get_config_value('\*.\*'),
+ get_config_value('kern.err'),
+ get_config_value('\*.warning'),
+ ]
expected = [f'@{host1}:999', f'@{host2}:514', '/dev/console']
- for i in range(0,3):
+ for i in range(0, 3):
self.assertIn(expected[i], config[i])
# Check for running process
self.assertTrue(process_named_running(PROCESS_NAME))
+ def test_syslog_global(self):
+ self.cli_set(['system', 'host-name', 'vyos'])
+ self.cli_set(['system', 'domain-name', 'example.local'])
+ self.cli_set(base_path + ['global', 'marker', 'interval', '600'])
+ self.cli_set(base_path + ['global', 'preserve-fqdn'])
+ self.cli_set(base_path + ['global', 'facility', 'kern', 'level', 'err'])
+
+ self.cli_commit()
+
+ config = cmd(f'sudo cat {RSYSLOG_CONF}')
+ expected = [
+ '$MarkMessagePeriod 600',
+ '$PreserveFQDN on',
+ 'kern.err',
+ '$LocalHostName vyos.example.local',
+ ]
+
+ for e in expected:
+ self.assertIn(e, config)
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/src/conf_mode/protocols_static.py b/src/conf_mode/protocols_static.py
index a2373218a..430cc69d4 100755
--- a/src/conf_mode/protocols_static.py
+++ b/src/conf_mode/protocols_static.py
@@ -88,7 +88,7 @@ def verify(static):
if {'blackhole', 'reject'} <= set(prefix_options):
raise ConfigError(f'Can not use both blackhole and reject for '\
- 'prefix "{prefix}"!')
+ f'prefix "{prefix}"!')
return None
diff --git a/src/conf_mode/service_snmp.py b/src/conf_mode/service_snmp.py
index f65d0d6bc..24c180b98 100755
--- a/src/conf_mode/service_snmp.py
+++ b/src/conf_mode/service_snmp.py
@@ -39,6 +39,7 @@ config_file_client = r'/etc/snmp/snmp.conf'
config_file_daemon = r'/etc/snmp/snmpd.conf'
config_file_access = r'/usr/share/snmp/snmpd.conf'
config_file_user = r'/var/lib/snmp/snmpd.conf'
+default_script_dir = r'/config/user-data/'
systemd_override = r'/run/systemd/system/snmpd.service.d/override.conf'
systemd_service = 'snmpd.service'
@@ -83,8 +84,20 @@ def get_config(config=None):
tmp = {'::1': {'port': '161'}}
snmp['listen_address'] = dict_merge(tmp, snmp['listen_address'])
+ if 'script_extensions' in snmp and 'extension_name' in snmp['script_extensions']:
+ for key, val in snmp['script_extensions']['extension_name'].items():
+ if 'script' not in val:
+ continue
+ script_path = val['script']
+ # if script has not absolute path, use pre configured path
+ if not os.path.isabs(script_path):
+ script_path = os.path.join(default_script_dir, script_path)
+
+ snmp['script_extensions']['extension_name'][key]['script'] = script_path
+
return snmp
+
def verify(snmp):
if 'deleted' in snmp:
return None
diff --git a/src/conf_mode/system_syslog.py b/src/conf_mode/system_syslog.py
index 07fbb0734..eb2f02eb3 100755
--- a/src/conf_mode/system_syslog.py
+++ b/src/conf_mode/system_syslog.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2023 VyOS maintainers and contributors
+# Copyright (C) 2018-2024 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
@@ -18,6 +18,7 @@ import os
from sys import exit
+from vyos.base import Warning
from vyos.config import Config
from vyos.configdict import is_node_changed
from vyos.configverify import verify_vrf
@@ -52,12 +53,29 @@ def get_config(config=None):
if syslog.from_defaults(['global']):
del syslog['global']
+ if (
+ 'global' in syslog
+ and 'preserve_fqdn' in syslog['global']
+ and conf.exists(['system', 'host-name'])
+ and conf.exists(['system', 'domain-name'])
+ ):
+ hostname = conf.return_value(['system', 'host-name'])
+ domain = conf.return_value(['system', 'domain-name'])
+ fqdn = f'{hostname}.{domain}'
+ syslog['global']['local_host_name'] = fqdn
+
return syslog
def verify(syslog):
if not syslog:
return None
+ if 'host' in syslog:
+ for host, host_options in syslog['host'].items():
+ if 'protocol' in host_options and host_options['protocol'] == 'udp':
+ if 'format' in host_options and 'octet_counted' in host_options['format']:
+ Warning(f'Syslog UDP transport for "{host}" should not use octet-counted format!')
+
verify_vrf(syslog)
def generate(syslog):
diff --git a/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper b/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper
index 5d879471d..2a1c5a7b2 100644
--- a/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper
+++ b/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper
@@ -72,6 +72,22 @@ function delroute () {
fi
}
+# try to communicate with vtysh
+function vtysh_conf () {
+ # perform 10 attempts with 1 second delay for retries
+ for i in {1..10} ; do
+ if vtysh -c "conf t" -c "$1" ; then
+ logmsg info "Command was executed successfully via vtysh: \"$1\""
+ return 0
+ else
+ logmsg info "Failed to send command to vtysh, retrying in 1 second"
+ sleep 1
+ fi
+ done
+ logmsg error "Failed to execute command via vtysh after 10 attempts: \"$1\""
+ return 1
+}
+
# replace ip command with this wrapper
function ip () {
# pass comand to system `ip` if this is not related to routes change
@@ -84,7 +100,7 @@ function ip () {
delroute ${@:4}
iptovtysh $@
logmsg info "Sending command to vtysh"
- vtysh -c "conf t" -c "$VTYSH_CMD"
+ vtysh_conf "$VTYSH_CMD"
else
# add ip route to kernel
logmsg info "Modifying routes in kernel: \"/usr/sbin/ip $@\""