diff options
author | Scott Ullrich <sullrich@pfsense.org> | 2009-10-13 21:36:49 -0400 |
---|---|---|
committer | Scott Ullrich <sullrich@pfsense.org> | 2009-10-13 21:36:49 -0400 |
commit | aba9cf49f326342965062f4c777d9a19bcf386bb (patch) | |
tree | 483ec7c973dfeaba7ae74094fbb3b6d1b69bb27d | |
parent | f95fb72a299cf416e01674db44557384499c8ea3 (diff) | |
download | pfsense-packages-aba9cf49f326342965062f4c777d9a19bcf386bb.tar.gz pfsense-packages-aba9cf49f326342965062f4c777d9a19bcf386bb.tar.bz2 pfsense-packages-aba9cf49f326342965062f4c777d9a19bcf386bb.zip |
Adding initial version of HAPRoxy package
-rwxr-xr-x | config/haproxy/binaries7/haproxy | bin | 0 -> 691728 bytes | |||
-rwxr-xr-x | config/haproxy/binaries8/haproxy | bin | 0 -> 735640 bytes | |||
-rw-r--r-- | config/haproxy/haproxy.inc | 198 | ||||
-rw-r--r-- | config/haproxy/haproxy.xml | 109 | ||||
-rwxr-xr-x | config/haproxy/haproxy_backends.php | 134 | ||||
-rwxr-xr-x | config/haproxy/haproxy_backends_edit.php | 610 | ||||
-rwxr-xr-x | config/haproxy/haproxy_global.php | 186 | ||||
-rwxr-xr-x | config/haproxy/haproxy_servers.php | 146 | ||||
-rwxr-xr-x | config/haproxy/haproxy_servers_edit.php | 244 |
9 files changed, 1627 insertions, 0 deletions
diff --git a/config/haproxy/binaries7/haproxy b/config/haproxy/binaries7/haproxy Binary files differnew file mode 100755 index 00000000..e0d869b7 --- /dev/null +++ b/config/haproxy/binaries7/haproxy diff --git a/config/haproxy/binaries8/haproxy b/config/haproxy/binaries8/haproxy Binary files differnew file mode 100755 index 00000000..290dd861 --- /dev/null +++ b/config/haproxy/binaries8/haproxy diff --git a/config/haproxy/haproxy.inc b/config/haproxy/haproxy.inc new file mode 100644 index 00000000..cb22d8c9 --- /dev/null +++ b/config/haproxy/haproxy.inc @@ -0,0 +1,198 @@ +<?php +/* + haproxy.inc + Copyright (C) 2008 Remco Hoef + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +/* include all configuration functions */ +require_once("functions.inc"); +require_once("pkg-utils.inc"); +require_once("notices.inc"); + +function haproxy_custom_php_install_command() { + global $g, $config; + conf_mount_rw(); + + $haproxy = <<<EOD +#!/bin/sh + +# PROVIDE: haproxy +# REQUIRE: LOGIN +# KEYWORD: FreeBSD + +. /etc/rc.subr + +name="haproxy" +rcvar=`set_rcvar` +command="/usr/local/bin/haproxy" +haproxy_enable=\${haproxy-"YES"} + +start_cmd="haproxy_start" +stop_postcmd="haproxy_stop_post" + +load_rc_config \$name + +haproxy_start () { + echo "Starting haproxy." + /usr/bin/env \ + PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ + /usr/local/bin/php -q -d auto_prepend_file=config.inc <<ENDOFF + <?php + require_once("globals.inc"); + require_once("functions.inc"); + require_once("haproxy.inc"); + function haproxy_configure(); + ?> +ENDOFF +} + +haproxy_stop_post () { + echo "Stopping haproxy." + killall haproxy +} + +run_rc_command "\$1" + +EOD; + + fwrite($fd, $haproxy); + fclose($fd); + conf_mount_ro(); + + exec("/usr/local/etc/rc.d/haproxy.sh start"); +} + +function haproxy_configure() { + global $config, $g; + + $a_global = &$config['installedpackages']['haproxy']; + $a_backends = &$config['installedpackages']['haproxy']['ha_backends']['item']; + $a_frontends = &$config['installedpackages']['haproxy']['ha_frontends']['item']; + $a_servers = &$config['installedpackages']['haproxy']['ha_servers']['item']; + + $fd = fopen("{$g['varetc_path']}/haproxy.cfg", "w"); + + if(is_array($a_global)) { + fwrite ($fd, "global\n"); + fwrite ($fd, "\tmaxconn\t\t\t".$a_global['maxconn']."\n"); + fwrite ($fd, "\tlog\t\t\t127.0.0.1 local0\n"); + fwrite ($fd, "\tuid\t\t\t200\n"); + fwrite ($fd, "\tgid\t\t\t200\n"); + $numprocs = trim(`/sbin/sysctl kern.smp.cpus | cut -d" " -f2`); + fwrite ($fd, "\tnbproc\t\t\t$numprocs\n"); + fwrite ($fd, "\tchroot\t\t\t/var/empty\n"); + fwrite ($fd, "\tdaemon\n"); + fwrite ($fd, "\n"); + } + + if(is_array($a_backends)) { + foreach ($a_backends as $backend) { + if($frontend['extaddr']=='any') + $listenip = "listen {$backend['name']}\t\t\t0.0.0.0:".$backend['port']."\n"; + else if($frontend['extaddr']=='') + $listenip = "listen {$backend['name']}\t\t\t" . get_current_wan_address('wan').":" . $backend['port']."\n"; + else + $listenip = "listen {$backend['name']}\t\t\t" . $backend['extaddr'] . ":" . $backend['port']."\n"; + + fwrite ($fd, "{$listenip}"); + fwrite ($fd, "\tmode\t\t\t".$backend['type'] . "\n"); + fwrite ($fd, "\tlog\t\t\tglobal\n"); + fwrite ($fd, "\toption\t\t\tdontlognull\n"); + fwrite ($fd, "\toption\t\t\thttpclose\n"); + fwrite ($fd, "\toption\t\t\tforwardfor\n"); + + if($backend['max_connections']) + fwrite ($fd, "\tmaxconn\t\t\t" . $backend['max_connections'] . "\n"); + + if($backend['client_timeout']) + fwrite ($fd, "\tclitimeout\t\t" . $backend['client_timeout'] . "\n"); + + if($backend['type']) + fwrite ($fd, "\tmode\t\t\t" . $backend['type'] . "\n"); + + if($backend['balance']) + fwrite ($fd, "\tbalance\t\t\t" . $backend['balance'] . "\n"); + + if($backend['connection_timeout']) + fwrite ($fd, "\tcontimeout\t\t" . $backend['connection_timeout'] . "\n"); + + if($backend['server_timeout']) + fwrite ($fd, "\tsrvtimeout\t\t" . $backend['server_timeout'] . "\n"); + + if($backend['retries']) + fwrite ($fd, "\tretries\t\t\t" . $backend['retries'] . "\n"); + + if($backend['cookie_name']) + fwrite ($fd, "\tcookie\t\t\t" . $backend['cookie_name'] . " insert indirect\n"); + + fwrite ($fd, "\toption\t\t\thttpchk HEAD " . $backend['monitor_uri'] . " HTTP/1.0\n"); + + if($backend['stats_enabled']=='yes') { + fwrite ($fd, "\tstats\t\t\tenable\n"); + if($backend['stats_uri']) + fwrite ($fd, "\tstats\t\t\turi ".$backend['stats_uri']."\n"); + if($backend['stats_realm']) + fwrite ($fd, "\tstats\t\t\trealm " . $backend['stats_realm'] . "\n"); + else + fwrite ($fd, "\tstats\t\t\trealm .\n"); + fwrite ($fd, "\tstats\t\t\tauth " . $backend['stats_username'].":". $backend['stats_password']."\n"); + } + + $a_acl=&$frontend['ha_acls']['item']; + if(!is_array($a_acl)) + $a_acl=array(); + + foreach ($a_acl as $acl) + fwrite ($fd, "\tacl\t\t\t".$acl['name']."\t\t".$acl['expression']."\n"); + + if(is_array($a_servers)) { + foreach ($a_servers as $server) { + if($server['backend']==$backend['name']) { + if($server['status']=='active') + fwrite ($fd, "\tserver\t\t\t".$server['name']." ".$server['address'].":".$server['port']." cookie ".$server['cookie']." check inter 1000 weight ".$server['weight']."\n"); + } + } + } + fwrite ($fd, "\n"); + } + } + + // create config file + fclose($fd); + + // reload haproxy + if(isset($a_global['enable'])) { + if(is_process_running('haproxy')) { + exec("/usr/local/sbin/haproxy -f /var/etc/haproxy.cfg -p /var/run/haproxy.pid -st `cat /var/run/haproxy.pid`"); + } else { + exec("/usr/local/sbin/haproxy -f /var/etc/haproxy.cfg -p /var/run/haproxy.pid -D"); + } + return (0); + } else { + return (1); + } +} + +?>
\ No newline at end of file diff --git a/config/haproxy/haproxy.xml b/config/haproxy/haproxy.xml new file mode 100644 index 00000000..db270467 --- /dev/null +++ b/config/haproxy/haproxy.xml @@ -0,0 +1,109 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "../schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="../xsl/package.xsl"?> +<packagegui> + <copyright> + <![CDATA[ +/* $Id$ */ +/* ========================================================================== */ +/* + haproxy.xml + part of pfSense (http://www.pfSense.com) + Copyright (C) 2009 Scott Ullrich + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + </copyright> + <description>Describe your package here</description> + <requirements>Describe your package requirements here</requirements> + <faq>Currently there are no FAQ items provided.</faq> + <name>haproxy</name> + <version>1.0</version> + <title>HAProxy</title> + <aftersaveredirect>/pkg_edit.php?xml=haproxy_servers.php</aftersaveredirect> + <include_file>/usr/local/pkg/haproxy.inc</include_file> + <menu> + <name>HAProxy</name> + <tooltiptext></tooltiptext> + <section>Services</section> + <url>/haproxy_backends.php</url> + </menu> + <service> + <name>HAProxy</name> + <rcfile>haproxy.sh</rcfile> + <executable>haproxy</executable> + <description>The Reliable, High Performance TCP/HTTP Load Balancer</description> + </service> + <configpath>installedpackages->haproxy->config</configpath> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>077</chmod> + <item>http://www.pfsense.com/packages/config/haproxy/haproxy.inc</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>077</chmod> + <item>http://www.pfsense.com/packages/config/haproxy/haproxy_backends.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>077</chmod> + <item>http://www.pfsense.com/packages/config/haproxy/haproxy_backends_edit.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>077</chmod> + <item>http://www.pfsense.com/packages/config/haproxy/haproxy_global.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>077</chmod> + <item>http://www.pfsense.com/packages/config/haproxy/haproxy_servers.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>077</chmod> + <item>http://www.pfsense.com/packages/config/haproxy/haproxy_servers_edit.php</item> + </additional_files_needed> + <custom_delete_php_command> + </custom_delete_php_command> + <custom_add_php_command> + </custom_add_php_command> + <custom_php_resync_config_command> + </custom_php_resync_config_command> + <custom_php_install_command> + if(!file_exists("/usr/local/bin/haproxy")) { + $freebsdv=`uname -r | cut -d'.' -f1`; + download_file_with_progress_bar("http://www.pfsense.org/packages/config/haproxy/binaries{$frebsdv}/haproxy", "/usr/local/bin/haproxy"); + exec("chmod a+rx /usr/local/bin/haproxy"); + } + </custom_php_install_command> + <custom_php_deinstall_command> + </custom_php_deinstall_command> + <custom_php_command_before_form> + </custom_php_command_before_form> +</packagegui>
\ No newline at end of file diff --git a/config/haproxy/haproxy_backends.php b/config/haproxy/haproxy_backends.php new file mode 100755 index 00000000..b1b3ce56 --- /dev/null +++ b/config/haproxy/haproxy_backends.php @@ -0,0 +1,134 @@ +<?php +/* $Id: load_balancer_virtual_server.php,v 1.6.2.1 2006/01/02 23:46:24 sullrich Exp $ */ +/* + haproxy_baclkends.php + part of pfSense (http://www.pfsense.com/) + Copyright (C) 2008 Remco Hoef <remcoverhoef@pfsense.com> + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +require_once("guiconfig.inc"); +require_once("haproxy.inc"); + +if (!is_array($config['installedpackages']['haproxy']['ha_backends']['item'])) { + $config['installedpackages']['haproxy']['ha_backends']['item'] = array(); +} +$a_backend = &$config['installedpackages']['haproxy']['ha_backends']['item']; + +if ($_POST) { + $pconfig = $_POST; + + if ($_POST['apply']) { + $retval = 0; + config_lock(); + $retval = haproxy_configure(); + config_unlock(); + $savemsg = get_std_save_message($retval); + unlink_if_exists($d_haproxyconfdirty_path); + } +} + +if ($_GET['act'] == "del") { + if ($a_backend[$_GET['id']]) { + if (!$input_errors) { + unset($a_backend[$_GET['id']]); + write_config(); + touch($d_haproxyconfdirty_path); + header("Location: haproxy_backends.php"); + exit; + } + } +} + +$pgtitle = "Services: HAProxy: Backends"; +include("head.inc"); + +?> +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<form action="haproxy_backends.php" method="post"> +<?php if ($input_errors) print_input_errors($input_errors); ?> +<?php if ($savemsg) print_info_box($savemsg); ?> +<?php if (file_exists($d_haproxyconfdirty_path)): ?><p> +<?php print_info_box_np("The virtual server configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br> +<?php endif; ?> +<table width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr><td class="tabnavtbl"> + <?php + /* active tabs */ + $tab_array = array(); + $tab_array[] = array("Settings", false, "haproxy_global.php"); + $tab_array[] = array("Backends", true, "haproxy_backends.php"); + $tab_array[] = array("Servers", false, "haproxy_servers.php"); + display_top_tabs($tab_array); + ?> + </td></tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td width="30%" class="listhdrr">Name</td> + <td width="50%" class="listhdrr">Description</td> + <td width="10%" class="listhdrr">Type</td> + <td width="10%" class="list"></td> + </tr> + <?php $i = 0; foreach ($a_backend as $backend): ?> + <tr> + <td class="listlr" ondblclick="document.location='haproxy_backends_edit.php?id=<?=$i;?>';"> + <?=$backend['name'];?> + </td> + <td class="listlr" ondblclick="document.location='haproxy_backends_edit.php?id=<?=$i;?>';"> + <?=$backend['desc'];?> + </td> + <td class="listlr" ondblclick="document.location='haproxy_backends_edit.php?id=<?=$i;?>';"> + <?=$backend['type'];?> + </td> + <td class="list" nowrap> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="haproxy_backends_edit.php?id=<?=$i;?>"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0"></a></td> + <td valign="middle"><a href="haproxy_backends.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this entry?')"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + <?php $i++; endforeach; ?> + <tr> + <td class="list" colspan="3"></td> + <td class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="haproxy_backends_edit.php"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + </table> + </div> + </table> + </form> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/haproxy/haproxy_backends_edit.php b/config/haproxy/haproxy_backends_edit.php new file mode 100755 index 00000000..06b9d974 --- /dev/null +++ b/config/haproxy/haproxy_backends_edit.php @@ -0,0 +1,610 @@ +<?php +/* $Id: load_balancer_pool_edit.php,v 1.24.2.23 2007/03/03 00:07:09 smos Exp $ */ +/* + haproxy_backends_edit.php + part of pfSense (http://www.pfsense.com/) + Copyright (C) 2008 Remco Hoef <remcoverhoef@pfsense.com> + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +require("guiconfig.inc"); + +if (!is_array($config['installedpackages']['haproxy']['ha_backends']['item'])) { + $config['installedpackages']['haproxy']['ha_backends']['item'] = array(); +} + +$a_backend = &$config['installedpackages']['haproxy']['ha_backends']['item']; + +if (isset($_POST['id'])) + $id = $_POST['id']; +else + $id = $_GET['id']; + +if (isset($id) && $a_backend[$id]) { + $pconfig['name'] = $a_backend[$id]['name']; + $pconfig['desc'] = $a_backend[$id]['desc']; + $pconfig['connection_timeout'] = $a_backend[$id]['connection_timeout']; + $pconfig['server_timeout'] = $a_backend[$id]['server_timeout']; + $pconfig['retries'] = $a_backend[$id]['retries']; + + $pconfig['type'] = $a_backend[$id]['type']; + $pconfig['balance'] = $a_backend[$id]['balance']; + $pconfig['monitor_uri'] = $a_backend[$id]['monitor_uri']; + + $pconfig['stats_enabled'] = $a_backend[$id]['stats_enabled']; + $pconfig['stats_username'] = $a_backend[$id]['stats_username']; + $pconfig['stats_password'] = $a_backend[$id]['stats_password']; + $pconfig['stats_uri'] = $a_backend[$id]['stats_uri']; + $pconfig['stats_realm'] = $a_backend[$id]['stats_realm']; + + $pconfig['type'] = $a_backend[$id]['type']; + $pconfig['extaddr'] = $a_backend[$id]['extaddr']; + $pconfig['max_connections'] = $a_backend[$id]['max_connections']; + $pconfig['client_timeout'] = $a_backend[$id]['client_timeout']; + $pconfig['stats_enabled'] = $a_backend[$id]['stats_enabled']; + $pconfig['stats_realm'] = $a_backend[$id]['stats_realm']; + $pconfig['stats_uri'] = $a_backend[$id]['stats_uri']; + $pconfig['stats_username'] = $a_backend[$id]['stats_username']; + $pconfig['stats_password'] = $a_backend[$id]['stats_password']; + $pconfig['port'] = $a_backend[$id]['port']; + $pconfig['a_acl']=&$a_backend[$id]['ha_acls']['item']; + +} + +$changedesc = "Services: HAProxy: Backends"; +$changecount = 0; + +if ($_POST) { + $changecount++; + + unset($input_errors); + $pconfig = $_POST; + + if ($_POST['stats_enabled']) { + $reqdfields = explode(" ", "name connection_timeout server_timeout retries stats_username stats_password stats_uri stats_realm"); + $reqdfieldsn = explode(",", "Name,Connection timeout,Server timeout,Retries,Stats Username,Stats Password,Stats Uri,Stats Realm"); + } else { + $reqdfields = explode(" ", "name connection_timeout server_timeout retries monitor_uri"); + $reqdfieldsn = explode(",", "Name,Connection timeout,Server timeout,Retries,Monitor Uri"); + } + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + $reqdfields = explode(" ", "name type port max_connections client_timeout"); + $reqdfieldsn = explode(",", "Name,Type,Port,Max connections,Client timeout"); + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['name'])) + $input_errors[] = "The field 'Name' contains invalid characters."; + + if (!is_numeric($_POST['connection_timeout'])) + $input_errors[] = "The field 'Connection timeout' value is not a number."; + + if (!is_numeric($_POST['server_timeout'])) + $input_errors[] = "The field 'Server timeout' value is not a number."; + + if (!is_numeric($_POST['retries'])) + $input_errors[] = "The field 'Retries' value is not a number."; + + if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['stats_username'])) + $input_errors[] = "The field 'Stats Username' contains invalid characters."; + + if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['stats_password'])) + $input_errors[] = "The field 'Stats Password' contains invalid characters."; + + if (!is_numeric($_POST['max_connections'])) + $input_errors[] = "The field 'Max connections' value is not a number."; + + if (!is_numeric($_POST['port'])) + $input_errors[] = "The field 'Port' value is not a number."; + + if (!is_numeric($_POST['client_timeout'])) + $input_errors[] = "The field 'Client timeout' value is not a number."; + + /* Ensure that our pool names are unique */ + for ($i=0; isset($config['installedpackages']['haproxy']['ha_backends']['item'][$i]); $i++) + if (($_POST['name'] == $config['installedpackages']['haproxy']['ha_backends']['item'][$i]['name']) && ($i != $id)) + $input_errors[] = "This backend name has already been used. Backend names must be unique."; + + $a_acl=array(); + $acl_names=array(); + for($x=0; $x<99; $x++) { + $acl_name=$_POST['acl_name'.$x]; + $acl_expression=$_POST['acl_expression'.$x]; + + if ($acl_name) { + // check for duplicates + if (in_array($acl_name, $acl_names)) { + $input_errors[] = "The name '$acl_name' is duplicate."; + } + + $acl_names[]=$acl_name; + + $acl=array(); + $acl['name']=$acl_name; + $acl['expression']=$acl_expression; + $a_acl[]=$acl; + + if (preg_match("/[^a-zA-Z0-9\.\-_]/", $acl_name)) + $input_errors[] = "The field 'Name' contains invalid characters."; + + if (!preg_match("/.{2,}/", $acl_expression)) + $input_errors[] = "The field 'Expression' is required."; + + if (!preg_match("/.{2,}/", $acl_name)) + $input_errors[] = "The field 'Name' is required."; + + } + } + + $pconfig['a_acl']=$a_acl; + + if (!$input_errors) { + $backend = array(); + if(isset($id) && $a_backend[$id]) + $backend = $a_backend[$id]; + + if($backend['name'] != "") + $changedesc .= " modified '{$backend['name']}' pool:"; + + if ($backend['name']!=$_POST['name']) { + // name changed: + // * update servers + // * update frontend (default backend and acl) + if (!is_array($config['installedpackages']['haproxy']['ha_servers']['item'])) { + $config['installedpackages']['haproxy']['ha_servers']['item'] = array(); + } + $a_server = &$config['installedpackages']['haproxy']['ha_servers']['item']; + + for ( $i = 0; $i < count($a_server); $i++) { + if ($a_server[$i]['backend']==$backend['name']) { + $a_server[$i]['backend']=$_POST['name']; + } + } + + if (!is_array($config['installedpackages']['haproxy']['ha_frontends']['item'])) { + $config['installedpackages']['haproxy']['ha_frontends']['item'] = array(); + } + $a_frontend = &$config['installedpackages']['haproxy']['ha_frontends']['item']; + + for ( $i = 0; $i < count($a_frontend); $i++) { + if ($a_frontend[$i]['backend']==$backend['name']) { + $a_frontend[$i]['backend']=$_POST['name']; + } + + if (!is_array($a_frontend[$i]['ha_acls']['item'])) { + $a_frontend[$i]['ha_acls']['item'] = array(); + } + + $a_acl = &$a_frontend[$i]['ha_acls']['item']; + for ( $j = 0; $j < count($a_acl); $j++) { + if ($a_acl[$j]['backend']==$backend['name']) { + $a_acl[$j]['backend']=$_POST['name']; + } + } + } + } + + update_if_changed("name", $backend['name'], $_POST['name']); + update_if_changed("description", $backend['desc'], $_POST['desc']); + update_if_changed("connection_timeout", $backend['connection_timeout'], $_POST['connection_timeout']); + update_if_changed("server_timeout", $backend['server_timeout'], $_POST['server_timeout']); + update_if_changed("retries", $backend['retries'], $_POST['retries']); + update_if_changed("type", $backend['type'], $_POST['type']); + update_if_changed("balance", $backend['balance'], $_POST['balance']); + update_if_changed("cookie_name", $backend['cookie_name'], $_POST['cookie_name']); + update_if_changed("monitor_uri", $backend['monitor_uri'], $_POST['monitor_uri']); + update_if_changed("stats_enabled", $backend['stats_enabled'], $_POST['stats_enabled']); + update_if_changed("stats_username", $backend['stats_username'], $_POST['stats_username']); + update_if_changed("stats_password", $backend['stats_password'], $_POST['stats_password']); + update_if_changed("stats_uri", $backend['stats_uri'], $_POST['stats_uri']); + update_if_changed("stats_realm", $backend['stats_realm'], $_POST['stats_realm']); + update_if_changed("type", $backend['type'], $_POST['type']); + update_if_changed("port", $backend['port'], $_POST['port']); + update_if_changed("extaddr", $backend['extaddr'], $_POST['extaddr']); + update_if_changed("max_connections", $backend['max_connections'], $_POST['max_connections']); + update_if_changed("client_timeout", $backend['client_timeout'], $_POST['client_timeout']); + + $backend['ha_acls']['item']=$a_acl; + + if (isset($id) && $a_backend[$id]) { + $a_backend[$id] = $backend; + } else { + $a_backend[] = $backend; + } + + if ($changecount > 0) { + touch($d_haproxyconfdirty_path); + write_config($changedesc); + } + + header("Location: haproxy_backends.php"); + exit; + } +} + +$pgtitle = "HAProxy: Backend: Edit"; +include("head.inc"); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<script type="text/javascript"> + // Global Variables + var rowname = new Array(99); + var rowtype = new Array(99); + var newrow = new Array(99); + var rowsize = new Array(99); + + for (i = 0; i < 99; i++) { + rowname[i] = ''; + rowtype[i] = ''; + newrow[i] = ''; + rowsize[i] = '25'; + } + + var field_counter_js = 0; + var loaded = 0; + var is_streaming_progress_bar = 0; + var temp_streaming_text = ""; + + var addRowTo = (function() { + return (function (tableId) { + var d, tbody, tr, td, bgc, i, ii, j; + d = document; + tbody = d.getElementById(tableId).getElementsByTagName("tbody").item(0); + tr = d.createElement("tr"); + totalrows++; + for (i = 0; i < field_counter_js; i++) { + td = d.createElement("td"); + if(rowtype[i] == 'textbox') { + td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + "'></input><input size='" + rowsize[i] + "' name='" + rowname[i] + totalrows + "'></input> "; + } else if(rowtype[i] == 'select') { + td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + "'></input><select name='" + rowname[i] + totalrows + "'><?php foreach ($a_backend as $backend) {?><option value=\"<?=$backend['name']?>\"><?=$backend['name']?></option><?php }?></select> "; + } else { + td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + "'></input><input type='checkbox' name='" + rowname[i] + totalrows + "'></input> "; + } + tr.appendChild(td); + } + td = d.createElement("td"); + td.rowSpan = "1"; + td.className = "list"; + td.innerHTML = '<img src="/themes/' + theme + '/images/icons/icon_x.gif" width="17" height="17" border="0" onclick="removeRow(this); return false;">'; + tr.appendChild(td); + tbody.appendChild(tr); + }); + })(); + + function removeRow(el) { + var cel; + while (el && el.nodeName.toLowerCase() != "tr") + el = el.parentNode; + + if (el && el.parentNode) { + cel = el.getElementsByTagName("td").item(0); + el.parentNode.removeChild(el); + } + } + + function find_unique_field_name(field_name) { + // loop through field_name and strip off -NUMBER + var last_found_dash = 0; + for (var i = 0; i < field_name.length; i++) { + // is this a dash, if so, update + // last_found_dash + if (field_name.substr(i,1) == "-" ) + last_found_dash = i; + } + if (last_found_dash < 1) + return field_name; + return(field_name.substr(0,last_found_dash)); + } + + rowname[0] = "acl_name"; + rowtype[0] = "textbox"; + rowsize[0] = "30"; + + rowname[1] = "acl_expression"; + rowtype[1] = "textbox"; + rowsize[1] = "35"; + + rowname[2] = "acl_backend"; + rowtype[2] = "select"; + rowsize[2] = "10"; + + function toggle_stats() { + var stats_enabled=document.getElementById('stats_enabled'); + var stats_realm_row=document.getElementById('stats_realm_row'); + var stats_username_row=document.getElementById('stats_username_row'); + var stats_password_row=document.getElementById('stats_password_row'); + var stats_uri_row=document.getElementById('stats_uri_row'); + + if (stats_enabled.checked) { + stats_realm_row.style.display=''; + stats_username_row.style.display=''; + stats_password_row.style.display=''; + stats_uri_row.style.display=''; + } else { + stats_realm_row.style.display='none'; + stats_username_row.style.display='none'; + stats_password_row.style.display='none'; + stats_uri_row.style.display='none'; + } + } +</script> +<?php include("fbegin.inc"); ?> +<?php if ($input_errors) print_input_errors($input_errors); ?> + <form action="haproxy_backends_edit.php" method="post" name="iform" id="iform"> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td colspan="2" valign="top" class="listtopic">Edit haproxy backend</td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncellreq">Name</td> + <td width="78%" class="vtable" colspan="2"> + <input name="name" type="text" <?if(isset($pconfig['name'])) echo "value=\"{$pconfig['name']}\"";?> size="25" maxlength="25"> + </td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncellreq">Description</td> + <td width="78%" class="vtable" colspan="2"> + <input name="desc" type="text" <?if(isset($pconfig['desc'])) echo "value=\"{$pconfig['desc']}\"";?> size="64"> + </td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncellreq">Connection timeout</td> + <td width="78%" class="vtable" colspan="2"> + <input name="connection_timeout" type="text" <?if(isset($pconfig['connection_timeout'])) echo "value=\"{$pconfig['connection_timeout']}\"";?> size="64"> + <div>the time (in milliseconds) we give up if the connection does not complete within (30000).</div> + </td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncellreq">Server timeout</td> + <td width="78%" class="vtable" colspan="2"> + <input name="server_timeout" type="text" <?if(isset($pconfig['server_timeout'])) echo "value=\"{$pconfig['server_timeout']}\"";?> size="64"> + <div>the time (in milliseconds) we accept to wait for data from the server, or for the server to accept data (30000).</div> + </td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncellreq">Retries</td> + <td width="78%" class="vtable" colspan="2"> + <input name="retries" type="text" <?if(isset($pconfig['retries'])) echo "value=\"{$pconfig['retries']}\"";?> size="64"> + <div>After a connection failure to a server, it is possible to retry, potentially +on another server. This is useful if health-checks are too rare and you don't +want the clients to see the failures. The number of attempts to reconnect is +set by the 'retries' parameter (2).</div> + </td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncellreq">Type</td> + <td width="78%" class="vtable" colspan="2"> + <select name="type" id="type" onchange="type_change();"> + <option value="http"<?php if($pconfig['type'] == "http") echo " SELECTED"; ?>>HTTP</option> + <option value="tcp"<?php if($pconfig['type'] == "tcp") echo " SELECTED"; ?>>TCP</option> + <option value="health"<?php if($pconfig['type'] == "health") echo " SELECTED"; ?>>Health</option> + </select> + </td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncellreq">Balance</td> + <td width="78%" class="vtable" colspan="2"> + <table width="100%"> + <tr> + <td width="20%" valign="top"><input type="radio" name="balance" id="balance" value="roundrobin"<?php if($pconfig['balance'] == +"roundrobin") echo " CHECKED"; ?>>Round robin</td><td>Each server is used in turns, according to their weights. + This is the smoothest and fairest algorithm when the server's + processing time remains equally distributed. This algorithm + is dynamic, which means that server weights may be adjusted + on the fly for slow starts for instance.</td></tr> + <tr><td valign="top"><input type="radio" name="balance" id="balance" value="source"<?php if($pconfig['balance'] == +"source") echo " CHECKED"; ?>>Source</td><td> + The source IP address is hashed and divided by the total + weight of the running servers to designate which server will + receive the request. This ensures that the same client IP + address will always reach the same server as long as no + server goes down or up. If the hash result changes due to the + number of running servers changing, many clients will be + directed to a different server. This algorithm is generally + used in TCP mode where no cookie may be inserted. It may also + be used on the Internet to provide a best-effort stickyness + to clients which refuse session cookies. This algorithm is + static, which means that changing a server's weight on the + fly will have no effect.</td></tr> + <tr><td valign="top"> + <input type="radio" name="balance" id="balance" value="uri"<?php if($pconfig['balance'] == +"uri") echo " CHECKED"; ?>>URI</td><td> +The left part of the URI (before the question mark) is hashed + and divided by the total weight of the running servers. The + result designates which server will receive the request. This + ensures that a same URI will always be directed to the same + server as long as no server goes up or down. This is used + with proxy caches and anti-virus proxies in order to maximize + the cache hit rate. Note that this algorithm may only be used + in an HTTP backend. This algorithm is static, which means + that changing a server's weight on the fly will have no + effect.</td> + </tr> + </table> + </td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncell">Stats Enabled</td> + <td width="78%" class="vtable" colspan="2"> + <input id="stats_enabled" name="stats_enabled" type="checkbox" value="yes" <?php if ($pconfig['stats_enabled']=='yes') echo "checked"; ?> onclick='toggle_stats();'><br/> + EXAMPLE: haproxystats + + </td> + </tr> + <tr align="left" id='stats_realm_row' name='stats_realm_row' <?if ($pconfig['stats_enabled']!='yes') echo "style=\"display: none;\"";?>> + <td width="22%" valign="top" class="vncellreq">Stats Realm</td> + <td width="78%" class="vtable" colspan="2"> + <input id="stats_realm" name="stats_realm" type="text" <?if(isset($pconfig['stats_realm'])) echo "value=\"{$pconfig['stats_realm']}\"";?> size="64"> + </td> + </tr> + <tr align="left" id='stats_uri_row' name='stats_uri_row' <?if ($pconfig['stats_enabled']!='yes') echo "style=\"display: none;\"";?>> + <td width="22%" valign="top" class="vncellreq">Stats Uri</td> + <td width="78%" class="vtable" colspan="2"> + <input id="stats_uri" name="stats_uri" type="text" <?if(isset($pconfig['stats_uri'])) echo "value=\"{$pconfig['stats_uri']}\"";?> size="64"><br/> + EXAMPLE: /haproxy?stats + </td> + </tr> + <tr align="left" id='stats_username_row' name='stats_username_row' <?if ($pconfig['stats_enabled']!='yes') echo "style=\"display: none;\"";?>> + <td width="22%" valign="top" class="vncellreq">Stats Username</td> + <td width="78%" class="vtable" colspan="2"> + <input id="stats_username" name="stats_username" type="text" <?if(isset($pconfig['stats_username'])) echo "value=\"{$pconfig['stats_username']}\"";?> size="64"> + </td> + </tr> + + <tr align="left" id='stats_password_row' name='stats_password_row' <?if ($pconfig['stats_enabled']!='yes') echo "style=\"display: none;\"";?>> + <td width="22%" valign="top" class="vncellreq">Stats Password</td> + <td width="78%" class="vtable" colspan="2"> + <input id="stats_password" name="stats_password" type="text" <?if(isset($pconfig['stats_password'])) echo "value=\"{$pconfig['stats_password']}\"";?> size="64"> + </td> + </tr> + <tr align="left"> + <td width="22%" valign="top" id="monitorport_text" class="vncell">Monitor Uri</td> + <td width="78%" class="vtable" colspan="2"> + <input name="monitor_uri" type="text" <?if(isset($pconfig['monitor_uri'])) echo "value=\"{$pconfig['monitor_uri']}\"";?> size="50" maxlength="50"><br> + </td> + </tr> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncellreq">Port</td> + <td width="78%" class="vtable" colspan="2"> + <input name="port" type="text" <?if(isset($pconfig['port'])) echo "value=\"{$pconfig['port']}\"";?> size="10" maxlength="10"> + <div>the port to listen to</div> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">External address</td> + <td width="78%" class="vtable"> + <select name="extaddr" class="formfld"> + <option value="" <?php if (!$pconfig['extaddr']) echo "selected"; ?>>Interface address</option> + <?php if (is_array($config['virtualip']['vip'])): + foreach ($config['virtualip']['vip'] as $sn): ?> + <option value="<?=$sn['subnet'];?>" <?php if ($sn['subnet'] == $pconfig['extaddr']) echo "selected"; ?>><?=htmlspecialchars("{$sn['subnet']} ({$sn['descr']})");?></option> + <?php endforeach; + endif; ?> + <option value="any" <?php if($pconfig['extaddr'] == "any") echo "selected"; ?>>any</option> + </select> + <br /> + <span class="vexpl"> + If you want this rule to apply to another IP address than the IP address of the interface chosen above, + select it here (you need to define <a href="firewall_virtual_ip.php">Virtual IP</a> addresses on the first). Also note that if you are trying to redirect connections on the LAN select the "any" option.</span></td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncellreq">Type</td> + <td width="78%" class="vtable" colspan="2"> + <select name="type" id="type"> + <option value="http"<?php if($pconfig['type'] == "http") echo " SELECTED"; ?>>HTTP</option> + <option value="tcp"<?php if($pconfig['type'] == "tcp") echo " SELECTED"; ?>>TCP</option> + <option value="health"<?php if($pconfig['type'] == "health") echo " SELECTED"; ?>>Health</option> + </select> + </td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncell">Max connections</td> + <td width="78%" class="vtable" colspan="2"> + <input name="max_connections" type="text" <?if(isset($pconfig['max_connections'])) echo "value=\"{$pconfig['max_connections']}\"";?> size="10" maxlength="10"> + <div>the time (in milliseconds) we give up if the connection does not complete within (8000).</div> + </td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncell">Client timeout</td> + <td width="78%" class="vtable" colspan="2"> + <input name="client_timeout" type="text" <?if(isset($pconfig['client_timeout'])) echo "value=\"{$pconfig['client_timeout']}\"";?> size="10" maxlength="10"> + <div>the time (in milliseconds) we accept to wait for data from the client, or for the client to accept data (30000).</div> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Access Control lists</td> + <td width="78%" class="vtable" colspan="2" valign="top"> + <table class="" width="100%" cellpadding="0" cellspacing="0" id='acltable'> + <tr> + <td width="35%" class="">Name</td> + <td width="40%" class="">Expression</td> + <td width="20%" class="">Backend</td> + <td width="5%" class=""></td> + </tr> + <?php + $a_acl=$pconfig['a_acl']; + + if (!is_array($a_acl)) { + $a_acl=array(); + } + + $i=0; + foreach ($a_acl as $acl) { + ?> + <tr> + <td><input name="acl_name<?=$i;?>" type="text" value="<?=$acl['name']; ?>" size="30"/></td> + <td><input name="acl_expression<?=$i;?>" type="text" value="<?=$acl['expression']; ?>" size="35"/></td> + <td> + <select name="acl_backend<?=$i;?>" id="acl_backend<?=$i;?>"> + <?php + if (!is_array($config['installedpackages']['haproxy']['ha_backends']['item'])) { + $config['installedpackages']['haproxy']['ha_backends']['item'] = array(); + } + $a_backend = &$config['installedpackages']['haproxy']['ha_backends']['item']; + foreach ($a_backend as $backend) { ?> + <option value="<?=$backend['name'];?>"<?php if($acl['backend'] == $backend['name']) echo " SELECTED"; ?>><?=$backend['name'];?></option> + <?php $i++; } ?> + </select> + </td> + <td class="list"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0" onclick="removeRow(this); return false;"></td> + </tr> + <?php + $i++; + } + ?> + </table> + <a onclick="javascript:addRowTo('acltable'); return false;" href="#"> + <img border="0" src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" alt="" title="add another entry" /> + </a><br/> + Fore more information about ACL's please see <a href='http://haproxy.1wt.eu/download/1.3/doc/configuration.txt' target='_new'>HAProxy Documentation</a> Section 7 - Using ACL's + </td> + </tr> + <tr align="left"> + <td width="22%" valign="top"> </td> + <td width="78%"> + <input name="Submit" type="submit" class="formbtn" value="Save"> + <?php if (isset($id) && $a_backend[$id]): ?> + <input name="id" type="hidden" value="<?=$id;?>"> + <?php endif; ?> + </td> + </tr> + </table> + </form> +<br> +<script type="text/javascript"> + field_counter_js = 3; + rows = 1; + <?php $counter=0; ?> + totalrows = <?php echo $counter; ?>;; + loaded = <?php echo $counter; ?>;; +</script> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/haproxy/haproxy_global.php b/config/haproxy/haproxy_global.php new file mode 100755 index 00000000..53784027 --- /dev/null +++ b/config/haproxy/haproxy_global.php @@ -0,0 +1,186 @@ +<?php +/* $Id: load_balancer_pool.php,v 1.5.2.6 2007/03/02 23:48:32 smos Exp $ */ +/* + haproxy_global.php + part of pfSense (http://www.pfsense.com/) + Copyright (C) 2008 Remco Hoef <remcoverhoef@pfsense.com> + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +require("globals.inc"); +require("guiconfig.inc"); +require_once("haproxy.inc"); + +if (!is_array($config['installedpackages']['haproxy'])) { + $config['installedpackages']['haproxy'] = array(); +} + +$pconfig['enable'] = isset($config['installedpackages']['haproxy']['enable']); +$pconfig['maxconn'] = $config['installedpackages']['haproxy']['maxconn']; + +if ($_POST) { + unset($input_errors); + $pconfig = $_POST; + + + if ($_POST['apply']) { + $retval = 0; + config_lock(); + $retval = haproxy_configure(); + config_unlock(); + $savemsg = get_std_save_message($retval); + unlink_if_exists($d_haproxyconfdirty_path); + } else { + if ($_POST['enable']) { + $reqdfields = explode(" ", "maxconn"); + $reqdfieldsn = explode(",", "Maximum connections"); + } else { + } + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + if ($_POST['maxconn'] && (!is_numeric($_POST['maxconn']))) { + $input_errors[] = "The maximum number of connections should be numeric."; + } + + if (!$input_errors) { + $config['installedpackages']['haproxy']['enable'] = $_POST['enable'] ? true : false; + $config['installedpackages']['haproxy']['maxconn'] = $_POST['maxconn'] ? $_POST['maxconn'] : false; + + touch($d_haproxyconfdirty_path); + write_config(); + } + } + +} + +$pgtitle = "Services: HAProxy: Settings"; +include("head.inc"); + +?> +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<script language="JavaScript"> +<!-- +function enable_change(enable_change) { + var endis; + endis = !(document.iform.enable.checked || enable_change); + document.iform.maxconn.disabled = endis; +} +//--> +</script> +<form action="haproxy_global.php" method="post" name="iform"> +<?php if ($input_errors) print_input_errors($input_errors); ?> +<?php if ($savemsg) print_info_box($savemsg); ?> +<?php if (file_exists($d_haproxyconfdirty_path)): ?><p> +<?php print_info_box_np("The load balancer configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br> +<?php endif; ?> +<table width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr><td class="tabnavtbl"> + <?php + /* active tabs */ + $tab_array = array(); + $tab_array[] = array("Settings", true, "haproxy_global.php"); + $tab_array[] = array("Backends", false, "haproxy_backends.php"); + $tab_array[] = array("Servers", false, "haproxy_servers.php"); + display_top_tabs($tab_array); + ?> + </td></tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td width="22%" valign="top" class="vtable"> </td> + <td width="78%" class="vtable"> + <input name="enable" type="checkbox" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)"> + <strong>Enable HAProxy</strong></td> + </tr> + <tr> + <td valign="top" class="vncell"> + Maximum connections + </td> + <td class="vtable"> + <table cellpadding="0" cellspacing="0"> + <tr> + <td> + <input name="maxconn" type="text" class="formfld" id="maxconn" size="5" <?if ($pconfig['enable']!='yes') echo "enabled=\"false\"";?> value="<?=htmlspecialchars($pconfig['maxconn']);?>"> per Backend. + </td> + </tr> + </table> + Sets the maximum per-process number of concurrent connections to X.<br/> + <strong>NOTE:</strong> setting this value too high will result in haproxy not being able to allocate enough memory.<br/> + <table style="border: 1px solid #000;"> + <tr> + <td><font size=-1>Connections</td> + <td><font size=-1>Memory usage</td> + </tr> + <tr> + <td colspan="2"> + <hr noshade style="border: 1px solid #000;"> + </td> + </tr> + <tr> + <td align="right"><font size=-1>999</td> + <td><font size=-1>3276 Kilobytes</td> + </tr> + <tr> + <td align="right"><font size=-1>99999</td> + <td><font size=-1>4448 Kilobytes</td> + </tr> + <tr> + <td align="right"><font size=-1>999999</td> + <td><font size=-1>32540 Kilobytes</td> + </tr> + <tr> + <td align="right"><font size=-1>9999999</td> + <td><font size=-1>143 Megabytes</td> + </tr> + </table> + </td> + </tr> + <tr> + <td> + + </td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <input name="Submit" type="submit" class="formbtn" value="Save" onClick="enable_change(true)"> + </td> + </td> + </tr> + </table> + </div> +</table> +</form> +<script language="JavaScript"> +<!-- +enable_change(false); +//--> +</script> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/haproxy/haproxy_servers.php b/config/haproxy/haproxy_servers.php new file mode 100755 index 00000000..6533b704 --- /dev/null +++ b/config/haproxy/haproxy_servers.php @@ -0,0 +1,146 @@ +<?php +/* $Id: load_balancer_virtual_server.php,v 1.6.2.1 2006/01/02 23:46:24 sullrich Exp $ */ +/* + haproxy_servers.php + part of pfSense (http://www.pfsense.com/) + Copyright (C) 2008 Remco Hoef <remcoverhoef@pfsense.com> + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +require_once("guiconfig.inc"); +require_once("haproxy.inc"); + +if (!is_array($config['installedpackages']['haproxy']['ha_servers']['item'])) { + $config['installedpackages']['haproxy']['ha_servers']['item'] = array(); +} +$a_server = &$config['installedpackages']['haproxy']['ha_servers']['item']; + +if ($_POST) { + $pconfig = $_POST; + + if ($_POST['apply']) { + $retval = 0; + config_lock(); + $retval = haproxy_configure(); + config_unlock(); + $savemsg = get_std_save_message($retval); + unlink_if_exists($d_haproxyconfdirty_path); + } +} + +if ($_GET['act'] == "del") { + if ($a_server[$_GET['id']]) { + if (!$input_errors) { + unset($a_server[$_GET['id']]); + write_config(); + touch($d_haproxyconfdirty_path); + header("Location: haproxy_servers.php"); + exit; + } + } +} + +$pgtitle = "Services: HAProxy: Backends"; +include("head.inc"); + +?> +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<form action="haproxy_servers.php" method="post"> +<?php if ($input_errors) print_input_errors($input_errors); ?> +<?php if ($savemsg) print_info_box($savemsg); ?> +<?php if (file_exists($d_haproxyconfdirty_path)): ?><p> +<?php print_info_box_np("The virtual server configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br> +<?php endif; ?> +<table width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr><td class="tabnavtbl"> + <?php + /* active tabs */ + $tab_array = array(); + $tab_array[] = array("Settings", false, "haproxy_global.php"); + $tab_array[] = array("Backends", false, "haproxy_backends.php"); + $tab_array[] = array("Servers", true, "haproxy_servers.php"); + display_top_tabs($tab_array); + ?> + </td></tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td width="30%" class="listhdrr">Name</td> + <td width="30%" class="listhdrr">Server</td> + <td width="20%" class="listhdrr">Status</td> + <td width="30%" class="listhdrr">Backend</td> + <td width="10%" class="listhdrr">Cookie</td> + <td width="10%" class="listhdrr">Weight</td> + <td width="10%" class="list"></td> + </tr> + <?php $i = 0; foreach ($a_server as $server): ?> + <tr> + <td class="listlr" ondblclick="document.location='haproxy_servers_edit.php?id=<?=$i;?>';"> + <?=$server['name'];?> + </td> + <td class="listlr" ondblclick="document.location='haproxy_servers_edit.php?id=<?=$i;?>';"> + <?=$server['address'] . ":". $server['port'];?> + </td> + <td class="listlr" ondblclick="document.location='haproxy_servers_edit.php?id=<?=$i;?>';"> + <?=$server['status'];?> + </td> + <td class="listlr" ondblclick="document.location='haproxy_servers_edit.php?id=<?=$i;?>';"> + <?=$server['backend'];?> + </td> + <td class="listlr" ondblclick="document.location='haproxy_servers_edit.php?id=<?=$i;?>';"> + <?=$server['cookie'];?> + </td> + <td class="listlr" ondblclick="document.location='haproxy_servers_edit.php?id=<?=$i;?>';"> + <?=$server['weight'];?> + </td> + <td class="list" nowrap> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="haproxy_servers_edit.php?id=<?=$i;?>"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0"></a></td> + <td valign="middle"><a href="haproxy_servers.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this entry?')"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + <?php $i++; endforeach; ?> + <tr> + <td class="list" colspan="6"></td> + <td class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="haproxy_servers_edit.php"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + </table> + </div> + </table> + </form> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/haproxy/haproxy_servers_edit.php b/config/haproxy/haproxy_servers_edit.php new file mode 100755 index 00000000..475c847e --- /dev/null +++ b/config/haproxy/haproxy_servers_edit.php @@ -0,0 +1,244 @@ +<?php +/* $Id: load_balancer_pool_edit.php,v 1.24.2.23 2007/03/03 00:07:09 smos Exp $ */ +/* + haproxy_servers_edit.php + part of pfSense (http://www.pfsense.com/) + Copyright (C) 2008 Remco Hoef <remcoverhoef@pfsense.com> + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +require("guiconfig.inc"); + +if (!is_array($config['installedpackages']['haproxy']['ha_servers']['item'])) { + $config['installedpackages']['haproxy']['ha_servers']['item'] = array(); +} + +$a_server = &$config['installedpackages']['haproxy']['ha_servers']['item']; + +if (isset($_POST['id'])) + $id = $_POST['id']; +else + $id = $_GET['id']; + +if (isset($id) && $a_server[$id]) { + $pconfig['name'] = $a_server[$id]['name']; + $pconfig['address'] = $a_server[$id]['address']; + $pconfig['port'] = $a_server[$id]['port']; + $pconfig['backend'] = $a_server[$id]['backend']; + $pconfig['weight'] = $a_server[$id]['weight']; + $pconfig['cookie'] = $a_server[$id]['cookie']; + $pconfig['status'] = $a_server[$id]['status']; +} + +$changedesc = "Services: HAProxy: Servers: "; +$changecount = 0; + +if ($_POST) { + $changecount++; + + unset($input_errors); + $pconfig = $_POST; + + $reqdfields = explode(" ", "name address port backend weight cookie"); + $reqdfieldsn = explode(",", "Name,Address,Port,Backend,Weight,Cookie"); + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['name'])) + $input_errors[] = "The field 'Name' contains invalid characters."; + + if (preg_match("/[^a-zA-Z0-9\.]/", $_POST['address'])) + $input_errors[] = "The field 'Address' contains invalid characters."; + + if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['cookie'])) + $input_errors[] = "The field 'Cookie' contains invalid characters."; + + if (!is_numeric($_POST['port'])) + $input_errors[] = "The field 'Port' value is not a number."; + else { + if (!($_POST['port']>=1 && $_POST['port']<=65535)) + $input_errors[] = "The field 'Port' value must be between 1 and 65535."; + } + + if (!is_numeric($_POST['weight'])) + $input_errors[] = "The field 'Weight' value is not a number."; + else { + if (!($_POST['weight']>=1 && $_POST['weight']<=256)) + $input_errors[] = "The field 'Weight' value must be between 1 and 256."; + } + + /* Ensure that our pool names are unique */ + for ($i=0; isset($config['installedpackages']['haproxy']['ha_servers']['item'][$i]); $i++) + if (($_POST['name'] == $config['installedpackages']['haproxy']['ha_servers']['item'][$i]['name']) && ($i != $id)) + $input_errors[] = "This server name has already been used. Server names must be unique."; + + if (!$input_errors) { + $server = array(); + if(isset($id) && $a_server[$id]) + $server = $a_server[$id]; + + if($server['name'] != "") + $changedesc .= " modified '{$server['name']}' pool:"; + + update_if_changed("name", $server['name'], $_POST['name']); + update_if_changed("address", $server['address'], $_POST['address']); + update_if_changed("port", $server['port'], $_POST['port']); + update_if_changed("backend", $server['backend'], $_POST['backend']); + update_if_changed("cookie", $server['cookie'], $_POST['cookie']); + update_if_changed("weight", $server['weight'], $_POST['weight']); + update_if_changed("status", $server['status'], $_POST['status']); + + if (isset($id) && $a_server[$id]) { + $a_server[$id] = $server; + } else { + $a_server[] = $server; + } + + if ($changecount > 0) { + touch($d_haproxyconfdirty_path); + write_config($changedesc); + /* + echo "<PRE>"; + print_r($config); + echo "</PRE>"; + */ + } + + header("Location: haproxy_servers.php"); + exit; + } +} + +$pgtitle = "HAProxy: Server: Edit"; +include("head.inc"); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<script type="text/javascript" language="javascript" src="pool.js"></script> + +<script language="javascript"> +function clearcombo(){ + for (var i=document.iform.serversSelect.options.length-1; i>=0; i--){ + document.iform.serversSelect.options[i] = null; + } + document.iform.serversSelect.selectedIndex = -1; +} +</script> + +<?php include("fbegin.inc"); ?> +<?php if ($input_errors) print_input_errors($input_errors); ?> + + <form action="haproxy_servers_edit.php" method="post" name="iform" id="iform"> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td colspan="2" valign="top" class="listtopic">Edit haproxy server</td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncellreq">Name</td> + <td width="78%" class="vtable" colspan="2"> + <input name="name" type="text" <?if(isset($pconfig['name'])) echo "value=\"{$pconfig['name']}\"";?> size="16" maxlength="16"> + </td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncellreq">Address</td> + <td width="78%" class="vtable" colspan="2"> + <input name="address" type="text" <?if(isset($pconfig['address'])) echo "value=\"{$pconfig['address']}\"";?> size="64"> + </td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncellreq">Port</td> + <td width="78%" class="vtable" colspan="2"> + <input name="port" type="text" <?if(isset($pconfig['port'])) echo "value=\"{$pconfig['port']}\"";?> size="5"> + </td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncellreq">Backend</td> + <td width="78%" class="vtable" colspan="2"> + <select name="backend"> + <?php + $i = 0; + if (!is_array($config['installedpackages']['haproxy']['ha_backends']['item'])) { + $config['installedpackages']['haproxy']['ha_backends']['item'] = array(); + } + $a_backend = &$config['installedpackages']['haproxy']['ha_backends']['item']; + + foreach ($a_backend as $backend) { + ?> + <option value="<?=$backend['name'];?>" <?php if($backend['name']==$pconfig['backend']) echo "SELECTED";?>><?=$backend['name'];?></option> + <?php } ?> + </select> + <div></div> + </td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncellreq">Status</td> + <td width="78%" class="vtable" colspan="2"> + <select name="status"> + <option value="active" <?php if($pconfig['status']=='active') echo "SELECTED";?>>active</option> + <option value="inactive" <?php if($pconfig['status']=='inactive') echo "SELECTED";?>>inactive</option> + </select> + </td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncell">Cookie</td> + <td width="78%" class="vtable" colspan="2"> + <input name="cookie" type="text" <?if(isset($pconfig['cookie'])) echo "value=\"{$pconfig['cookie']}\"";?>size="64"><br/> + This value will be checked in incoming requests, and the first + operational server possessing the same value will be selected. In return, in + cookie insertion or rewrite modes, this value will be assigned to the cookie + sent to the client. There is nothing wrong in having several servers sharing + the same cookie value, and it is in fact somewhat common between normal and + backup servers. See also the "cookie" keyword in backend section. + + </td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncell">Weight</td> + <td width="78%" class="vtable" colspan="2"> + <input name="weight" type="text" <?if(isset($pconfig['weight'])) echo "value=\"{$pconfig['weight']}\"";?>size="64"><br/> + The default weight is 1, and the maximal value is 255.<br/> + NOTE: If this + parameter is used to distribute the load according to server's capacity, it + is recommended to start with values which can both grow and shrink, for + instance between 10 and 100 to leave enough room above and below for later + adjustments. + + </td> + </tr> + <tr align="left"> + <td width="22%" valign="top"> </td> + <td width="78%"> + <input name="Submit" type="submit" class="formbtn" value="Save"> + <?php if (isset($id) && $a_server[$id]): ?> + <input name="id" type="hidden" value="<?=$id;?>"> + <?php endif; ?> + </td> + </tr> + </table> + </form> +<br> +<?php include("fend.inc"); ?> +</body> +</html> |