NAME

Mnet::Stanza - Manipulate stanza outline text

SYNOPSIS

    # use this module
    use Mnet::Stanza;

    # read current config from standard input, trim extra spaces
    my $sh_run = undef;
    $sh_run .= "$_\n" while <STDIN>;
    $sh_run = Mnet::Stanza::trim($sh_run);

    # parse existing version of secure acl from current config
    my $acl_old = Mnet::Stanza::parse($sh_run, /^ip access-list SECURE/);

    # note latest version of secure acl, trim extra spaces
    my $acl_new = Mnet::Stanza::trim("
        ip access-list SECURE
         permit 192.168.0.0 0.0.255.255
    ");

    # print config to update acl if current acl is different than latest
    if (Mnet::Stanza::diff($acl_old, $acl_new)) {
        print "no ip access-list SECURE\n" if $acl_old;
        print "$acl_new\n";
    }

    # print config applying acl to shutdown interfaces, if needed
    my @ints = Mnet::Stanza::parse($sh_run, /^interface/);
    foreach my $int (@ints) {
        next if $int !~ /^\s*shutdown/m;
        next if $int =~ /^\s*ip access-group SECURE in/m;
        die "error, $int" if $int !~ /^interface (\S+)/;
        print "interface $1\n";
        print " ip access-group SECURE in\n";
    }

DESCRIPTION

Mnet::Stanza can be used on text arranged in stanzas of indented lines or text in outline format, such as the following:

    line
    stanza 1
     indented line
    stanza 2
     sub-stanza 1
      indented 1
      indented 2
      sub-sub-stanza 1
       indented 1
       indented 2
    end

In the above example the following would be true:

    stanza 1 contains a single indented line
    stanza 2 contains sub-stanza 1 and everything under sub-stanza 1
    sub-stanza 1 contains two indented lines and a sub-sub-stanza 1
    sub-sub-stanza 1 contains two indented lines

This can be used to parse cisco ios configs, amongst other things.

FUNCTIONS

Mnet::Stanza implements the functions listed below.

trim

    $output = Mnet::Stanza::trim($input)

The trim function can be used to normalize stanza spacing and may be useful before calling the diff function or outputting a stanza to the user.

This function does the following:

    - replaces multiple spaces inside text with single spaces
    - removes spaces at the end of any line of input
    - removes blank lines and any linefeeds at end of input
    - removes extra leading spaces while preserving indentation

A null value will be output if the input is undefined.

Note that in some cases extra spaces in the input may be significant and it may not be appropriate to use this trim function. This must be determined by the developer. Also note that this function does not touch tabs.

parse

    @output = Mnet::Stanza::parse($input, /$match_re/)
    $output = Mnet::Stanza::parse($input, /$match_re/)

The parse function can be used to output one or more matching stanza sections from the input text, either as a list of matching stanzas or a single string.

Here's some sample input text:

    hostname test
    interface Ethernet1
     no ip address
     shutdown
    interface Ethernet2
     ip address 1.2.3.4 255.255.255.0

Using an input match_re of qr/^interface/ the following two stanzas are output:

    interface Ethernet1
     no ip address
     shutdown
    interface Ethernet2
     ip address 1.2.3.4 255.255.255.0

Refer also to the trim function in this module.

diff

    $diff = Mnet::Stanza::diff($old, $new)

The diff function checks to see if the input old and new stanza strings are the same.

The returned diff value will be set as follows:

    <null>      indicates old and new inputs match
    <undef>     indicates both inputs are undefined
    undef       indicates either new or old is undefined
    line        indicates mismatch line number and line text
    other       indicates mismatch such as extra eol chars at end

Note that blank lines and all other spaces are significant. The trim function in this module can be used to remove extra spaces before calling this function.

SEE ALSO

Mnet

Mnet::Log