It's not possible to set gateway_ip of Subnet to None

Bug #1226666 reported by mouadino
10
This bug affects 2 people
Affects Status Importance Assigned to Milestone
OpenStack Heat
Fix Released
Medium
Steve Baker

Bug Description

Hi,

In Neutron the "gateway_ip" field of a subnet is treaded differently depending of wether it's was set by user to None or not given which respectively mean don't set a gateway ip for gateway_ip=None and choose first available ip as gateway ip in the case where it's not given.

Now from Heat perspective if you set gateway_ip in the template to "null", heat will interpreter as if gateway_ip was set to empty string which will make Neutron raise an exception telling you that **'' is not a valid ip**, so AFAIK there is no way right now to create a subnet from Heat with no gateway ip.

Two possible fixes that i have in mind:

1- I tried to create a patch to enable using "null" as a value to gateway_ip and adding a new schema option AcceptNone (true or false) which IMHO sound to me like the correct way to handle this (and any upcoming cases Where None has a special meaning), but i found (the hard way) that Heat treat None and "not set" as the same thing and it rely heavily on this behavior which is very wrong IMHO.

2- Another fix which is specific to this case only (i.e. gateway ip) is to add a new resource Boolean property "no_gateway" and of course make sure that gateway_ip and this new property are mutually exclusive.

Thanks,

mouadino (mouadino)
description: updated
Revision history for this message
Steve Baker (steve-stevebaker) wrote :

Could you please describe exactly what should be passed to create_subnet for these cases?
- user specifies no gateway_ip
- user specifies 'null' for gateway_ip

Changed in heat:
status: New → Triaged
importance: Undecided → Medium
assignee: nobody → Steve Baker (steve-stevebaker)
mouadino (mouadino)
description: updated
Revision history for this message
mouadino (mouadino) wrote :

Well like i said and according the specification from here : https://wiki.openstack.org/wiki/Neutron/APIv2-specification and i quote:

... If the parameter for the gateway address, gateway_ip is not specified, then Quantum will allocate an address from the subnet's cidr for the subnet's gateway. In order to specify a subnet without a gateway, users should specify the value null for the gateway_ip attribute in the request body. ...

So to answer your question:

- user specifies no gateway_ip: The subnet **will** have a gateway ip chose by Neutron.
- user specifies 'null' for gateway_ip: The subnet will **not** have a gateway ip.

Cheers,

Revision history for this message
Steve Baker (steve-stevebaker) wrote :

yaml has 2 representations of null - both unquoted:
null
~

Have you tried these?

Revision history for this message
mouadino (mouadino) wrote :

Hi Steve,

Yes, i did try them.

Now if i set the gateway_ip property to null (or ~) as soon as this property is validated this code (https://github.com/openstack/heat/blob/master/heat/engine/properties.py#L557) will transform the value None to empty string, which then will be sent to the Neutron server and cause the request to fail with **'' is not a valid ip**.

Now in general and to extend of when i said that "Heat treat properties set to None and **Not set** as the same thing". Basically resource properties are represented in heat using the the Properties class Mapping (dict-like) and accessing the value of a property is done using __getitem__ (https://github.com/openstack/heat/blob/master/heat/engine/properties.py#L679) and as you can see what happen in that method is that accessing properties that wasn't set by the user in the template will return None (implicitly in the code) if this property doesn't have a default.

Now if you go now to the method responsible of preparing properties for Neutron for example (https://github.com/openstack/heat/blob/master/heat/engine/resources/neutron/neutron.py#L54) you will see that all properties set to None are ignored, the main point actually was to ignore all properties that wasn't set by the user (and doesn't have a default).

Another place where None is equivalent to not set is for example here (https://github.com/openstack/heat/blob/master/heat/engine/resources/instance.py#L305) and i can go on and on where this behavior is used, which IMHO is very wrong.

This is why my first try of fixing this by allowing None as a value to a property in general (and gateway_ip in particular) hit so many problems in the code.

Cheers,

Revision history for this message
Steve Baker (steve-stevebaker) wrote :

OK, I have enough info now to mark this as an RC1 bug, I'll take a look now.

Changed in heat:
milestone: none → havana-rc1
status: Triaged → In Progress
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to heat (master)

Fix proposed to branch: master
Review: https://review.openstack.org/48150

Revision history for this message
Steven Hardy (shardy) wrote :

> which IMHO is very wrong.

Well one thing to mention is that it seems only Neutron treats None arguments as significant. AFAIK almost all other openstack services treat a None argument the same as not passing the argument (because they are internally defaulted to None anyway)

So whilst I agree we should align with the required conventions to make Heat work with Neutron, I think "very wrong" is an unfair statement - arguably Neutron is doing something "very wrong" by treating None arguments as significant, as it represents a significant misaligment with the rest of OpenStack.

Revision history for this message
Steve Baker (steve-stevebaker) wrote :

> which IMHO is very wrong.

Just to elaborate on shardy's comment, this comes down to whether it is appropriate for a declarative orchestration template format to support the concept of "null" values; it is not clear to me that it is.

It could be argued that this neutron API has a design flaw and implementing a special-case workaround in heat is entirely appropriate.

Revision history for this message
mouadino (mouadino) wrote :

Hi Again.

That's one way of putting it, i was just curious about why the code was designed this way with the assumption that None is not a special value instead of doing the safest way which is to send whatever template creator set (with minimal checking) i.e. without mangling value neither rewriting the same logic of the remote api's in heat (Assumption free) because this way we let the remote (neutron, nova... ) api decide of wether a request is correct or no, but i may be just wrong which usually the case and probably there is a reason for this that i am not aware of right now :)

Thanks for the explanation BTW.

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to heat (master)

Reviewed: https://review.openstack.org/48150
Committed: http://github.com/openstack/heat/commit/cdd38962ebd4d0cbc6c57b7892260ee359a08798
Submitter: Jenkins
Branch: master

commit cdd38962ebd4d0cbc6c57b7892260ee359a08798
Author: Steve Baker <email address hidden>
Date: Wed Sep 25 09:55:16 2013 +1200

    For Subnet gateway_ip, pass None for empty string

    A None gateway_ip has special meaning for create_subnet but
    properties sanitise None values to be empty strings.

    With this change, the following properties should all result
    in gateway_ip=None being passed to create_subnet:
    gateway_ip: null
    gateway_ip: ~
    gateway_ip: ''

    Change-Id: I234542f7f2d7bddf7dee01f8a9c56c021b5f0c8c
    Closes-Bug: #1226666

Changed in heat:
status: In Progress → Fix Committed
Thierry Carrez (ttx)
Changed in heat:
status: Fix Committed → Fix Released
Thierry Carrez (ttx)
Changed in heat:
milestone: havana-rc1 → 2013.2
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.