Config Scripts

Cisco IOS XR config scripts can validate and make modifications to configuration changes. They allow device administrators to enforce custom configuration validation rules, or to simplify certain repetitive configuration tasks. These scripts are invoked automatically when you change a configuration and commit the changes. When a configuration commit is in progress, a config script inserts itself into the commit process. The config script can modify the current config candidate. For example, consider you want to maintain certain parameters for routers such as switched off ports or security policies. The config script is triggered to validate the updated configuration and take appropriate action. If the change is valid, the script allows committing the new configuration. If the configuration is invalid, or does not adhere to the enforced constraints, the script notifies you about the mismatch and blocks the commit operation. Overall, config scripts help to maintain crucial device parameters, and reduce human error in managing the network.

When you commit or validate a configuration change, the system invokes each of the active scripts to validate that change. Config scripts can perform the following actions:

  • Analyze the proposed new configuration.

  • If the configuration is invalid, block the commit by returning an error message along with the set of configuration items to which it relates.

  • Return a warning message with the related details but does not block the commit operation.

  • Modify the configuration to be included in the commit operation to make the configuration valid, or to simplify certain repetitive configuration tasks. For example, where a value needs duplicating between one configuration item and another configuration item.

  • Generate system log messages for in-depth analysis of the configuration change. This log also helps in troubleshooting a failed commit operation.

Config Scripts Limitations

The following are the configuration and software restrictions when using config scripts:

  • Config scripts cannot make modifications to configuration that is protected by CCV process, in particular:

    • Script checksum configuration.

    • Other sensitive security configuration such as AAA configuration.

  • Config scripts do not explicitly support importing helper modules or other custom imports to provide shared functionality. Although such imports appear to function correctly when set up, they can potentially represent a security risk becaue there is no checksum validation on the imported modules. Modifications to these imported modules are not automatically detected. To reflect changes to the imported module in the running scripts, you must manually unconfigure and reconfigure any scripts using the imported module.

Get Started with Config Scripts

Config scripts can be written in Python 3.5 programming language using the packages that Cisco supports. For more information about the supported packages

This chapter gets you started with provisioning your Python automation scripts on the router.


Note


This chapter does not delve into creating Python scripts, but assumes that you have basic understanding of Python programming language. This section will walk you through the process involved in deploying and using the scripts on the router.


Workflow to Run Config Scripts

Complete the following tasks to provision config scripts:

  • Enable the config scripts feature—Globally activate the config scripts feature on the router using configuration validation scripts command.

  • Download the script—Store the config script on an HTTP server or copy to the harddisk of the router. Add the config script from the HTTP server to the script management repository (hardisk:/mirror/script-mgmt) on the router using the script add config command.

  • Validate the script—Check script integrity and authenticity using the script config script.py checksum command. A script cannot be used unless the checksum is configured. After the checksum is configured, the script is active.


    Note


    A config script is invoked automatically when you validate or commit a configuration change to modify the candidate configuration.


  • Validate the configuration—Ensure that the configuration changes comply with the predefined conditions in the script and uncover potential errors using validate config-scripts apply-policy-modifications command.

  • View the script execution details—Retrieve the operational data using the show operational Config Global Validation Script Execution command.

The following image shows a workflow diagram representing the steps involved in using a config script:

A workflow diagram representing the steps and the CLI commands involved in using a config script.

Enable Config Scripts Feature

Config scripts are driven by commit operations. To run the config scripts, you must enable the feature on the router. You must have root user privileges to enable the config scripts.


Note


You must commit the configuration to enable the config scripts feature before committing any script checksum configuration.


Procedure


Step 1

Enable the config scripts.

Example:

Router(config)#configuration validation scripts

Step 2

Commit the configuration.

Example:

Router(config)#commit

Download the Script to the Router

To manage the scripts, you must add the scripts to the script management repository on the router. A subdirectory is created for each script type. By default, this repository stores the downloaded scripts in the appropriate subdirectory based on script type.

Script Type Download Location

config

harddisk:/mirror/script-mgmt/config

exec

harddisk:/mirror/script-mgmt/exec

process

harddisk:/mirror/script-mgmt/process

eem

harddisk:/mirror/script-mgmt/eem

The scripts are added to the script management repository using two methods:
  • Method 1: Add script from a server

  • Method 2: Copy script from external repository to harddisk using scp or copy command

