Bug 1706222

Summary: Neutron API - problem parsing semi-colon
Product: Red Hat OpenStack Reporter: Andreas Karis <akaris>
Component: openstack-neutronAssignee: Nate Johnston <njohnston>
Status: CLOSED UPSTREAM QA Contact: Eran Kuris <ekuris>
Severity: medium Docs Contact:
Priority: medium    
Version: 16.0 (Train)CC: amuller, bcafarel, brent.becker, chrisw, njohnston, scohen, twilson
Target Milestone: zstreamKeywords: Reopened, Triaged, ZStream
Target Release: 15.0 (Stein)   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of:
: 1854443 (view as bug list) Environment:
Last Closed: 2020-07-15 11:36:28 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Andreas Karis 2019-05-03 20:19:33 UTC
Description of problem:

In the current state when the GET is sent with “Accept: application/json; charset=utf-8”, we receive the following Neutron error:


$ curl -s -H "Accept: application/json; charset=utf-8" -H "X-Auth-Token: $OS_TOKEN" "http://10.240.50.25:9696/v2.0/networks" | python -mjson.tool

{
    "NeutronError": {

        "detail": "",

        "message": "The server could not comply with the request since it is either malformed or otherwise incorrect.",

        "type": "HTTPNotAcceptable"

    }

}

This worked on previous releases (ie. 12 & 13)

The semi colon (;) seems to be cause the issue.  If this is changed to a comma it works or if it is setup in different headers it works.


Version-Release number of selected component (if applicable):


How reproducible:


Steps to Reproduce:
1.
2.
3.

Actual results:


Expected results:


Additional info:



-------------------------------------------------------------------

OSP 14:

    curl -s -H "Accept: application/json; charset=utf-8" -H "X-Auth-Token: gAAAAABczJ0_kURQo99ZZyXKP0fFNPXImvkkhRx4sVgnFtPGAABmWJbh6z5YezJhNwWPgJoU3LWYDzmxEmlctKXxpUNgx3x-jNejCjh9HKnRyICd0xSTipRMoy5ZkeLhJVIeQFKMqoP05N9xmMkQL5wzGptLvNkpBUVA7QYnk4NtOKbJDAdH42g" "http://192.168.100.1:9696/v2.0/networks" | python -mjson.tool
    {
        "NeutronError": {
            "detail": "",
            "message": "The server could not comply with the request since it is either malformed or otherwise incorrect.",
            "type": "HTTPNotAcceptable"
        }
    }
    (undercloud) [root@director14 stack]#
     
     
     
    ##neutron net-list
     
     
     
    (undercloud) [root@director14 stack]# curl -g -i -X GET http://192.168.100.1:9696/v2.0/networks -H "Accept: application/json" -H "User-Agent: python-neutronclient" -H "X-Auth-Token: gAAAAABczJ0_kURQo99ZZyXKP0fFNPXImvkkhRx4sVgnFtPGAABmWJbh6z5YezJhNwWPgJoU3LWYDzmxEmlctKXxpUNgx3x-jNejCjh9HKnRyICd0xSTipRMoy5ZkeLhJVIeQFKMqoP05N9xmMkQL5wzGptLvNkpBUVA7QYnk4NtOKbJDAdH42g"
     
     
    HTTP/1.1 200 OK
    Content-Type: application/json
    Content-Length: 1372
    X-Openstack-Request-Id: req-fc2f9984-3489-4c80-a538-8ab37e210fe6
    Date: Fri, 03 May 2019 20:02:18 GMT
     
    {"networks":[{"provider:physical_network":"ctlplane","ipv6_address_scope":null,"revision_number":15,"port_security_enabled":true,"mtu":1500,"id":"86b7f7a5-e341-4fa6-af7a-503b160e6b5e","router:external":false,"availability_zone_hints":[],"availability_zones":["nova"],"ipv4_address_scope":null,"shared":false,"project_id":"f276d14534a4409a82f31fd8064a5673","l2_adjacency":true,"status":"ACTIVE","subnets":["7678978f-ea4d-4812-8da9-2b6919e5d7e6"],"description":"","tags":[],"updated_at":"2019-04-02T19:49:33Z","provider:segmentation_id":null,"name":"ctlplane","admin_state_up":true,"tenant_id":"f276d14534a4409a82f31fd8064a5673","created_at":"2019-03-29T14:54:53Z","provider:network_type":"flat"},{"provider:physical_network":"external","ipv6_address_scope":null,"revision_number":2,"port_security_enabled":true,"mtu":1500,"id":"9c745fd9-2fda-43d4-b01e-2e18f5811f15","router:external":false,"availability_zone_hints":[],"availability_zones":[],"ipv4_address_scope":null,"shared":false,"project_id":"f276d14534a4409a82f31fd8064a5673","l2_adjacency":true,"status":"ACTIVE","subnets":["e131a1be-5ab2-41b6-816f-80b540680f02"],"description":"","tags":[],"updated_at":"2019-04-04T16:06:46Z","provider:segmentation_id":null,"name":"external","admin_state_up":false,"tenant_id":"f276d14534a4409a82f31fd8064a5673","created_at":"2019-04-04T16:06:42Z","provider:network_type":"flat"}]}(undercloud) [root@director14 stack]#
    (undercloud) [root@director14 stack]#
    (undercloud) [root@director14 stack]#

-------------------------------------------------------------------

OSP 13: 

(undercloud) [stack@undercloud-r430 ~]$ curl -s -H "Accept: application/json; charset=utf-8" -H "X-Auth-Token: $OS_TOKEN" "http://192.168.24.1:9696/v2.0/networks" | python -mjson.tool
{
    "networks": [
        {
            "admin_state_up": true,
            "availability_zone_hints": [],
            "availability_zones": [
                "nova"
            ],
            "created_at": "2019-04-10T21:29:55Z",
            "description": "",
            "id": "a7259fe4-d842-486f-a3c5-c37897d6f358",
            "ipv4_address_scope": null,
            "ipv6_address_scope": null,
            "l2_adjacency": true,
            "mtu": 1500,
            "name": "ctlplane",
            "port_security_enabled": true,
            "project_id": "98a410ea1ea6462c98d111c2f8e4e73c",
            "provider:network_type": "flat",
            "provider:physical_network": "ctlplane",
            "provider:segmentation_id": null,
            "revision_number": 8,
            "router:external": false,
            "shared": false,
            "status": "ACTIVE",
            "subnets": [
                "c168cbf6-0906-479d-9186-4b6d44dbc856"
            ],
            "tags": [],
            "tenant_id": "98a410ea1ea6462c98d111c2f8e4e73c",
            "updated_at": "2019-04-10T21:39:13Z"
        }
    ]
}

Comment 6 Nate Johnston 2019-05-07 17:44:34 UTC
I was able to reproduce this on my own setup.  I believe that there are some changes with how Accept header handling is managed, in a Neutron dependency library called WebOb [1].  Neutron uses Pecan which uses WebOb, and Pecan already had to adapt to the changes in Accept header handling [2].  But even using a version of Neutron that has the fix, I still see the issue you describe.

I will note that the error seen in the Neutron server.log when this happens tells me that it is not handling parsing the string correctly.  

% curl -s -H "Accept: application/json;charset=utf-8" -H "X-Auth-Token: gAAAAABc0cHuHmvz0YFb0uuPv5ADSxi5Vda_pi-Z8KwIeqjfIu2MtjBLA6NaoRorAjS8HrPzbmrby0K28uajyYj5GiKIJcMCDDYRhN1Hs_2Bfb-4ORbBBj2_X7o2gnybxaBak-TVdrQWdWsHyYnBfTq5CCT-K_mCwPd4KgQfUtoM6_4IUzDPKnQ" "http://192.168.24.1:9696/v2.0/networks" 
{
    "NeutronError": {
        "detail": "",
        "message": "The server could not comply with the request since it is either malformed or otherwise incorrect.",
        "type": "HTTPNotAcceptable"
    }
}

The logs: 

