Skip to content

Commit

Permalink
feat: proper api endpoints for network
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex4386 committed May 6, 2022
1 parent 66f301c commit c114f32
Show file tree
Hide file tree
Showing 11 changed files with 197 additions and 7 deletions.
47 changes: 47 additions & 0 deletions API/v1/Network/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from typing import Optional
from xmlrpc.client import Fault

from fastapi import APIRouter, Depends, HTTPException
from XenAPI.XenAPI import Failure
from XenGarden.Network import Network
from XenGarden.session import create_session

from API.v1.Common import xenapi_failure_jsonify
from API.v1.Network.info import router as _network_info
from API.v1.Network.list import router as _network_list
from app.settings import Settings


# === Condition Checker ===
async def verify_network_uuid(cluster_id: str, network_uuid: Optional[str] = None):
if network_uuid is None:
return

session = create_session(cluster_id, get_xen_clusters=Settings.get_xen_clusters())

try:
network = Network.get_by_uuid(session, network_uuid)

except Failure as xenapi_error:
if xenapi_error.details[0] == "UUID_INVALID":
raise HTTPException(
status_code=404, detail=f"Network {network_uuid} does not exist"
)

raise HTTPException(
status_code=500, detail=xenapi_failure_jsonify(xenapi_error)
)
except Fault as xml_rpc_error:
raise HTTPException(
status_code=int(xml_rpc_error.faultCode),
detail=xml_rpc_error.faultString,
)

session.xenapi.session.logout()


# === Router Actions ===
network_router = APIRouter(dependencies=[Depends(verify_network_uuid)])

network_router.include_router(_network_list, tags=["network"])
network_router.include_router(_network_info, tags=["network"])
43 changes: 43 additions & 0 deletions API/v1/Network/info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from http.client import RemoteDisconnected
from xmlrpc.client import Fault

from fastapi import APIRouter, HTTPException
from XenAPI.XenAPI import Failure
from XenGarden.Network import Network
from XenGarden.session import create_session

from API.v1.Common import xenapi_failure_jsonify
from API.v1.Network.serialize import serialize
from app.settings import Settings

router = APIRouter()


@router.get("/{cluster_id}/network/{network_uuid}")
async def network_get_by_uuid(cluster_id: str, network_uuid: str):
"""Get Virtual Network by UUID"""
try:
session = create_session(
_id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()
)

network: Network = Network.get_by_uuid(session=session, uuid=network_uuid)

if network is not None:
ret = dict(success=True, data=await serialize(network))
else:
ret = dict(success=False)

session.xenapi.session.logout()
return ret
except Failure as xenapi_error:
raise HTTPException(
status_code=500, detail=xenapi_failure_jsonify(xenapi_error)
)
except Fault as xml_rpc_error:
raise HTTPException(
status_code=int(xml_rpc_error.faultCode),
detail=xml_rpc_error.faultString,
)
except RemoteDisconnected as rd_error:
raise HTTPException(status_code=500, detail=rd_error.strerror)
45 changes: 45 additions & 0 deletions API/v1/Network/list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import asyncio
from http.client import RemoteDisconnected
from xmlrpc.client import Fault

from fastapi import APIRouter, HTTPException
from XenAPI.XenAPI import Failure
from XenGarden.Network import Network
from XenGarden.session import create_session

from API.v1.Common import xenapi_failure_jsonify
from API.v1.Network.serialize import serialize
from app.settings import Settings

router = APIRouter()


@router.get("/{cluster_id}/network/list")
async def network_list(cluster_id: str):
"""Get All Virtual Network from cluster"""

try:
session = create_session(
_id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()
)

networks = Network.get_all(session=session)
__santilized_networks = await asyncio.gather(
*[serialize(network) for network in networks]
)

ret = dict(success=True, data=__santilized_networks)

session.xenapi.session.logout()
return ret
except Failure as xenapi_error:
raise HTTPException(
status_code=500, detail=xenapi_failure_jsonify(xenapi_error)
)
except Fault as xml_rpc_error:
raise HTTPException(
status_code=int(xml_rpc_error.faultCode),
detail=xml_rpc_error.faultString,
)
except RemoteDisconnected as rd_error:
raise HTTPException(status_code=500, detail=rd_error.strerror)
10 changes: 10 additions & 0 deletions API/v1/Network/serialize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from XenGarden.Network import Network


