Jinja Syntax and Examples for Configuration Templates
CSO configuration templates consist of three components:
A Jinja template configuration, which contains the logic and the configuration for the configuration template. (Jinja is a template engine for Python and you can find several Jinja resources on the Web.)
A Yang data model file, which contains the descriptors for the configuration schema.
A ViewDef (view definition) file, which is a JavaScript Object Notation (JSON) file that is used to specify the GUI aspects of the configuration template.
When you use the Add Configuration Template workflow to add a template, you specify the template configuration and logic by using the Jinja template language. CSO then generates the Yang data model and the ViewDef files automatically based on template configuration and logic that you specified. The generation of the Yang and ViewDef files is transparent to the user and doesn’t require any user intervention.
Jinja Syntax and CSO Keywords
The tables below list the Jinja syntax used commonly in configuration templates and the keywords used in configuration templates respectively.
Syntax |
Explanation |
---|---|
|
Denotes a variable or expression that will be printed to the template output. For example: {{tenant_name}} Note:
Hyphens are not recognized by the CSO template engine, so use underscores (_) in variables or expressions. |
|
Denotes a comment that will not be included in the template output. For example: {# This is an example of comment in Jinja syntax #} |
|
Denotes statements that are used to create conditional logic:
|
Dot (.) |
A dot [operator] is used to reference an attribute of a variable.
The following example shows a {% for prefix in Trusted_Network_Prefix_List %} set groups trusted‐prefix policy‐options prefix‐list re‐ssh {{prefix.Trusted_Network_Prefix_List}} {% endfor %} |
You can use configuration template keywords if you enable advanced mode for the configuration template.
Keyword |
Explanation |
---|---|
post_config |
Indicates to CSO that the variable that follows is a data type. |
pre_config |
Indicates to CSO the current configuration associated with a device. The pre_config keyword is used to compare a variable field’s value and then modify or delete existing configuration from a target device. |
diff_config |
Indicates to CSO that the pre_config and post_config should be compared and that CSO should create a new rendered configuration and then push it to target device. |
Example 1: Convert a Single Junos OS Command to Jinja Syntax
If you want to convert a single Junos OS command into Jinja syntax for use in a configuration template:
Identify the variables that are configured in the Junos OS command.
For example, in the command
set snmp trap-group CSO-Trp-Grp targets 192.0.2.100
, the variables configured are CSO-Trp-Grp and 192.0.2.100.Convert the Junos OS CLI command to Jinja syntax by enclosing each variable in double curly braces as follows:
{{ Variable_Name }}
.So, in this example, if we use Trap_Group_Name and SNMP_Host_IP_Address as the variable names, the Jinja syntax for the command is as follows:
set snmp trap-group {{ Trap_Group_Name }} targets {{ SNMP_Host_IP_Address }}
If you paste this in the Template Configuration section of the Add Configuration Template workflow, CSO detects the parameters as follows:
Parameters
SNMP_Host_IP_Addresses Trap_Group_Name
If you use the preview feature to render the configuration (for an OpCo named Juniper and a configuration template named Test), using the values indicated in the first step, CSO renders the configuration as follows:
delete groups default-domain_Juniper_Test delete apply-groups default-domain_Juniper_Test edit groups default-domain_Juniper_Test set snmp trap-group CSO-Trp-Grp targets 192.0.2.100 exit set apply-groups default-domain_Juniper_Test
Notice that although you provided the JInja syntax for a single Junos OS command, CSO added additional commands to the configuration. This is because, by default, CSO uses Junos OS groups to generate the configuration. Junos OS groups make it easier to apply and delete configurations. For more information, see Understanding Junos OS Configuration Groups.
If you don’t want to use Junos OS groups, you must turn on the advanced mode in the configuration template, when you specify the configuration in Jinja syntax..
Example 2: Convert a Junos OS Configuration Snippet to Jinja Syntax
In this example, we’ll convert the following Junos OS configuration snippet into Jinja syntax for use in a configuration template:
set forwarding-options dhcp-relay server-group DHCP-SERVER 192.0.2.50 set forwarding-options dhcp-relay active-server-group DHCP-SERVER set forwarding-options dhcp-relay group CSO-Relay-Grp1 interface ge-0/0/2.0 set security zones security-zone trust host-inbound-traffic system-services dhcp
To convert the Junos OS configuration into Jinja syntax:
Identify the variables that are configured in the Junos OS commands. For ease of understanding, the variables are enclosed within angular brackets (<>) in the example below.
Note:In this example, we’re not considering DHCP-SERVER as a variable.
set forwarding-options dhcp-relay server-group DHCP-SERVER <Relay_IP> set forwarding-options dhcp-relay active-server-group DHCP-SERVER set forwarding-options dhcp-relay group <Relay_Group_Name> interface <Relay_Interface> set security zones security-zone <Relay_Zone> host-inbound-traffic system-services dhcp
Convert each Junos OS CLI command to Jinja syntax by identifying the variables, providing a name for each variable, and enclosing each variable in double curly braces. So, in this case, the Jinja syntax is as follows:
set forwarding-options dhcp-relay server-group DHCP-SERVER {{Relay_IP}} set forwarding-options dhcp-relay active-server-group DHCP-SERVER set forwarding-options dhcp-relay group {{Relay_Group_Name}} interface {{Relay_Interface}} set security zones security-zone {{Relay_Zone}} host-inbound-traffic system-services dhcp
When you paste this in the Template Configuration section of the Add Configuration Template workflow, CSO detects the parameters as follows:
Parameters
Relay_IP Relay_Interface Relay_Zone Relay_Group_Name
If you use the preview feature to render the configuration (for an OpCo named Juniper and a configuration template named Test), using the values for this example, CSO renders the configuration as follows:
delete groups default-domain_Juniper_Test delete apply-groups default-domain_Juniper_Test edit groups default-domain_Juniper_Test set forwarding-options dhcp-relay server-group DHCP-SERVER 192.0.2.50 set forwarding-options dhcp-relay active-server-group DHCP-SERVER set forwarding-options dhcp-relay group CSO-Relay-Grp1 interface ge-0/0/2.0 set security zones security-zone trust host-inbound-traffic system-services dhcp exit set apply-groups default-domain_Juniper_Test
Example 3: Use Conditional Logic
In this example, which is a modified version of the preceding
example, we’ll see how you can use conditional logic (if
and for
statements) in
a configuration template.
{%- if enable_Forwarding_Options %} set forwarding-options dhcp-relay server-group DHCP-SERVER {{RelayIP }} set forwarding-options dhcp-relay active-server-group DHCP-SERVER {% for relay in RelayOptions %} set forwarding-options dhcp-relay group {{ relay.Relay_Group_Name }} interface {{ relay.Relay_Interface }} set security zones security-zone {{ relay.Relay_Zone }} host-inbound-traffic system-services dhcp {% endfor %} {% endif %}
The explanation of the example above is as follows:
In this example, we add an
if
statement and enclose the configuration within that statement as follows:{%- if enable_Forwarding_Options %} ... ... {% endif %}
This means that the configuration is applied only if the enable_Forwarding_Options is True. If enable_Forwarding_Options is False, then no configuration is applied.
Tip:If you want to apply a different configuration when enable_Forwarding_Options is False, you can use the
else
statement.Then, we add a
for
statement to enable the configuration of more than one set of values for theRelay_Group_Name
,Relay_Interface
, andRelay_Zone
variables.{% for relay in RelayOptions %} set forwarding-options dhcp-relay group {{ relay.Relay_Group_Name }} interface {{ relay.Relay_Interface }} set security zones security-zone {{ relay.Relay_Zone }} host-inbound-traffic system-services dhcp {% endfor %}
When you use a
for
statement, the GUI rendered by CSO (when you use the preview feature) displays the variables in table (grid). You can then use the Add icon (+) to add rows to the table and configure one or more sets of values as needed.When you paste the Jinja commands in the Template Configuration section of the Add Configuration Template workflow, CSO detects the parameters as follows:
Parameters
RelayIP enable_Forwarding_Options RelayOptions Relay_Interface Relay_Zone Relay_Group_Name
If you use the preview feature to render the configuration (for an OpCo named Juniper and a configuration template named Test), and provide values for the parameters, including two sets of values for
Relay_Group_Name
,Relay_Interface
, andRelay_Zone
, CSO renders the configuration as follows:delete groups default-domain_BLR_SOLN_test delete apply-groups default-domain_BLR_SOLN_test edit groups default-domain_BLR_SOLN_test set forwarding-options dhcp-relay server-group DHCP-SERVER 192.0.2.50 set forwarding-options dhcp-relay active-server-group DHCP-SERVER set forwarding-options dhcp-relay group CSO-RelayGrp1 interface ge-0/0/2.0 set security zones security-zone trust host-inbound-traffic system-services dhcp set forwarding-options dhcp-relay group RelayGrp2 interface ge-1/0/2.0 set security zones security-zone untrust host-inbound-traffic system-services dhcp exit set apply-groups default-domain_BLR_SOLN_test
Example 4: Use Variable Substitution
In this example, we use a variable as part of the configuration command such that the value that we specify for the variable is used in the command.
set groups MIST vlans V-{{pool.VLAN_Id}} vlan-id {{pool.VLAN_Id}}
The explanation of the example above is as follows:
We use the
VLAN_Id
attribute of thepool
parameter to set the Junos OS configuration parametersvlans
andvlan-id
.When you paste the Jinja command
set groups MIST vlans V-{{pool.VLAN_Id}} vlan-id {{pool.VLAN_Id}}
in the Template Configuration section of the Add Configuration Template workflow, CSO detects the parameters as follows:Parameters
pool VLAN_Id
This is because we’ve used the dot (.) operator to reference the attribute
VLAN_Id
of the parameterpool
.If you use the preview feature to render the configuration (for an OpCo named Juniper and a configuration template named Test), and provide the value 120 for
VLAN_Id
, CSO renders the configuration as follows:delete groups default-domain_Juniper_Test delete apply-groups default-domain_Juniper_Test edit groups default-domain_Juniper_Test set groups MIST vlans V-120 vlan-id 120 exit set apply-groups default-domain_Juniper_Test
In the rendered configuration command, you can see that the parameters
vlans
andvlan-id
are set toV-120
and120
respectively, based on the value that we provided for the VLAN_Id parameter.
Example 5: Use Filters, Concatenation, and Set Variables
In this example, we’ll look at how to set a variable using concatenation and filters, and then use that variable in a Junos OS configuration command.
{% set pool_name = Dhcp_Server_Name + '_' + Interface | replace("/", "_") %} set system services dhcp-local-server overrides process-inform pool {{pool_name}}
The explanation of the example above is as follows:
The Jinja statement
{% set pool_name = Dhcp_Server_Name + ’_’ + Interface | replace(“/”,”_”) %}
is used to set a variable called pool_name, using two other variables Dhcp_Server_Name and Interface, as follows:The
|
(pipe) operator is used to separate variables from filters, which are functions that modify variables. In this example, we use thereplace(“/”,”_”)
filter to modify the Interface variable by replacing the / (forward slash) characters with _ (underscore) characters.Then, we use the
+
operator to concatenate the resulting string with the variable Dhcp_Server_Name.Note:The operator
+
is typically used to add numbers, but when the values are strings, the strings are concatenated.Finally, the tag
set
is used (along with the=
operator) to set the variable called pool_name to the concatenated variable.
Then, the Junos OS command
set system services dhcp-local-server overrides process-inform pool {{pool_name}}
is used to configure the Junos OS configuration statementpool
using the variablepool_name
that we set in the preceding step.When you paste the Jinja commands in the Template Configuration section of the Add Configuration Template workflow, CSO detects the parameters as follows:
Parameters
Interface Dhcp_Server_Name
As you can see, the Junos OS command or the pool_name variables are not displayed because we’re using the Interface and Dhcp_Server_Name variables to arrive at the final Junos OS configuration.
If you use the preview feature to render the configuration (for an OpCo named Juniper and a configuration template named Test), and provide the values LA_dhcp_srvr for
Dhcp_Server_Name
and ge-0/1/2 for theInterface
, CSO renders the configuration as follows:delete groups default-domain_Juniper_Test delete apply-groups default-domain_Juniper_Test edit groups default-domain_Juniper_Test set system services dhcp-local-server overrides process-inform pool LA_dhcp_srvr_ge-0_1_2 exit set apply-groups default-domain_Juniper_Test
As explained in a previous step, the / characters in ge-0/1/2 are first replaced with _ characters, which changes the string to ge-0_1_2. This string is concatenated with LA_dhcp_srvr to produce the string LA_dhcp_srvr_ge-0_1_2, which is used in the Junos OS configuration command.
Therefore, the Junos OS configuration command generated is
set system services dhcp-local-server overrides process-inform pool LA_dhcp_srvr_ge-0_1_2
.
Example 6: Test a Value
In this example, we’ll look at how to test a value and perform actions based on the result of the test conditions.
{%- if NewNetwork.VLAN_Id is defined and (NewNetwork.VLAN_Id | count) > 2 -%} set vlan-id {{NewNetwork.VLAN_Id}} {% else %} set vlans VL-{{NewNetwork.VLAN_Id}} {% endif %}
The explanation of the example above is as follows:
We test the parameter
NewNetwork.VLAN_Id
for two conditions:Whether the parameter is defined (by using the
NewNetwork.VLAN_Id is defined
condition)Whether the length of the parameter is greater than two (by using the condition
(NewNetwork.VLAN_Id | count) > 2
)
Because we use the keyword
and
:The configuration command
set vlan-id {{NewNetwork.VLAN_Id}}
is added to the configuration (that CSO generates) when both conditions hold true.The configuration
set vlans VL-{{NewNetwork.VLAN_Id}}
is added to the configuration when either of the conditions is false.
When you paste the Jinja commands in the Template Configuration section of the Add Configuration Template workflow, CSO detects the parameters as follows:
Parameters
NewNetwork VLAN_Id
If you use the preview feature to render the configuration (for an OpCo named Juniper and a configuration template named Test), and:
Provide the value 125 for
VLAN_Id
, CSO renders the configuration as follows because both conditions are true:delete groups default-domain_Juniper_Test delete apply-groups default-domain_Juniper_Test edit groups default-domain_Juniper_Testset vlan-id 125 exit set apply-groups default-domain_Juniper_Test
Provide the value 65 for
VLAN_Id
, CSO renders the configuration as follows because one of the conditions is false (length of the parameter is not greater than 2):delete groups default-domain_BLR_SOLN_testtmp delete apply-groups default-domain_BLR_SOLN_testtmp edit groups default-domain_BLR_SOLN_testtmp set vlans VL-65 exit set apply-groups default-domain_BLR_SOLN_testtmp