Remove fwaas_v1 exceptions and definitions
There are still fwaas_v1 exceptions and definitions in neutron-lib, it is necessary to remove them because the fwaas_v1 code has been removed in the Stein cycle[1] and the related extensions will be removed. [1] https://review.opendev.org/#/c/616410/ Depends-On: https://review.opendev.org/#/c/692094/ Change-Id: Ibfc6dab327c9df59222cda3e6a1f5dc566aa1bde Closes-bug: #1850602
This commit is contained in:
parent
7e95f32e34
commit
9f56e984c3
|
@ -1,817 +0,0 @@
|
|||
==========================================================================
|
||||
FWaaS v1.0 (DEPRECATED) (fw, firewalls, firewall_policies, firewall_rules)
|
||||
==========================================================================
|
||||
|
||||
.. note::
|
||||
|
||||
While FWaaS v1.0 is still maintained, new features will be
|
||||
implemented in FWaaS v2.0 API.
|
||||
|
||||
Use the Firewall-as-a-Service (FWaaS) v1.0 extension to deploy
|
||||
firewalls to protect your networks.
|
||||
|
||||
The FWaaS extension enables you to:
|
||||
|
||||
- Apply firewall rules on traffic entering and leaving project
|
||||
networks.
|
||||
|
||||
- Apply TCP, UDP, ICMP, or protocol-agnostic rules.
|
||||
|
||||
- Create and share firewall policies that hold an ordered collection
|
||||
of the firewall rules.
|
||||
|
||||
- Audit firewall rules and policies.
|
||||
|
||||
This extension introduces these resources:
|
||||
|
||||
- ``firewall``. A logical firewall resource that a project can
|
||||
instantiate and manage. A firewall can have one firewall policy.
|
||||
|
||||
- ``firewall_policy``. An ordered collection of firewall rules. You
|
||||
can share a firewall policy across projects. You can include a
|
||||
firewall policy as part of an audit workflow so that an
|
||||
authorized relevant entity can audit the firewall policy. This
|
||||
entity can differ from the user who created, or the projects
|
||||
that use, the firewall policy.
|
||||
|
||||
- ``firewall_rule``. A collection of attributes, such as ports and
|
||||
IP addresses. These attributes define match criteria and an
|
||||
action to take, such as allow or deny, on matched data traffic.
|
||||
|
||||
List firewall policies
|
||||
======================
|
||||
|
||||
.. rest_method:: GET /v2.0/fw/firewall_policies
|
||||
|
||||
Lists all firewall policies.
|
||||
|
||||
Use the ``fields`` query parameter to control which fields are
|
||||
returned in the response body. Additionally, you can filter results
|
||||
by using query string parameters. For information, see `Filtering
|
||||
and Column Selection <https://wiki.openstack.org/wiki/Neutron/APIv2
|
||||
-specification#Filtering_and_Column_Selection>`__.
|
||||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: 401, 403
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- fields: fields
|
||||
|
||||
Response Parameters
|
||||
-------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- tenant_id: project_id
|
||||
- firewall_policies: firewall_policies
|
||||
- audited: audited
|
||||
- description: description
|
||||
- firewall_rules: firewall_rules
|
||||
- id: firewall_policy_id-body
|
||||
- name: name
|
||||
- shared: shared-response
|
||||
- project_id: project_id
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-policies-list-response.json
|
||||
:language: javascript
|
||||
|
||||
Create firewall policy
|
||||
======================
|
||||
|
||||
.. rest_method:: POST /v2.0/fw/firewall_policies
|
||||
|
||||
Creates a firewall policy.
|
||||
|
||||
Normal response codes: 201
|
||||
|
||||
Error response codes: 400, 401
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_policy: firewall_policy
|
||||
- firewall_rules_id: firewall_rules_id
|
||||
- name: name
|
||||
- tenant_id: project_id-request
|
||||
- project_id: project_id-request
|
||||
- shared: shared
|
||||
- audited: audited
|
||||
- description: description-request
|
||||
|
||||
Request Example
|
||||
---------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-policy-create-request.json
|
||||
:language: javascript
|
||||
|
||||
Response Parameters
|
||||
-------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_policy: firewall_policy
|
||||
- name: name
|
||||
- firewall_rules: firewall_rules
|
||||
- tenant_id: project_id
|
||||
- project_id: project_id
|
||||
- audited: audited
|
||||
- shared: shared-response
|
||||
- id: firewall_policy_id-body
|
||||
- description: description
|
||||
|
||||
Show firewall policy details
|
||||
============================
|
||||
|
||||
.. rest_method:: GET /v2.0/fw/firewall_policies/{firewall_policy_id}
|
||||
|
||||
Shows details for a firewall policy.
|
||||
|
||||
If the user is not an administrative user and the firewall policy
|
||||
object does not belong to the project, this call returns the
|
||||
``Forbidden (403)`` response code.
|
||||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: 401, 403, 404
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_policy_id: firewall_policy_id-path
|
||||
|
||||
Response Parameters
|
||||
-------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_policy: firewall_policy
|
||||
- tenant_id: project_id
|
||||
- project_id: project_id
|
||||
- audited: audited
|
||||
- description: description
|
||||
- firewall_rules: firewall_rules
|
||||
- id: firewall_policy_id-body
|
||||
- name: name
|
||||
- shared: shared-response
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-policy-show-response.json
|
||||
:language: javascript
|
||||
|
||||
Update firewall policy
|
||||
======================
|
||||
|
||||
.. rest_method:: PUT /v2.0/fw/firewall_policies/{firewall_policy_id}
|
||||
|
||||
Updates a firewall policy.
|
||||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: 400, 401, 404
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_policy_id: firewall_policy_id-path
|
||||
- firewall_rule: firewall_rule
|
||||
- shared: shared
|
||||
- audited: audited
|
||||
- description: description-request
|
||||
- name: name
|
||||
|
||||
Request Example
|
||||
---------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-policy-update-request.json
|
||||
:language: javascript
|
||||
|
||||
Response Parameters
|
||||
-------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_policy: firewall_policy
|
||||
- project_id: project_id
|
||||
- audited: audited
|
||||
- description: description
|
||||
- firewall_rules: firewall_rules
|
||||
- id: firewall_policy_id-body
|
||||
- name: name
|
||||
- shared: shared-response
|
||||
- tenant_id: project_id
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-policy-update-response.json
|
||||
:language: javascript
|
||||
|
||||
Delete firewall policy
|
||||
======================
|
||||
|
||||
.. rest_method:: DELETE /v2.0/fw/firewall_policies/{firewall_policy_id}
|
||||
|
||||
Deletes a firewall policy.
|
||||
|
||||
Normal response codes: 204
|
||||
|
||||
Error response codes: 401, 404, 409
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_policy_id: firewall_policy_id-path
|
||||
|
||||
Response
|
||||
--------
|
||||
|
||||
There is no body content for the response of a successful DELETE request.
|
||||
|
||||
Insert rule into a firewall policy
|
||||
==================================
|
||||
|
||||
.. rest_method:: PUT /v2.0/fw/firewall_policies/{firewall_policy_id}/insert_rule
|
||||
|
||||
Insert firewall rule into a policy.
|
||||
|
||||
A firewall_rule_id is inserted relative to the position of the
|
||||
firewall_rule_id set in ``insert_before`` or ``insert_after``. If
|
||||
``insert_before`` is set, ``insert_after`` is ignored. If both
|
||||
``insert_before`` and ``insert_after`` are not set, the new
|
||||
firewall_rule_id is inserted at the top of the policy.
|
||||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: 400, 401, 404, 409
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_policy_id: firewall_policy_id-path
|
||||
- firewall_rule_id: firewall_rule_id-body
|
||||
- insert_after: insert_after
|
||||
- insert_before: insert_before
|
||||
|
||||
Request Example
|
||||
---------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-policy-insert-rule-request.json
|
||||
:language: javascript
|
||||
|
||||
Response Parameters
|
||||
-------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- audited: audited
|
||||
- description: description
|
||||
- firewall_list: firewall_list
|
||||
- firewall_rules: firewall_rules
|
||||
- tenant_id: project_id
|
||||
- project_id: project_id
|
||||
- id: firewall_policy_id-body
|
||||
- name: name
|
||||
- shared: shared-response
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-policy-insert-rule-response.json
|
||||
:language: javascript
|
||||
|
||||
Remove rule from firewall policy
|
||||
================================
|
||||
|
||||
.. rest_method:: PUT /v2.0/fw/firewall_policies/{firewall_policy_id}/remove_rule
|
||||
|
||||
Remove firewall rule from a policy.
|
||||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: 400, 401, 404
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_policy_id: firewall_policy_id-path
|
||||
- firewall_rule_id: firewall_rule_id-body
|
||||
|
||||
Request Example
|
||||
---------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-policy-remove-rule-request.json
|
||||
:language: javascript
|
||||
|
||||
Response Parameters
|
||||
-------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- tenant_id: project_id
|
||||
- project_id: project_id
|
||||
- audited: audited
|
||||
- description: description
|
||||
- firewall_list: firewall_list
|
||||
- firewall_rules: firewall_rules
|
||||
- id: firewall_id-body
|
||||
- name: name
|
||||
- shared: shared-response
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-policy-remove-rule-response.json
|
||||
:language: javascript
|
||||
|
||||
List firewall rules
|
||||
===================
|
||||
|
||||
.. rest_method:: GET /v2.0/fw/firewall_rules
|
||||
|
||||
Lists all firewall rules.
|
||||
|
||||
The list might be empty.
|
||||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: 401, 403
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
Response Parameters
|
||||
-------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_rule: firewall_rule
|
||||
- action: action-response
|
||||
- description: description
|
||||
- tenant_id: project_id
|
||||
- project_id: project_id
|
||||
- destination_ip_address: destination_ip_address-response
|
||||
- destination_port: destination_port-response
|
||||
- enabled: enabled-response
|
||||
- firewall_policy_id: firewall_policy_id-body
|
||||
- id: firewall_id-body
|
||||
- ip_version: ip_version-response
|
||||
- name: name
|
||||
- position: position
|
||||
- protocol: protocol-response
|
||||
- shared: shared-response
|
||||
- source_ip_address: source_ip_address
|
||||
- source_port: source_port-response
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-rules-list-response.json
|
||||
:language: javascript
|
||||
|
||||
Create firewall rule
|
||||
====================
|
||||
|
||||
.. rest_method:: POST /v2.0/fw/firewall_rules
|
||||
|
||||
Creates a firewall rule.
|
||||
|
||||
Normal response codes: 201
|
||||
|
||||
Error response codes: 400, 401
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_rule: firewall_rule
|
||||
- action: action
|
||||
- destination_port: destination_port
|
||||
- enabled: enabled
|
||||
- description: description-request
|
||||
- tenant_id: project_id-request
|
||||
- project_id: project_id-request
|
||||
- enabled: enabled
|
||||
- name: name
|
||||
- protocol: protocol
|
||||
- ip_version: ip_version
|
||||
- destination_ip_address: destination_ip_address
|
||||
- source_port: source_port
|
||||
- shared: shared
|
||||
|
||||
Request Example
|
||||
---------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-rule-create-request.json
|
||||
:language: javascript
|
||||
|
||||
Response Parameters
|
||||
-------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_rule: firewall_rule
|
||||
- action: action-response
|
||||
- description: description
|
||||
- tenant_id: project_id
|
||||
- project_id: project_id
|
||||
- destination_ip_address: destination_ip_address-response
|
||||
- destination_port: destination_port-response
|
||||
- enabled: enabled-response
|
||||
- firewall_policy_id: firewall_policy_id-body
|
||||
- id: firewall_id-body
|
||||
- ip_version: ip_version-response
|
||||
- name: name
|
||||
- position: position
|
||||
- protocol: protocol-response
|
||||
- shared: shared-response
|
||||
- source_ip_address: source_ip_address
|
||||
- source_port: source_port-response
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-rule-create-response.json
|
||||
:language: javascript
|
||||
|
||||
Show firewall rule details
|
||||
==========================
|
||||
|
||||
.. rest_method:: GET /v2.0/fw/firewall_rules/{firewall_rule_id}
|
||||
|
||||
Shows details for a firewall rule.
|
||||
|
||||
If the user is not an administrative user and the firewall rule
|
||||
object does not belong to the project, this call returns the
|
||||
``Forbidden (403)`` response code.
|
||||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: 401, 403, 404
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_rule_id: firewall_rule_id
|
||||
|
||||
Response Parameters
|
||||
-------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_rule: firewall_rule
|
||||
- action: action-response
|
||||
- description: description
|
||||
- tenant_id: project_id
|
||||
- project_id: project_id
|
||||
- destination_ip_address: destination_ip_address-response
|
||||
- destination_port: destination_port-response
|
||||
- enabled: enabled-response
|
||||
- firewall_policy_id: firewall_policy_id
|
||||
- id: firewall_rule_id-body
|
||||
- ip_version: ip_version-response
|
||||
- name: name
|
||||
- position: position
|
||||
- protocol: protocol-response
|
||||
- shared: shared-response
|
||||
- source_ip_address: source_ip_address
|
||||
- source_port: source_port-response
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-rule-show-response.json
|
||||
:language: javascript
|
||||
|
||||
Update firewall rule
|
||||
====================
|
||||
|
||||
.. rest_method:: PUT /v2.0/fw/firewall_rules/{firewall_rule_id}
|
||||
|
||||
Updates a firewall rule.
|
||||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: 400, 401, 404
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_rule_id: firewall_rule_id
|
||||
- firewall_rule: firewall_rule
|
||||
- shared: shared
|
||||
- description: description-request
|
||||
- tenant_id: project_id-request
|
||||
- project_id: project_id-request
|
||||
- enabled: enabled
|
||||
- ip_version: ip_version
|
||||
- destination_ip_address: destination_ip_address
|
||||
- source_port: source_port
|
||||
- action: action
|
||||
- protocol: protocol
|
||||
- destination_port: destination_port
|
||||
- name: name
|
||||
|
||||
Request Example
|
||||
---------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-rule-update-request.json
|
||||
:language: javascript
|
||||
|
||||
Response Parameters
|
||||
-------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_rule: firewall_rule
|
||||
- action: action-response
|
||||
- description: description
|
||||
- source_ip_address: source_ip_address
|
||||
- tenant_id: project_id
|
||||
- project_id: project_id
|
||||
- enabled: enabled
|
||||
- protocol: protocol
|
||||
- source_port: source_port
|
||||
- ip_version: ip_version
|
||||
- destination_ip_address: destination_ip_address-response
|
||||
- destination_port: destination_port-response
|
||||
- enabled: enabled-response
|
||||
- firewall_policy_id: firewall_policy_id
|
||||
- id: firewall_rule_id-body
|
||||
- ip_version: ip_version-response
|
||||
- name: name
|
||||
- position: position
|
||||
- protocol: protocol-response
|
||||
- shared: shared-response
|
||||
- source_ip_address: source_ip_address
|
||||
- source_port: source_port-response
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-rule-update-response.json
|
||||
:language: javascript
|
||||
|
||||
Delete firewall rule
|
||||
====================
|
||||
|
||||
.. rest_method:: DELETE /v2.0/fw/firewall_rules/{firewall_rule_id}
|
||||
|
||||
Deletes a firewall rule.
|
||||
|
||||
Normal response codes: 204
|
||||
|
||||
Error response codes: 401, 404, 409
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_rule_id: firewall_rule_id
|
||||
|
||||
Response
|
||||
--------
|
||||
|
||||
There is no body content for the response of a successful DELETE request.
|
||||
|
||||
List firewalls
|
||||
==============
|
||||
|
||||
.. rest_method:: GET /v2.0/fw/firewalls
|
||||
|
||||
Lists all firewalls.
|
||||
|
||||
The list might be empty.
|
||||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: 401, 403
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
Response Parameters
|
||||
-------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewalls: firewalls
|
||||
- admin_state_up: admin_state_up
|
||||
- tenant_id: project_id
|
||||
- project_id: project_id
|
||||
- description: description
|
||||
- firewall_policy_id: firewall_policy_id-body
|
||||
- id: firewall_id-body
|
||||
- name: name
|
||||
- status: firewall-status
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewalls-list-response.json
|
||||
:language: javascript
|
||||
|
||||
Create firewall
|
||||
===============
|
||||
|
||||
.. rest_method:: POST /v2.0/fw/firewalls
|
||||
|
||||
Creates a firewall.
|
||||
|
||||
The firewall must be associated with a firewall policy.
|
||||
|
||||
If ``admin_state_up`` is ``false``, the firewall would block all
|
||||
traffic.
|
||||
|
||||
Normal response codes: 201
|
||||
|
||||
Error response codes: 400, 401
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall: firewall
|
||||
- admin_state_up: admin_state_up
|
||||
- firewall_policy_id: firewall_policy_id-body
|
||||
- description: description-request
|
||||
- name: name
|
||||
- router_ids: router_ids
|
||||
|
||||
Request Example
|
||||
---------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-create-request.json
|
||||
:language: javascript
|
||||
|
||||
Response Parameters
|
||||
-------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall: firewall
|
||||
- tenant_id: project_id
|
||||
- project_id: project_id
|
||||
- admin_state_up: admin_state_up
|
||||
- description: description
|
||||
- firewall_policy_id: firewall_policy_id-body
|
||||
- id: firewall_id-body
|
||||
- name: name
|
||||
- status: firewall-status
|
||||
- router_ids: router_ids-response
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-create-response.json
|
||||
:language: javascript
|
||||
|
||||
Show firewall details
|
||||
=====================
|
||||
|
||||
.. rest_method:: GET /v2.0/fw/firewalls/{firewall_id}
|
||||
|
||||
Shows details for a firewall.
|
||||
|
||||
If the user is not an administrative user and the firewall object
|
||||
does not belong to the project, this call returns the
|
||||
``Forbidden (403)`` response code.
|
||||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: 401, 403, 404
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_id: firewall_id
|
||||
|
||||
Response Parameters
|
||||
-------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall: firewall
|
||||
- tenant_id: project_id
|
||||
- project_id: project_id
|
||||
- admin_state_up: admin_state_up
|
||||
- description: description
|
||||
- status: firewall-status
|
||||
- firewall_policy_id: firewall_policy_id
|
||||
- id: firewall_rule_id-body
|
||||
- name: name
|
||||
- router_ids: router_ids-response
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-show-response.json
|
||||
:language: javascript
|
||||
|
||||
Update firewall
|
||||
===============
|
||||
|
||||
.. rest_method:: PUT /v2.0/fw/firewalls/{firewall_id}
|
||||
|
||||
Updates a firewall.
|
||||
|
||||
To update a service, the service status cannot be a ``PENDING_*``
|
||||
status.
|
||||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: 400, 401, 404
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_id: firewall_id
|
||||
- firewall: firewall
|
||||
- admin_state_up: admin_state_up
|
||||
- description: description-request
|
||||
- firewall_policy_id: firewall_policy_id-body
|
||||
- name: name
|
||||
- router_ids: router_ids
|
||||
|
||||
Request Example
|
||||
---------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-update-request.json
|
||||
:language: javascript
|
||||
|
||||
Response Parameters
|
||||
-------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall: firewall
|
||||
- tenant_id: project_id
|
||||
- project_id: project_id
|
||||
- admin_state_up: admin_state_up
|
||||
- description: description
|
||||
- status: firewall-status
|
||||
- firewall_policy_id: firewall_policy_id-body
|
||||
- id: firewall_id-body
|
||||
- name: name
|
||||
- router_ids: router_ids-response
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
|
||||
.. literalinclude:: samples/firewalls/firewall-update-response.json
|
||||
:language: javascript
|
||||
|
||||
Delete firewall
|
||||
===============
|
||||
|
||||
.. rest_method:: DELETE /v2.0/fw/firewalls/{firewall_id}
|
||||
|
||||
Deletes a firewall.
|
||||
|
||||
Normal response codes: 204
|
||||
|
||||
Error response codes: 401, 404, 409
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- firewall_id: firewall_id
|
||||
|
||||
Response
|
||||
--------
|
||||
|
||||
There is no body content for the response of a successful DELETE request.
|
|
@ -37,7 +37,6 @@ Layer 3 Networking
|
|||
########
|
||||
Security
|
||||
########
|
||||
.. include:: fwaas.inc
|
||||
.. include:: fwaas-v2.inc
|
||||
.. include:: rbac-policy.inc
|
||||
.. include:: security-group-rules.inc
|
||||
|
|
|
@ -40,9 +40,7 @@ from neutron_lib.api.definitions import extraroute_atomic
|
|||
from neutron_lib.api.definitions import filter_validation
|
||||
from neutron_lib.api.definitions import fip64
|
||||
from neutron_lib.api.definitions import fip_port_details
|
||||
from neutron_lib.api.definitions import firewall
|
||||
from neutron_lib.api.definitions import firewall_v2
|
||||
from neutron_lib.api.definitions import firewallrouterinsertion
|
||||
from neutron_lib.api.definitions import flavors
|
||||
from neutron_lib.api.definitions import floating_ip_port_forwarding
|
||||
from neutron_lib.api.definitions import floatingip_autodelete_internal
|
||||
|
@ -146,9 +144,7 @@ _ALL_API_DEFINITIONS = {
|
|||
extraroute_atomic,
|
||||
filter_validation,
|
||||
fip64,
|
||||
firewall,
|
||||
firewall_v2,
|
||||
firewallrouterinsertion,
|
||||
fip_port_details,
|
||||
flavors,
|
||||
floating_ip_port_forwarding,
|
||||
|
|
|
@ -1,187 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib.api import converters
|
||||
from neutron_lib.api.definitions import constants as api_const
|
||||
from neutron_lib import constants
|
||||
from neutron_lib.db import constants as db_const
|
||||
|
||||
# The alias of the extension.
|
||||
ALIAS = 'fwaas'
|
||||
|
||||
# Whether or not this extension is simply signaling behavior to the user
|
||||
# or it actively modifies the attribute map.
|
||||
IS_SHIM_EXTENSION = False
|
||||
|
||||
# Whether the extension is marking the adoption of standardattr model for
|
||||
# legacy resources, or introducing new standardattr attributes. False or
|
||||
# None if the standardattr model is adopted since the introduction of
|
||||
# resource extension.
|
||||
# If this is True, the alias for the extension should be prefixed with
|
||||
# 'standard-attr-'.
|
||||
IS_STANDARD_ATTR_EXTENSION = False
|
||||
|
||||
# The name of the extension.
|
||||
NAME = 'FWaaS v1'
|
||||
|
||||
# The description of the extension.
|
||||
DESCRIPTION = "Provides support for firewall-as-a-service version 1"
|
||||
|
||||
# A timestamp of when the extension was introduced.
|
||||
UPDATED_TIMESTAMP = "2016-01-01T10:00:00-00:00"
|
||||
|
||||
# Base for the API calls
|
||||
API_PREFIX = '/fw'
|
||||
|
||||
RESOURCE_ATTRIBUTE_MAP = {
|
||||
api_const.FIREWALL_RULES: {
|
||||
'id': {'allow_post': False, 'allow_put': False,
|
||||
'validate': {'type:uuid': None},
|
||||
'is_visible': True, 'primary_key': True},
|
||||
'tenant_id': {'allow_post': True, 'allow_put': False,
|
||||
'required_by_policy': True,
|
||||
'is_visible': True},
|
||||
'name': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:string': db_const.NAME_FIELD_SIZE},
|
||||
'is_visible': True, 'default': ''},
|
||||
'description': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:string':
|
||||
db_const.DESCRIPTION_FIELD_SIZE},
|
||||
'is_visible': True, 'default': ''},
|
||||
'firewall_policy_id': {'allow_post': False, 'allow_put': False,
|
||||
'validate': {'type:uuid_or_none': None},
|
||||
'is_visible': True},
|
||||
constants.SHARED: {
|
||||
'allow_post': True, 'allow_put': True,
|
||||
'default': False,
|
||||
'convert_to': converters.convert_to_boolean,
|
||||
'is_visible': True, 'required_by_policy': True,
|
||||
'enforce_policy': True
|
||||
},
|
||||
'protocol': {
|
||||
'allow_post': True, 'allow_put': True,
|
||||
'is_visible': True, 'default': None,
|
||||
'convert_to': converters.convert_to_protocol,
|
||||
'validate': {'type:values': api_const.FW_PROTOCOL_VALUES}},
|
||||
'ip_version': {'allow_post': True, 'allow_put': True,
|
||||
'default': 4, 'convert_to': converters.convert_to_int,
|
||||
'validate': {'type:values': [4, 6]},
|
||||
'is_visible': True},
|
||||
'source_ip_address': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:ip_or_subnet_or_none':
|
||||
None},
|
||||
'is_visible': True, 'default': None},
|
||||
'destination_ip_address': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:ip_or_subnet_or_none':
|
||||
None},
|
||||
'is_visible': True, 'default': None},
|
||||
'source_port': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:port_range': None},
|
||||
'convert_to': converters.convert_to_string,
|
||||
'default': None, 'is_visible': True},
|
||||
'destination_port': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:port_range': None},
|
||||
'convert_to': converters.convert_to_string,
|
||||
'default': None, 'is_visible': True},
|
||||
'position': {'allow_post': False, 'allow_put': False,
|
||||
'default': None, 'is_visible': True},
|
||||
'action': {'allow_post': True, 'allow_put': True,
|
||||
'convert_to': converters.convert_string_to_case_insensitive,
|
||||
'validate': {'type:values':
|
||||
api_const.FW_VALID_ACTION_VALUES},
|
||||
'is_visible': True, 'default': 'deny'},
|
||||
'enabled': {'allow_post': True, 'allow_put': True,
|
||||
'default': True, 'is_visible': True,
|
||||
'convert_to': converters.convert_to_boolean},
|
||||
},
|
||||
api_const.FIREWALL_POLICIES: {
|
||||
'id': {'allow_post': False, 'allow_put': False,
|
||||
'validate': {'type:uuid': None},
|
||||
'is_visible': True,
|
||||
'primary_key': True},
|
||||
'tenant_id': {'allow_post': True, 'allow_put': False,
|
||||
'required_by_policy': True,
|
||||
'is_visible': True},
|
||||
'name': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:string': db_const.NAME_FIELD_SIZE},
|
||||
'is_visible': True, 'default': ''},
|
||||
'description': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:string':
|
||||
db_const.DESCRIPTION_FIELD_SIZE},
|
||||
'is_visible': True, 'default': ''},
|
||||
constants.SHARED: {
|
||||
'allow_post': True, 'allow_put': True,
|
||||
'default': False, 'enforce_policy': True,
|
||||
'convert_to': converters.convert_to_boolean,
|
||||
'is_visible': True, 'required_by_policy': True
|
||||
},
|
||||
'firewall_rules': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:uuid_list': None},
|
||||
'convert_to': converters.convert_none_to_empty_list,
|
||||
'default': None, 'is_visible': True},
|
||||
'audited': {'allow_post': True, 'allow_put': True,
|
||||
'default': False, 'is_visible': True,
|
||||
'convert_to': converters.convert_to_boolean},
|
||||
},
|
||||
api_const.FIREWALLS: {
|
||||
'id': {'allow_post': False, 'allow_put': False,
|
||||
'validate': {'type:uuid': None},
|
||||
'is_visible': True,
|
||||
'primary_key': True},
|
||||
'tenant_id': {'allow_post': True, 'allow_put': False,
|
||||
'required_by_policy': True,
|
||||
'is_visible': True},
|
||||
'name': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:string': db_const.NAME_FIELD_SIZE},
|
||||
'is_visible': True, 'default': ''},
|
||||
'description': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:string':
|
||||
db_const.DESCRIPTION_FIELD_SIZE},
|
||||
'is_visible': True, 'default': ''},
|
||||
'admin_state_up': {'allow_post': True, 'allow_put': True,
|
||||
'default': True, 'is_visible': True,
|
||||
'convert_to': converters.convert_to_boolean},
|
||||
'status': {'allow_post': False, 'allow_put': False,
|
||||
'is_visible': True},
|
||||
constants.SHARED: {
|
||||
'allow_post': True, 'allow_put': True,
|
||||
'default': False, 'enforce_policy': True,
|
||||
'convert_to': converters.convert_to_boolean,
|
||||
'is_visible': False, 'required_by_policy': True
|
||||
},
|
||||
'firewall_policy_id': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:uuid_or_none': None},
|
||||
'is_visible': True},
|
||||
},
|
||||
}
|
||||
|
||||
# The subresource attribute map for the extension. This extension has only
|
||||
# top level resources, not child resources, so this is set to an empty dict.
|
||||
SUB_RESOURCE_ATTRIBUTE_MAP = {
|
||||
}
|
||||
|
||||
# The action map.
|
||||
ACTION_MAP = {
|
||||
'firewall_policy': {'insert_rule': 'PUT', 'remove_rule': 'PUT'},
|
||||
}
|
||||
|
||||
# The action status.
|
||||
ACTION_STATUS = {
|
||||
}
|
||||
|
||||
# The list of required extensions.
|
||||
REQUIRED_EXTENSIONS = [
|
||||
]
|
||||
|
||||
# The list of optional extensions.
|
||||
OPTIONAL_EXTENSIONS = [
|
||||
]
|
|
@ -1,74 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib.api.definitions import constants as api_const
|
||||
from neutron_lib import constants
|
||||
|
||||
# The alias of the extension.
|
||||
ALIAS = 'fwaasrouterinsertion'
|
||||
|
||||
# Whether or not this extension is simply signaling behavior to the user
|
||||
# or it actively modifies the attribute map.
|
||||
IS_SHIM_EXTENSION = False
|
||||
|
||||
# Whether the extension is marking the adoption of standardattr model for
|
||||
# legacy resources, or introducing new standardattr attributes. False or
|
||||
# None if the standardattr model is adopted since the introduction of
|
||||
# resource extension.
|
||||
# If this is True, the alias for the extension should be prefixed with
|
||||
# 'standard-attr-'.
|
||||
IS_STANDARD_ATTR_EXTENSION = False
|
||||
|
||||
# The name of the extension.
|
||||
NAME = 'FWaaS Router Insertion'
|
||||
|
||||
# The description of the extension.
|
||||
DESCRIPTION = "Provides router insertion support for FWaaS version 1"
|
||||
|
||||
# A timestamp of when the extension was introduced.
|
||||
UPDATED_TIMESTAMP = "2016-01-01T10:00:00-00:00"
|
||||
|
||||
# The name of the resource
|
||||
RESOURCE_NAME = "firewall"
|
||||
|
||||
# The plural for the resource
|
||||
COLLECTION_NAME = api_const.FIREWALLS
|
||||
|
||||
RESOURCE_ATTRIBUTE_MAP = {
|
||||
COLLECTION_NAME: {
|
||||
'router_ids': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:uuid_list': None},
|
||||
'is_visible': True,
|
||||
'default': constants.ATTR_NOT_SPECIFIED},
|
||||
}
|
||||
}
|
||||
|
||||
# The subresource attribute map for the extension. This extension has only
|
||||
# top level resources, not child resources, so this is set to an empty dict.
|
||||
SUB_RESOURCE_ATTRIBUTE_MAP = {
|
||||
}
|
||||
|
||||
# The action map.
|
||||
ACTION_MAP = {
|
||||
}
|
||||
|
||||
# The action status.
|
||||
ACTION_STATUS = {
|
||||
}
|
||||
|
||||
# The list of required extensions.
|
||||
REQUIRED_EXTENSIONS = [
|
||||
]
|
||||
|
||||
# The list of optional extensions.
|
||||
OPTIONAL_EXTENSIONS = [
|
||||
]
|
|
@ -13,7 +13,7 @@
|
|||
# under the License.
|
||||
|
||||
from neutron_lib.api import converters
|
||||
from neutron_lib.api.definitions import firewall
|
||||
from neutron_lib.api.definitions import firewall_v2
|
||||
from neutron_lib.db import constants as db_const
|
||||
|
||||
|
||||
|
@ -132,7 +132,7 @@ ACTION_STATUS = {
|
|||
|
||||
# The list of required extensions.
|
||||
REQUIRED_EXTENSIONS = [
|
||||
firewall.ALIAS,
|
||||
firewall_v2.ALIAS,
|
||||
]
|
||||
|
||||
# The list of optional extensions.
|
||||
|
|
|
@ -1,140 +0,0 @@
|
|||
# Copyright 2013 Big Switch Networks, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from neutron_lib._i18n import _
|
||||
from neutron_lib import exceptions
|
||||
|
||||
|
||||
class FirewallNotFound(exceptions.NotFound):
|
||||
message = _("Firewall %(firewall_id)s could not be found.")
|
||||
|
||||
|
||||
class FirewallInUse(exceptions.InUse):
|
||||
message = _("Firewall %(firewall_id)s is still active.")
|
||||
|
||||
|
||||
class FirewallInPendingState(exceptions.Conflict):
|
||||
message = _("Operation cannot be performed since associated firewall "
|
||||
"%(firewall_id)s is in %(pending_state)s.")
|
||||
|
||||
|
||||
class FirewallPolicyNotFound(exceptions.NotFound):
|
||||
message = _("Firewall policy %(firewall_policy_id)s could not be found.")
|
||||
|
||||
|
||||
class FirewallPolicyInUse(exceptions.InUse):
|
||||
message = _("Firewall policy %(firewall_policy_id)s is being used.")
|
||||
|
||||
|
||||
class FirewallPolicyConflict(exceptions.Conflict):
|
||||
"""FWaaS exception raised for firewall policy conflict
|
||||
|
||||
Raised when user tries to use another project's unshared policy.
|
||||
"""
|
||||
message = _("Operation cannot be performed since firewall policy "
|
||||
"%(firewall_policy_id)s is not shared and does not belong to "
|
||||
"your project.")
|
||||
|
||||
|
||||
class FirewallRuleSharingConflict(exceptions.Conflict):
|
||||
"""FWaaS exception raised for conflict with shared rules
|
||||
|
||||
Raised if shared policy is created/updated with unshared rules.
|
||||
"""
|
||||
message = _("Operation cannot be performed since firewall policy "
|
||||
"%(firewall_policy_id)s is shared but firewall rule "
|
||||
"%(firewall_rule_id)s is not shared.")
|
||||
|
||||
|
||||
class FirewallPolicySharingConflict(exceptions.Conflict):
|
||||
"""FWaaS exception raised for shared policies
|
||||
|
||||
Raised if policy is shared without sharing its rules.
|
||||
"""
|
||||
message = _("Operation cannot be performed. Before sharing firewall "
|
||||
"policy %(firewall_policy_id)s, share associated firewall "
|
||||
"rule %(firewall_rule_id)s.")
|
||||
|
||||
|
||||
class FirewallRuleNotFound(exceptions.NotFound):
|
||||
message = _("Firewall rule %(firewall_rule_id)s could not be found.")
|
||||
|
||||
|
||||
class FirewallRuleInUse(exceptions.InUse):
|
||||
message = _("Firewall rule %(firewall_rule_id)s is being used.")
|
||||
|
||||
|
||||
class FirewallRuleNotAssociatedWithPolicy(exceptions.InvalidInput):
|
||||
message = _("Firewall rule %(firewall_rule_id)s is not associated "
|
||||
"with firewall policy %(firewall_policy_id)s.")
|
||||
|
||||
|
||||
class FirewallRuleInvalidProtocol(exceptions.InvalidInput):
|
||||
message = _("Firewall rule protocol %(protocol)s is not supported. "
|
||||
"Only protocol values %(values)s and their integer "
|
||||
"representation (0 to 255) are supported.")
|
||||
|
||||
|
||||
class FirewallRuleInvalidAction(exceptions.InvalidInput):
|
||||
message = _("Firewall rule action %(action)s is not supported. "
|
||||
"Only action values %(values)s are supported.")
|
||||
|
||||
|
||||
class FirewallRuleInvalidICMPParameter(exceptions.InvalidInput):
|
||||
message = _("%(param)s are not allowed when protocol "
|
||||
"is set to ICMP.")
|
||||
|
||||
|
||||
class FirewallRuleWithPortWithoutProtocolInvalid(exceptions.InvalidInput):
|
||||
message = _("Source/destination port requires a protocol.")
|
||||
|
||||
|
||||
class FirewallRuleInvalidPortValue(exceptions.InvalidInput):
|
||||
message = _("Invalid value for port %(port)s.")
|
||||
|
||||
|
||||
class FirewallRuleInfoMissing(exceptions.InvalidInput):
|
||||
message = _("Missing rule info argument for insert/remove "
|
||||
"rule operation.")
|
||||
|
||||
|
||||
class FirewallIpAddressConflict(exceptions.InvalidInput):
|
||||
message = _("Invalid input - IP addresses do not agree with IP Version.")
|
||||
|
||||
|
||||
class FirewallInternalDriverError(exceptions.NeutronException):
|
||||
"""FWaaS exception for all driver errors
|
||||
|
||||
On any failure or exception in the driver, driver should log it and
|
||||
raise this exception to the agent.
|
||||
"""
|
||||
message = _("%(driver)s: Internal driver error.")
|
||||
|
||||
|
||||
class FirewallRuleConflict(exceptions.Conflict):
|
||||
"""FWaaS rule conflict exception
|
||||
|
||||
Occurs when admin policy tries to use another project's rule that is
|
||||
not shared.
|
||||
"""
|
||||
message = _("Operation cannot be performed since firewall rule "
|
||||
"%(firewall_rule_id)s is not shared and belongs to "
|
||||
"another project %(project_id)s.")
|
||||
|
||||
|
||||
class FirewallRouterInUse(exceptions.InUse):
|
||||
message = _("Router(s) %(router_ids)s provided already associated with "
|
||||
"other firewall(s).")
|
|
@ -1,24 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib.api.definitions import firewall
|
||||
from neutron_lib.tests.unit.api.definitions import base
|
||||
|
||||
|
||||
class FirewallDefinitionTestCase(base.DefinitionBaseTestCase):
|
||||
extension_module = firewall
|
||||
extension_resources = ('firewalls', 'firewall_policies', 'firewall_rules')
|
||||
extension_attributes = ('action', 'admin_state_up', 'audited',
|
||||
'destination_ip_address', 'destination_port',
|
||||
'enabled', 'firewall_policy_id', 'firewall_rules',
|
||||
'ip_version', 'position', 'protocol',
|
||||
'source_ip_address', 'source_port')
|
|
@ -1,20 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib.api.definitions import firewallrouterinsertion
|
||||
from neutron_lib.tests.unit.api.definitions import base
|
||||
|
||||
|
||||
class FirewallDefinitionTestCase(base.DefinitionBaseTestCase):
|
||||
extension_module = firewallrouterinsertion
|
||||
extension_resources = ('firewalls',)
|
||||
extension_attributes = ('router_ids',)
|
Loading…
Reference in New Issue