Re: Configure Haproxy to dynamically set backend server

2015-06-01 Thread Mrunmayi Dhume
Hello,
Thanks for all your help. Any rough estimate on when the patch for doing DNS 
resolutions during runtime with asynchronous methods might be out?
-Mrunmayi 


 On Saturday, May 30, 2015 2:47 AM, Thierry FOURNIER 
tfourn...@haproxy.com wrote:
   

 On Sat, 30 May 2015 00:25:59 + (UTC)
Mrunmayi Dhume mrunmayi.dh...@yahoo.com wrote:

 Hello Thierry,
 This seems to be what we are looking for, however it doesn't seem to work as 
 expected. When we use your example as is, it seems to fail with a 500 error. 
 When we switch to using a IP address, it works, so it seems like DNS 
 resolution is a problem?


Yes, haproxy can not execute DNS résolutions while is running. It does
DNS resolution only during the configuration parsing. Its because the
standard DNS resolution are a synchronous process, and the HAProxy
architecture does not accept synchronous processes.

Note that a patch is currently in development for doing DNS resolutions
during the runtime with asynchronous methods.


As per this doc -
http://cbonte.github.io/haproxy-dconv/configuration-1.6.html#4-option%20http_proxy
 http-proxy mode does not accept hostname, instead it only accepts IP. 
 The below example works:
   core.register_fetches(choose_backend, function(txn) if 
txn.sf.req_fhdr(Host) == 'example.test.com' and    txn.sf.req_path == 
'/test' then    return 1.1.1.1 else if [...] end return 
default_backend  end);
 In the haproxy configuration file, you must load the lua file, and usethe new 
 declared fetch in your frontend:
   global [...] lua-load your-lua-file.lua [...]
   listen your_frt [...]  option http_proxy http-request set-uri 
http://%[lua.choose_backend]%[url]
 We don’t want to have to specify the IP as that means that we will have to 
 perform some sort of dns resolution in lua. Can you suggest an alternative?


Actually, you can use maps to do this. A map is a file containing a
name and his correspondance. You can put a hostname and the associated
ip.

This map can be updated throught the HAProxy's socket (without
restarting HAProxy). This is not a real DNS Resolution, you must kown
the full list of your domains.

Thierry


   Thanks!
 -Mrunmayi 
 
 
      On Wednesday, May 27, 2015 1:50 AM, Thierry FOURNIER 
