← Back to team overview

yahoo-eng-team team mailing list archive

[Bug 1802006] [NEW] Floating IP attach/detach fails for non-admin user and unbound port with router in different tenant

 

Public bug reported:

Seeing this on pike, but code looks same in master so issue still likely
exists.

We have a shared external network connected to router in TenantA. Now
create a network, either shared in tenantA or owned by tenantB, and
attach to tenantA's router (an admin user will have to do this).

Now suppose a non-admin user in the different tenantB creates a Floating
IP on shared ext network. They then try to attach it to a port. It
passes if the port is bound to a VM. It fails if the port is unbound.
For example, pre-create a port on a network/subnet available to this
tenant, and then try the following /floatingips/ PUT API call. It will
fail. Then bring up a VM on same network, and attach Floating IP to it's
port, this will pass:

curl -k -X PUT -i https://localhost/neutron/v2.0/floatingips/cc56cbb4-2c3b-4d53-9506-1baaa8e7b2d6  -H "X-Auth-Token: $TOK" -H "Content-Type: application/json" -d '{"floatingip": {"port_id": "6af4bb1c-85b4-42c0-8b96-6efb90443aa7"}}'
HTTP/1.1 404 Not Found
Server: nginx/1.12.2
Date: Tue, 06 Nov 2018 07:31:54 GMT
Content-Type: application/json
Content-Length: 135
Connection: keep-alive
X-Openstack-Request-Id: req-31b02819-844c-4d41-a471-938f092b4a57
Access-Control-Allow-Credentials: true

{"NeutronError": {"message": "Router b819cfbb-7e8b-4bce-964e-
ec4b29614241 could not be found", "type": "RouterNotFound", "detail":
""}}

curl -k -X PUT -i https://localhost/neutron/v2.0/floatingips/44361b51-7928-441e-8478-4fd35919e5c3  -H "X-Auth-Token: $TOK" -H "Content-Type: application/json" -d '{"floatingip": {"port_id": "7ea1b40a-e3b1-490d-8a02-d5e2cf18b89c"}}'
HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Tue, 06 Nov 2018 07:15:10 GMT
Content-Type: application/json
Content-Length: 584
Connection: keep-alive
X-Openstack-Request-Id: req-50cb5289-fcbb-4a65-91d4-33f59b0f4632
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: X-Subject-Token

{"floatingip": {"router_id": "b819cfbb-7e8b-4bce-964e-ec4b29614241",
"status": "DOWN", "description": "", "tags": [], "updated_at":
"2018-11-06T07:15:09Z", "dns_domain": "", "floating_network_id":
"6580471a-cac0-4f03-ae2e-77ddfb76b181", "fixed_ip_address":
"10.168.1.14", "floating_ip_address": "10.4.252.154", "revision_number":
16, "port_id": "7ea1b40a-e3b1-490d-8a02-d5e2cf18b89c", "id":
"44361b51-7928-441e-8478-4fd35919e5c3", "dns_name": "", "created_at":
"2018-11-06T02:53:23Z", "tenant_id": "5e09d64a521b440e9ffbec28f5fb7de0",
"project_id": "5e09d64a521b440e9ffbec28f5fb7de0"}}

Problem is due to new code which allows binding FIP to unbound ports via
SNAT router, from this diff:
https://github.com/openstack/neutron/commit/9515c771e742a5b6d29b17f84f49a0b39706489b

An additional get_router() call is made here, and it needs the elevated
admin context to be passed in. It fails because default policy for
get_router is admin_or_owner, and it can't fetch the SNAT router in
different tenant. This code path is not hit for a VM port, as it is
bound and has a host:

https://github.com/openstack/neutron/blob/master/neutron/db/l3_dvr_db.py#L1098

which invokes get_router() here:

https://github.com/openstack/neutron/blob/master/neutron/db/l3_hascheduler_db.py#L45

Need to pass in context.elevated() in either one of those 2 places -
thinking the first location might be better?

** Affects: neutron
     Importance: Undecided
         Status: New

