Cannot get router.external_gateway_info if it is None

Bug #1527967 reported by Tang Chen
14
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack SDK
Fix Committed
Undecided
Tang Chen

Bug Description

Now, python-openstackclient (OSC) is using SDK to implement network functionalities. When implementing router related functionalitites, I found the following problem:

# openstack router create aaa [1]
# openstack router list --long [2]
'NoneType' object is not iterable

To reproduce this, please install the latest OSC.

The cause of this problem is: Using command [1] to create a router, no option is specified, then the router's external_gateway_info is None. But in SDK, openstack/network/v2/router.py,

class Router(resource.Resource):
    ......
    #: The ``network_id``, for the external gateway. *Type: dict*
    external_gateway_info = resource.prop('external_gateway_info', type=dict)
    ......

resource.prop() will restrict the type of external_gateway_info is dict, which has reimplemented __get__().

def __get__(self, instance, owner):
    ......
    if self.type and not isinstance(value, self.type):
            if issubclass(self.type, Resource):
                if isinstance(value, six.string_types):
                    value = self.type({self.type.id_attribute: value})
                else:
                    value = self.type(value)
    ......

It will fall into this block, and when doing type(None), here it is dict(None), it gives "'NoneType' object is not iterable" error.

The same thing won't happen to router.routes because if there is no routes in the router, router.routes is [], not None.

On OSC side, we can do nothing. So there are two solution:
1. Modify neutron to return a {}, not None, if the external_gateway_info is not set.
2. Modify SDK to check if an attr is None, do not do type() on it because self.type could be overwritten to any type.

Tang Chen (tangchen)
Changed in python-openstacksdk:
assignee: nobody → Tang Chen (tangchen)
Tang Chen (tangchen)
description: updated
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to python-openstacksdk (master)

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

Qiming Teng (tengqim)
Changed in python-openstacksdk:
status: New → Confirmed
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to python-openstacksdk (master)

Reviewed: https://review.openstack.org/259745
Committed: https://git.openstack.org/cgit/openstack/python-openstacksdk/commit/?id=2574e9585a55f2554ac10299f18be9fd9c0e852f
Submitter: Jenkins
Branch: master

commit 2574e9585a55f2554ac10299f18be9fd9c0e852f
Author: Tang Chen <email address hidden>
Date: Mon Dec 21 15:17:06 2015 +0800

    Return None when getting an attr which is None when using resource.prop()

    In resource.prop, __get__() will do self.type() on the value it got to
    construct an object of the type. But the type could be overwritten to any
    type. And the type may not be able to construct an object from None.

    For example, if self.type=dict, then self.type(None) will become dict(None),
    which will give "'NoneType' object is not iterable" error.

    This patch fix it by returning None if the attr's value is None.

    Change-Id: Ied255c52bc3f0d024ca70d1239956ba17430b13e
    Closed-bug: #1527967

Tang Chen (tangchen)
Changed in python-openstacksdk:
status: Confirmed → Fix Committed
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.