PAN Perl Package for configuration

Reply
Not applicable

PAN Perl Package for configuration

Does anyone know who is maintaining the PAN Perl package?  I've searched around and found a series of threads where people have been asking for configuration CLI integration within the PAN Perl Package, but didn't see anyone making a move to add the feature so I took a little time to dig through the module to add it in myself.  If someone else has already done this, and likely in a less crufty way than I, can you please point me in the direction of their code.  What I found with the current package is it has the ability to run operational commands (show, etc) as well as commits but it was lacking the ability to run commands in configure mode.  So I've created a patch to the CLI.pm that has worked well in my environment and would like to share with the community.  It is essentially a clone of the operational exec mode with the addition of the configure command being inserted in before the execution of a command.  It is called by:

my $cli = PAN::CLI->new(timeout => 20, debug => 0);

$cli->CLI_configuration_mode_exec(username => $PANUSER, password => $PANPASS, hostname => $PANHOST, cmd => $cmd)

Currently it only takes a single command, if I get the time in the coming weeks I plan on working to get it to take a series of commands.  Such as if you wanted to create a new rule and then place it somewhere in the rulebase.  Adding the patch is fairly simple, take the patch diff below and drop it into a file (CLI.patch for example) and then execute the patch command against it.  Remember you willl need to have the appropriate level of privs for this.

patch /usr/local/share/perl5/PAN/CLI.pm < CLI.patch

Assuming of course that you have your perl modules installed in /usr/local/share/perl5/PAN, if you aren't sure run "perldoc -l PAN::CLI" and it will tell you where your file is located. 

The here is the patch diff:

--- /home/tighe/CLI.pm 2014-11-20 08:33:36.734063956 -0700

+++ /usr/local/share/perl5/PAN/CLI.pm   2014-11-20 07:58:50.693908070 -0700

@@ -501,6 +501,104 @@

     $exp->hard_close;

}

+sub CLI_configuration_mode_exec {

+    my ($this, %argv) = @_;

+

+    $this->{error_detail} = '';

+    $this->{cmd_output} = undef;

+

+    my $argv = $this->_panrc(\%argv);

+    return 0 unless $argv;

+    $argv->{cmd} = $argv{cmd} if defined $argv{cmd};

+

+    my @required_args = ('username',

+                         'password',

+                         'hostname',

+                         'cmd',

+        );

+    for (@required_args) {

+        unless (defined $argv->{$_}) {

+            my $msg = "missing argument: $_";

+            $this->{error_detail} = $msg;

+            return 0;

+        }

+    }

+    print STDERR Dumper($argv),"\n" if $this->{debug};

+

+    my $exp = _CLI_login($this, $argv);

+    return 0 unless $exp;

+

+    my $exp_eof = 0;

+    my $exp_timeout = 0;

+    my @errors = (

+        [ eof => sub { $exp_eof = 1; } ],

+        [ timeout => sub { $exp_timeout = 1; } ],

+        );

+    my $prompt_re = "$argv->{username}\@$hostname_re";

+    my $operational_prompt_re = $prompt_re . $operational_end . '$';

+    my $configuration_prompt_re = $prompt_re . $configuration_end . '$';

+

+    $exp->expect($this->{timeout},

+                 @errors,

+                 [ qr/$operational_prompt_re/,

+                   sub { my $self = shift;

+                        $self->send("configure\n");

+                         $self->send("$argv->{cmd}\n");

+                   }

+                 ],

+        );

+    if ($exp_eof || $exp_timeout) {

+        _error_close($this, $exp);

+        return 0;

+    }

+

+    my $unknown_command = 0;

+    my $invalid_syntax = 0;

+    $exp->expect($this->{timeout},

+                 @errors,

+                 [ qr/\r\nUnknown command: .+\r\n/s,

+                   sub { my $self = shift;

+                         $self->send("exit\n");

+                         $unknown_command = 1;

+                         $this->{error_detail} =

+                             "Unknown command"; }

+                 ],

+                 [ qr/\r\nInvalid syntax\.\r\n/s,

+                   sub { my $self = shift;

+                         $self->send("exit\n");

+                         $invalid_syntax = 1;

+                         $this->{error_detail} =

+                             "Invalid syntax"; }

+                 ],

+                 #[ qr/$operational_prompt_re/,

+                 [ qr/$configuration_prompt_re/,

+                   sub { my $self = shift;

+                         $self->send("exit\n");

+                         my $s = $self->exp_before();

+                         # remove echoed command

+                         my $cmd = quotemeta($argv->{cmd});

+                         $s =~ s/^$cmd\r\n//;

+                         # canonize to '\n' only

+                         $s =~ s/\r//g;

+                         # remove first and last blank line in CLI output

+                         $s =~ s/^\n//g;

+                         $s =~ s/\n\n$/\n/g;

+                         $this->{cmd_output} = $s; }

+                 ],

+        );

+    if ($unknown_command || $invalid_syntax) {

+        $exp->soft_close;

+        return 0;

+    }

+    if ($exp_eof || $exp_timeout) {

+        _error_close($this, $exp);

+        return 0;

+    }

+

+    $exp->soft_close;

+    return 1;

+}

+

1;

__END__

Like what you see?

Show your appreciation!

Click Like if a post is helpful to you or if you just want to show your support.

Click Accept as Solution to acknowledge that the answer to your question has been provided.

The button appears next to the replies on topics you’ve started. The member who gave the solution and all future visitors to this topic will appreciate it!

These simple actions take just seconds of your time, but go a long way in showing appreciation for community members and the Live Community as a whole!

The Live Community thanks you for your participation!