** Description changed:

  Seeing this on pike, but code looks same in master so issue still likely
  exists.
  
  We have a shared external network connected to router in TenantA. Now
  create a network, either shared in tenantA or owned by tenantB, and
  attach to tenantA's router (an admin user will have to do this).
  
  Now suppose a non-admin user in the different tenantB creates a Floating
  IP on shared ext network. They then try to attach it to a port. It
  passes if the port is bound to a VM. It fails if the port is unbound.
  For example, pre-create a port on a network/subnet available to this
  tenant, and then try the following /floatingips/ PUT API call. It will
  fail. Then bring up a VM on same network, and attach Floating IP to it's
  port, this will pass:
  
  curl -k -X PUT -i https://localhost/neutron/v2.0/floatingips/cc56cbb4-2c3b-4d53-9506-1baaa8e7b2d6  -H "X-Auth-Token: $TOK" -H "Content-Type: application/json" -d '{"floatingip": {"port_id": "6af4bb1c-85b4-42c0-8b96-6efb90443aa7"}}'
  HTTP/1.1 404 Not Found
  Server: nginx/1.12.2
  Date: Tue, 06 Nov 2018 07:31:54 GMT
  Content-Type: application/json
  Content-Length: 135
  Connection: keep-alive
  X-Openstack-Request-Id: req-31b02819-844c-4d41-a471-938f092b4a57
  Access-Control-Allow-Credentials: true
  
  {"NeutronError": {"message": "Router b819cfbb-7e8b-4bce-964e-
  ec4b29614241 could not be found", "type": "RouterNotFound", "detail":
  ""}}
  
  curl -k -X PUT -i https://localhost/neutron/v2.0/floatingips/44361b51-7928-441e-8478-4fd35919e5c3  -H "X-Auth-Token: $TOK" -H "Content-Type: application/json" -d '{"floatingip": {"port_id": "7ea1b40a-e3b1-490d-8a02-d5e2cf18b89c"}}'
  HTTP/1.1 200 OK
  Server: nginx/1.12.2
  Date: Tue, 06 Nov 2018 07:15:10 GMT
  Content-Type: application/json
  Content-Length: 584
  Connection: keep-alive
  X-Openstack-Request-Id: req-50cb5289-fcbb-4a65-91d4-33f59b0f4632
  Access-Control-Allow-Credentials: true
  Access-Control-Expose-Headers: X-Subject-Token
  
  {"floatingip": {"router_id": "b819cfbb-7e8b-4bce-964e-ec4b29614241",
  "status": "DOWN", "description": "", "tags": [], "updated_at":
  "2018-11-06T07:15:09Z", "dns_domain": "", "floating_network_id":
  "6580471a-cac0-4f03-ae2e-77ddfb76b181", "fixed_ip_address":
  "10.168.1.14", "floating_ip_address": "10.4.252.154", "revision_number":
  16, "port_id": "7ea1b40a-e3b1-490d-8a02-d5e2cf18b89c", "id":
  "44361b51-7928-441e-8478-4fd35919e5c3", "dns_name": "", "created_at":
  "2018-11-06T02:53:23Z", "tenant_id": "5e09d64a521b440e9ffbec28f5fb7de0",
  "project_id": "5e09d64a521b440e9ffbec28f5fb7de0"}}
  
- 
- Problem is due to new code which allows binding FIP to unbound ports via SNAT router, from this diff: https://github.com/openstack/neutron/commit/9515c771e742a5b6d29b17f84f49a0b39706489b
+ Problem is due to new code which allows binding FIP to unbound ports via
+ SNAT router, from this diff:
+ https://github.com/openstack/neutron/commit/9515c771e742a5b6d29b17f84f49a0b39706489b
  
  An additional get_router() call is made here, and it needs the elevated
  admin context to be passed in. It fails because default policy for
  get_router is admin_or_owner, and it can't fetch the SNAT router in
  different tenant. This code path is not hit for a VM port, as it is
  bound and has a host:
  
- https://github.com/openstack/neutron/blob/master/neutron/db/l3_dvr_db.py#1098
+ https://github.com/openstack/neutron/blob/master/neutron/db/l3_dvr_db.py#L1098
  
  which invokes get_router() here:
  
  https://github.com/openstack/neutron/blob/master/neutron/db/l3_hascheduler_db.py#L45
  
  Need to pass in context.elevated() in either one of those 2 places -
  thinking the first location might be better?

-- 
You received this bug notification because you are a member of Yahoo!
Engineering Team, which is subscribed to neutron.
https://bugs.launchpad.net/bugs/1802006