tfourn...@haproxy.com wrote:
    
 
  On Tue, 26 May 2015 21:39:23 + (UTC)
 Mrunmayi Dhume mrunmayi.dh...@yahoo.com wrote:
 
  Thanks for your detailed reply Thierry. While this approach would solve the 
  aspect of choosing the backend dynamically we still need to explicitly 
  define each backend server separately in the haproxy config file. Our 
  use-case involves having 100+ backends and we would prefer not to 
  complicate the config file by defining each backend server as it is not 
  easy to maintain. We  prefer to set it based on incoming http request 
  information like path or host header and keep haproxy config file simple 
  with just listen and FE  directives and of course single default backend 
  server
 
 
 Hi,
 
 HAProxy does not permit to choose the destination IP and PORT.
 
 But, maybe I have an ugly solution to your problem.
 
 You can try to deal with the option option http_proxy. This option
 understand the base proxy requests.
 
 You create a listen section which use Lua for rewriting the path of
 the HTTP request like this:
 
    core.register_fetches(choose_backend, function(txn)
       if txn.sf.req_fhdr(Host) == 'example.test.com' and
         txn.sf.req_path == '/test' then
         return test1. example.com:8081
       else if
       [...]
       end
       return default_backend
    end);
  
 In the haproxy configuration file, you must load the lua file, and use
 the new declared fetch inyour frontend:
  
    global
       [...]
       lua-load your-lua-file.lua
       [...]
  
    listen your_frt
       [...]
       option http_proxy
       http-request set-uri http://%[lua.choose_backend]%[url]
       [...]
 
 Thierry
 
 
  if (Host == aaa.example.com’ and path == ‘/test’) thenbackend server == 
  test1. example.com:8081  (Origin  port changed) elsif (Host == 
  aaa.example.com’ and path == ‘/test2’) backend server == test2. 
  example.com:8080 (Origin  port changed) elsif (Host == aaa.example.com’ and 
  path == ‘/test3’) backend server == xxx.example.com: ((Origin  host and 
   port changed) 
  
  looking for something like the Traffic server lua api - 
  https://docs.trafficserver.apache.org/en/latest/reference/plugins/ts_lua.en.html#ts-client-request-set-url-host

  Thanks,
  Mrunmayi 
  
  
  
       On Tuesday, May 26, 2015 3:15 AM, Thierry FOURNIER 
 tfourn...@haproxy.com wrote:
     
  
   On Fri, 22 May 2015 19:06:59 + (UTC)
  Mrunmayi Dhume mrunmayi.dh...@yahoo.com wrote:
  
   Hello,
   I am using haproxy-1.6 with Lua. I have a use-case where I want to set 
   the destination (backend server) very dynamically, based on certain layer 
   7 information (I am trying to avoid updating haproxy configuration

Re: Configure Haproxy to dynamically set backend server

2015-05-29 Thread Mrunmayi Dhume
Hello Thierry,
This seems to be what we are looking for, however it doesn't seem to work as 
expected. When we use your example as is, it seems to fail with a 500 error. 
When we switch to using a IP address, it works, so it seems like DNS resolution 
is a problem? As per this doc - 
http://cbonte.github.io/haproxy-dconv/configuration-1.6.html#4-option%20http_proxy
  http-proxy mode does not accept hostname, instead it only accepts IP. 
The below example works:
  core.register_fetches(choose_backend, function(txn) if 
txn.sf.req_fhdr(Host) == 'example.test.com' and    txn.sf.req_path == 
'/test' then    return 1.1.1.1 else if [...] end return 
default_backend  end);
In the haproxy configuration file, you must load the lua file, and usethe new 
declared fetch in your frontend:
  global [...] lua-load your-lua-file.lua [...]
  listen your_frt [...]  option http_proxy http-request set-uri 
http://%[lua.choose_backend]%[url]
We don’t want to have to specify the IP as that means that we will have to 
perform some sort of dns resolution in lua. Can you suggest an alternative?
  Thanks!
-Mrunmayi 


 On Wednesday, May 27, 2015 1:50 AM, Thierry FOURNIER 
tfourn...@haproxy.com wrote:
   

 On Tue, 26 May 2015 21:39:23 + (UTC)
Mrunmayi Dhume mrunmayi.dh...@yahoo.com wrote:

 Thanks for your detailed reply Thierry. While this approach would solve the 
 aspect of choosing the backend dynamically we still need to explicitly define 
 each backend server separately in the haproxy config file. Our use-case 
 involves having 100+ backends and we would prefer not to complicate the 
 config file by defining each backend server as it is not easy to maintain. We 
  prefer to set it based on incoming http request information like path or 
 host header and keep haproxy config file simple with just listen and FE  
 directives and of course single default backend server


Hi,

HAProxy does not permit to choose the destination IP and PORT.

But, maybe I have an ugly solution to your problem.

You can try to deal with the option option http_proxy. This option
understand the base proxy requests.

You create a listen section which use Lua for rewriting the path of
the HTTP request like this:

   core.register_fetches(choose_backend, function(txn)
      if txn.sf.req_fhdr(Host) == 'example.test.com' and
        txn.sf.req_path == '/test' then
        return test1. example.com:8081
      else if
      [...]
      end
      return default_backend
   end);
 
In the haproxy configuration file, you must load the lua file, and use
the new declared fetch inyour frontend:
 
   global
      [...]
      lua-load your-lua-file.lua
      [...]
 
   listen your_frt
      [...]
      option http_proxy
      http-request set-uri http://%[lua.choose_backend]%[url]
      [...]

Thierry


 if (Host == aaa.example.com’ and path == ‘/test’) thenbackend server == 
 test1. example.com:8081  (Origin  port changed) elsif (Host == 
 aaa.example.com’ and path == ‘/test2’) backend server == test2. 
 example.com:8080 (Origin  port changed) elsif (Host == aaa.example.com’ and 
 path == ‘/test3’) backend server == xxx.example.com: ((Origin  host and  
 port changed) 
 
 looking for something like the Traffic server lua api - 
 https://docs.trafficserver.apache.org/en/latest/reference/plugins/ts_lua.en.html#ts-client-request-set-url-host
   
 Thanks,
 Mrunmayi 
 
 
 
      On Tuesday, May 26, 2015 3:15 AM, Thierry FOURNIER 
tfourn...@haproxy.com wrote:
    
 
  On Fri, 22 May 2015 19:06:59 + (UTC)
 Mrunmayi Dhume mrunmayi.dh...@yahoo.com wrote:
 
  Hello,
  I am using haproxy-1.6 with Lua. I have a use-case where I want to set the 
  destination (backend server) very dynamically, based on certain layer 7 
  information (I am trying to avoid updating haproxy configuration and make 
  it complicated with a ~100 domain names and their corresponding backend 
  server name and do a map lookup,  I want lua to do it  ) 
  eg:  from lua, based on certain layer 7 information I want to change the 
  backend server (set destination) it should connect to..  
   if Host is ‘example.test.com’; then backend is test1.server.com  elsif 
 Host is ‘example2.test.com; then backend is test2.server.com    I want to 
 keep the haproxy config simple and have only the Listen directive listed and 
 take more control of the request flow from the LUA code.
  The ATS traffic server does provide such functionality through the LUA API 
  hook to override backend server dynamically from Lua end 
   if ts.client_request.header[Host] == 'example.test.com' then  
 ts.client_request.set_url_host( 
 test1.server.comts.client_request.set_url_port(80)elsif 
 ts.client_request.header[Host] == 'example2.test.com' then  
 ts.client_request.set_url_host( test2.server.com  )     
 ts.client_request.set_url_port(80)end
  Is it possible to do the same using Haproxy and Lua?
 
 
 Hi,
 
 Yes, you can, but the way is a little bit

Re: Configure Haproxy to dynamically set backend server

2015-05-26 Thread Mrunmayi Dhume
Thanks for your detailed reply Thierry. While this approach would solve the 
aspect of choosing the backend dynamically we still need to explicitly define 
each backend server separately in the haproxy config file. Our use-case 
involves having 100+ backends and we would prefer not to complicate the config 
file by defining each backend server as it is not easy to maintain. We  prefer 
to set it based on incoming http request information like path or host header 
and keep haproxy config file simple with just listen and FE  directives and of 
course single default backend server 
if (Host == aaa.example.com’ and path == ‘/test’) thenbackend server == test1. 
example.com:8081  (Origin  port changed) elsif (Host == aaa.example.com’ and 
path == ‘/test2’) backend server == test2. example.com:8080 (Origin  port 
changed) elsif (Host == aaa.example.com’ and path == ‘/test3’) backend server 
== xxx.example.com: ((Origin  host and  port changed) 

looking for something like the Traffic server lua api - 
https://docs.trafficserver.apache.org/en/latest/reference/plugins/ts_lua.en.html#ts-client-request-set-url-host
  
Thanks,
Mrunmayi 



 On Tuesday, May 26, 2015 3:15 AM, Thierry FOURNIER tfourn...@haproxy.com 
wrote:
   

 On Fri, 22 May 2015 19:06:59 + (UTC)
Mrunmayi Dhume mrunmayi.dh...@yahoo.com wrote:

 Hello,
 I am using haproxy-1.6 with Lua. I have a use-case where I want to set the 
 destination (backend server) very dynamically, based on certain layer 7 
 information (I am trying to avoid updating haproxy configuration and make it 
 complicated with a ~100 domain names and their corresponding backend server 
 name and do a map lookup,  I want lua to do it  ) 
 eg:  from lua, based on certain layer 7 information I want to change the 
 backend server (set destination) it should connect to..  
  if Host is ‘example.test.com’; then backend is test1.server.com  elsif Host 
is ‘example2.test.com; then backend is test2.server.com    I want to keep the 
haproxy config simple and have only the Listen directive listed and take more 
control of the request flow from the LUA code.
 The ATS traffic server does provide such functionality through the LUA API 
 hook to override backend server dynamically from Lua end 
  if ts.client_request.header[Host] == 'example.test.com' then  
ts.client_request.set_url_host( 
test1.server.comts.client_request.set_url_port(80)elsif 
ts.client_request.header[Host] == 'example2.test.com' then  
ts.client_request.set_url_host( test2.server.com  )     
ts.client_request.set_url_port(80)end
 Is it possible to do the same using Haproxy and Lua?


Hi,

Yes, you can, but the way is a little bit different.

You must create a new sample fetch in Lua. This fetch executes the
analysis of your HTTP resuest and returns the backend name. The
following code (untested) must set in a lua file:

  core.register_fetches(choose_backend, function(txn)
      if txn.sf.req_fhdr(Host) == 'example.test.com' then
        return backend1
      else if txn.sf.req_fhdr(Host) == 'other.domain.com' then
        return backend2
      [...]
      end
      return default_backend
  end);

In the haproxy configuration file, you must load the lua file, and use
the new declared fetch inyour frontend:

  global
      [...]
      lua-load your-lua-file.lua
      [...]

  frontend your_frt
      [...]
      use_backend %[lua.choose_backend]
      [...]

Note that your example code seem to choose a backend regarding only the
header host. In this case, the lua is useless, you can use the maps
to choose your backend. The configuration looks like this:

  frontend yur_frt
      [...]
      use_backend %[req.fhdr(host),tolower,map(host_to_bck.map,default)]
      [...]

The default argument is the name of the default backend. And the file
host_to_bck.map contains a mapping between the hostnames (in lower
case) and the backend names:

  example.test.com  backend1
  other.domain.com  backend2

  etc...

Thierry


 
 Thank you,
 Mrunmayi