Skip to content

Commit

Permalink
[dhcp_server] Add rsyslog support for dhcp_server (#19303)
Browse files Browse the repository at this point in the history
Why I did it
Fix issue that dhcp_server doesn't create syslog into host #18472

Work item tracking
Microsoft ADO (number only): 28396389
How I did it
Modify rsyslog config template

How to verify it
UTs passed
Buildimage and install in testbed to verify
  • Loading branch information
yaqiangz authored and mssonicbld committed Jul 12, 2024
1 parent 15980f7 commit 37b1a6d
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 64 deletions.
6 changes: 1 addition & 5 deletions dockers/docker-dhcp-server/Dockerfile.j2
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ FROM docker-config-engine-bookworm-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}}

ARG docker_container_name
ARG image_version
RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf

## Make apt-get non-interactive
ENV DEBIAN_FRONTEND=noninteractive
Expand All @@ -21,8 +20,6 @@ RUN apt-get update && \
RUN mkdir -p /var/run/kea

RUN pip3 install psutil
# TODO issue on remote rsyslog server in non-host container
RUN rm -f /etc/supervisor/conf.d/containercfgd.conf

{% if docker_dhcp_server_debs.strip() -%}
# Copy locally-built Debian package dependencies
Expand Down Expand Up @@ -52,11 +49,10 @@ RUN apt-get clean -y && \
COPY ["docker_init.sh", "start.sh", "/usr/bin/"]
COPY ["supervisord.conf", "/etc/supervisor/conf.d/"]
COPY ["files/supervisor-proc-exit-listener", "/usr/bin"]
COPY ["rsyslog/rsyslog.conf.j2", "kea-dhcp4.conf.j2", "/usr/share/sonic/templates/"]
COPY ["kea-dhcp4.conf.j2", "/usr/share/sonic/templates/"]
COPY ["critical_processes", "/etc/supervisor/"]
COPY ["lease_update.sh", "/etc/kea/"]
COPY ["kea-dhcp4-init.conf", "/etc/kea/kea-dhcp4.conf"]
COPY ["cli", "/cli/"]
COPY ["rsyslog/default.conf", "/etc/rsyslog.d"]

ENTRYPOINT ["/usr/bin/docker_init.sh"]
5 changes: 0 additions & 5 deletions dockers/docker-dhcp-server/docker_init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ mkdir -p /etc/supervisor/conf.d/
mkdir -p /etc/kea/
udp_server_ip=$(ip -j -4 addr list lo scope host | jq -r -M '.[0].addr_info[0].local')
hostname=$(hostname)
# Generate the following files from templates:
# port-to-alias name map
sonic-cfggen -d -t /usr/share/sonic/templates/rsyslog.conf.j2 \
-a "{\"udp_server_ip\": \"$udp_server_ip\", \"hostname\": \"$hostname\"}" \
> /etc/rsyslog.conf

# Make the script that waits for all interfaces to come up executable
chmod +x /etc/kea/lease_update.sh /usr/bin/start.sh
Expand Down
27 changes: 0 additions & 27 deletions dockers/docker-dhcp-server/rsyslog/default.conf

This file was deleted.