Title:
  Floating IP attach/detach fails for non-admin user and unbound port
  with router in different tenant

Status in neutron:
  New

Bug description:
  Seeing this on pike, but code looks same in master so issue still
  likely exists.

  We have a shared external network connected to router in TenantA. Now
  create a network, either shared in tenantA or owned by tenantB, and
  attach to tenantA's router (an admin user will have to do this).

  Now suppose a non-admin user in the different tenantB creates a
  Floating IP on shared ext network. They then try to attach it to a
  port. It passes if the port is bound to a VM. It fails if the port is
  unbound. For example, pre-create a port on a network/subnet available
  to this tenant, and then try the following /floatingips/ PUT API call.
  It will fail. Then bring up a VM on same network, and attach Floating
  IP to it's port, this will pass:

  curl -k -X PUT -i https://localhost/neutron/v2.0/floatingips/cc56cbb4-2c3b-4d53-9506-1baaa8e7b2d6  -H "X-Auth-Token: $TOK" -H "Content-Type: application/json" -d '{"floatingip": {"port_id": "6af4bb1c-85b4-42c0-8b96-6efb90443aa7"}}'
  HTTP/1.1 404 Not Found
  Server: nginx/1.12.2
  Date: Tue, 06 Nov 2018 07:31:54 GMT
  Content-Type: application/json
  Content-Length: 135
  Connection: keep-alive
  X-Openstack-Request-Id: req-31b02819-844c-4d41-a471-938f092b4a57
  Access-Control-Allow-Credentials: true

  {"NeutronError": {"message": "Router b819cfbb-7e8b-4bce-964e-
  ec4b29614241 could not be found", "type": "RouterNotFound", "detail":
  ""}}

  curl -k -X PUT -i https://localhost/neutron/v2.0/floatingips/44361b51-7928-441e-8478-4fd35919e5c3  -H "X-Auth-Token: $TOK" -H "Content-Type: application/json" -d '{"floatingip": {"port_id": "7ea1b40a-e3b1-490d-8a02-d5e2cf18b89c"}}'
  HTTP/1.1 200 OK
  Server: nginx/1.12.2
  Date: Tue, 06 Nov 2018 07:15:10 GMT
  Content-Type: application/json
  Content-Length: 584
  Connection: keep-alive
  X-Openstack-Request-Id: req-50cb5289-fcbb-4a65-91d4-33f59b0f4632
  Access-Control-Allow-Credentials: true
  Access-Control-Expose-Headers: X-Subject-Token

  {"floatingip": {"router_id": "b819cfbb-7e8b-4bce-964e-ec4b29614241",
  "status": "DOWN", "description": "", "tags": [], "updated_at":
  "2018-11-06T07:15:09Z", "dns_domain": "", "floating_network_id":
  "6580471a-cac0-4f03-ae2e-77ddfb76b181", "fixed_ip_address":
  "10.168.1.14", "floating_ip_address": "10.4.252.154",
  "revision_number": 16, "port_id": "7ea1b40a-e3b1-490d-
  8a02-d5e2cf18b89c", "id": "44361b51-7928-441e-8478-4fd35919e5c3",
  "dns_name": "", "created_at": "2018-11-06T02:53:23Z", "tenant_id":
  "5e09d64a521b440e9ffbec28f5fb7de0", "project_id":
  "5e09d64a521b440e9ffbec28f5fb7de0"}}

  Problem is due to new code which allows binding FIP to unbound ports
  via SNAT router, from this diff:
  https://github.com/openstack/neutron/commit/9515c771e742a5b6d29b17f84f49a0b39706489b

  An additional get_router() call is made here, and it needs the
  elevated admin context to be passed in. It fails because default
  policy for get_router is admin_or_owner, and it can't fetch the SNAT
  router in different tenant. This code path is not hit for a VM port,
  as it is bound and has a host:

  https://github.com/openstack/neutron/blob/master/neutron/db/l3_dvr_db.py#L1098

  which invokes get_router() here:

  https://github.com/openstack/neutron/blob/master/neutron/db/l3_hascheduler_db.py#L45

  Need to pass in context.elevated() in either one of those 2 places -
  thinking the first location might be better?

To manage notifications about this bug go to:
https://bugs.launchpad.net/neutron/+bug/1802006/+subscriptions


Follow ups