In this section, you learn how to add config-script.py script to the script management repository.

Procedure


Step 1

Add the script to the script management repository on the router using one of the two options:

  • Add Script From a Server
    Add the script from a configured HTTP server or the harddisk location in the router.
    Router#script add config <script-location> <script.py>
    
    The following example shows a config script config-script.py downloaded from an external repository http://192.0.2.0/scripts:
    Router#script add config http://192.0.2.0/scripts config-script.py
    Fri Aug 20 05:03:40.791 UTC
    config-script.py has been added to the script repository
    
    You can add a maximum of 10 scripts simultaneously.
    Router#script add config <script-location> <script1.py> <script2.py> ... <script10.py>
    You can also specify the checksum value while downloading the script. This value ensures that the file being copied is genuine. You can fetch the checksum of the script from the server from where you are downloading the script. However, specifying checksum while downloading the script is optional.
    Router#script add config http://192.0.2.0/scripts config-script.py checksum SHA256 <checksum-value>
    For multiple scripts, use the following syntax to specify the checksum:
    Router#script add config http://192.0.2.0/scripts <script1.py> <script1-checksum> <script2.py> <script2-checksum>
    ... <script10.py> <script10-checksum>
    If you specify the checksum for one script, you must specify the checksum for all the scripts that you download.

    Note

     

    Only SHA256 checksum is supported.

  • Copy the Script from an External Repository

    You can copy the script from the external repository to the routers' harddisk and then add the script to the script management repository.

    1. Copy the script from a remote location to harddisk using scp or copy command.
      Router#scp userx@192.0.2.0:/scripts/config-script.py /harddisk:/
    2. Add the script from the harddisk to the script management repository.
      Router#script add config /harddisk:/ config-script.py
      Fri Aug 20 05:03:40.791 UTC
      config-script.py has been added to the script repository
      

Step 2

Verify that the scripts are downloaded to the script management repository on the router.

Example:

Router#show script status
Router#show script status
Wed Aug 25 23:10:50.453 UTC
==========================================================================================
 Name              | Type     | Status           | Last Action | Action Time
------------------------------------------------------------------------------------------
 config-script.py  | config   | Config Checksum  | NEW         | Tue Aug 24 10:18:23 2021
 
Script config-script.py is copied to harddisk:/mirror/script-mgmt/config directory on the router.

Configure Checksum for Config Script

Every script is associated with a checksum hash value. This value ensures the integrity of the script, and that the script is not tampered with. The checksum is a string of numbers and letters that act as a fingerprint for script. The checksum of the script is compared with the configured checksum. If the values do not match, the script is not run and a syslog warning message is displayed.

It is mandatory to configure the checksum to run the script.


Note


Config scripts support SHA256 checksum.


Before you begin

Ensure that the following prerequisites are met before you run the script:
  1. Enable Config Scripts Feature

Procedure


Step 1

Retrieve the SHA256 checksum hash value for the script. Ideally this action would be performed on a trusted device, such as the system on which the script was created. This minimizes the possibility that the script is tampered with. However, if the router is secure, you can retrieve the checksum hash value from the IOS XR Linux bash shell.

Example:

Router#run
[node0_RP0_CPU0:~]$sha256sum /harddisk:/mirror/script-mgmt/config/config-script.py
94336f3997521d6e1aec0ee6faab0233562d53d4de7b0092e80b53caed58414b /harddisk:/mirror/script-mgmt/config/config-script.py

Make note of the checksum value.

Step 2

View the status of the script.

Example:

Router#show script status detail
Fri Aug 20 05:04:13.539 UTC
======================================================================================================
 Name                            | Type   | Status           | Last Action | Action Time
------------------------------------------------------------------------------------------------------
 config-script.py                | config | Config Checksum  | NEW         | Fri Aug 20 05:03:41 2021
------------------------------------------------------------------------------------------------------
 Script Name       : config-script.py
 History:
 --------
 1.   Action       : NEW
      Time         : Fri Aug 20 05:03:41 2021
      Description  : User action IN_CLOSE_WRITE
===========================================================================================

The Status shows that the checksum is not configured.

Step 3

Configure the checksum.

Example:

Router#configure
Router(config)#script config config-script.py checksum SHA256 94336f3997521d6e1aec0ee6faab0233562d53d4de7b0092e80b53caed58414b
Router(config)#commit
Tue Aug 24 10:23:10.546 UTC
Router(config)#end