2019-05-07 14:47:47.341 77 DEBUG neutron.wsgi [-] (77) accepted ('172.17.1.31', 36530) server /usr/lib/python2.7/site-packages/eventlet/wsgi.py:883
2019-05-07 14:47:47.345 77 ERROR pecan.core [req-58872c3a-e917-4e3e-82cf-d3dbd931b6b2 21ec7039924a46e9aec6a9fa490da066 fb53e9370fb0427fadb680238d90987a - default default] Controller 'index' defined does not support content_type 'None'. Supported type(s): ['application/json']
2019-05-07 14:47:47.346 77 INFO neutron.pecan_wsgi.hooks.translation [req-58872c3a-e917-4e3e-82cf-d3dbd931b6b2 21ec7039924a46e9aec6a9fa490da066 fb53e9370fb0427fadb680238d90987a - default default] GET failed (client error): The server could not comply with the request since it is either malformed or otherwise incorrect.
2019-05-07 14:47:47.347 77 INFO neutron.wsgi [req-58872c3a-e917-4e3e-82cf-d3dbd931b6b2 21ec7039924a46e9aec6a9fa490da066 fb53e9370fb0427fadb680238d90987a - default default] 172.17.1.31 "GET /v2.0/networks HTTP/1.1" status: 406  len: 360 time: 0.0057609

Comment 7 Nate Johnston 2019-05-07 18:00:17 UTC
It gets weirder.  This is only a problem for certain methods.

/v2.0/address-scopes is fine:

[stack@undercloud-0 ~]$ curl -s -H "Accept: application/json;charset=utf-8" -H "X-Auth-Token: gAAAAABc0cHuHmvz0YFb0uuPv5ADSxi5Vda_pi-Z8KwIeqjfIu2MtjBLA6NaoRorAjS8HrPzbmrby0K28uajyYj5GiKIJcMCDDYRhN1Hs_2Bfb-4ORbBBj2_X7o2gnybxaBak-TVdrQWdWsHyYnBfTq5CCT-K_mCwPd4KgQfUtoM6_4IUzDPKnQ" "http://192.168.24.1:9696/v2.0/address-scopes" | python -mjson.tool
{
    "address_scopes": []
}

/v2.0/ports is no good:

[stack@undercloud-0 ~]$ curl -s -H "Accept: application/json;charset=utf-8" -H "X-Auth-Token: gAAAAABc0cHuHmvz0YFb0uuPv5ADSxi5Vda_pi-Z8KwIeqjfIu2MtjBLA6NaoRorAjS8HrPzbmrby0K28uajyYj5GiKIJcMCDDYRhN1Hs_2Bfb-4ORbBBj2_X7o2gnybxaBak-TVdrQWdWsHyYnBfTq5CCT-K_mCwPd4KgQfUtoM6_4IUzDPKnQ" "http://192.168.24.1:9696/v2.0/ports" | python -mjson.tool
{
    "NeutronError": {
        "detail": "",
        "message": "The server could not comply with the request since it is either malformed or otherwise incorrect.",
        "type": "HTTPNotAcceptable"
    }
}

/v2.0/flavors is fine:

[stack@undercloud-0 ~]$ curl -s -H "Accept: application/json;charset=utf-8" -H "X-Auth-Token: gAAAAABc0cHuHmvz0YFb0uuPv5ADSxi5Vda_pi-Z8KwIeqjfIu2MtjBLA6NaoRorAjS8HrPzbmrby0K28uajyYj5GiKIJcMCDDYRhN1Hs_2Bfb-4ORbBBj2_X7o2gnybxaBak-TVdrQWdWsHyYnBfTq5CCT-K_mCwPd4KgQfUtoM6_4IUzDPKnQ" "http://192.168.24.1:9696/v2.0/flavors" | python -mjson.tool
{
    "flavors": []
}

/v2.0/routers is fine:

[stack@undercloud-0 ~]$ curl -s -H "Accept: application/json;charset=utf-8" -H "X-Auth-Token: gAAAAABc0cHuHmvz0YFb0uuPv5ADSxi5Vda_pi-Z8KwIeqjfIu2MtjBLA6NaoRorAjS8HrPzbmrby0K28uajyYj5GiKIJcMCDDYRhN1Hs_2Bfb-4ORbBBj2_X7o2gnybxaBak-TVdrQWdWsHyYnBfTq5CCT-K_mCwPd4KgQfUtoM6_4IUzDPKnQ" "http://192.168.24.1:9696/v2.0/routers" | python -mjson.tool
{
    "routers": []
}

/v2.0/subnets is a problem again:

