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 -- Mailing list: https://launchpad.net/~yahoo-eng-team Post to : yahoo-eng-team@lists.launchpad.net Unsubscribe : https://launchpad.net/~yahoo-eng-team More help : https://help.launchpad.net/ListHelp