<div dir="ltr"><div>Hi folks,</div><div><br></div>I think it's ok to include content modification in a general API proposal as long as it would then receive separate spec document in neutron-specs.<div>When it comes to particular feature design and implementation it's better to be more granular.</div>
<div><br></div><div>Thanks,</div><div>Eugene.</div><div><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, May 6, 2014 at 4:05 AM, Stephen Balukoff <span dir="ltr"><<a href="mailto:sbalukoff@bluebox.net" target="_blank">sbalukoff@bluebox.net</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Sam,<div><br></div><div>In working off the document in the wiki on L7 functionality for LBaaS (<a href="https://wiki.openstack.org/wiki/Neutron/LBaaS/l7" target="_blank">https://wiki.openstack.org/wiki/Neutron/LBaaS/l7</a> ), I notice that "MODIFY_CONTENT" is one of the actions listed for a <span style="background-color:rgb(245,245,245);color:rgb(51,51,51);font-family:Monaco,Menlo,Consolas,'Courier New',monospace;font-size:13px;line-height:20px;white-space:pre-wrap">L7VipPolicyAssociation. </span>That's the primary reason I included this in the API design I created.</div>
<div><br></div><div>To be honest, it frustrates me more than a little to hear after the fact that the only locate-able documentation like this online is inaccurate on many meaningful details like this.</div><div><br></div>
<div>I could actually go either way on this issue: I included content modification as one possible action of L7Policies, but it is somewhat wedged in there: It works, but in L7Policies that do content modification or blocking of the request, the order field as I've proposed it could be confusing for users, and these L7Policies wouldn't be associated with a back-end pool anyway.</div>
<div><br></div><div>I'm interested in hearing others' opinions on this as well.</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>Stephen</div><div><br></div></font></span></div><div class="gmail_extra">
<br><br><div class="gmail_quote"><div><div class="h5">On Mon, May 5, 2014 at 6:47 AM, Samuel Bercovici <span dir="ltr"><<a href="mailto:SamuelB@radware.com" target="_blank">SamuelB@radware.com</a>></span> wrote:<br>
</div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
<div lang="EN-US" link="blue" vlink="purple">
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Hi Stephen,<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">For Icehouse we did not go into L7 content modification as the general feeling was that it might not be exactly the same as content switching and we wanted
to tackle content switching fiest.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">L7 content switching and L7 content modification are different, I prefer to be explicit and declarative and use different objects.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">This will make the API more readable.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">What do you think?<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">I plan to look deeper into L7 content modification later this week to propose a list of capabilities.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">-Sam.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p>
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> Stephen Balukoff [mailto:<a href="mailto:sbalukoff@bluebox.net" target="_blank">sbalukoff@bluebox.net</a>]
<br>
<b>Sent:</b> Saturday, May 03, 2014 1:33 AM</span></p><div><br>
<b>To:</b> OpenStack Development Mailing List (not for usage questions)<br>
</div><div><b>Subject:</b> Re: [openstack-dev] [Neutron][LBaaS]L7 conent switching APIs<u></u><u></u></div><p></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal">Hi Adam and Samuel!<u></u><u></u></p><div><div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Thanks for the questions / comments! Reactions in-line:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><u></u> <u></u></p>
<div>
<p class="MsoNormal">On Thu, May 1, 2014 at 8:14 PM, Adam Harwell <<a href="mailto:adam.harwell@rackspace.com" target="_blank">adam.harwell@rackspace.com</a>> wrote:<u></u><u></u></p>
<div>
<div>
<p class="MsoNormal"><span style="color:red">Stephen, the way I understood your API proposal, I thought you could essentially combine L7Rules in an L7Policy, and have multiple L7Policies, implying that the L7Rules would use AND style combination, while the
L7Policies themselves would use OR combination (I think I said that right, almost seems like a tongue-twister while I'm running on pure caffeine). So, if I said:</span><u></u><u></u></p>
</div>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Well, my goal wasn't to create a whole DSL for this (or anything much resembling this) because:<u></u><u></u></p>
</div>
<div>
<ol start="1" type="1">
<li class="MsoNormal">
Real-world usage of the L7 stuff is generally pretty primitive. Most L7Policies will consist of 1 rule. Those that consist of more than one rule are almost always the sort that need a simple sort. This is based off the usage data collected here (which admittedly
only has Blue Box's data-- because apparently nobody else even offers L7 right now?) <a href="https://docs.google.com/spreadsheet/ccc?key=0Ar1FuMFYRhgadDVXZ25NM2NfbGtLTkR0TDFNUWJQUWc&usp=sharing" target="_blank">https://docs.google.com/spreadsheet/ccc?key=0Ar1FuMFYRhgadDVXZ25NM2NfbGtLTkR0TDFNUWJQUWc&usp=sharing</a><u></u><u></u></li>
<li class="MsoNormal">
I was trying to keep things as simple as possible to make it easier for load balancer vendors to support. (That is to say, I wouldn't expect all vendors to provide the same kind of functionality as HAProxy ACLs, for example.)<u></u><u></u></li>
</ol>
</div>
<div>
<p class="MsoNormal">Having said this, I think yours and Sam's clarification that different L7Policies can be used to effective "OR" conditions together makes sense, and therefore assuming all the Rules in a given policy are ANDed together makes sense.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">If we do this, it therefore also might make sense to expose other criteria on which L7Rules can be made, like HTTP method used for the request and whatnot.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Also, should we introduce a flag to say whether a given Rule's condition should be negated? (eg. "HTTP method is GET and URL is *not* "/api") This would get us closer to being able to use more sophisticated logic for L7 routing. <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Does anyone foresee the need to offer this kind of functionality?<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal"><span style="color:red"> * The policy { rules: [ rule1: match path REGEX ".*index.*", rule2: match path REGEX "hello/.*" ] } directs to Pool A</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="color:red"> * The policy { rules: [ rule1: match hostname EQ "<a href="http://mysite.com" target="_blank">mysite.com</a>" ] } directs to Pool B</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="color:red">then order would matter for the policies themselves. In this case, if they ran in the order I listed, it would match "<a href="http://mysite.com/hello/index.htm" target="_blank">mysite.com/hello/index.htm</a>" and
direct it to Pool A, while "<a href="http://mysite.com/hello/nope.htm" target="_blank">mysite.com/hello/nope.htm</a>" would not match BOTH rules in the first policy, and would be caught by the second policy, directing it to Pool B. If I had wanted the first
policy to use OR logic, I would have just specified two separate policies both pointing to Pool A:</span><u></u><u></u></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Clarification on this: There is an 'order' attribute to L7Policies. :) But again, if all the L7Rules in a given policy are ANDed together, then order doesn't matter within the rules that make up an L7Policy.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<div>
<p class="MsoNormal"><span style="color:red"> * The policy { rules: [ rule1: match path REGEX ".*index.*" ] } directs to Pool A</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="color:red"> * The policy { rules: [ rule1: match path REGEX "hello/.*" ] } directs to Pool A</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="color:red"> * The policy { rules: [ rule1: match hostname EQ "<a href="http://mysite.com" target="_blank">mysite.com</a>" ] } directs to Pool B</span><u></u><u></u></p>
</div>
</div>
<div>
<p class="MsoNormal"><span style="color:red">In that case, it would match "<a href="http://mysite.com/hello/nope.htm" target="_blank">mysite.com/hello/nope.htm</a>" on the second policy, still directing to Pool A.</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="color:red">In both cases, "<a href="http://mysite.com/hi/" target="_blank">mysite.com/hi/</a>" would only be caught by the last policy, directing to Pool B.</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="color:red">Maybe I was making some crazy jumps of logic, and that's not how you intended it? That said, even if that wasn't your intention, could it work that way? It seems like that allows a decent amount of options… :)</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="color:#888888"><u></u> <u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="color:red"> --Adam</span><span style="color:#888888"><u></u><u></u></span></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"> On Fri, May 2, 2014 at 4:59 AM, Samuel Bercovici <<a href="mailto:SamuelB@radware.com" target="_blank">SamuelB@radware.com</a>> wrote:<u></u><u></u></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal">Adam, you are correct to show why order matters in policies. <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">It is a good point to consider AND between rules. <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">If you really want to OR rules you can use different policies. <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Stephen, the need for order contradicts using content modification with the same API since for modification you would really want to evaluate the whole list. <u></u><u></u></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Hi Sam, I was a bit confused on this point since we don't see users often using both content modification and content switching in the same configuration. However, checking the haproxy manual regarding content modification rules:<u></u><u></u></p>
</div>
<div>
<pre style="word-wrap:break-word;white-space:pre-wrap"><span style="color:black"> - req* statements are applied after "block" statements, so that "block" is<u></u><u></u></span></pre>
<pre><span style="color:black"> always the first one, but before "use_backend" in order to permit rewriting<u></u><u></u></span></pre>
<pre><span style="color:black"> before switching.<u></u><u></u></span></pre>
</div>
<div>
<p class="MsoNormal">And this in the 'use_backend' definition having to do with switching based on L7 content:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<pre style="word-wrap:break-word;white-space:pre-wrap"><span style="color:black"><u></u> <u></u></span></pre>
<pre><span style="color:black">There may be as many "use_backend" rules as desired. All of these rules are<u></u><u></u></span></pre>
<pre><span style="color:black"> evaluated in their declaration order, and the first one which matches will<u></u><u></u></span></pre>
<pre><span style="color:black"> assign the backend.<u></u><u></u></span></pre>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">If this is true, this seem to imply that for HAProxy at least, order only really matters for policies which switch back-ends. That is to say, all the 'block' policies get processed first, followed by all the content modification policies,
followed by the switching policies. If you have two conflicting content modification policies, what actually happens isn't defined in the manual (though again-- why would anyone do this? Seems like a scenario in which users shoot themselves in the foot.)<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Given this, it may make sense to enforce this order in our model somehow, assuming other load balancer vendors would want to duplicate this behavior. Otherwise, users might be confused why (for example) a modification rule is applying a
header to a request when that policy comes after a switching policy in the overall list of policies. (One could do this by always inserting new 'block' policies in order before any 'modification' policies, and 'modification' policies before any 'redirect'
policies, and not allowing any API updates to move any rules in a way that would violate this order.) Or, we could make that 'order' attribute only allowed (and necessary) for 'redirect' policies-- the implication being no order applies to block or content
modification policies because they always get processed first.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">We could do this by splitting modification, block, and switching L7 policy types into their own separate objects (all of which would have similar 'rule' semantics), but I'm really not seeing a compelling reason to do so. (Again, I'm usually
in favor of introducing fewer new objects.)<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">What seems like the least confusing thing to do for the user? What are others' thoughts on this?<u></u><u></u></p>
</div>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Thanks,<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">Stephen<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<p class="MsoNormal">-- <br>
Stephen Balukoff <br>
Blue Box Group, LLC <br>
<a href="tel:%28800%29613-4305%20x807" target="_blank">(800)613-4305 x807</a> <u></u>
<u></u></p>
</div>
</div></div></div>
</div>
</div>
<br></div></div><div class="">_______________________________________________<br>
OpenStack-dev mailing list<br>
<a href="mailto:OpenStack-dev@lists.openstack.org" target="_blank">OpenStack-dev@lists.openstack.org</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
<br></div></blockquote></div><br><br clear="all"><div class=""><div><br></div>-- <br><span></span>Stephen Balukoff
<br>Blue Box Group, LLC
<br>(800)613-4305 x807
</div></div>
<br>_______________________________________________<br>
OpenStack-dev mailing list<br>
<a href="mailto:OpenStack-dev@lists.openstack.org">OpenStack-dev@lists.openstack.org</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
<br></blockquote></div><br></div>