async def serialize(network: Network):
return dict(
uuid=network.get_uuid(),
name=network.get_name(),
description=network.get_description(),
mtu=network.get_mtu(),
)
2 changes: 1 addition & 1 deletion API/v1/PIF/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
router = APIRouter()


@router.get("/{cluster_id}/pif/{vif_uuid}")
@router.get("/{cluster_id}/pif/{pif_uuid}")
async def pif_get_by_uuid(cluster_id: str, pif_uuid: str):
"""Get PIF by UUID"""
try:
Expand Down
42 changes: 40 additions & 2 deletions API/v1/VIF/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

from fastapi import APIRouter, HTTPException
from XenAPI.XenAPI import Failure
from XenGarden.Network import Network
from XenGarden.session import create_session
from XenGarden.VIF import VIF
from XenGarden.VM import VM

from API.v1.Common import xenapi_failure_jsonify
from API.v1.VIF.model import VIFCreateModel
Expand All @@ -18,19 +20,55 @@
async def vif_create(cluster_id: str, vif_model: VIFCreateModel):
"""Create VIF with provided parameters"""
try:
params = vif_model.dict()
params = vif_model.dict(exclude_unset=True)
if params.get("other_config") is None:
params["other_config"] = dict()

if params.get("qos_algorithm_type") is None:
params["qos_algorithm_type"] = ""
params["qos_algorithm_params"] = dict()

mtu = params.get("mtu")
if mtu is None:
params["mtu"] = 1500

mac = params.get("mac")
if mac is None:
import random

sample_mac = "52:54:00:%02x:%02x:%02x" % (
random.randint(0, 255),
random.randint(0, 255),
random.randint(0, 255),
)

params["mac"] = sample_mac

if params.get("vm") is None or params.get("network") is None:
raise HTTPException(
status_code=400,
detail=dict(type="invalid_request", error="missing required parameter"),
)

session = create_session(
_id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()
)

vif: VIF = VIF.create(session, params)
vm = VM.get_by_uuid(session, params.get("vm"))
network = Network.get_by_uuid(session, params.get("network"))

if vm is None or network is None:
raise HTTPException(
status_code=404,
detail=dict(
type="not_found", error="requested resource could not be found"
),
)

params["network"] = network
params["vm"] = vm

vif: VIF = VIF.create(session, **params)

if vif is not None:
ret = dict(success=True, data=await serialize(vif))
Expand Down
4 changes: 2 additions & 2 deletions API/v1/VIF/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ class VIFCreateModel(BaseModel):
device: str
network: str
vm: str
mac: str
mtu: int
mac: Optional[str]
mtu: Optional[int]
other_config: Optional[dict]
qos_algorithm_type: Optional[str]
qos_algorithm_params: Optional[dict]
Expand Down
1 change: 1 addition & 0 deletions API/v1/VIF/serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ async def serialize(vif: VIF):
info=vif.get_qos_info(),
supported=vif.supported_qos_types(),
),
device=vif.get_device(),
locking_mode=vif.get_locking_mode(),
ipv4=dict(address=vif.get_address_v4(), gateway=vif.get_gateway_v4()),
ipv6=dict(address=vif.get_address_v6(), gateway=vif.get_gateway_v6()),
Expand Down
6 changes: 6 additions & 0 deletions API/v1/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
from xmlrpc.client import Fault

from fastapi import APIRouter, Depends, HTTPException
from XenAPI.XenAPI import Failure
from XenGarden.session import create_session

from API.v1.Common import xenapi_failure_jsonify
from API.v1.Console import console_router
from API.v1.GuestMetrics import guest_router
from API.v1.Host import host_router
from API.v1.Network import network_router
from API.v1.PIF import pif_router
from API.v1.root import root_router
from API.v1.SR import sr_router
Expand Down Expand Up @@ -51,6 +56,7 @@ async def verify_cluster_id(cluster_id: str):
_api_router.include_router(vdi_router)
_api_router.include_router(vif_router)
_api_router.include_router(pif_router)
_api_router.include_router(network_router)
_api_router.include_router(vm_router)
_api_router.include_router(guest_router)

Expand Down
2 changes: 1 addition & 1 deletion app/controller/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import asyncio
from asyncio import AbstractEventLoop
from typing import List, Optional
from typing import Optional

from fastapi import Depends

Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ databases[mysql]
mysqlclient
requests
schedule
XenGarden==1.2.7
XenGarden==1.2.9
pyfiglet
fastapi
uvicorn
Expand Down

0 comments on commit c114f32

Please sign in to comment.