Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update dl_vlan validation to allow mask #135

Merged
merged 9 commits into from
Mar 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ file.
[UNRELEASED] - Under development
********************************

Added
=====

- Added support for VLAN with mask. ``dl_vlan`` now also supports a string ``"vlan/mask"``.

Changed
=======
- Update endpoint ``GET v2/stored_flows`` to return the flows in descending order by `priority`.
Expand Down
18 changes: 16 additions & 2 deletions db/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from datetime import datetime
from decimal import Decimal
from enum import Enum
from typing import List, Optional
from typing import List, Optional, Union

from bson.decimal128 import Decimal128
from pydantic import BaseModel, Field, validator
Expand Down Expand Up @@ -50,7 +50,7 @@ class MatchSubDoc(BaseModel):
dl_src: Optional[str]
dl_dst: Optional[str]
dl_type: Optional[int]
dl_vlan: Optional[int]
dl_vlan: Optional[Union[int, str]]
dl_vlan_pcp: Optional[int]
nw_src: Optional[str]
nw_dst: Optional[str]
Expand Down Expand Up @@ -87,6 +87,20 @@ class MatchSubDoc(BaseModel):
metadata: Optional[int]
tun_id: Optional[int]

@validator("dl_vlan")
def vlan_with_mask(cls, v):
"""Validate vlan format"""
try:
return int(v)
except ValueError:
try:
[int(part) for part in v.split("/")]
except ValueError:
raise ValueError(
"must be an integer or an integer with a mask in format vlan/mask"
)
return v


class FlowSubDoc(BaseModel):
"""Flow DB SubDocument Model."""
Expand Down
8 changes: 5 additions & 3 deletions openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,11 @@ components:
format: int16
example: 2048
dl_vlan:
type: integer
format: int16
example: 300
oneOf:
- type: string
example: "40/4088"
- type: integer
example: 40
dl_vlan_pcp:
type: integer
format: int8
Expand Down
25 changes: 25 additions & 0 deletions tests/unit/test_db_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,28 @@ def test_flow_doct(self) -> None:
flow_doc = FlowDoc(**data)
assert flow_doc
assert flow_doc.flow.instructions == flow_dict["instructions"]

def test_flow_vlan_range(self) -> None:
"""Test a flow with a vlan range match."""
flow_dict = {
"match": {
"in_port": 9,
"dl_vlan": "24/4088",
"dl_type": 2048,
"nw_proto": 6,
},
"instructions": [
{
"instruction_type": "apply_actions",
"actions": [{"action_type": "output", "port": 4}],
},
],
}
data = {
"switch": "00:00:00:00:00:00:00:02",
"flow_id": "1",
"id": "0",
"flow": flow_dict,
}
flow_doc = FlowDoc(**data)
assert flow_doc
1 change: 0 additions & 1 deletion tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ def test_validate_range_exceptions(self):
test_data = [((1,), ValueError), ((2, 1), ValueError), ((1, "1"), TypeError)]
for values, exception in test_data:
with self.subTest(values=values, exception=exception):

with self.assertRaises(exception) as exc:
_validate_range(values)

Expand Down