Updated Branches: refs/heads/vpc-multi-tier-public-lb [created] 269e87591
Summary: Initial commit for vpc multi-network public loadbalancer Detail: Adjust vpc_loadbalance.sh to adjust firewall rules for multi-tier LB, call /root/reconfigLB_vpc rather than /root/reconfigLB.sh (single isolatednet script). Disable check that only allows one loadbalanced network offering per VPC. BUG-ID: CLOUDSTACK-2367 Signed-off-by: Marcus Sorensen <mar...@betterservers.com> 1367957466 -0600 Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/269e8759 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/269e8759 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/269e8759 Branch: refs/heads/vpc-multi-tier-public-lb Commit: 269e87591eee7b54762a1ea68a6d096b5d32d686 Parents: 732566e Author: Marcus Sorensen <mar...@betterservers.com> Authored: Tue May 7 14:22:21 2013 -0600 Committer: Marcus Sorensen <mar...@betterservers.com> Committed: Tue May 7 14:22:21 2013 -0600 ---------------------------------------------------------------------- .../config/opt/cloud/bin/vpc_loadbalancer.sh | 56 ++++-- patches/systemvm/debian/config/root/reconfigLB_vpc | 148 +++++++++++++++ .../src/com/cloud/network/vpc/VpcManagerImpl.java | 16 -- 3 files changed, 186 insertions(+), 34 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/269e8759/patches/systemvm/debian/config/opt/cloud/bin/vpc_loadbalancer.sh ---------------------------------------------------------------------- diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_loadbalancer.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_loadbalancer.sh index 334c617..9a01143 100755 --- a/patches/systemvm/debian/config/opt/cloud/bin/vpc_loadbalancer.sh +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_loadbalancer.sh @@ -54,8 +54,8 @@ fw_remove() { fw_backup() { fw_remove_backup - sudo iptables -E load_balancer back_load_balancer 2> /dev/null - sudo iptables -E lb_stats back_lb_stats 2> /dev/null + iptables -S load_balancer | sed 's/load_balancer/back_load_balancer/g'|xargs -i /bin/bash -c "/sbin/iptables {} 2>/dev/null" + iptables -S lb_stats | sed 's/lb_stats/back_lb_stats/g'|xargs -i /bin/bash -c "/sbin/iptables {} 2>/dev/null" } fw_restore() { @@ -65,7 +65,6 @@ fw_restore() { } fw_chain_create () { - fw_backup sudo iptables -N load_balancer 2> /dev/null sudo iptables -A INPUT -p tcp -j load_balancer 2> /dev/null sudo iptables -N lb_stats 2> /dev/null @@ -87,26 +86,45 @@ fw_entry() { fi local a=$(echo $added | cut -d, -f1- --output-delimiter=" ") local r=$(echo $removed | cut -d, -f1- --output-delimiter=" ") - fw_chain_create + fw_backup + sudo iptables -L load_balancer >/dev/null 2>&1 || fw_chain_create success=0 while [ 1 ] do for i in $a do local pubIp=$(echo $i | cut -d: -f1) - local dport=$(echo $i | cut -d: -f2) - sudo iptables -A load_balancer -p tcp -d $pubIp --dport $dport -j ACL_INBOUND_$dev 2>/dev/null - success=$? - if [ $success -gt 0 ] + local dport=$(echo $i | cut -d: -f2) + if ! sudo iptables -C load_balancer -p tcp -d $pubIp --dport $dport -j ACL_INBOUND_$dev 2>/dev/null then - break + sudo iptables -A load_balancer -p tcp -d $pubIp --dport $dport -j ACL_INBOUND_$dev 2>/dev/null + success=$? + if [ $success -gt 0 ] + then + break + fi + fi + done + for i in $r + do + local pubIp=$(echo $i | cut -d: -f1) + local dport=$(echo $i | cut -d: -f2) + if sudo iptables -C load_balancer -p tcp -d $pubIp --dport $dport -j ACL_INBOUND_$dev 2>/dev/null + then + sudo iptables -D load_balancer -p tcp -d $pubIp --dport $dport -j ACL_INBOUND_$dev 2>/dev/null + success=$? + if [ $success -gt 0 ] + then + break + fi fi done if [ "$stats" != "none" ] then local pubIp=$(echo $stats | cut -d: -f1) - local dport=$(echo $stats | cut -d: -f2) + local dport=$(echo $stats | cut -d: -f2) local cidrs=$(echo $stats | cut -d: -f3 | sed 's/-/,/') + sudo iptables -F lb_stats sudo iptables -A lb_stats -s $cidrs -p tcp -d $pubIp --dport $dport -j ACCEPT 2>/dev/null success=$? fi @@ -117,13 +135,14 @@ fw_entry() { fw_restore else fw_remove_backup - fi + fi return $success } #Hot reconfigure HA Proxy in the routing domain reconfig_lb() { - /root/reconfigLB.sh + logger -t cloud "running reconfigLB.sh -d $1" + /root/reconfigLB_vpc -d $1 return $? } @@ -131,12 +150,12 @@ reconfig_lb() { restore_lb() { logger -t cloud "Restoring HA Proxy to previous state" # Copy the old version of haproxy.cfg into the file that reconfigLB.sh uses - cp /etc/haproxy/haproxy.cfg.old /etc/haproxy/haproxy.cfg.new - + # cp /etc/haproxy/haproxy.cfg.old /etc/haproxy/haproxy.cfg.new + if [ $? -eq 0 ] then # Run reconfigLB.sh again - /root/reconfigLB.sh + /root/reconfigLB_vpc -R fi } @@ -166,6 +185,7 @@ do esac done +logger -t cloud "haproxy: i=$ip a=$addedIps d=$removedIps s=$statsIp" dev=$(getEthByIp $ip) @@ -180,7 +200,7 @@ then fi # hot reconfigure haproxy -reconfig_lb +reconfig_lb $removedIps if [ $? -gt 0 ] then @@ -190,12 +210,12 @@ fi # iptables entry to ensure that haproxy receives traffic fw_entry $addedIps $removedIps $statsIp -result=$? +result=$? if [ $result -gt 0 ] then logger -t cloud "Failed to apply firewall rules for load balancing, reverting HA Proxy config" # Restore the LB restore_lb fi - + unlock_exit $result $lock $locked http://git-wip-us.apache.org/repos/asf/cloudstack/blob/269e8759/patches/systemvm/debian/config/root/reconfigLB_vpc ---------------------------------------------------------------------- diff --git a/patches/systemvm/debian/config/root/reconfigLB_vpc b/patches/systemvm/debian/config/root/reconfigLB_vpc new file mode 100755 index 0000000..67f9d4c --- /dev/null +++ b/patches/systemvm/debian/config/root/reconfigLB_vpc @@ -0,0 +1,148 @@ +#!/usr/bin/perl +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# @VERSION@ + +use strict; +use Getopt::Std; +my $debug = 0; + +my $opts = {}; +getopts('d:R',$opts); + +my @removedips = split(/,/,$opts->{d}); + +# remove trailing colons from ip/port entries, if exists +removecolon(\@removedips); + +if($opts->{R}){ + # restore .save file if -R was passed in + `mv -f /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.reverted`; + `mv /etc/haproxy/haproxy.cfg.save /etc/haproxy/haproxy.cfg`; +} else { + # merge passed config with current config + logger("reconfigLB got removedips=$opts->{d}"); + `mv -f /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.save`; + open(FILE,">/etc/haproxy/haproxy.cfg"); + print FILE generate_config(); + close FILE; +} + +# graceful restart +`mv /var/run/haproxy.pid /var/run/haproxy.pid.old`; +my $oldpid = `cat /var/run/haproxy.pid.old`; + +`kill -TTOU $oldpid`; +sleep 2; + +`haproxy -D -p /var/run/haproxy.pid -f /etc/haproxy/haproxy.cfg`; +if ($? == 0) { + logger("New haproxy instance successfully loaded, stopping previous one."); + `kill -KILL $oldpid`; + `rm -f /var/run/haproxy.pid.old`; + exit 0; +} else { + logger("New instance failed to start, resuming previous one."); + `kill -TTIN $oldpid`; + `rm -f /var/run/haproxy.pid`; + `mv /var/run/haproxy.pid.old /var/run/haproxy.pid`; + `mv -f /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.newfail`; + `mv /etc/haproxy/haproxy.cfg.save /etc/haproxy/haproxy.cfg`; + exit 1; +} + +########### subs ########### + +sub generate_config { + + my $config; + + open (NEWFILE, "/etc/haproxy/haproxy.cfg.new"); + open (CURFILE, "/etc/haproxy/haproxy.cfg.save"); + + # read in new config + my $sections = {}; + my $section; + while (my $line = <NEWFILE>) { + $section = $line if $line =~ /^\w/; + print "found line for section $section\n" if $debug; + push @{$sections->{$section}},$line; + } + + close NEWFILE; + + # fetch old config + my $oldsections = {}; + my $oldsection; + while (my $line = <CURFILE>){ + $oldsection = $line if $line =~ /^\w/; + + # skip default, global, and stats lines, we always want the latest + next if $oldsection =~ /^global/; + next if $oldsection =~ /^default/; + next if $oldsection =~ /^listen\sstats/; + next if $oldsection =~ /^listen\scloud-default/; + + # delete/skip it if it is on remove list + my $skip = 0; + foreach my $remip (@removedips) { + if($oldsection =~ /^listen/ && $oldsection =~ /$remip/){ + $skip = 1; + print "skipping line for section $oldsection since it is on remove list\n" if $debug; + } + } + next if $skip; + + push @{$oldsections->{$oldsection}},$line; + } + + close CURFILE; + + # print new config + print "############ printing new config:\n\n" if $debug; + foreach my $section (sort keys %{$sections}) { + foreach my $line(@{$sections->{$section}}) { + $config .= $line; + } + $config .= "\n"; + } + + # add in old config that we didn't get a new config for + print "############ printing existing config:\n\n" if $debug; + foreach my $oldsection (sort keys %{$oldsections}) { + next if exists $sections->{$oldsection}; + foreach my $line(@{$oldsections->{$oldsection}}) { + $config .= $line; + } + $config .= "\n"; + } + + return $config; +} + +sub logger { + my $msg = shift; + `logger -t cloud $msg`; +} + +sub removecolon { + my $list = shift; + foreach(@{$list}){ + $_ =~ s/:$//; + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/269e8759/server/src/com/cloud/network/vpc/VpcManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index a7f06e9..9a49a11 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -1037,22 +1037,6 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis pr + " is not supported by VPC " + vpc); } } - - //4) Only one network in the VPC can support LB - if (_ntwkModel.areServicesSupportedByNetworkOffering(guestNtwkOff.getId(), Service.Lb)) { - List<? extends Network> networks = getVpcNetworks(vpc.getId()); - for (Network network : networks) { - if (networkId != null && network.getId() == networkId.longValue()) { - //skip my own network - continue; - } else { - if (_ntwkModel.areServicesSupportedInNetwork(network.getId(), Service.Lb)) { - throw new InvalidParameterValueException("LB service is already supported " + - "by network " + network + " in VPC " + vpc); - } - } - } - } } @Override