Policy enforcement variance between openstackcli and Horizon

Bug #1989627 reported by Brendan Shephard
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack Dashboard (Horizon)
New
Undecided
Unassigned

Bug Description

Summary
Neutron enforces Policy different between Horizon and the openstackcli

High Level Description
If a user without admin permission tried to modify security groups on a port via Horizon, they are denied via policy enforcement in line with the defaults from oslopolicy. But the same user is able to modify the port security groups via the CLI.

Reproduce:
1. Create a new non-admin user:
❯ openstack user create --project bne-home --password-prompt test
❯ openstack role add --project bne-home --user test member

2. Add user to clouds.yaml
  bne-home-test:
    auth:
      auth_url: https://openstack.bne-home.net:13000
      password: "test"
      project_domain_name: Default
      project_name: bne-home
      user_domain_name: Default
      username: test
    cacert: ~/.certs/overcloud-cacert.pem
    identity_api_version: '3'
    region_name: regionOne
    volume_api_version: '3'

3. Try to add/remove security group from port using the openstackcli:
❯ openstack server show test-lb-net -c security_groups -c addresses -f yaml
addresses:
  lb-mgmt-net:
  - 172.24.0.90
  vlan4-infra:
  - 172.20.13.175
security_groups:
- name: management-bne

❯ openstack port show 4df563ce-5464-4f7d-8aaf-c5496cdaefda -c fixed_ips -c port_security_enabled -c security_group_ids -f yaml
fixed_ips:
- ip_address: 172.20.13.175
  subnet_id: 71aad09a-3e7b-4399-97bf-075f066f6713
port_security_enabled: true
security_group_ids:
- a3ae6e20-67df-4a72-9d5b-cc21ad87464f

❯ openstack port unset --security-group a3ae6e20-67df-4a72-9d5b-cc21ad87464f 4df563ce-5464-4f7d-8aaf-c5496cdaefda
❯ openstack port show 4df563ce-5464-4f7d-8aaf-c5496cdaefda -c fixed_ips -c port_security_enabled -c security_group_ids -f yaml
fixed_ips:
- ip_address: 172.20.13.175
  subnet_id: 71aad09a-3e7b-4399-97bf-075f066f6713
port_security_enabled: true
security_group_ids: []

Verify that I’m definitely not a admin user:
❯ openstack server list --all
Policy doesn't allow os_compute_api:servers:detail:get_all_tenants to be performed. (HTTP 403) (Request-ID: req-75c19210-ad91-471f-b500-e1f3482825f8)

We can see this works. Let's try the same from Horizon. We need to login, select Instances > Interfaces > "Edit Security Groups"

This will deny the request. The error from Horizon is:
2022-09-14 22:23:13,612 65 INFO openstack_dashboard.dashboards.project.networks.ports.workflows Failed to update port 4df563ce-5464-4f7d-8aaf-c5496cdaefda: ((rule:update_port and rule:update_port:binding:vnic_type) and rule:update_port:port_security_enabled) is disallowed by policy

Which seems consistent with:
[root@overcloud-controller-0 horizon]# podman exec -it neutron_api oslopolicy-policy-generator --namespace neutron | grep "update_port:port_security_enabled"
"update_port:port_security_enabled": "rule:context_is_advsvc or rule:network_owner or rule:admin_only"

From the Neutron logs for both requests we can see:

https://paste.opendev.org/show/bn6zKrSXW5321hpJChvd/

Environment:
TripleO (current-tripleo)

Version:
# podman exec -it neutron_api rpm -q openstack-neutron
openstack-neutron-20.1.0-0.20220907082912.b4beddd.el9.noarch

[root@overcloud-controller-0 ~]# podman inspect neutron_api | jq '.[] | "image=\(.Image), image_url=\(.ImageName)"'
"image=7cf0c193041e437c39fe231c5eb39dc7f3f34229187de8e3d675cda28bdf1525, image_url=quay.io/tripleomastercentos9/openstack-neutron-server:current-tripleo"

Note that this is also an issue for RHOSP16.x:
https://lists.openstack.org/pipermail/openstack-discuss/2022-September/030468.html

Revision history for this message
Brendan Shephard (bshephar) wrote :