Note

 

When you commit this configuration, the script is automatically run to validate the resulting running configuration. If the script returns any errors, this commit operation fails. This way, the running configuration always remains valid with respect to all currently active scripts with checksums configured.

If you are configuring multiple scripts, the system decides an appropriate order to run the scripts. However, you can control the order in which scripts execute using a priority value. For more information on configuring the priority value, see Control Priority When Running Multiple Scripts.

Step 4

Verify the status of the script.

Example:

Router#show script status detail
Fri Aug 20 05:06:17.296 UTC
======================================================================================================
 Name                            | Type   | Status           | Last Action | Action Time
------------------------------------------------------------------------------------------------------
 config-script.py                | config | Ready            | NEW         | Fri Aug 20 05:03:41 2021
------------------------------------------------------------------------------------------------------
 Script Name       : config-script.py
 Checksum          : 94336f3997521d6e1aec0ee6faab0233562d53d4de7b0092e80b53caed58414b
 History:
 --------
 1.   Action       : NEW
      Time         : Fri Aug 20 05:03:41 2021
      Checksum     : 94336f3997521d6e1aec0ee6faab0233562d53d4de7b0092e80b53caed58414b
      Description  : User action IN_CLOSE_WRITE
===========================================================================================

The status Ready indicates that the checksum is configured and the script is ready to be run. When the script is run, the checksum value is recalculated to check if it matches with the configured hash value. If the values differ, the script is not run, and the commit operation that triggered the script is rejected. It is mandatory for the checksum values to match for the script to run.


Validate or Commit Configuration to Invoke Config Script

You can validate a configuration change on the set of active config scripts (including any scripts newly activated as part of the configuration change) before committing the changes. This validation ensures that the configuration complies with predefined conditions defined in the active scripts based on your network requirements. With validation, you can update the target configuration buffer with any modifications that are made by the config scripts. You can review the target configuration using the show configuration command, and further refine the changes to resolve any outstanding errors before revalidating or committing the configuration.


Note


If the config script rejects one or more items in the commit operation, the entire commit operation is rejected.


Before you begin

Ensure that the following prerequisites are met before you run the script:
  1. Enable Config Scripts Feature

  2. Configure Checksum for Config Script

Procedure


Step 1

Validate the configuration with the conditions in the config script.

Example:

Router(config)#validate config-scripts apply-policy-modifications
Tue Aug 31 08:30:38.613 UTC

% Policy modifications were made to target configuration, please issue 'show configuration'
from this session to view the resulting configuration                                                                          figuration' from this session to view the resulting configuration

The output shows that there are no errors in the changed configuration. You can view the modifications made to the target configuration.

Note

 

If you do not want the config buffer to be updated with the modifications, omit the apply-policy-modifications keyword in the command.

The script validates the configuration changes with the conditions set in the script. Based on the configuration, the script stops the commit operation, or modifies the configuration.

Step 2

View the modified target configuration.

Example:

Router(config)#show configuration
Tue Aug 31 08:30:56.833 UTC
Building configuration...
!! IOS XR Configuration 7.3.2
script config config-script.py checksum SHA256 94336f3997521d6e1aec0ee6faab0233562d53d4de7b0092e80b53caed58414b                                                                             d342adb35cbc8a0cd4b6ea1063d0eda2d58
......----- configuration details
end

Step 3

Commit the configuration.

Example:

Router(config)#commit
Tue Aug 31 08:31:32.926 UTC

If the script returns an error, use the show configuration failed if-committed command to view the errors. If there are no validation errors, the commit operation is successful including any modifications that are made by config scripts.

You can view the recent commit operation that the script modified, and display the original configuration changes before the script modified the values using show configuration commit changes original last-modified command.

If the commit operation is successful, you can check what changes were committed including the script modifications using show configuration commit changes last 1 command.

Note

 

If a config script returns a modified value that is syntactically invalid, such as an integer that is out of range, then the configuration is not converted to CLI format for use in operational commands. This action impacts the validate config-scripts apply-policy-modifications command and show configuration command to view the modifications, and show configuration failed [if-committed] command during a failed commit operation.

Step 4

After the configuration change is successful, view the running configuration and logs for details.

Example:

