Must contain and must not contain
Must contain and must not contain
Section titled “Must contain and must not contain”Most compliance rules are presence checks: this line must be in the config, or that line must not be. rConfig has several methods for this, and they do not all compare text the same way. This page shows how each one behaves, using results asserted by the rConfig Pro test suite.
The examples on this page use this IOS-XE config excerpt (sanitised from tests/storage/test_router_showrun.txt):
hostname router1!aaa new-modelaaa authentication login default localaaa session-id common!ip domain name example.com!no ip subnet-zero!interface GigabitEthernet1 ip address dhcp negotiation auto!snmp-server host 192.0.2.1 EXAMPLECOMMsnmp-server host 192.0.2.2 EXAMPLECOMM10snmp-server host 192.0.2.2 EXAMPLECOMM12xxxxxxxsnmp-server host 192.0.2.3 EXAMPLECOMM20snmp-server host 192.0.2.4 EXAMPLECOMM30!line con 0 logging synchronous stopbits 1line vty 0 4 transport input telnet ssh!endHow each method compares text
Section titled “How each method compares text”| Method | Compares against | Case | Passes when |
|---|---|---|---|
must_match_single_string | Each whole line, trimmed | Sensitive | One line equals the body exactly |
must_not_match_single_string | Each whole line, trimmed, runs of whitespace collapsed | Insensitive | No line equals the body |
must_match_all_from_array | The whole config as one block of text | Sensitive | Every body line appears somewhere, even inside a longer line |
can_match_any_from_array | The whole config as one block of text | Sensitive | At least one body line appears somewhere |
must_not_match_all_from_array | The whole config as one block of text | Sensitive | Not all body lines appear. See avoiding false positives |
The difference between “whole line” and “somewhere in the config” matters more than anything else on this page.
One exact line: must_match_single_string
Section titled “One exact line: must_match_single_string”The body must equal a complete config line. Leading and trailing spaces are ignored on both sides; nothing else is.
// Trap host 192.0.2.2 uses community EXAMPLECOMM10#[must_match_single_string]snmp-server host 192.0.2.2 EXAMPLECOMM10
// Trap host 192.0.2.2 uses community EXAMPLECOMM12#[must_match_single_string]snmp-server host 192.0.2.2 EXAMPLECOMM12
// Trap host 192.0.2.2 uses community EXAMPLECOMM100#[must_match_single_string]snmp-server host 192.0.2.2 EXAMPLECOMM100
// Partial line#[must_match_single_string]interface G| Rule | Result | Why |
|---|---|---|
...EXAMPLECOMM10 | pass | The line exists exactly. |
...EXAMPLECOMM12 | fail | The config line is ...EXAMPLECOMM12xxxxxxx. A prefix is not a match. |
...EXAMPLECOMM100 | fail | No such line. |
interface G | fail | Part of a line is not a match. |
Source: PolicyMethodsTest::test_must_match_single_string_tests1 and test_must_match_single_string_tests2_with_partial_string_fails. Minimum version 8.0.0.
One forbidden line: must_not_match_single_string
Section titled “One forbidden line: must_not_match_single_string”The body must not equal any config line. This method is more forgiving than its positive twin: it ignores case and treats any run of spaces as one space, as well as ignoring leading indentation.
// No DHCP relay to 198.51.100.31#[must_not_match_single_string]ip dhcp relay address 198.51.100.31
// No DHCP relay to 198.51.100.99#[must_not_match_single_string]ip dhcp relay address 198.51.100.99Against this config:
hsrp 14 preempt delay minimum 100 priority 120 ip 192.0.2.1 ip dhcp relay address 198.51.100.31 ip dhcp relay address 203.0.113.64| Rule | Result | Why |
|---|---|---|
| Relay to 198.51.100.31 | fail | The indented line matches once trimmed. |
| Relay to 198.51.100.99 | pass | No such line. |
Case and spacing differences still match:
// BGP feature is not enabled#[must_not_match_single_string]FEATURE BGP
// OSPF feature is not enabled#[must_not_match_single_string]feature ospffeature bgprouter bgp 65000 neighbor 198.51.100.1 remote-as 65001| Rule | Result | Why |
|---|---|---|
FEATURE BGP | fail | Matches feature bgp after lowercasing and collapsing spaces. |
feature ospf | pass | No such line. |
Source: MustNotMatchSingleStringCustomerTest. Minimum version 8.0.0.
Several lines: the array methods
Section titled “Several lines: the array methods”A body with more than one line is a list. The array methods look for each list item anywhere in the config text, so an item can match part of a longer line.
// At least one of these lines is present#[can_match_any_from_array]snmp-server host 192.0.2.2 EXAMPLECOMM10snmp-server host 192.0.2.1 EXAMPLECOMM310aaa session-id1
// At least one of these lines is present (none are)#[can_match_any_from_array]snmp-server host 192.0.2.1 EXAMPLECOMM110snmp-server host 192.0.2.1 EXAMPLECOMM310aaa session-id1
// Every one of these lines is present#[must_match_all_from_array]snmp-server host 192.0.2.2 EXAMPLECOMM10snmp-server host 192.0.2.4 EXAMPLECOMM30aaa session-idno ip subnet-zeroip domain name example.comline vty 0 4
// Every one of these lines is present (one is not)#[must_match_all_from_array]snmp-server host 192.0.2.2 EXAMPLECOMM10snmp-server host 192.0.2.4 EXAMPLECOMM30aaa session-idno ip subnet-zeroip domain name example.comline vty 0 5
// Not all of these lines are present (none are)#[must_not_match_all_from_array]snmp-server host 192.0.2.2 EXAMPLECOMM100snmp-server host 192.0.2.4 EXAMPLECOMM300aaa session-id0no ip subnet-zero0ip domain name example.com0line vty 0 40
// Not all of these lines are present (all are)#[must_not_match_all_from_array]snmp-server host 192.0.2.2 EXAMPLECOMM10snmp-server host 192.0.2.4 EXAMPLECOMM30aaa session-idno ip subnet-zeroip domain name example.comline vty 0 4Against the IOS-XE excerpt at the top of the page:
| Rule | Result | Why |
|---|---|---|
can_match_any, one present | pass | snmp-server host 192.0.2.2 EXAMPLECOMM10 is present. |
can_match_any, none present | fail | No item appears. |
must_match_all, all present | pass | Every item appears. aaa session-id matches inside aaa session-id common. |
must_match_all, one missing | fail | line vty 0 5 does not appear. |
must_not_match_all, none present | pass | Not every item appears. |
must_not_match_all, all present | fail | Every item appears. |
Source: PolicyMethodsTest::test_can_match_any_from_array_tests, test_must_match_all_from_array_tests and test_must_not_match_all_from_array_tests. Minimum version 8.0.0.
The third row is the substring behaviour in action: aaa session-id is not a line in the config, but it is part of one. That is useful when you want “starts with”, and a source of false passes when you do not. Avoiding false positives covers both array traps.
Choosing between them
Section titled “Choosing between them”Exact line required: must_match_single_string.
Line forbidden: must_not_match_single_string for a fixed line, wildcard_must_not_match_single_string when part of it varies.
Several lines required: must_match_all_from_array, accepting that items match inside longer lines.
One of several alternatives: can_match_any_from_array.
Lines must sit inside one section: use a section-scoped check instead.