Forum Discussion

Notanf5engineer's avatar
Notanf5engineer
Icon for Nimbostratus rankNimbostratus
Apr 01, 2023

Standard irule that can be used for multiple urls

Here is a usecase I have and I am trying to find a solution for it.

ABCD.com/app1/anything

Translated to: app1.internaldomain.com/everything

Abcd.com/app2/api/hello

App2.internaldomain.com/API/hello

I am able to get till app1/app2 but the rest just fails as I am breaking the split.

 

ABCD.com/app1/api/hello/test

 

App1.internaldomain.com/api 

 

The hello/test keeps getting omitted because of split function.

 

Any suggestions.

 

Thanks in advance

  • Hello Notanf5engineer 
    I've built the following bsed on given examples, it might still be incomplete and not cover all of your scenarios but it might be a good starting point 

    Let me know if I can help you with improving it 

    Edit: fixed syntax, tested irule 

    CA

     

    when HTTP_REQUEST {
    
      #If you have multiple SNI that resolve to this VS, consider enabling row below
    #  if {[string tolower [HTTP::host]] ne "abcd.com"}{ return }
    
      switch -glob [HTTP::uri] {
        /app1/* {
    	  # this will match everything starting with /app1/* (case sensitive) , remove "app1" folder and redirect 
    	  # ex. /app1/test to /test 
    	  # client will see the redirect
    
    	  set uri [string trimleft [HTTP::uri] /app1]
          HTTP::redirect "http://app1.internaldomain.com/$uri"
        }
        /app2/API/hello {
    	  # this is an exact match on a specific URI (case sensitive) 
    	  # URI is not trimmed and is passed as-is 
    	  # client will see the redirect
    	  
    	  HTTP::redirect "http://api2.internaldomain.com/[HTTP::uri]"
    	}
    	default { 
          # this matches everything not specified before
    	  # HTTP::respond 401 
    	}
      }
    }

     

     

  • Notanf5engineer Is this a redirect that needs to occur or does the client need to see the original URL and the server needs to see the modified one?

    • Notanf5engineer's avatar
      Notanf5engineer
      Icon for Nimbostratus rankNimbostratus

      Hi Paulius,

       

      It's a redirect. Url stays the same no modification needed.

       

      Thanks

  • Thank you CA_Valli.
    I think this works when we are hardcoding the app1 in the condition.

    I was wondering if this irule can be agnostic in a way it can be used for any number of Virtual servers.


    Example:

     

    testurl.externaldomain.com/app1/api/hello

    testurl.extenaldomain.com/app2/api/bye

    testdifferenturl.externaldomain.com/app4/api/test/*/*

    so all these urls will have one virutal server which should have a common generalized irule.

    testurl.externaldomain.com/app1dev/api/hello  - it would be a redirect the customer still sees the same url in the browser.

    set hostname: app1dev.internaldomain.com/api/hello

    set pool : testurl.externaldomain.com_app1dev

     

    testurl.externaldomain.com/app1qa/api/getemployeedetails  - it would be a redirect the customer still sees the same url in the browser.

    set hostname: app1qa.internaldomain.com/api/getemployeedetails

    set pool : testurl.externaldomain.com_app1qa

    the way we formulated the url is 

    externaldomain/appname/whateverapitheappsupports.
    appname needs to be appended with internaldomain and the whateverapitheappsupports need to the URI.
    whateverapitheappsupports - this can be just /api/hello or /api/employee/1234 or /swagger anything that comes after the app name.


    Please let me know if the above example is clear or if i am not explaining it properly.

    • Paulius's avatar
      Paulius
      Icon for MVP rankMVP

      Notanf5engineer Is the app name always the same length or does it vary between a certain amount of characters? Sadly for this type of configuration you are better off configuring an iRule per virtual server based on what traffic you are sending to the virtual server. In all honesty you should really use the appropriate FQDN rather trying to move pieces of the URL around to meet the needs of each particular application. If you were provided a list of all the applications per FQDN you could create one virtual server with an iRule that references a data-group along with a FQDN match and then send them to the appropraite pool while keeping the iRule relatively short. Typically you would only want to result to using an iRule for this URL modification if for some reason these FQDNs had to be formatted the way you have stated.

      • Notanf5engineer's avatar
        Notanf5engineer
        Icon for Nimbostratus rankNimbostratus

        Hi Paulius,

         

        The appname varies. The reason why we are trying to create an appname.internaldomain.com is because the service hosts all the apps  with a single ip in front but the hostnames vary..(if you are familiar with Azure App service hosted in an internal ASE)
        I understand this is very esoteric. We were able to achieve a generalized irule for ip based pools. Since these are hostnames it gets very tricky. The issue with creating an irule per app is like we have around 80 apps and it might need similar functionality and managing all of them with different virtual servers and irules is lot of overhead but can be done. 
        Please let me know if you have any suggestions.

         

        Thank you.

    • CA_Valli's avatar
      CA_Valli
      Icon for MVP rankMVP

      It's possible, indeed. 
      I'm struggling a bit to see the logic you want to implement based on naming conventions, I've developed the following, feel free to adjust it as you require. 

       

      when HTTP_REQUEST {
      
        set hostname [string tolower [HTTP::host]]
      
        #This IF exists to implement hostname exclusion 
      #  if {[class match $hostname eq datagroup_irule_exlcusion]}{ return }
      
        set uri [HTTP::uri]
        set poolname "testurl.externaldomain.com_"
        set newhost ".internaldomain.com"
      
        set application [substr $uri 1 "/"] ; log local0. "application is $application"
        set newuri [string trimleft $uri "/$application"]
        set poolname "$poolname$application" ; log local0. "pool $poolname"
        set newhost "$application$newhost" ; log local0. "host $newhost"
      
        # do you need a redirect (1), or a rewrite (2)? 
        
        # (1) client will see the redirect
      #  HTTP::redirect "http://$newhost/$newuri"
        
        # (2) rewrite is transparent to client 
      #  HTTP::header replace "Host" "$newhost"
      #  HTTP::uri "$newuri"
      #  pool $poolname
        
      }

       

      With redirect instruction, client sees this. As you can see URL was changed to new host and URI is cropped and retained. 

       

       

      LTM logs: