neutron port-update allocates double fixed ip

Bug #1341096 reported by Xurong Yang
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
python-neutronclient
Expired
Medium
Unassigned

Bug Description

1.create a new port
707BE8C6:/home # neutron port-create 23d588e1-3861-4f6f-89ed-2b177e7b8b36 --name why_port
Created a new port:
+-----------------------+----------------------------------------------------------------------------------+
| Field | Value |
+-----------------------+----------------------------------------------------------------------------------+
| admin_state_up | True |
| allowed_address_pairs | |
| binding:capabilities | {"port_filter": false} |
| binding:host_id | |
| binding:profile | {} |
| binding:vif_details | {} |
| binding:vif_type | unbound |
| binding:vnic_type | normal |
| device_id | |
| device_owner | |
| fixed_ips | {"subnet_id": "7f5ae8f6-3882-4e58-bea7-1d76c5fa1bc1", "ip_address": "200.1.1.7"} |
| id | d91892d0-43cf-4929-ba58-92da2a723e62 |
| mac_address | fa:16:3e:0e:ac:b6 |
| mac_range_id | |
| name | why_port |
| network_id | 23d588e1-3861-4f6f-89ed-2b177e7b8b36 |
| status | DOWN |
| tenant_id | 4015230803414ea3b183d4f3a4e57a57 |
+-----------------------+----------------------------------------------------------------------------------+

2.update the port
707BE8C6:/home # neutron port-update d91892d0-43cf-4929-ba58-92da2a723e62 --fixed-ips type=dict {subnet_id=7f5ae8f6-3882-4e58-bea7-1d76c5fa1bc1,ip_address=200.1.1.5}
Updated port: d91892d0-43cf-4929-ba58-92da2a723e62

3. show the port
707BE8C6:/home # neutron port-show d91892d0-43cf-4929-ba58-92da2a723e62
+-----------------------+----------------------------------------------------------------------------------+
| Field | Value |
+-----------------------+----------------------------------------------------------------------------------+
| admin_state_up | True |
| allowed_address_pairs | |
| binding:capabilities | {"port_filter": false} |
| binding:host_id | |
| binding:profile | {} |
| binding:vif_details | {} |
| binding:vif_type | unbound |
| binding:vnic_type | normal |
| device_id | |
| device_owner | |
| extra_dhcp_opts | |
| fixed_ips | {"subnet_id": "7f5ae8f6-3882-4e58-bea7-1d76c5fa1bc1", "ip_address": "200.1.1.8"} |
| | {"subnet_id": "7f5ae8f6-3882-4e58-bea7-1d76c5fa1bc1", "ip_address": "200.1.1.5"} |
| id | d91892d0-43cf-4929-ba58-92da2a723e62 |
| mac_address | fa:16:3e:0e:ac:b6 |
| name | why_port |
| network_id | 23d588e1-3861-4f6f-89ed-2b177e7b8b36 |
| status | DOWN |
| tenant_id | 4015230803414ea3b183d4f3a4e57a57 |
+-----------------------+----------------------------------------------------------------------------------+

we can see, the port allocates two fixed ip "ip_address": "200.1.1.8" and "ip_address": "200.1.1.5"

Xurong Yang (idopra)
summary: - neutron port-update allocate double fix ip
+ neutron port-update allocates double fixed ip
Changed in neutron:
assignee: nobody → Xurong Yang (idopra)
Revision history for this message
yong sheng gong (gongysh) wrote :

It is weird.
the correct command is:
neutron port-update 55b72fe9-2c8b-4ada-b071-9e41b87454cd --fixed-ips type=dict list=true subnet_id=c256df04-550d-4ad2-87ec-3ec725799a07,ip_address=192.168.0.15

and the corresponding API is:
REQ: curl -i 'http://l7.0.ymy.ustack.in:9696/v2.0/ports/55b72fe9-2c8b-4ada-b071-9e41b87454cd.json' -X PUT -H "X-Auth-Token: 9206b92e6c5e49ca9472c60878e2258a" -H "Content-Type: application/json" -H "Accept: application/json" -H "User-Agent: python-neutronclient" -d '{"port": {"fixed_ips": [{"subnet_id": "c256df04-550d-4ad2-87ec-3ec725799a07", "ip_address": "192.168.0.15"}]}}'

Revision history for this message
Eugene Nikanorov (enikanorov) wrote :

I think it's expected behavior for the commands in bug description. You're actually adding another fixed ip, not updating existing one

Changed in neutron:
status: New → Incomplete
Revision history for this message
Kevin Benton (kevinbenton) wrote :

In case someone stumbles across this like I did.

What's happening in the first case is that the client parsing is getting confused and turns that into a list of two port updates, one specifying a subnet_id and one specifying an ip_address. The latter ends up giving you the IP you wanted and the first one allocates a random IP from the subnet.

There is no way to just add an IP with the CLI without specifying the old addresses. We don't have a concept of a patch list in the API as far as I can tell.

This seems to be a bug in the way the neutron client breaks down the first case into a list of two things.

For example, the following works to set three IP addresses:

neutron port-update 7521786b-6c7f-4385-b5e1-fb9565552696 --fixed-ips type=dict {ip_address=42.42.42.93,ip_address=42.42.42.92,ip_address=42.42.42.91}

Changed in neutron:
status: Incomplete → Confirmed
affects: neutron → python-neutronclient
Revision history for this message
Kevin Benton (kevinbenton) wrote :

If someone does want to fix this, the neutronclient should be updated to handle dict=true without list=true in a more sane way.

Changed in python-neutronclient:
assignee: Xurong Yang (idopra) → nobody
Kahou Lei (kahou82)
Changed in python-neutronclient:
assignee: nobody → Kahou Lei (kahou82)
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to python-neutronclient (master)

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

Changed in python-neutronclient:
assignee: Kahou Lei (kahou82) → yalei wang (yalei-wang)
status: Confirmed → In Progress
Revision history for this message
yalei wang (yalei-wang) wrote :

It's hard to deal with it in pythonneutron-client,

and maybe the another way is that add verification in neutron code, don't allocate new ip if there is a IP specified in list has the in the same subnet pool that also in the list.

Revision history for this message
Akihiro Motoki (amotoki) wrote :

I think it is a bug of parsing mechanism in neutronclient.

Honestly speaking, this kind of parsing is a technical debt in neutronclient. A mechinism of unknown arguments is useful for extension, but we received many bug reports around this. I am not sure we should keep this when we move to openstackclient. At now, I don't have a plan to propose to support unknown arguments for openstackclient and we should have explicit arguments for updateable fields.

Revision history for this message
yalei wang (yalei-wang) wrote :

yes, after think about it just now, if we remove the redundant one in neutron, neutron will lost the capability of allocating two fixed ips in a same subnet pool.

and amotoki, if you have any proposal about the new parsing mechanism for the 'unknown arguments', I want to join it.
Thanks

Revision history for this message
yong sheng gong (gongysh) wrote :

in original intent, we shuld not pass in metadata words such as {} or []. I don't know when we have this ability.
the right way to do this is:
neutron port-update 55b72fe9-2c8b-4ada-b071-9e41b87454cd --fixed-ips type=dict list=true subnet_id=c256df04-550d-4ad2-87ec-3ec725799a07,ip_address=192.168.0.15 subnet_id=c256df04-550d-4ad2-87ec-3ec725799a07,ip_address=192.168.0.16

Revision history for this message
Simon (xchenum) wrote :

I occasionally run into the same problem when launching VMs. My understanding is that nova uses neutron client to allocate one port on a network, but that action is sometimes perceived as failed on the client (nova) side. As a result, neutron client automatically retries. In reality, that port creation action actually succeeds on neutron server side, and therefore two ports are created.

Revision history for this message
Akihiro Motoki (amotoki) wrote :

I think the most straight-forward approach is to introduce a more command option like --fixed-ip.

In addition, extra argument parsing mechanism should be fixed, but it is too^100 complicated......

Revision history for this message
Akihiro Motoki (amotoki) wrote :

For #10, I don't think neutronclient does retry in POST operation.

neutronclient/v2_0/client.py

    def post(self, action, body=None, headers=None, params=None):
        # Do not retry POST requests to avoid the orphan objects problem.
        return self.do_request("POST", action, body=body,
                               headers=headers, params=params)

Revision history for this message
Akihiro Motoki (amotoki) wrote :

Regarding using {...}, it turns out there is nothing to do in neutronclient side.

{xxx,yyy,zzz} seems to be expanded to "xxx" "yyy" "zzz" by a shell.

I created the following shell script to check how command line parameters are parsed.

$ cat aaaa.sh
#!/bin/bash

i=0
while [ -n "$1" ]; do
  echo $i: $1
  shift
  i=`expr $i + 1`
done

and then I got the following:

$ ./aaaa.sh port-update p1 -- --fixed-ips type=dict subnet_id=024b4d12-4461-4e22-9b0b-e8dbbe782561,ip_address=10.0.0.12
0: port-update
1: p1
2: --
3: --fixed-ips
4: type=dict
5: subnet_id=024b4d12-4461-4e22-9b0b-e8dbbe782561,ip_address=10.0.0.12

It means if we run:

  neutron port-update d91892d0-43cf-4929-ba58-92da2a723e62 \
  --fixed-ips type=dict {subnet_id=7f5ae8f6-3882-4e58-bea7-1d76c5fa1bc1,ip_address=200.1.1.5}

neutron CLI receives

  neutron port-update d91892d0-43cf-4929-ba58-92da2a723e62 \
  --fixed-ips type=dict \
    subnet_id=7f5ae8f6-3882-4e58-bea7-1d76c5fa1bc1 \
    ip_address=200.1.1.5

In the current extra args parsing logic, it will be interpreted as a list with two elements: the one is subnet_id, the other is ip_address.

Revision history for this message
Akihiro Motoki (amotoki) wrote :

My current vote is to add an option --fixed-ip to port-update:

    --fixed-ip subnet_id=SUBNET,ip_address=IP_ADDR
                        Desired IP and/or subnet for this port:
                        subnet_id=<name_or_id>,ip_address=<ip>. You can repeat
                        this option.

Akihiro Motoki (amotoki)
Changed in python-neutronclient:
importance: Undecided → Medium
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Change abandoned on python-neutronclient (master)

Change abandoned by Armando Migliaccio (<email address hidden>) on branch: master
Review: https://review.openstack.org/202538
Reason: This review is > 4 weeks without comment, and failed Jenkins the last time it was checked. We are abandoning this for now. Feel free to reactivate the review by pressing the restore button and leaving a 'recheck' comment to get fresh test results.

Changed in python-neutronclient:
status: In Progress → Incomplete
assignee: yalei wang (yalei-wang) → nobody
Revision history for this message
Launchpad Janitor (janitor) wrote :

[Expired for python-neutronclient because there has been no activity for 60 days.]

Changed in python-neutronclient:
status: Incomplete → Expired
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.