Router(config)#show logging
Tue Aug 31 08:31:54.472 UTC
Syslog logging: enabled (0 messages dropped, 0 flushes, 0 overruns)
    Console logging: Disabled
    Monitor logging: level debugging, 0 messages logged
    Trap logging: level informational, 0 messages logged
    Buffer logging: level debugging, 13 messages logged

Log Buffer (2097152 bytes):
-------------------- snipped for brevity ---------------------------------------
Configuration committed by user 'cisco'. Use 'show configuration commit changes  
1000000006' to view the changes.

Manage Scripts

This section shows the additional operations that you can perform on a script.

Delete Config Script from the Router

You can delete a config script from the script management repository using the script remove command.

Procedure


Step 1

View the active scripts on the router.

Example:

Router#show script status
Wed Aug 24 10:10:50.453 UTC
======================================================================================================
 Name                            | Type   | Status           | Last Action | Action Time
------------------------------------------------------------------------------------------------------
 ssh_config_script.py            | config | Ready            | NEW         | Tue Aug 24 09:18:23 2021
 ======================================================================================================

Ensure the script that you want to delete is present in the repository.

Alternatively you can also view the list of scripts from the IOS XR Linux bash shell.
[node0_RP0_CPU0:/harddisk:/mirror/script-mgmt/config]$ls -lrt
total 1
-rw-rw-rw-. 1 root root 110 Aug 24 10:44 ssh_config_script.py

Step 2

Delete script ssh_config_script.py.

Example:

Router#script remove config ssh_config_script.py
Tue Aug 24 10:19:38.170 UTC
ssh_config_script.py has been deleted from the script repository
You can also delete multiple scripts simultaneously.
Router#script remove config sample1.py sample2.py sample3.py

Step 3

Verify that the script is deleted from the subdirectory.

Example:

Router#show script status
Tue Aug 24 10:24:38.170 UTC
### No scripts found ###

The script is deleted from the script management repository.

If a config script is still configured when it is removed, subsequent commit operations are rejected. So, you must also undo the configuration of the script:
Router(config)#no script config ssh_config_script.py  
Router(config)#commit

Control Priority When Running Multiple Scripts

If the set of active scripts includes two (or more) that may attempt to modify the same configuration item but to different values, whichever script runs last takes precedence. The script that was last run supersedes the values written by the script (or scripts) that ran before it. It is recommended to avoid such dependencies between scripts. For example, you can combine such scripts into a single script. If the dependency cannot be resolved, you can specify which script takes precedence by ensuring it runs last.

Priority can also be used to ensure scripts run in an optimal order, which may be important if scripts consume resources and impacts performance. For example, consider that script A sets configuration that is validated by script B. Without a set priority, the system may run script B first, then script A, and then script B a second time to validate the changes made by script A. With a configured priority, the system ensures that script A runs first, and script B needs to run only once.

The priority value is an integer between 0-4294967295. The default value is 500.

Consider script sample1.py depends on sample2.py to validate the configuration that the script sets. The script sample1.py must be run first, followed by sample2.py. Configure the priority to ensure that the system runs the scripts in a specified order.

Procedure


Step 1

Configure script sample1.py with a lower priority.

Example:

Router(config)#script config sample1.py checksum sha256 2b061f11ede3c1c0c18f1ee97269fd342adb35cbc8a0cd4b6ea1063d0eda2d58
priority 10

Step 2

Configure script sample2.py with a higher priority.

Example:

Router(config)#script config sample2.py checksum sha256 2fa34b64542f005ed58dcaa1f3560e92a03855223e130535978f8c35bc21290c
priority 20

Step 3

Commit the configuration.

Example:

Router(config)#commit

The system checks the priority values, and runs the one with lower priority first (sample1.py), followed by the one with the higher priority value (sample2.py).


Example: Validate and Activate an SSH Config Script

This section presents examples for config script that enforces various constraints related to SSH configuration, including making modifications to the configuration in some cases. The following sub-sections illustrate the behaviour of this script in various scenarios.

Before you begin