[stack@undercloud-0 ~]$ curl -s -H "Accept: application/json;charset=utf-8" -H "X-Auth-Token: gAAAAABc0cHuHmvz0YFb0uuPv5ADSxi5Vda_pi-Z8KwIeqjfIu2MtjBLA6NaoRorAjS8HrPzbmrby0K28uajyYj5GiKIJcMCDDYRhN1Hs_2Bfb-4ORbBBj2_X7o2gnybxaBak-TVdrQWdWsHyYnBfTq5CCT-K_mCwPd4KgQfUtoM6_4IUzDPKnQ" "http://192.168.24.1:9696/v2.0/subnets" | python -mjson.tool
{
    "NeutronError": {
        "detail": "",
        "message": "The server could not comply with the request since it is either malformed or otherwise incorrect.",
        "type": "HTTPNotAcceptable"
    }
}

Comment 8 Nate Johnston 2019-05-07 19:53:47 UTC
And it's definitely a combination of "charset=UTF-8" and those methods.  A semicolon followed by "hamburger" is fine.

[stack@undercloud-0 ~]$ curl -s -H "Accept: application/json;hamburger" -H "X-Auth-Token: gAAAAABc0cHuHmvz0YFb0uuPv5ADSxi5Vda_pi-Z8KwIeqjfIu2MtjBLA6NaoRorAjS8HrPzbmrby0K28uajyYj5GiKIJcMCDDYRhN1Hs_2Bfb-4ORbBBj2_X7o2gnybxaBak-TVdrQWdWsHyYnBfTq5CCT-K_mCwPd4KgQfUtoM6_4IUzDPKnQ" "http://192.168.24.1:9696/v2.0/subnets" | python -mjson.tool | head -5
{
    "subnets": [
        {
            "allocation_pools": [
                {

Using "charset" on it's own is fine:

[stack@undercloud-0 ~]$ curl -s -H "Accept: application/json;charset" -H "X-Auth-Token: gAAAAABc0cHuHmvz0YFb0uuPv5ADSxi5Vda_pi-Z8KwIeqjfIu2MtjBLA6NaoRorAjS8HrPzbmrby0K28uajyYj5GiKIJcMCDDYRhN1Hs_2Bfb-4ORbBBj2_X7o2gnybxaBak-TVdrQWdWsHyYnBfTq5CCT-K_mCwPd4KgQfUtoM6_4IUzDPKnQ" "http://192.168.24.1:9696/v2.0/subnets" | python -mjson.tool | head -5
{
    "subnets": [
        {
            "allocation_pools": [
                {

Using "hamburger=food" is an error:

[stack@undercloud-0 ~]$ curl -s -H "Accept: application/json;hamburger=food" -H "X-Auth-Token: gAAAAABc0cHuHmvz0YFb0uuPv5ADSxi5Vda_pi-Z8KwIeqjfIu2MtjBLA6NaoRorAjS8HrPzbmrby0K28uajyYj5GiKIJcMCDDYRhN1Hs_2Bfb-4ORbBBj2_X7o2gnybxaBak-TVdrQWdWsHyYnBfTq5CCT-K_mCwPd4KgQfUtoM6_4IUzDPKnQ" "http://192.168.24.1:9696/v2.0/subnets" | python -mjson.tool | head -5
{
    "NeutronError": {
        "detail": "",
        "message": "The server could not comply with the request since it is either malformed or otherwise incorrect.",
        "type": "HTTPNotAcceptable"

And of course, the original request "charset=UTF-8" is an error:

[stack@undercloud-0 ~]$ curl -s -H "Accept: application/json;charset=UTF-8" -H "X-Auth-Token: gAAAAABc0cHuHmvz0YFb0uuPv5ADSxi5Vda_pi-Z8KwIeqjfIu2MtjBLA6NaoRorAjS8HrPzbmrby0K28uajyYj5GiKIJcMCDDYRhN1Hs_2Bfb-4ORbBBj2_X7o2gnybxaBak-TVdrQWdWsHyYnBfTq5CCT-K_mCwPd4KgQfUtoM6_4IUzDPKnQ" "http://192.168.24.1:9696/v2.0/subnets" | python -mjson.tool | head -5
{
    "NeutronError": {
        "detail": "",
        "message": "The server could not comply with the request since it is either malformed or otherwise incorrect.",
        "type": "HTTPNotAcceptable"

Interestingly enough, reversing the order and saying "charset=UTF-8;application/json" works just fine:

[stack@undercloud-0 ~]$ curl -s -H "Accept: charset=UTF-8;application/json" -H "X-Auth-Token: gAAAAABc0cHuHmvz0YFb0uuPv5ADSxi5Vda_pi-Z8KwIeqjfIu2MtjBLA6NaoRorAjS8HrPzbmrby0K28uajyYj5GiKIJcMCDDYRhN1Hs_2Bfb-4ORbBBj2_X7o2gnybxaBak-TVdrQWdWsHyYnBfTq5CCT-K_mCwPd4KgQfUtoM6_4IUzDPKnQ" "http://192.168.24.1:9696/v2.0/subnets" | python -mjson.tool | head -5
{
    "subnets": [
        {
            "allocation_pools": [
                {

Based on this I think that we can say that:

1. The issue only occurs for certain methods (/v2.0/subnets, /v2.0/networks) but not others.
2. The issue only occurs when there is a semicolon with an equals sign after it.

Comment 10 Bernard Cafarelli 2019-05-14 12:11:30 UTC
I also started to look into this issue, comparing working and non-working requests, the requests going through neutron.api.v2.resource (flavor, router) work, while the failing ones (nets/subnets) do not use that.

Comment 11 Bernard Cafarelli 2019-05-14 16:21:00 UTC
OK so a few additional comments.

This is only happening for "base" resources not handled by neutron.api.v2 and wsgi.request: the list seems to be limited to ports,networks and subnets
This was broken by WebOb >= 1.8.0, which changed a lot in Accept handling [0]. 13 uses 1.7.x, and as a reproducer here, it will break if updating WebOb to 1.8
Other resources are not affected as there is additional processing done on neutron side for them (including the content type)

This can be reproduced on devstack master, I filled a launchpad bug [1]

Short-term, the workaround is (if possible in tool) to use a separate header for charset:
$ curl -s -H "Accept: application/json" -H "Accept-Charset: UTF-8" -H "X-Auth-Token: $OS_TOKEN" "http://localhost:9696/v2.0/ports" | python -mjson.tool
{
    "ports": []
}


[0] https://github.com/Pylons/webob/blob/master/docs/whatsnew-1.8.txt#L24
[1] https://bugs.launchpad.net/neutron/+bug/1829042

Comment 13 Andreas Karis 2019-05-15 21:03:07 UTC
 #26 (Customer) Make PrivatePrivate Helps Resolution? 0
Created By: Brent Becker  (5/15/2019 4:26 PM)

We do know about this working around, but unfortunately the request is being sent by a Vendor supplied application so we are unable to make this change.  Is there any sort of timeline for a fix?

Comment 23 Andreas Karis 2020-01-13 17:37:39 UTC
Hi,

I'm just curious if this is still being worked upon?

Thanks,

Andreas

Comment 24 Nate Johnston 2020-01-13 21:10:30 UTC
Yes, this is still on the docket, although it is below a number of lower priority items.

Comment 31 Nate Johnston 2020-05-07 18:15:17 UTC
Since the upstream bug covers this issue in detail, I am going to mark this CLOSED UPSTREAM and we can track progress there.  I hope to get some upstream experts to look at this, people that have different kinds of expertise than is available in-house.

Comment 32 Andreas Karis 2020-07-13 10:58:16 UTC
Hi,

RHOSP 16 is still affected:

(overcloud) [stack@undercloud-0 ~]$ cat /etc/rhosp-release 
Red Hat OpenStack Platform release 16.0.2 (Train)
(overcloud) [stack@undercloud-0 ~]$ TOKEN=`openstack token issue -f value -c id`; time curl -s -H "Accept: application/json; charset=utf-8" -H "X-Auth-Token: $TOKEN" "http://10.0.0.147:9696/v2.0/networks" | python3 -mjson.tool
{
    "NeutronError": {
        "type": "HTTPNotAcceptable",
        "message": "The server could not comply with the request since it is either malformed or otherwise incorrect.",
        "detail": ""
    }
}

real    0m0.653s
user    0m0.058s
sys     0m0.012s

Comment 34 Andreas Karis 2020-07-13 11:01:22 UTC
I'd prefer to keep the downstream bug open as the customer case refers to the downstream bug; and the downstream bug refers to the upstream bug in turn.

Comment 35 Bernard Cafarelli 2020-07-15 10:21:05 UTC
Hi Andreas, this bug was for OSP14, the 16 one is bug 1854443 (visible in the clones list) which is under active investigation

Comment 36 Andreas Karis 2020-07-15 11:36:28 UTC
Great thanks. Sorry that I missed this.