# # Module: walk_op_mode.pl # # **** License **** # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # This code was originally developed by Vyatta, Inc. # Portions created by Vyatta are Copyright (C) 2009-2010 Vyatta, Inc. # All Rights Reserved. # # Author: Stig Thormodsrud # Date: August 2010 # Description: Script to use rest api to walk op mode commands. # # **** End License **** # use strict; use warnings; use lib "/opt/vyatta/share/perl5/"; use POSIX; use JSON; use MIME::Base64; use Getopt::Long; use Data::Dumper; use LWP::UserAgent; use HTTP::Request; my $target = '127.0.0.1'; my $base_url = "https://$target/rest"; my $user = "vyatta"; my $passwd = "vyatta"; my $ua; my $op_cmds_run = 0; my $op_cmds_skipped = 0; my $op_cmds_stopped = 0; sub read_op_output { my ($location) = @_; my $url = "https://$target/$location"; my ($response, $output, $count); $count = 0; do { $response = $ua->get($url); if ($response->is_success) { $output = $response->content; $output =~ s/[\x00-\x08\x0B-\x1F\x7F-\xFF]//g; print $output; if ($output eq '') { if ($count++ > 10) { print "No new output - Stopping\n"; $op_cmds_stopped++; my $request = HTTP::Request->new(DELETE => $url); $response = $ua->request($request); return; } } } else { if ($response->code != 410) { print "Failed to GET [$url]: ", $response->status_line; return; } } } while ($response->code != 410); } sub run_op_cmd { my ($path) = @_; print "running [$path]\n"; my $url = "$base_url/op/$path"; my $response = $ua->post($url); if ($response->is_success) { my $location = $response->header('Location'); if (defined $location) { read_op_output($location); print "\n"; $op_cmds_run++; } else { print "No location found\n"; } } else { print "Failed to GET [$url]: ", $response->status_line; } } sub get_op_children { my ($path) = @_; my @empty = (); my $url = "$base_url/op/$path/"; my $response = $ua->get($url); if ($response->is_error) { return @empty if $response->code == 404; print "Failed to GET [$url]: ", $response->status_line; return @empty; } if ($response->header('content-type') eq 'application/json') { my $perl_scalar = decode_json($response->content); my $children = $perl_scalar->{children}; my $action = $perl_scalar->{action}; if (defined $action and $action eq "true") { if ($path =~ /\*/) { print "skipping [$path]\n\n"; $op_cmds_skipped++; } else { run_op_cmd($path); } } return @$children if defined $children; return @empty; } } sub get_op_cmds { my ($path) = @_; my @outs = get_op_children($path); foreach my $out (@outs) { get_op_cmds("$path/$out"); } } # main $target = $ARGV[0] if defined $ARGV[0]; $user = $ARGV[1] if defined $ARGV[1]; $passwd = $ARGV[2] if defined $ARGV[2]; $base_url = "https://$target/rest"; print "target [$target] [$user:$passwd]\n\n"; $ua = LWP::UserAgent->new; my $auth = encode_base64("$user:$passwd"); $ua->default_header('content-lenght' => 0); $ua->default_header("authorization" => "Basic $auth"); get_op_cmds('show'); # do the real work print "\nTotals:\n"; print "=======\n"; print "Ran : $op_cmds_run\n"; print "Skipped: $op_cmds_skipped\n"; print "Stopped: $op_cmds_stopped\n\n"; if ($op_cmds_run) { print "Check for left over processes\n"; my $url = "$base_url/op"; my $response = $ua->get($url); if ($response->is_success) { my $content = $response->content; if ($content ne '') { print $response->content; } else { print "No left over processes\n"; } } else { print "Failed to GET [$url]: ", $response->status_line; } } exit 0;