Seems Horizon is still using python-neutronclient rather than the openstacksdk. So there may be a difference in behaviour there:

But I have enabled debug in Horizon as well and captured the error. Logs attached from Neutron and Horizon both with debug enabled.

Revision history for this message
Miguel Lavalle (minsel) wrote (last edit ):

Hi Brendan,

I tested this with a devstack built from master branch and ml2/ovn. Both ways of doing this were successful:

1) CLI: https://paste.openstack.org/show/bEp1mvZiaUC6JAS8vAjz/

2) Horizon: https://paste.openstack.org/show/b2qHDErtjpUa6ZexPMS0/

So at least in master we don't have the variance mentioned in this bug. What version / release of Neutron are you using?

Revision history for this message
Brendan Shephard (bshephar) wrote :
Download full text (3.6 KiB)

Hey Miguel,

I think we narrowed down the issue to the Horizon side. This is from the email I tried to send to openstack-discuss but it was blocked for being too large. Should provide the insights to what is happening here though:

"""
Thanks for your input. I did indeed find that patch and used it to patch my env. In this case though, it didn’t seem to change the API request sent to Neutron.

If I log the data variable at this point after applying the patch. It contains all of the fields:

2022-09-16 00:01:55,046 35 INFO openstack_dashboard.dashboards.project.networks.ports.workflows bshephar - Data variable = {'port_id': '4df563ce-5464-4f7d-8aaf-c5496cdaefda', 'network_id': 'acefae53-b4d5-422f-bcca-dc32a0785d21', 'name': '', 'admin_state': True, 'target_tenant_id': '3ff28fc7abf742a6b7a0d016771dee49', 'binding__vnic_type': 'normal', 'port_security_enabled': True, 'instance_id': 'ccb72b14-3694-40fa-9b3b-ec1a8d7ef046', 'mac_state': None, 'wanted_groups': ['a3ae6e20-67df-4a72-9d5b-cc21ad87464f']}

 So checking this
         if data['port_security_enabled'] is not None:
            params['port_security_enabled'] = data['port_security_enabled']

This is still True, so we’re setting the param to the data value and using that in our API call to Neutron.

I’m really not familiar at all with the Horizon code base. So let me know if I’m misunderstanding the intention of the patch you referenced. But I think the idea would be to check our params against the actual value returned from neutron.port_get() and only have fields that are changed in our params. So when we call the port_update() here:

At least in the case we’re discussing here, that resolves the issue. This is just rudimentary hackery to see what works, but this fixes the issue for me (Ignore the LOG line obviously):

❯ diff horizon/openstack_dashboard/dashboards/project/networks/ports/workflows.py workflows.py
411c411
<         params = self._construct_parameters(data)
---
>         params = self._construct_parameters(request, data)
420c420
<     def _construct_parameters(self, data):
---
>     def _construct_parameters(self, request, data):
424a425,426
>         LOG.info("bshephar - Data variable = %s", data)
>         initial = api.neutron.port_get(request, self.context['port_id'])
431c433,434
<         if data['port_security_enabled'] is not None:
---
>         if (data['port_security_enabled'] is not None and data['port_security_enabled']
>             != initial['port_security_enabled']):

The API call after this change looks like this:

2022-09-16 00:17:49,147 31 DEBUG neutronclient.client REQ: b'curl -i https://openstack.bne-home.net:13696/v2.0/ports/4df563ce-5464-4f7d-8aaf-c5496cdaefda -X PUT -H "X-Auth-Token: {SHA256}65efff6982c871ae21a157ab46e4e2bebf69fc8619e8a1512d7ce0dd96b94369" -H "User-Agent: python-neutronclient" -d \'{"port": {"name": "", "admin_state_up": true, "security_groups": ["a3ae6e20-67df-4a72-9d5b-cc21ad87464f"], "binding:vnic_type": "normal"}}\''

And subsequently is accepted by Neutron. So I’m not too sure about the approach within your existing Horizon framework.

"""

So the problem is that Horizon is always including port_security_enabled: True in the API cal...

Read more...

affects: neutron → horizon
Revision history for this message
Miguel Lavalle (minsel) wrote :

Thanks for the update!

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.