How to use commit scripts to modify the Junos system’s commit process

Customize the Junos configuration process to make it work for your environment.

By Jonathan Looney and Stacy Smith
June 14, 2016
Tools on a work bench Tools on a work bench (source: blickpixel via Pixabay)

Commit scripts are a powerful way to modify the commit process. They let you transform the
configuration between the time the user types commit and the time the configuration is read by
the daemons. You can enforce custom configuration checks, automatically fix
common configuration mistakes, and dynamically expand the configuration. In
short, you can customize the configuration process to make it work for
your environment.

Use Cases

Before diving into the details, let’s take a look at some of the target use cases
for commit scripts.

Learn faster. Dig deeper. See farther.

Join the O'Reilly online learning platform. Get a free trial today and find answers on the fly, or master something new and useful.

Learn more

Custom Configuration Checks

The Junos software enforces a set of configuration checks that ensure basic configuration
sanity. For example, the Junos software may prevent you from committing
a BGP configuration that references a policy that is undefined, or it
may prevent you from configuring the same IP address for two different
BGP peers. However, these configuration checks do not
ensure the configuration is correct for your
environment. Rather, they merely check that the configuration may be
suitable for some environment. Put differently,
they check that the configuration is syntactically correct, not
contextually correct. And this behavior makes sense. After all, how is
the Junos software to know what makes sense in any given network?

However, you may know a certain configuration
is appropriate, or inappropriate, for your environment. Some
organizations distill this knowledge into standards or configuration
templates. Using commit scripts, you can add configuration checks to
enforce these standards.

For example, assume that you know that all BGP neighbors should be
in one of three BGP groups: internal,
peers, or customers. You can add a commit check that
ensures no additional BGP groups are configured.

Next, let’s assume your configuration standard requires all BGP
neighbors in the peers and customers groups to have both import and
export policies applied to them, and that the last policy in each policy
chain must be the deny-all policy.
You can add commit checks to enforce these constraints.

If you find the configuration changes do not meet your standards,
you can have the commit script issue a warning to the user (but allow
the commit process to continue), issue an error to the user (and stop
the commit process), or take other actions (such as logging an error
message through syslog).

This gives you a small idea of the kinds of commit checks you can
do. However, there are many (almost limitless!) possibilities for commit
checks.

Automatically Fixing Mistakes

Just as you can find places where the configuration does not meet your
standards, you can also attempt to automatically correct the
configuration.

Perhaps the best examples of this use case are in the area of MPLS
or ISIS configuration. For both protocols, something must often be
configured at both the [edit
interfaces]
and [edit
protocols]
hierarchy levels in order to achieve the desired
results.

For MPLS, it is often the case that any interface listed in the
[edit protocols mpls] hierarchy
should also have family mpls
configured on the interface. For ISIS, any non-passive interface listed
in the [edit protocols isis]
hierarchy should also have family iso
configured on the interface.

If this is not the case, using a commit script, you can detect
this error and attempt to correct it by adding the missing
configuration. You can also include your configuration corrections in
the static configuration database.

Dynamically Expanding Configuration

Often, configuration elements are formed from a template. For example, all
customer BGP sessions may use the same configuration, except for the IP
address, AS number, import policy, and export policy. This network
standard allows customer BGP configurations to be simplified to a
template with variables that are replaced as appropriate. For example,
the template in a particular network might look like Example 1-1.

Example 1-1. A sample BGP configuration template
protocols {
    bgp {
        group customers {
            neighbor $ip_addr {
                import [ filter-customer-generic prefix-size
                         handle-communities as-$peer_as deny-all ];
                family inet {
                    unicast {
                        accepted-prefix-limit {
                            maximum $limit;
                            teardown 80 idle-timeout 10;
                        }
                    }
                }
                family inet6 {
                    unicast {
                        accepted-prefix-limit {
                            maximum $limit;
                            teardown 80 idle-timeout 10;
                        }
                    }
                }
                export [ $route_type deny-all ];
                peer-as $peer_as;
            }
        }
    }
}

Here, the critical pieces of information are the neighbor IP, peer
AS, prefix limit, and type of routes the user wants to receive. You can
write a commit script that takes those options as input parameters and
outputs the correct neighbor configuration. You can even choose to have
the commit script dynamically modify the configuration every time there
is a commit. This functionality has the impact of reducing the size of
the candidate configuration, while also ensuring that any changes to the
template are reflected in the existing BGP sessions. (In other words,
the configuration can be dynamically updated to reflect the new template
when the configuration template is updated.)

A commit script’s input values can be stored in apply-macro
configuration statements or derived from other configuration elements,
or you can simply use default values. For example, the configuration for
a customer BGP session could look like Example 1-2.

Example 1-2. A sample configuration snippet that provides values for a
commit script
interfaces {
    ge-1/0/0 {
        unit 0 {
            family inet {
                address 192.168.1.1/30 {
                    apply-macro bgp {
                        peer_as 65534;
                        route_type full_routes;
                    }
                }
            }
        }
    }
}

The commit script can read this configuration snippet and infer
the remote IP address, apply a default prefix limit of 10,000 prefixes,
and use the supplied values from the apply-macro bgp configuration hierarchy. It
can expand this configuration to that shown in Example 1-3.

Example 1-3. A sample configuration after a commit script has applied a
template
interfaces {
    ge-1/0/0 {
        unit 0 {
            family inet {
                address 192.168.1.1/30;
            }
        }
    }
}     
protocols {
    bgp {
        group customers {
            neighbor 192.168.1.2 {
                import [ filter-customer-generic prefix-size
                         handle-communities as-65534 deny-all ];
                family inet {
                    unicast {
                        accepted-prefix-limit {
                            maximum 10000;
                            teardown 80 idle-timeout 10;
                        }
                    }
                }
                family inet6 {
                    unicast {
                        accepted-prefix-limit {
                            maximum 10000;
                            teardown 80 idle-timeout 10;
                        }
                    }
                }
                export [ full_routes deny-all ];
                peer-as 65534;
            }
        }
    }
 }

There are, of course, many options for expanding the
configuration. Some users may prefer to configure the customer’s BGP
information, stored in the apply-macro
bgp
statement, under the [edit
protocols bgp]
hierarchy, while others may prefer to group all
customer information together in the [edit
interfaces]
hierarchy. Likewise, some users may prefer to keep
the simple template values (shown in Example 1-2) in their static
configuration, while others may prefer to have the commit script expand
the template one time and store the expanded configuration (shown in
Example 1-3) in their static
configuration. Whichever way you choose to use commit scripts, they can
help you apply templates to your network.

Post topics: Operations
Share: