Skip to content

Commit

Permalink
fix: Cisco IOS XR (#2270)
Browse files Browse the repository at this point in the history
  • Loading branch information
mstopa-splunk authored Dec 11, 2023
1 parent 8c11aae commit c2005bf
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 22 deletions.
3 changes: 3 additions & 0 deletions docs/sources/vendor/Cisco/cisco_ios.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,21 @@ Cisco Network Products of multiple types share common logging characteristics th
| NX-OS Manual | <https://www.cisco.com/c/en/us/td/docs/switches/datacenter/nexus9000/sw/6-x/system_management/configuration/guide/b_Cisco_Nexus_9000_Series_NX-OS_System_Management_Configuration_Guide/sm_5syslog.html>|
| Cisco ACI | <https://community.cisco.com/legacyfs/online/attachments/document/technote-aci-syslog_external-v1.pdf> |
| Cisco WLC & AP | <https://www.cisco.com/c/en/us/support/docs/wireless/4100-series-wireless-lan-controllers/107252-WLC-Syslog-Server.html#anc8> |
| Cisco IOS-XR | <https://www.cisco.com/c/en/us/td/docs/iosxr/cisco8000/system-monitoring/73x/b-system-monitoring-cg-cisco8k-73x/implementing_system_logging.html> |

## Sourcetypes

| sourcetype | notes |
|----------------|---------------------------------------------------------------------------------------------------------|
| cisco:ios | This source type is also used for NX-OS, ACI and WLC product lines |
| cisco:xr | This source type is used for Cisco IOS XR |

## Sourcetype and Index Configuration

| key | sourcetype | index | notes |
|----------------|----------------|----------------|----------------|
| cisco_ios | cisco:ios | netops | none |
| cisco_xr | cisco:xr | netops | none |

### Filter type

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,25 @@ block parser app-almost-syslog-cisco_syslog() {

filter {
#Arista EOS uses a valid semi program syntax this should avoid catching Arista which is otherwise similar to cisco logs
( "${.values.identifier}" eq "ACE"
or "${.values.identifier}" eq "ASA"
or "${.values.identifier}" eq "FWSM"
or "${.values.identifier}" eq "PIX"
or match(': ?|\*', value('.tmp.header'))
or match('[A-Z]{3,4}:?$', value('.tmp.header'))
or match('\d+:?$', value('.tmp.header'))

(
(
"${.values.identifier}" eq "ACE"
or "${.values.identifier}" eq "ASA"
or "${.values.identifier}" eq "FWSM"
or "${.values.identifier}" eq "PIX"

or match(': ?|\*', value('.tmp.header'))
or match('[A-Z]{3,4}:?$', value('.tmp.header'))
or match('\d+:?$', value('.tmp.header'))
)
and not match('[a-z]\S+$', value('.tmp.header'))
and not match(' \w+\[\d+\]$', value('.tmp.header'));
)
or (
match('LICENSE', value('.values.identifier') type(string) flags(prefix))
or match('MGBL', value('.values.identifier') type(string) flags(prefix))
or match('SECURITY', value('.values.identifier') type(string) flags(prefix))
)
and not match('[a-z]\S+$', value('.tmp.header'))
and not match(' \w+\[\d+\]$', value('.tmp.header'));

};

if {
Expand Down
21 changes: 21 additions & 0 deletions package/etc/conf.d/conflib/cisco-syslog/app-cisco-cisco_xr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
block parser app-cisco-cisco_xr() {
channel {
rewrite {
r_set_splunk_dest_default(
index("netops")
sourcetype('cisco:xr')
vendor('cisco')
product('xr')
);
};
};
};

application app-cisco-cisco_xr[cisco_syslog] {
filter {
message('%LICENSE-' type(string) flags(prefix))
or message('%MGBL-' type(string) flags(prefix))
or message('%SECURITY-' type(string) flags(prefix));
};
parser { app-cisco-cisco_xr(); };
};
28 changes: 17 additions & 11 deletions package/lite/etc/addons/cisco/app-almost-syslog-cisco_syslog.conf
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,25 @@ block parser app-almost-syslog-cisco_syslog() {

filter {
#Arista EOS uses a valid semi program syntax this should avoid catching Arista which is otherwise similar to cisco logs
( "${.values.identifier}" eq "ACE"
or "${.values.identifier}" eq "ASA"
or "${.values.identifier}" eq "FWSM"
or "${.values.identifier}" eq "PIX"
or match(': ?|\*', value('.tmp.header'))
or match('[A-Z]{3,4}:?$', value('.tmp.header'))
or match('\d+:?$', value('.tmp.header'))

(
(
"${.values.identifier}" eq "ACE"
or "${.values.identifier}" eq "ASA"
or "${.values.identifier}" eq "FWSM"
or "${.values.identifier}" eq "PIX"

or match(': ?|\*', value('.tmp.header'))
or match('[A-Z]{3,4}:?$', value('.tmp.header'))
or match('\d+:?$', value('.tmp.header'))
)
and not match('[a-z]\S+$', value('.tmp.header'))
and not match(' \w+\[\d+\]$', value('.tmp.header'));
)
or (
match('LICENSE', value('.values.identifier') type(string) flags(prefix))
or match('MGBL', value('.values.identifier') type(string) flags(prefix))
or match('SECURITY', value('.values.identifier') type(string) flags(prefix))
)
and not match('[a-z]\S+$', value('.tmp.header'))
and not match(' \w+\[\d+\]$', value('.tmp.header'));

};

if {
Expand Down
21 changes: 21 additions & 0 deletions package/lite/etc/addons/cisco/app-cisco-cisco_xr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
block parser app-cisco-cisco_xr() {
channel {
rewrite {
r_set_splunk_dest_default(
index("netops")
sourcetype('cisco:xr')
vendor('cisco')
product('xr')
);
};
};
};

application app-cisco-cisco_xr[cisco_syslog] {
filter {
message('%LICENSE-' type(string) flags(prefix))
or message('%MGBL-' type(string) flags(prefix))
or message('%SECURITY-' type(string) flags(prefix));
};
parser { app-cisco-cisco_xr(); };
};
52 changes: 52 additions & 0 deletions tests/test_cisco_ios.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import datetime

import pytest
import random
import shortuuid

env = Environment(autoescape=select_autoescape(default_for_string=False))
Expand Down Expand Up @@ -386,3 +387,54 @@ def test_cisco_aci_acl(record_property, setup_splunk, setup_sc4s):
record_property("message", message)

assert result_count == 1


# RP/0/RP0/CPU0:Oct 20 17:14:37.407 UTC: config[65539]: %MGBL-CONFIGCLI-3-COMMIT_FAILURE : Configuration commit running under 'vty0': by :'core' failed,commit results stored in '/cfs/cfg/lr/failed/seamless/1000000007_failed.cfg'
# RP/0/RP0/CPU0:Oct 20 17:42:15.454 UTC: plat_sl_client[147]: %LICENSE-PLAT_CLIENT-2-SIA_INSUFFICIENT_LICENSE : Number of SIA license(s) used is more than available. SW Upgrade will still be allowed as SIA Grace Period is remaining
# RP/0/RP0/CPU0:Oct 20 18:41:50.646 UTC: config[67105]: %MGBL-SYS-5-CONFIG_I : Configured from console by core on vty0 (10.0.1.100)
# RP/0/RP0/CPU0:Oct 20 19:34:46.088 UTC: nfsvr[317]: %MGBL-NETFLOW-6-INFO_CACHE_SIZE_EXCEEDED : Cache size of 65535 for monitor NETFLOW has been exceeded
# RP/0/RP0/CPU0:Oct 20 19:39:57.914 UTC: ssh_syslog_proxy[1214]: %SECURITY-SSHD_SYSLOG_PRX-6-INFO_GENERAL : sshd[39770]: Failed authentication/pam for <unknown> from 10.0.1.100 port 48906 ssh2
testdata = [
"{{ mark }}{{ node_id }}:{{ bsd }}: config[65539]: %MGBL-CONFIGCLI-3-COMMIT_FAILURE : Configuration commit running under 'vty0': by :'core' failed,commit results stored in '/cfs/cfg/lr/failed/seamless/1000000007_failed.cfg",
"{{ mark }}{{ node_id }}:{{ bsd }}: plat_sl_client[147]: %LICENSE-PLAT_CLIENT-2-SIA_INSUFFICIENT_LICENSE : Number of SIA license(s) used is more than available. SW Upgrade will still be allowed as SIA Grace Period is remaining",
"{{ mark }}{{ node_id }}:{{ bsd }}: config[67105]: %MGBL-SYS-5-CONFIG_I : Configured from console by core on vty0 (10.0.1.100)",
"{{ mark }}{{ node_id }}:{{ bsd }}: nfsvr[317]: %MGBL-NETFLOW-6-INFO_CACHE_SIZE_EXCEEDED : Cache size of 65535 for monitor NETFLOW has been exceeded",
"{{ mark }}{{ node_id }}:{{ bsd }}: ssh_syslog_proxy[1214]: %SECURITY-SSHD_SYSLOG_PRX-6-INFO_GENERAL : sshd[39770]: Failed authentication/pam for <unknown> from 10.0.1.100 port 48906 ssh2"
]

@pytest.mark.parametrize("event", testdata)
@pytest.mark.addons("cisco")
def test_cisco_ios_xr(
record_property, setup_splunk, setup_sc4s, event
):
random_number = lambda max: random.randint(0, max)
node_id = f"RP/{random_number(4)}/RP{random_number(4)}/CPU{random_number(4)}"

dt = datetime.datetime.now()
_, bsd, _, _, _, _, epoch = time_operations(dt)

# Tune time functions
epoch = epoch[:-7]

mt = env.from_string(event + "\n")
message = mt.render(
mark="<166>",
node_id=node_id,
bsd=bsd
)

sendsingle(message, setup_sc4s[0], setup_sc4s[1][514])

category_group = "-".join(message.split("%")[1].split("-")[:2])

st = env.from_string(
'search index=netops _time={{ epoch }} sourcetype="cisco:xr" {{distinction}}'
)
search = st.render(epoch=epoch, distinction=category_group)

result_count, _ = splunk_single(setup_splunk, search)

record_property("resultCount", result_count)
record_property("message", message)

assert result_count == 1

0 comments on commit c2005bf

Please sign in to comment.