Skip to content

Commit

Permalink
Merge pull request #166 from kytos-ng/epic/vlan_pool_request_get
Browse files Browse the repository at this point in the history
feature: Added get endpoints for Interface tag ranges
  • Loading branch information
viniarck authored Oct 11, 2023
2 parents 3b720ae + b2adf30 commit 151db27
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Added
=====
- Added endpoint ``POST v3/interfaces/{interface_id}/tag_ranges`` to set ``tag_ranges`` to interfaces.
- Added endpoint ``DELETE v3/interfaces/{interface_id}/tag_ranges`` to delete ``tag_ranges`` from interfaces.
- Added endpoint ``GET v3/interfaces/{interface_id}/tag_ranges`` to get ``available_tags`` and ``tag_ranges`` from an interface.
- Added endpoint ``GET v3/interfaces/tag_ranges`` to get ``available_tags`` and ``tag_ranges`` from all interfaces.
- Added ``Tag_ranges`` documentation to openapi.yml
- Added API request POST and DELETE to modify ``Interface.tag_ranges``
- Added listener for ``kytos/core.interface_tags`` event to save any changes made to ``Interface`` attributes ``tag_ranges`` and ``available_tags``
Expand Down
29 changes: 29 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,35 @@ def delete_tag_range(self, request: Request) -> JSONResponse:
raise HTTPException(400, detail=detail)
return JSONResponse("Operation Successful", status_code=200)

@rest('v3/interfaces/tag_ranges', methods=['GET'])
@validate_openapi(spec)
def get_all_tag_ranges(self, _: Request) -> JSONResponse:
"""Get all tag_ranges and available_tags from interfaces"""
result = {}
for switch in self.controller.switches.copy().values():
for interface in switch.interfaces.copy().values():
result[interface.id] = {
"available_tags": interface.available_tags,
"tag_ranges": interface.tag_ranges
}
return JSONResponse(result, status_code=200)

@rest('v3/interfaces/{interface_id}/tag_ranges', methods=['GET'])
@validate_openapi(spec)
def get_tag_ranges_by_intf(self, request: Request) -> JSONResponse:
"""Get tag_ranges and available_tags an interface"""
interface_id = request.path_params["interface_id"]
interface = self.controller.get_interface_by_id(interface_id)
if not interface:
raise HTTPException(404, detail="Interface not found")
result = {
interface_id: {
"available_tags": interface.available_tags,
"tag_ranges": interface.tag_ranges
}
}
return JSONResponse(result, status_code=200)

# Link related methods
@rest('v3/links')
def get_links(self, _request: Request) -> JSONResponse:
Expand Down
63 changes: 63 additions & 0 deletions openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,59 @@ paths:
schema:
type: string
example: Switch not found
/v3/interfaces/tag_ranges:
get:
summary: Get tag_ranges and available_tags from all interface
responses:
'200':
description: Ok
content:
application/json:
schema:
type: object
properties:
interface_id:
type: object
properties:
tag_ranges:
$ref: '#/components/schemas/InterfaceRanges'
available_tags:
$ref: '#/components/schemas/InterfaceRanges'
example:
"00:00:00:00:00:00:00:01:2":
"available_tags": [[1, 4096]]
"tag_ranges": [[1,4096]]
/v3/interfaces/{interface_id}/tag_ranges:
get:
summary: Get tag_ranges and available_tags from an interface
parameters:
- name: interface_id
schema:
type: string
required: true
description: The interface ID
in: path
responses:
'200':
description: Ok
content:
application/json:
schema:
type: object
properties:
interface_id:
type: object
properties:
tag_ranges:
$ref: '#/components/schemas/InterfaceRanges'
available_tags:
$ref: '#/components/schemas/InterfaceRanges'
example:
"00:00:00:00:00:00:00:01:2":
"available_tags": [[1, 4096]]
"tag_ranges": [[1,4096]]
'404':
description: Interface not found
post:
summary: Set tag_range from an interface
parameters:
Expand Down Expand Up @@ -753,3 +805,14 @@ components:
- type: array
- type: integer
example: [[1, 500], 2096, [3001]]
InterfaceRanges: # Can be referenced via '#/components/schemas/InterfaceRanges'
type: object
properties:
vlan:
type: array
items:
type: array
items:
type: integer
minItems: 2
maxItems: 2
52 changes: 52 additions & 0 deletions tests/unit/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1807,3 +1807,55 @@ async def test_delete_tag_range_type_error(self, event_loop):
url = f"{self.base_endpoint}/interfaces/{interface_id}/tag_ranges"
response = await self.api_client.delete(url)
assert response.status_code == 400

async def test_get_all_tag_ranges(self, event_loop):
"""Test get_all_tag_ranges"""
self.napp.controller.loop = event_loop
dpid = '00:00:00:00:00:00:00:01'
switch = get_switch_mock(dpid)
interface = get_interface_mock('s1-eth1', 1, switch)
tags = {'vlan': [[1, 4095]]}
interface.tag_ranges = tags
interface.available_tags = tags
switch.interfaces = {1: interface}
self.napp.controller.switches = {dpid: switch}
url = f"{self.base_endpoint}/interfaces/tag_ranges"
response = await self.api_client.get(url)
expected = {dpid + ":1": {
'available_tags': tags,
'tag_ranges': tags
}}
assert response.status_code == 200
assert response.json() == expected

async def test_get_tag_ranges_by_intf(self, event_loop):
"""Test get_tag_ranges_by_intf"""
self.napp.controller.loop = event_loop
dpid = '00:00:00:00:00:00:00:01'
switch = get_switch_mock(dpid)
interface = get_interface_mock('s1-eth1', 1, switch)
tags = {'vlan': [[1, 4095]]}
interface.tag_ranges = tags
interface.available_tags = tags
self.napp.controller.get_interface_by_id = MagicMock()
self.napp.controller.get_interface_by_id.return_value = interface
url = f"{self.base_endpoint}/interfaces/{dpid}:1/tag_ranges"
response = await self.api_client.get(url)
expected = {
'00:00:00:00:00:00:00:01:1': {
"available_tags": tags,
"tag_ranges": tags
}
}
assert response.status_code == 200
assert response.json() == expected

async def test_get_tag_ranges_by_intf_error(self, event_loop):
"""Test get_tag_ranges_by_intf with NotFound"""
self.napp.controller.loop = event_loop
dpid = '00:00:00:00:00:00:00:01'
self.napp.controller.get_interface_by_id = MagicMock()
self.napp.controller.get_interface_by_id.return_value = None
url = f"{self.base_endpoint}/interfaces/{dpid}:1/tag_ranges"
response = await self.api_client.get(url)
assert response.status_code == 404

0 comments on commit 151db27

Please sign in to comment.