--- /dev/null
+#!/usr/local/bin/perl
+
+# Author: Cecilie Fritzvold <cecilihf@linpro.no>
+
+package Varnish::CLI;
+
+use IO::Socket;
+
+# Send a command to varnish over telnet.
+# This function takes a hash as parameter.
+# Valid keys for the hash are:
+# * address : Address of varnish
+# * port: port where varnish listens for telnet connections
+# * command : the command to send
+# * params : parameters to the command as a string. (optional)
+# The function returns a tuple with the return code and the result.
+# If missing or invalid parameters, 0 is returned.
+sub send_command {
+ my ($args) = shift;
+ my $sock;
+ my $line;
+ my $status, $size, $read;
+ my $response = "";
+
+ if (!$args->{'address'} || !$args->{'port'} || !$args->{'command'}) {
+ return 0;
+ }
+
+ $sock = IO::Socket::INET->new(
+ Proto => "tcp",
+ PeerAddr => $args->{'address'},
+ PeerPort => $args->{'port'},
+ ) or return 0;
+
+ if ($args->{'params'}) {
+ $args->{'command'} .= " $args->{'params'}";
+ }
+ print $sock "$args->{'command'}\r\n";
+
+ if (!($line = <$sock>)) {
+ return 0;
+ }
+ $line =~ /^(\d+) (\d+)/;
+ $status = $1;
+ $size = $2;
+
+ while ($line = <$sock>) {
+ $response .= $line;
+ $read += length($line);
+ if ($read >= $size) {
+ last;
+ }
+ }
+
+ close $sock;
+
+ return ($status, $response);
+}
+
+return 1;
\ No newline at end of file
--- /dev/null
+address=Address to varnish,3,localhost
+port=Port number varnish listens for telnet connections on,3,23
--- /dev/null
+#!/usr/local/bin/perl
+
+# Author: Cecilie Fritzvold <cecilihf@linpro.no>
+
+require './varnishadm-lib.pl';
+
+&ui_print_header(undef, $module_info{'name'}, "", undef, 1, 1);
+
+@olinks = ("varnish_vcl.cgi", "varnish_params.cgi", "varnish_status.cgi", "varnish_purge.cgi");
+@otitles = ("VCL", "Params", "Start/Stop", "Purge");
+@oicons = ("images/vcl_icon.gif", "images/params_icon.gif", "images/status_icon.gif", "images/purge_icon.gif");
+
+&icons_table(\@olinks, \@otitles, \@oicons);
--- /dev/null
+name=Varnish Admin
+desc=Varnish Admin
+
--- /dev/null
+#!/usr/local/bin/perl
+
+# Author: Cecilie Fritzvold <cecilihf@linpro.no>
+
+require './varnishadm-lib.pl';
+use Varnish::CLI;
+
+&ui_print_header(undef, "Params", "", undef, 1, 1);
+&ReadParse();
+&error_setup("Failed");
+
+my %attrs = ('address' => $config{'address'}, 'port' => $config{'port'},
+ 'command' => 'param.show');
+my ($status, $res) = Varnish::CLI::send_command(\%attrs);
+
+if (!($status eq '200')) {
+ &error("$status - $res");
+}
+
+my @params = ();
+foreach my $line (split(/\n/, $res)) {
+ if ($line =~ /(\w+)\s+([a-zA-z0-9.:]+)(\s+(\[|\()(\w+|%)(\]|\)))?/) {
+ push @params, {'name' => $1, 'value' => $2, 'unit' => $5};
+ }
+}
+if ($in{'save'}) {
+ foreach $param (@params) {
+ if ($in{$param->{'name'}} && !($in{$param->{'name'}} eq $param->{'value'})) {
+ $attrs{'command'} = 'param.set';
+ $attrs{'params'} = "$param->{'name'} $in{$param->{'name'}}";
+ $status, $res = Varnish::CLI::send_command(\%attrs);
+ if (!($status eq '200')) {
+ &error("$status - $res");
+ }
+ $param->{'value'} = $in{$param->{'name'}};
+ }
+ }
+}
+
+my $cmd_num = 0;
+print "<form action=varnish_params.cgi>";
+print "<table border width=100%>\n";
+print "<tr $tb> <td><b>params</b></td> </tr>\n";
+print "<tr $cb> <td><table width=100%>\n";
+foreach $param (@params) {
+ if (($cmd_num % 2) == 0) {
+ print "<tr>\n";
+ }
+ print "<td>$param->{'name'}</td><td nowrap>";
+ if ($param->{'unit'} eq 'bool') {
+ print "<input type=radio name=$param->{'name'} value=on " .
+ (($param->{'value'} eq 'on') ? "checked" : "") . " /> On\n";
+ print "<input type=radio name=$param->{'name'} value=off " .
+ (($param->{'value'} eq 'off') ? "checked" : "") . " /> Off\n";
+
+ }
+ else {
+ print "<input name=$param->{'name'} value=$param->{'value'} size=25 /> $param->{'unit'}";
+ }
+ print "</td>\n";
+ if (($cmd_num % 2) != 0) {
+ print "</tr>\n";
+ }
+ $cmd_num++;
+}
+print "</tr></table>";
+print "</table>";
+print "<input type=submit name=save value=save />";
+print "</form>";
+
+&ui_print_footer("", 'module index');
--- /dev/null
+#!/usr/local/bin/perl
+
+# Author: Cecilie Fritzvold <cecilihf@linpro.no>
+
+require './varnishadm-lib.pl';
+use Varnish::CLI;
+
+&ui_print_header(undef, "Purge", "", undef, 1, 1);
+
+&ReadParse();
+&error_setup("Purge failed");
+
+my %attrs = ('address' => $config{'address'}, 'port' => $config{'port'},
+ 'command' => 'url.purge');
+if ($in{'regexp'}) {
+ $attrs{'params'} = $in{'regexp'};
+ my ($status, $res) = Varnish::CLI::send_command(\%attrs);
+
+ if ($status eq '200') {
+ print "Purging succesful<br />";
+ print "$res<br />";
+ print "<hr />";
+ }
+ else {
+ &error("$status - $res");
+ }
+}
+
+print "<form action=varnish_purge.cgi>\n";
+print "What to purge (regexp): <input name=regexp size=10 /><br />\n";
+print "<input type=submit value=Purge /><br />\n";
+print "</form>";
+
+&ui_print_footer("", 'module index');
--- /dev/null
+#!/usr/local/bin/perl
+
+# Author: Cecilie Fritzvold <cecilihf@linpro.no>
+
+require './varnishadm-lib.pl';
+use Varnish::CLI;
+
+&ReadParse();
+&error_setup("Start command failed: ");
+
+my %attrs = ('address' => $config{'address'}, 'port' => $config{'port'},
+ 'command' => 'start');
+my ($status, $res) = Varnish::CLI::send_command(\%attrs);
+if (!($status eq 200)) {
+ &error("$status - $res");
+}
+&webmin_log("start");
+&redirect("varnish_status.cgi");
+
--- /dev/null
+#!/usr/local/bin/perl
+
+# Author: Cecilie Fritzvold <cecilihf@linpro.no>
+
+require './varnishadm-lib.pl';
+use Varnish::CLI;
+
+&ui_print_header(undef, "Status", "", undef, 1, 1);
+&error_setup("Could not get status");
+
+my %attrs = ('address' => $config{'address'}, 'port' => $config{'port'},
+ 'command' => 'ping');
+my ($status, $res) = Varnish::CLI::send_command(\%attrs);
+if ($status eq '200') {
+ if ($res =~ /^PONG/) {
+ print "Varnish is up<br />";
+ }
+ else {
+ print "Varnish is down<br />";
+ }
+}
+else {
+ &error("$status - $res");
+}
+
+$attrs{'command'} = 'status';
+$status, $res = Varnish::CLI::send_command(\%attrs);
+if ($status eq '200') {
+ print "$res<br />";
+}
+else {
+ &error("$status - $res");
+}
+
+print "<hr>\n";
+print &ui_buttons_start();
+
+print &ui_buttons_row("varnish_stop.cgi","Stop varnish child");
+print &ui_buttons_row("varnish_start.cgi", "Start varnish child");
+
+print &ui_buttons_end();
+
+&ui_print_footer("", 'module index');
--- /dev/null
+#!/usr/local/bin/perl
+
+# Author: Cecilie Fritzvold <cecilihf@linpro.no>
+
+require './varnishadm-lib.pl';
+use Varnish::CLI;
+
+&ReadParse();
+&error_setup("Stop command failed: ");
+
+my %attrs = ('address' => $config{'address'}, 'port' => $config{'port'},
+ 'command' => 'stop');
+my ($status, $res) = Varnish::CLI::send_command(\%attrs);
+if (!($status eq 200)) {
+ &error("$status - $res");
+}
+&webmin_log("stop");
+&redirect("varnish_status.cgi");
+
--- /dev/null
+#!/usr/local/bin/perl
+
+# Author: Cecilie Fritzvold <cecilihf@linpro.no>
+
+require './varnishadm-lib.pl';
+use Varnish::CLI;
+
+&ui_print_header(undef, "VCL Admin", "", undef, 1, 1);
+&error_setup("Failed");
+
+my %attrs = ('address' => $config{'address'}, 'port' => $config{'port'},
+ 'command' => 'vcl.list');
+my ($status, $res) = Varnish::CLI::send_command(\%attrs);
+
+if (!($status eq '200')) {
+ &error("$status - $res");
+}
+
+print "<table border width=100%>";
+print "<tr $tb> <td><b>Available vcl files</b></td> </tr>\n";
+print "<tr $cb><td>";
+print "<form action=varnish_vcl_use.cgi method=post>";
+my $confname = "";
+my $set = 0;
+foreach my $line (split(/\n/, $res)) {
+ if ($line =~ /\*?\s+\d\s+(\w+)/) {
+ $confname = $1;
+ if ($line =~ /^\*/) {
+ $set = 1;
+ }
+ }
+ print "<input type=radio name=vcl_name value=$confname" .
+ ($set ? " checked" : "") . " />\n";
+ print "<a href=varnish_vcl_view.cgi?vcl_file=$confname>$confname</a>";
+ print "<br />\n";
+ $set = 0;
+}
+
+print "<input type=submit name=use value='Save change in active vcl file' />\n";
+print "</form>";
+
+print "</td></tr>";
+print "<tr $tb> <td><b>Upload new vcl file</b></td> </tr>\n";
+print "<tr $cb><td><table width=100%>";
+print "<form action=varnish_vcl_upload.cgi enctype=multipart/form-data method=post>";
+print "<tr><td>";
+print "Config name: <input name=vcl_name size=25 /> ";
+print "</td></tr><tr><td>";
+print "VCL file: ";
+print &ui_upload("vcl_file", 25);
+print "</td></tr><tr><td>";
+print "<input type=submit name=upload value='Upload file'>\n";
+print "</td></tr>";
+print "</table>";
+print "</form>";
+
+print "</td></tr>";
+print "</table>";
+
+&ui_print_footer("", 'module index');
--- /dev/null
+#!/usr/local/bin/perl
+
+# Author: Cecilie Fritzvold <cecilihf@linpro.no>
+
+require './varnishadm-lib.pl';
+use Varnish::CLI;
+use File::Temp qw (mkstemp);
+use Fcntl qw (F_SETFD F_GETFD :mode);
+
+&ReadParseMime();
+&error_setup("Failed");
+
+my %attrs = ('address' => $config{'address'}, 'port' => $config{'port'},
+ 'command' => 'vcl.load');
+
+my ($fh, $file) = mkstemp("/tmp/tmp.vcl.XXXXXXX");
+print $fh $in{'vcl_file'};
+close($fh);
+
+chmod S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, $file;
+
+$attrs{'params'} = "$in{'vcl_name'} $file";
+
+my ($status, $res) = Varnish::CLI::send_command(\%attrs);
+
+if (!($status eq '200')) {
+ &error("$status - $res");
+}
+
+&redirect("varnish_vcl.cgi");
--- /dev/null
+#!/usr/local/bin/perl
+
+# Author: Cecilie Fritzvold <cecilihf@linpro.no>
+
+require './varnishadm-lib.pl';
+use Varnish::CLI;
+
+&ReadParse();
+&error_setup("Failed");
+
+my %attrs = ('address' => $config{'address'}, 'port' => $config{'port'},
+ 'command' => 'vcl.use');
+
+$attrs{'params'} = "$in{'vcl_name'}";
+
+my ($status, $res) = Varnish::CLI::send_command(\%attrs);
+
+if (!($status eq '200')) {
+ &error("$status - $res");
+}
+
+&redirect("varnish_vcl.cgi");
\ No newline at end of file
--- /dev/null
+#!/usr/local/bin/perl
+
+# Author: Cecilie Fritzvold <cecilihf@linpro.no>
+
+require './varnishadm-lib.pl';
+use Varnish::CLI;
+
+&ReadParse();
+&error_setup("Failed");
+
+&ui_print_header(undef, "vcl file: $in{'vcl_file'}", "", undef, 1, 1);
+
+my %attrs = ('address' => $config{'address'}, 'port' => $config{'port'},
+ 'command' => 'vcl.show');
+
+$attrs{'params'} = "$in{'vcl_file'}";
+
+my ($status, $res) = Varnish::CLI::send_command(\%attrs);
+
+if (!($status eq '200')) {
+ &error("$status - $res");
+}
+
+$res =~ s/ / /g;
+$res =~ s/\n/<br \/>/g;
+
+print $res;
+
+&ui_print_footer("varnish_vcl.cgi", 'vcl index');
--- /dev/null
+#!/usr/local/bin/perl
+
+do '../web-lib.pl';
+&init_config();
+do '../ui-lib.pl';
+
+if (!$config{'address'}) {
+ $config{'address'} = 'localhost';
+}
+if (!$config{'port'}) {
+ $config{'port'} = 23;
+}
+
+return 1;