Skip to content

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-model
aaa authentication login default local
aaa 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 EXAMPLECOMM
snmp-server host 192.0.2.2 EXAMPLECOMM10
snmp-server host 192.0.2.2 EXAMPLECOMM12xxxxxxx
snmp-server host 192.0.2.3 EXAMPLECOMM20
snmp-server host 192.0.2.4 EXAMPLECOMM30
!
line con 0
logging synchronous
stopbits 1
line vty 0 4
transport input telnet ssh
!
end

MethodCompares againstCasePasses when
must_match_single_stringEach whole line, trimmedSensitiveOne line equals the body exactly
must_not_match_single_stringEach whole line, trimmed, runs of whitespace collapsedInsensitiveNo line equals the body
must_match_all_from_arrayThe whole config as one block of textSensitiveEvery body line appears somewhere, even inside a longer line
can_match_any_from_arrayThe whole config as one block of textSensitiveAt least one body line appears somewhere
must_not_match_all_from_arrayThe whole config as one block of textSensitiveNot 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.


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
RuleResultWhy
...EXAMPLECOMM10passThe line exists exactly.
...EXAMPLECOMM12failThe config line is ...EXAMPLECOMM12xxxxxxx. A prefix is not a match.
...EXAMPLECOMM100failNo such line.
interface GfailPart 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.99

Against 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
RuleResultWhy
Relay to 198.51.100.31failThe indented line matches once trimmed.
Relay to 198.51.100.99passNo 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 ospf
feature bgp
router bgp 65000
neighbor 198.51.100.1 remote-as 65001
RuleResultWhy
FEATURE BGPfailMatches feature bgp after lowercasing and collapsing spaces.
feature ospfpassNo such line.

Source: MustNotMatchSingleStringCustomerTest. Minimum version 8.0.0.


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 EXAMPLECOMM10
snmp-server host 192.0.2.1 EXAMPLECOMM310
aaa session-id1
// At least one of these lines is present (none are)
#[can_match_any_from_array]
snmp-server host 192.0.2.1 EXAMPLECOMM110
snmp-server host 192.0.2.1 EXAMPLECOMM310
aaa session-id1
// Every one of these lines is present
#[must_match_all_from_array]
snmp-server host 192.0.2.2 EXAMPLECOMM10
snmp-server host 192.0.2.4 EXAMPLECOMM30
aaa session-id
no ip subnet-zero
ip domain name example.com
line 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 EXAMPLECOMM10
snmp-server host 192.0.2.4 EXAMPLECOMM30
aaa session-id
no ip subnet-zero
ip domain name example.com
line 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 EXAMPLECOMM100
snmp-server host 192.0.2.4 EXAMPLECOMM300
aaa session-id0
no ip subnet-zero0
ip domain name example.com0
line 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 EXAMPLECOMM10
snmp-server host 192.0.2.4 EXAMPLECOMM30
aaa session-id
no ip subnet-zero
ip domain name example.com
line vty 0 4

Against the IOS-XE excerpt at the top of the page:

RuleResultWhy
can_match_any, one presentpasssnmp-server host 192.0.2.2 EXAMPLECOMM10 is present.
can_match_any, none presentfailNo item appears.
must_match_all, all presentpassEvery item appears. aaa session-id matches inside aaa session-id common.
must_match_all, one missingfailline vty 0 5 does not appear.
must_not_match_all, none presentpassNot every item appears.
must_not_match_all, all presentfailEvery 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.


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.