# # Cookbook Name:: haproxy # Recipe:: tcp_lb # # Copyright 2014, Sam Su # # Licensed 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. # defaultbag = "openstack" if !Chef::DataBag.list.key?(defaultbag) Chef::Application.fatal!("databag '#{defaultbag}' doesn't exist.") return end myitem = node.attribute?('cluster')? node['cluster']:"env_default" if !search(defaultbag, "id:#{myitem}") Chef::Application.fatal!("databagitem '#{myitem}' doesn't exist.") return end mydata = data_bag_item(defaultbag, myitem) if mydata['ha']['status'].eql?('enable') node.set['haproxy']['enabled_services'] = nil node.set['haproxy']['incoming_address'] = mydata['ha']['haproxy']['vip'] mydata['ha']['haproxy']['roles'].each do |role, services| services.each do |service| node.set['haproxy']['services'][service]['role'] = role unless node['haproxy']['enabled_services'].include?(service) # node['haproxy']['enabled_services'] << service node.set['haproxy']['enabled_services'] = node['haproxy']['enabled_services'] + [service] end end end end node['haproxy']['services'].each do |name, service| unless node['haproxy']['enabled_services'].include?(name) next end if node['haproxy']['choose_backend'].eql?("prefeed") pool_members = [] mydata['node_mapping'].each do |nodename, nodeinfo| if nodeinfo['roles'].include?(service['role']) pool_members << nodename end end else pool_members = search(:node, "run_list:role\\[#{service['role']}\\] AND chef_environment:#{node.chef_environment}") || [] # load balancer may be in the pool pool_members << node if node.run_list.roles.include?(service[:role]) end # we prefer connecting via local_ipv4 if # pool members are in the same cloud # TODO refactor this logic into library...see COOK-494 pool_members.map! do |member| if node['haproxy']['choose_backend'].eql?("prefeed") server_ip = mydata['node_mapping']["#{member}"]['management_ip'] {:ipaddress => server_ip, :hostname => member} else server_ip = begin if member.attribute?('cloud') if node.attribute?('cloud') && (member['cloud']['provider'] == node['cloud']['provider']) member['cloud']['local_ipv4'] else member['cloud']['public_ipv4'] end else member['ipaddress'] end end {:ipaddress => server_ip, :hostname => member['hostname']} end end pool = ["options httpchk #{node['haproxy']['httpchk']}"] if node['haproxy']['httpchk'] pool = service[:options] servers = pool_members.uniq.map do |s| # novncproxy cannot to be checked if name.eql?("novncproxy") "#{s[:hostname]} #{s[:ipaddress]}:#{service[:backend_port]}" else "#{s[:hostname]} #{s[:ipaddress]}:#{service[:backend_port]} check inter 2000 rise 2 fall 5" end end haproxy_lb name do bind node['haproxy']['incoming_address'] + ':' + service[:frontend_port] servers servers params pool end end include_recipe "haproxy::install_#{node['haproxy']['install_method']}" template "#{node['haproxy']['conf_dir']}/haproxy.cfg" do source "haproxy.cfg.erb" owner "root" group "root" mode 00644 notifies :reload, "service[haproxy]" variables( :defaults_options => haproxy_defaults_options, :defaults_timeouts => haproxy_defaults_timeouts ) end case node["platform_family"] when "debian" cookbook_file "/etc/default/haproxy" do source "haproxy-default" owner "root" group "root" mode 00644 notifies :restart, "service[haproxy]" end end service "haproxy" do supports :restart => true, :status => true, :reload => true action [:enable, :start] end