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.

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.

Article image: Tools on a work bench (source: blickpixel via Pixabay).