Ensure you have completed the following prerequisites before you validate the script:

  1. Enable config scripts feature on the router. See Enable Config Scripts Feature.

  2. Create a config script ssh_config_script.py. Store the script on an HTTP server or copy the script to the harddisk of the router.
    import cisco.config_validation as xr
    from cisco.script_mgmt import xrlog
    syslog = xrlog.getSysLogger('xr_cli_config')
    
    def check_ssh_late_cb(root):
        SSH = "/crypto-ssh-cfg:ssh"
        SERVER = "/crypto-ssh-cfg:ssh/server"
        SESSION_LIMIT = "session-limit"
        LOGGING = "logging"
        RATE_LIMIT = "rate-limit"
        V2 = "v2"
        server = root.get_node(SERVER)
        if server is None:
            xr.add_error(SSH, "SSH must be enabled.")
    
        if server :
            session_limit = server.get_node(SESSION_LIMIT)
            rate_limit = server.get_node(RATE_LIMIT)
            ssh_logging = server.get_node(LOGGING)
            ssh_v2 = server.get_node(V2)
    
            if session_limit is None or session_limit.value >= 100:
                server.set_node(SESSION_LIMIT, 80)
            if rate_limit.value == 60:
                xr.add_warning(rate_limit, "RATE_LIMIT should not be set to default value")
            if not ssh_logging:
                server.set_node(LOGGING)
            if not ssh_v2:
                xr.add_error(server, "Server V2 need to be set")
            
    xr.register_validate_callback(["/crypto-ssh-cfg:ssh/server/*"], check_ssh_late_cb)
    

    The script checks the following actions:

    • Check if SSH is enabled. If not, generate an error message SSH must be enabled and stop the commit operation.

    • Check if the rate-limit is set to 60, display a warning message that the RATE_LIMIT should not be set to default value and allow the commit operation.

    • Check if the session-limit is set. If the limit is 100 sessions or more, set the value to 80 and allow the commit operation.

    • Set the logging if not already enabled.

  3. Add the script from HTTP server or harddisk to the script management repository.

Scenario 1: Validate the Script Without SSH Configuration

In this example, you validate a script without SSH configuration. The script is programmed to check the SSH configuration. If not configured, the script instructs the system to display an error message and stop the commit operation until SSH is configured.

Procedure


Step 1

Configure the checksum to verify the authenticity and integrity of the script. See Configure Checksum for Config Script.

Step 2

Validate the config script.

Example:

Router(config)#validate config-scripts apply-policy-modifications 
Wed Sep 1 23:21:34.730 UTC

% Validation of configuration items failed. Please issue 'show configuration failed if-committed' from this 
session to view the errors

The validation of the configuration failed.

Step 3

View the configuration of the failed operation.

Example:

Router#show configuration failed if-committed
Wed Sep 1 22:01:07.492 UTC
!! SEMANTIC ERRORS: This configuration was rejected by !! the system due to semantic errors. 
!! The individual errors with each failed configuration command can be found below.

script config ssh_config_script.py checksum SHA256 2b061f11ede3c1c0c18f1ee97269fd342adb35cbc8a0cd4b6ea1063d0eda2d58
!!% ERROR: SSH must be enabled.
end

The message for the failure is displayed. Here, the error SSH must be enabled is displayed as programmed in the script. The script stops the commit operation because the changes do not comply with the rule set in the script.

Step 4

Check the syslog output for the count of errors, warnings, and modifications.

Example:

Router#show logging  | in Error
Wed Sep 1 22:02:05.559 UTC
Router:Wed Sep 1 22:45:05.559 UTC: ccv[394]: %MGBL-CCV-6-CONFIG_SCRIPT_CALLBACK_EXECUTED :
The function check_ssh_late_cb registered by the config script ssh_config_script.py was 
executed in 0.000 seconds. 
Error/Warning/Modification counts: 1/0/0 

In this example, the script displays an error about the missing SSH configuration. When an error is displayed, the warning and modification count always show 0/0 respectively even if modifications exist on the target buffer.


Scenario 2: Configure SSH and Validate the Script

In this example, you configure SSH to resolve the error displayed in scenario 1, and validate the script again.

Procedure


Step 1

Configure SSH.

Example:

Router(config)#ssh server v2
Router(config)#ssh server vrf default
Router(config)#ssh server netconf vrf default

Step 2

Configure the checksum.

Step 3

Validate the configuration again.

Example:

Router(config)#validate config-scripts apply-policy-modifications 
Wed Sep 1 22:03:05.448 UTC

% Policy modifications were made to target configuration, please issue 'show configuration' 
from this session to view the resulting configuration

The script is programmed to display an error and stop the commit operation if the system detects that SSH server is not configured. After the SSH server is configured, the script is validated successfully.

Step 4

Commit the configuration.

Example:

Router(config)#commit
Tue Aug 31 08:31:32.926 UTC

Step 5

View the SSH configuration that is applied or modified after the commit operation.

Example:

Router#show running-config ssh 
Wed Sep 1 22:15:05.448 UTC
ssh server logging
ssh server session-limit 80
ssh server v2
ssh server vrf default
ssh server netconf vrf default

In addition, you see the modifications that are made by the script to the target buffer. The session-limit is used to configure the number of allowable concurrent incoming SSH sessions. In this example, the default limit is set to 80 sessions. Outgoing connections are not part of the limit. The script is programmed to check the session limit. If the limit is greater or equal to 100 sessions, the script reconfigures the value to the default 80 sessions. However, if the limit is within 100 sessions, the configuration is accepted without modification.

Step 6

Check the syslog output for the count of errors, warnings, and modifications.

Example:

Router#show logging  | in Error
Wed Sep 1 22:45:05.559 UTC
Router:Wed Sep 1 22:45:05.559 UTC: ccv[394]: %MGBL-CCV-6-CONFIG_SCRIPT_CALLBACK_EXECUTED :
The function check_ssh_late_cb registered by the config script ssh_config_script.py was 
executed in 0.000 seconds. 
Error/Warning/Modification counts: 0/0/2 

In this example, the script did not display an error or warning, but made two modifications for server logging and session-limit.


Scenario 3: Set Rate-limit Value to Default Value in the Script

In this example, you see the response after setting the rate-limit to the default value configured in the script. The rate-limit is used to limit the incoming SSH connection requests to the configured rate. The SSH server rejects any connection request beyond the rate-limit. Changing the rate-limit does not affect established SSH sessions. For example, if the rate-limit argument is set to 60, then 60 requests are allowed per minute. The script checks if the rate-limit is set to the default value 60. If yes, the script displays a warning message that the RATE_LIMIT should not be set to default value, but allow the commit operation.

Procedure


Step 1

Configure rate-limit to the default value of 60.

Example:

Router(config)#ssh server rate-limit 60

Step 2

Commit the configuration.

Example:

Router(config)#commit
Wed Sep 1 22:11:05.448 UTC

% Validation warnings detected as a result of the commit operation. 
Please issue 'show configuration warnings' to view the warnings

The script displays a warning message but proceeds with the commit operation.

Step 3

View the warning message.

Example:

Router(config)#show configuration warnings
Wed Sep 1 22:12:05.448 UTC
!! SEMANTIC ERRORS: This configuration was rejected by the system due to 
semantic errors. The individual errors with each failed configuration command 
can be found below.

script config ssh_config_script.py checksum SHA256 
2b061f11ede3c1c0c18f1ee97269fd342adb35cbc8a0cd4b6ea1063d0eda2d58
!!% WARNING: RATE_LIMIT should not be set to default value
end

The rate limit is default value of 60. The script is programmed to display a warning message if the rate limit is set to the default value. You can either change the limit or leave the value as is.

Step 4

View the running configuration.

Example:

Router(config)#do show running-config  script
Wed Sep 1 22:15:05.448 UTC
script config ssh_config_script.py checksum SHA256 
2b061f11ede3c1c0c18f1ee97269fd342adb35cbc8a0cd4b6ea1063d0eda2d58

The script ssh_config_script.py is active.


Scenario 4: Delete SSH Server Configuration

In this example, you delete the SSH server configurations, and see the response when the script is validated.

Procedure


Step 1

Remove the SSH server configuration.

Example:

Router(config)#no ssh server v2 

Step 2

Commit the configuration.

Example:

Router(config)#commit
Wed Sep 1 22:45:05.559 UTC

% Failed to commit one or more configuration items during an atomic operation. 
No changes have been made. Please issue 'show configuration failed if-committed' from 
this session to view the errors

Step 3

View the error message.

Example:

Router(config)#show configuration failed if-committed
Wed Sep 1 22:47:53.202 UTC
!! SEMANTIC ERRORS: This configuration was rejected by the system due to semantic errors. The individual
errors with each failed configuration command can be found below.

no ssh server v2
!!% ERROR: Server V2 need to be set
end

The message is displayed based on the rule set in the script.