4 changes: 4 additions & 0 deletions files/build_templates/docker_image_ctl.j2
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,11 @@ start() {
fi

# Default rsyslog target IP for single ASIC platform
{%- if docker_container_name == "dhcp_server" %}
SYSLOG_TARGET_IP=$(docker network inspect bridge --format={{ "'{{(index .IPAM.Config 0).Gateway}}'" }})
{%- else %}
SYSLOG_TARGET_IP=127.0.0.1
{%- endif %}
if [[ ($NUM_ASIC -gt 1) ]]; then
SYSLOG_TARGET_IP=$(docker network inspect bridge --format={{ "'{{(index .IPAM.Config 0).Gateway}}'" }})
fi
Expand Down
8 changes: 7 additions & 1 deletion files/image_config/rsyslog/rsyslog-config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,16 @@ if [[ ($NUM_ASIC -gt 1) ]]; then
else
udp_server_ip=$(ip -j -4 addr list lo scope host | jq -r -M '.[0].addr_info[0].local')
fi

contain_dhcp_server=$(sonic-db-cli CONFIG_DB keys "FEATURE|dhcp_server")
if [ $contain_dhcp_server ]; then
docker0_ip=$(ip -o -4 addr list docker0 | awk '{print $4}' | cut -d/ -f1)
fi

hostname=$(hostname)

sonic-cfggen -d -t /usr/share/sonic/templates/rsyslog.conf.j2 \
-a "{\"udp_server_ip\": \"$udp_server_ip\", \"hostname\": \"$hostname\"}" \
-a "{\"udp_server_ip\": \"$udp_server_ip\", \"hostname\": \"$hostname\", \"docker0_ip\": \"$docker0_ip\"}" \
> /etc/rsyslog.conf

systemctl restart rsyslog
4 changes: 4 additions & 0 deletions files/image_config/rsyslog/rsyslog.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ $ModLoad imklog # provides kernel logging support
$ModLoad imudp
$UDPServerAddress {{udp_server_ip}} #bind to localhost before udp server run
$UDPServerRun 514
{% if docker0_ip and docker0_ip != "" %}
$UDPServerAddress {{docker0_ip}}
$UDPServerRun 514
{% endif%}

# provides TCP syslog reception
#$ModLoad imtcp
Expand Down
18 changes: 9 additions & 9 deletions src/sonic-config-engine/tests/data/rsyslog/config_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -207,22 +207,22 @@
"DEVICE_NEIGHBOR_METADATA": {
"ARISTA01T1": {
"hwsku": "Arista-VM",
"mgmt_addr": "172.16.190.114",
"mgmt_addr": "3.3.3.14",
"type": "LeafRouter"
},
"ARISTA02T1": {
"hwsku": "Arista-VM",
"mgmt_addr": "172.16.190.115",
"mgmt_addr": "3.3.3.15",
"type": "LeafRouter"
},
"ARISTA03T1": {
"hwsku": "Arista-VM",
"mgmt_addr": "172.16.190.116",
"mgmt_addr": "3.3.3.16",
"type": "LeafRouter"
},
"ARISTA04T1": {
"hwsku": "Arista-VM",
"mgmt_addr": "172.16.190.117",
"mgmt_addr": "3.3.3.17",
"type": "LeafRouter"
}
},
Expand Down Expand Up @@ -411,11 +411,11 @@
"Loopback0|FC00:1::32/128": {}
},
"MGMT_INTERFACE": {
"eth0|10.150.22.115/23": {
"gwaddr": "10.150.22.1"
"eth0|1.1.1.15/23": {
"gwaddr": "1.1.1.10"
},
"eth0|2404:f801:10:2200::a96:1673/64": {
"gwaddr": "2404:f801:10:2200::1"
"eth0|2404:::2/64": {
"gwaddr": "2404::1"
}
},
"MGMT_PORT": {
Expand Down Expand Up @@ -867,7 +867,7 @@
}
},
"SYSLOG_SERVER": {
"10.150.22.222": {}
"3.3.3.3": {}
},
"VERSIONS": {
"DATABASE": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,14 @@

$ModLoad imuxsock # provides support for local system logging

{% set gconf = (SYSLOG_CONFIG | d({})).get('GLOBAL', {}) -%}
{% set rate_limit_interval = gconf.get('rate_limit_interval') %}
{% set rate_limit_burst = gconf.get('rate_limit_burst') %}

{% if rate_limit_interval is not none %}
$SystemLogRateLimitInterval {{ rate_limit_interval }}
{% endif %}
{% if rate_limit_burst is not none %}
$SystemLogRateLimitBurst {{ rate_limit_burst }}
{% endif %}

$ModLoad imklog # provides kernel logging support
#$ModLoad immark # provides --MARK-- message capability

# provides UDP syslog reception
$ModLoad imudp
$UDPServerAddress {{udp_server_ip}} #bind to localhost before udp server run
$UDPServerAddress 1.1.1.1 #bind to localhost before udp server run
$UDPServerRun 514

# provides TCP syslog reception
Expand All @@ -42,21 +33,21 @@ $UDPServerRun 514
###########################
#### GLOBAL DIRECTIVES ####
###########################
{% set format = gconf.get('format', 'standard') -%}
{% set fw_name = gconf.get('welf_firewall_name', hostname) -%}
#
# Use traditional timestamp format.
# To enable high precision timestamps, comment out the following line.
#
#$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat

# Define a custom template
$template SONiCFileFormat,"%TIMESTAMP%.%timestamp:::date-subseconds% %HOSTNAME% %syslogseverity-text:::uppercase% dhcp_server#%syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"
$template SONiCFileFormat,"%timegenerated:::date-year% %timegenerated%.%timegenerated:::date-subseconds% %HOSTNAME% %syslogseverity-text:::uppercase% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"
$ActionFileDefaultTemplate SONiCFileFormat
$template SONiCForwardFormat,"<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogseverity-text:::uppercase% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"
$ActionForwardDefaultTemplate SONiCForwardFormat

template(name="WelfRemoteFormat" type="string" string="%TIMESTAMP% id=firewall time=\"%timereported\
:::date-year%-%timereported:::date-month%-%timereported:::date-day% %timereported:::date-hour%:%timereported:::date-minute%:%timereported\
:::date-second%\" fw=\"{{ fw_name }}\" pri=%syslogpriority% msg=\"%syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\"\n")
:::date-second%\" fw=\"kvm-host\" pri=%syslogpriority% msg=\"%syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\"\n")

#
# Set the default permissions for all log files.
Expand Down Expand Up @@ -93,4 +84,7 @@ $RepeatedMsgReduction on
# The omfwd plug-in provides the core functionality of traditional message
# forwarding via UDP and plain TCP. It is a built-in module that does not need
# to be loaded.
# TODO rsyslog issue in bridge mode container, don't update to remote server for now

*.*
action(type="omfwd" Target="3.3.3.3" Port="514" Protocol="udp" Template="SONiCForwardFormat")

Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
###############################################################################
# Managed by Ansible
# file: ansible/roles/acs/templates/rsyslog.conf.j2
###############################################################################
#
# /etc/rsyslog.conf Configuration file for rsyslog.
#
# For more information see
# /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html


#################
#### MODULES ####
#################

$ModLoad imuxsock # provides support for local system logging



$ModLoad imklog # provides kernel logging support
#$ModLoad immark # provides --MARK-- message capability

# provides UDP syslog reception
$ModLoad imudp
$UDPServerAddress 1.1.1.1 #bind to localhost before udp server run
$UDPServerRun 514
$UDPServerAddress 2.2.2.2
$UDPServerRun 514

# provides TCP syslog reception
#$ModLoad imtcp
#$InputTCPServerRun 514


###########################
#### GLOBAL DIRECTIVES ####
###########################
#
# Use traditional timestamp format.
# To enable high precision timestamps, comment out the following line.
#
#$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat

# Define a custom template
$template SONiCFileFormat,"%timegenerated:::date-year% %timegenerated%.%timegenerated:::date-subseconds% %HOSTNAME% %syslogseverity-text:::uppercase% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"
$ActionFileDefaultTemplate SONiCFileFormat
$template SONiCForwardFormat,"<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogseverity-text:::uppercase% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"
$ActionForwardDefaultTemplate SONiCForwardFormat

template(name="WelfRemoteFormat" type="string" string="%TIMESTAMP% id=firewall time=\"%timereported\
:::date-year%-%timereported:::date-month%-%timereported:::date-day% %timereported:::date-hour%:%timereported:::date-minute%:%timereported\
:::date-second%\" fw=\"kvm-host\" pri=%syslogpriority% msg=\"%syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\"\n")

#
# Set the default permissions for all log files.
#
$FileOwner root
$FileGroup adm
$FileCreateMode 0640
$DirCreateMode 0755
$Umask 0022

#
# Where to place spool and state files
#
$WorkDirectory /var/spool/rsyslog

#
# Include all config files in /etc/rsyslog.d/
#
$IncludeConfig /etc/rsyslog.d/*.conf

#
# Suppress duplicate messages and report "message repeated n times"
#
$RepeatedMsgReduction on

###############
#### RULES ####
###############

#
# Remote syslog logging
#

# The omfwd plug-in provides the core functionality of traditional message
# forwarding via UDP and plain TCP. It is a built-in module that does not need
# to be loaded.

*.*
action(type="omfwd" Target="3.3.3.3" Port="514" Protocol="udp" Template="SONiCForwardFormat")

23 changes: 21 additions & 2 deletions src/sonic-config-engine/tests/test_j2files.py
Original file line number Diff line number Diff line change
Expand Up @@ -759,16 +759,35 @@ def test_rsyslog_conf(self):
# Skip on python2 as the change will not be backported to previous version
return

conf_template = os.path.join(self.test_dir, '..', '..', '..', 'files', 'image_config', 'rsyslog', 'rsyslog.conf.j2')
conf_template = os.path.join(self.test_dir, '..', '..', '..', 'files', 'image_config', 'rsyslog',
'rsyslog.conf.j2')
config_db_json = os.path.join(self.test_dir, "data", "rsyslog", "config_db.json")
additional_data = "{\"udp_server_ip\": \"10.150.22.222\", \"hostname\": \"kvm-host\"}"
additional_data = "{\"udp_server_ip\": \"1.1.1.1\", \"hostname\": \"kvm-host\"}"

argument = ['-j', config_db_json, '-t', conf_template, '-a', additional_data]
self.run_script(argument, output_file=self.output_file)
with open(self.output_file) as file:
pattern = r'^action.*Device="eth0".*'
for line in file:
assert not bool(re.match(pattern, line.strip())), "eth0 is not allowed in Mgfx device"
self.assertTrue(utils.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'rsyslog.conf'),
self.output_file))

def test_rsyslog_conf_docker0_ip(self):
if utils.PYvX_DIR != 'py3':
# Skip on python2 as the change will not be backported to previous version
return

conf_template = os.path.join(self.test_dir, '..', '..', '..', 'files', 'image_config', 'rsyslog',
'rsyslog.conf.j2')
config_db_json = os.path.join(self.test_dir, "data", "rsyslog", "config_db.json")
additional_data = "{\"udp_server_ip\": \"1.1.1.1\", \"hostname\": \"kvm-host\", " + \
"\"docker0_ip\": \"2.2.2.2\"}"

argument = ['-j', config_db_json, '-t', conf_template, '-a', additional_data]
self.run_script(argument, output_file=self.output_file)
self.assertTrue(utils.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR,
'rsyslog_with_docker0.conf'), self.output_file))

def tearDown(self):
os.environ["CFGGEN_UNIT_TESTING"] = ""
Expand Down

0 comments on commit 37b1a6d

Please sign in to comment.