<div dir="ltr">Thanks for bringing up this use case Miguel - these are the use cases we need to make informed decisions.<div>Some answers inline.</div><div><br></div><div>Salvatore<br><div class="gmail_extra"><br><div class="gmail_quote">On 10 March 2015 at 07:53, Miguel Ángel Ajo <span dir="ltr"><<a href="mailto:majopela@redhat.com" target="_blank">majopela@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><span style="font-size:14px">Thanks to everybody working on this,</span></div><div><span style="font-size:14px"><br></span></div><div><span style="font-size:14px">Answers inline:</span></div>
<p style="color:#a0a0a8">On Tuesday, 10 de March de 2015 at 0:34, Tidwell, Ryan wrote:</p>
<blockquote type="cite" style="border-left-style:solid;border-width:1px;margin-left:0px;padding-left:10px">
<span><div><div>
<div>
<p style="margin:0px"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Thanks Salvatore. Here are my thoughts, hopefully there’s some merit to them:<u></u><u></u></span></p>
<p style="margin:0px"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p>
<p style="margin:0px"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">With implicit allocations, the thinking is that this is where a subnet is created in a backward-compatible way with no subnetpool_id and the subnets API’s continue
to work as they always have.<u></u><u></u></span></p>
<p style="margin:0px"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p>
<p style="margin:0px"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">In the case of a specific subnet allocation request (create-subnet passing a pool ID and specific CIDR), I would look in the pool’s available prefix list and
carve out a subnet from one of those prefixes and ask for it to be reserved for me. In that case I know the CIDR I’ll be getting up front. In such a case, I’m not sure I’d ever specify my gateway using notation like 0.0.0.1, even if I was allowed to. If
I know I’ll be getting <a href="http://10.10.10.0/24" target="_blank">10.10.10.0/24</a>, I can simply pass gateway_ip as 10.10.10.1 and be done with it. I see no added value in supporting that wildcard notation for a gateway on a specific subnet allocation.<u></u><u></u></span></p>
<p style="margin:0px"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p>
<p style="margin:0px"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">In the case of an “any” subnet allocation request (create-subnet passing a pool ID, but no specific CIDR), I’m already delegating responsibility for addressing
my subnet to Neutron. As such, it seems reasonable to not have strong opinions about details like gateway_ip when making the request to create a subnet in this manner.<u></u><u></u></span></p>
<p style="margin:0px"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p>
<p style="margin:0px"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">To me, this all points to not supporting wildcards for gateway_ip and allocation_pools on subnet create (even though it found its way into the spec). My opinion
(which I think lines up with yours) is that on an any request it makes sense to let the pool fill in allocation_pools and gateway_ip when requesting an “any” allocation from a subnet pool. When creating a specific subnet from a pool, gateway IP and allocation
pools could still be passed explicitly by the user.<u></u><u></u></span></p>
<p style="margin:0px"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p>
<p style="margin:0px"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">-Ryan<u></u><u></u></span></p>
<p style="margin:0px"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p>
<div style="border:none;border-top:solid #b5c4df 1.0pt;padding:3.0pt 0in 0in 0in">
<p style="margin:0px"><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""> Salvatore Orlando [<a href="mailto:sorlando@nicira.com" target="_blank">mailto:sorlando@nicira.com</a>]
<br>
<b>Sent:</b> Monday, March 09, 2015 6:06 AM<br>
<b>To:</b> OpenStack Development Mailing List<br>
<b>Subject:</b> [openstack-dev] [api][neutron] Best API for generating subnets from pool<u></u><u></u></span></p>
</div>
<p style="margin:0px"><u></u> <u></u></p>
<div>
<p style="margin:0px">Greetings!<u></u><u></u></p>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<p style="margin:0px">Neutron is adding a new concept of "subnet pool". To put it simply, it is a collection of IP prefixes from which subnets can be allocated. In this way a user does not have to specify a full CIDR, but simply a desired prefix length, and
then let the pool generate a CIDR from its prefixes. The full spec is available at [1], whereas two patches are up for review at [2] (CRUD) and [3] (integration between subnets and subnet pools).<u></u><u></u></p>
</div>
<div>
<p style="margin:0px">While [2] is quite straightforward, I must admit I am not really sure that the current approach chosen for generating subnets from a pool might be the best one, and I'm therefore seeking your advice on this matter.<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<p style="margin:0px">A subnet can be created with or without a pool.<u></u><u></u></p>
</div>
<div>
<p style="margin:0px">Without a pool the user will pass the desired cidr:<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<p style="margin:0px">POST /v2.0/subnets<u></u><u></u></p>
</div>
<div>
<p style="margin:0px">{'network_id': 'meh',<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"> 'cidr': '<a href="http://192.168.0.0/24" target="_blank">192.168.0.0/24</a>'}<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<p style="margin:0px">Instead with a pool the user will pass pool id and desired prefix lenght:<u></u><u></u></p>
</div>
<div>
<p style="margin:0px">POST /v2.0/subnets<u></u><u></u></p>
</div>
<div>
<p style="margin:0px">{'network_id': 'meh',<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"> 'prefix_len': 24,<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"> 'pool_id': 'some_pool'}<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<p style="margin:0px">The response to the previous call would populate the subnet cidr.<u></u><u></u></p>
</div>
<div>
<p style="margin:0px">So far it looks quite good. Prefix_len is a bit of duplicated information, but that's tolerable.<u></u><u></u></p>
</div>
<div>
<p style="margin:0px">It gets a bit awkward when the user specifies also attributes such as desired gateway ip or allocation pools, as they have to be specified in a "cidr-agnostic" way. For instance:<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<div>
<p style="margin:0px">POST /v2.0/subnets<u></u><u></u></p>
</div>
<div>
<p style="margin:0px">{'network_id': 'meh',<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"> 'gateway_ip': '0.0.0.1',<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"> 'prefix_len': 24,<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"> 'pool_id': 'some_pool'}<u></u><u></u></p>
</div>
</div>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<p style="margin:0px">would indicate that the user wishes to use the first address in the range as the gateway IP, and the API would return something like this:<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<div>
<div>
<p style="margin:0px">POST /v2.0/subnets<u></u><u></u></p>
</div>
<div>
<p style="margin:0px">{'network_id': 'meh',<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"> 'cidr': '<a href="http://10.10.10.0/24" target="_blank">10.10.10.0/24</a>'<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"> 'gateway_ip': '10.10.10.1',<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"> 'prefix_len': 24,<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"> 'pool_id': 'some_pool'}<u></u><u></u></p>
</div>
</div>
</div>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<p style="margin:0px">The problem with this approach is, in my opinion, that attributes such as gateway_ip are used with different semantics in requests and responses; this might also need users to write client applications expecting the values in the response
might differ from those in the request.<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<p style="margin:0px">I have been considering alternatives, but could not find any that I would regard as winner.<u></u><u></u></p>
</div>
<div>
<p style="margin:0px">I therefore have some questions for the neutron community and the API working group:<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<p style="margin:0px">1) (this is more for neutron people) Is there a real use case for requesting specific gateway IPs and allocation pools when allocating from a pool? If not, maybe we should let the pool set a default gateway IP and allocation pools. The
user can then update them with another call. Another option would be to provide "subnet templates" from which a user can choose. For instance one template could have the gateway as first IP, and then a single pool for the rest of the CIDR.</p></div></div></div></div></div></span></blockquote><div> </div><div><span style="font-size:14px">a) What if the subnet pools go into an external network, so, the gateway is predefined and external, we may want to be able to specify it, we could assume the convention </span><span style="font-size:14px">that we’re going to expect the gateway to be on the first IP of the subnet...</span></div></blockquote><div><br></div><div>One the one hand we might argue that since an external network is controlled by the operator you might not want need pools at all. On the other hand, I'd say that the rationale for using pool makes sense for external networks as well, especially for pure v6 deployments. This convention might make sense at first glance, but I think it won't apply in the majority of real cases. This would be for the reason you list below, for instance. Moreover, operators might want to restrict IP usage using allocation pools, since some addresses might be reserved for other uses.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div> </div><div><span style="font-size:14px">b) Thinking of an on-link route, the gateway could be a fixed IP (regardless of the subnet CIDR), this case is not fully supported now in neutron l3-agent now, but I plan to add it on the next cycle [5] (sorry, I’ve been a bit slow at this), it’s a very neat standard where you can route RIPE blocks as subnets to a physical net without spending any extra IP for the router.</span></div></blockquote><div><br></div><div>This is a valid use case I guess. In that case I would provide a "request" to the pool where the gateway IP is fixed, but the pool is left free to pick any available CIDR matching the desired prefix length, <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><span style="font-size:14px"><br></span></div><div><span style="font-size:14px">And, how would we cover b?, </span></div><div><span style="font-size:14px"><br></span></div><div><span style="font-size:14px">may be having gateway_ip i) “mask:0.0.0.1” or ii) gateway_ip “11.22.33.44” ? </span></div></blockquote><div><br></div><div>I'm the last person who should comment on API aesthetics, but this looks quite ugly.</div><div>It might be argued that is functional but the semantics of 0.0.0.1 are definitely not those of a netmask. Further, this requires the management layer to do some extra parsing on the value of the gateway_ip attribute, complicating validation.</div><div>Anyway, the two issues listed above are not serious. What I do not like about this solution is that the semantics of gateway_ip differ between request and response.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><br></div><div><span style="font-size:14px">or considering the first octect=0 to make a mask?</span></div><div><span style="font-size:14px"><br></span></div><div><span style="font-size:14px">If we step over the REST standard, we could use gateway_ip_mask vs gateway_ip,</span></div></blockquote><div><br></div><div>I think this would be slightly less ugly, but still kind of ugly. </div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><span style="font-size:14px"><br></span></div><div><span style="font-size:14px">Another option for “i” / "ii" could be to include a fixed gateway IP / mask in the subnet CIDR, so when user doesn’t specify, it’s automatically picked up.</span></div></blockquote><div><br></div><div>How would the request look like in this case?</div><div>Consider Ryan's opinion, the use case you're exposing here, and my personal opinions, I believe we'd better do without "wildcarding" for gateway_ip and allocation_pools.</div><div>If one does not specify they're generated according a predefined rule (as it is today, btw). Otherwise one has to specify them explicitly. </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><br></div><blockquote type="cite" style="border-left-style:solid;border-width:1px;margin-left:0px;padding-left:10px"><span>
<div>
<p style="margin:0px">2) Is the action of creating a subnet from a pool better realized as a different way of creating a subnet, or should there be some sort of "pool action"? Eg.:<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<p style="margin:0px">POST /subnet_pools/my_pool_id/subnet<u></u><u></u></p>
</div>
<div>
<p style="margin:0px">{'prefix_len': 24}<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<p style="margin:0px">which would return a subnet response like this (note prefix_len might not be needed in this case)<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<p style="margin:0px">{'id': 'meh',<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"> 'cidr': '<a href="http://192.168.0.0/24" target="_blank">192.168.0.0/24</a>',<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"> 'gateway_ip': '192.168.0.1',<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"> 'pool_id': 'my_pool_id'}<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<p style="margin:0px">I am generally not a big fan of RESTful actions. But in this case the semantics of the API operation are that of a subnet creation from within a pool, so that might be ok.<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<p style="margin:0px">3) Would it be possible to consider putting information about how to generate a subnet from a pool in the subnet request body as follows?<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<p style="margin:0px">POST /v2.0/subnets<u></u><u></u></p>
</div>
<div>
<p style="margin:0px">{<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"> 'pool_info':<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"> {'pool_id': my_pool_id,<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"> 'prefix_len': 24}<u></u><u></u></p>
</div>
<div>
<p style="margin:0px">}<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<p style="margin:0px">This would return a response like the previous.<u></u><u></u></p>
</div>
<div>
<p style="margin:0px">This approach is in theory simple, but composite attributes proved to a difficult beast already - for instance you can look at external_gateway_info in the router definition [4]<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"><u></u><u></u></p></div></span></blockquote><div><span style="font-size:14px">Options 1, 2 or 3 make sense to me, but, considering your complexity argument I believe 1 or 2 are more reasonable.</span></div></blockquote><div><br></div><div>I am just collecting opinions here. I'm reconsidering option 3 as the complexity might not exist in this case since the attributes pertaining to the pool are immutable throughout the subnet lifecycle.<br></div><div>The other aspect to consider is however whether structured attributes are acceptable from an API style perspective.</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div> </div><blockquote type="cite" style="border-left-style:solid;border-width:1px;margin-left:0px;padding-left:10px"><span><div><p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<p style="margin:0px">Thanks for your time and thanks in advance for your feedback.<u></u><u></u></p>
</div>
<div>
<p style="margin:0px">Salvatore<u></u><u></u></p>
</div>
<div>
<p style="margin:0px"><u></u> <u></u></p>
</div>
<div>
<p style="margin:0px">[1] <a href="http://specs.openstack.org/openstack/neutron-specs/specs/kilo/subnet-allocation.html" target="_blank">http://specs.openstack.org/openstack/neutron-specs/specs/kilo/subnet-allocation.html</a><u></u><u></u></p>
</div>
<div>
<p style="margin:0px">[2] <a href="https://review.openstack.org/#/c/148698/" target="_blank">https://review.openstack.org/#/c/148698/</a><u></u><u></u></p>
</div>
<div>
<p style="margin:0px">[3] <a href="https://review.openstack.org/#/c/157597/21/neutron/api/v2/attributes.py" target="_blank">https://review.openstack.org/#/c/157597/21/neutron/api/v2/attributes.py</a><u></u><u></u></p>
</div>
<div>
<p style="margin:0px">[4] <a href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/extensions/l3.py#n106" target="_blank">http://git.openstack.org/cgit/openstack/neutron/tree/neutron/extensions/l3.py#n106</a></p></div></span></blockquote><div><br></div><div><span style="font-size:14px">[5] </span><a href="https://bugs.launchpad.net/neutron/+bug/1398768" target="_blank">https://bugs.launchpad.net/neutron/+bug/1398768</a> </div><blockquote type="cite" style="border-left-style:solid;border-width:1px;margin-left:0px;padding-left:10px"><span><div><div><div><div><div><p style="margin:0px"><u></u><u></u></p>
</div>
</div>
</div>
</div><div><div>__________________________________________________________________________</div><div>OpenStack Development Mailing List (not for usage questions)</div><div>Unsubscribe: <a href="mailto:OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" target="_blank">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a></div><div><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></div></div></div></span>
</blockquote>
<div>
<br>
</div>
<br>__________________________________________________________________________<br>
OpenStack Development Mailing List (not for usage questions)<br>
Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" target="_blank">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</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></div></div>