forked from kytos/mef_eline
-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.py
99 lines (80 loc) · 3.51 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
"""Utility functions."""
import functools
from pathlib import Path
from flask import request
from openapi_core import create_spec
from openapi_core.contrib.flask import FlaskOpenAPIRequest
from openapi_core.validation.request.validators import RequestValidator
from openapi_spec_validator import validate_spec
from openapi_spec_validator.readers import read_from_filename
from werkzeug.exceptions import BadRequest, UnsupportedMediaType
from kytos.core import log
from kytos.core.events import KytosEvent
def emit_event(controller, name, **kwargs):
"""Send an event when something happens with an EVC."""
event_name = f"kytos/mef_eline.{name}"
event = KytosEvent(name=event_name, content=kwargs)
controller.buffers.app.put(event)
def notify_link_available_tags(controller, link):
"""Notify link available tags."""
emit_event(controller, "link_available_tags", link=link)
def compare_endpoint_trace(endpoint, vlan, trace):
"""Compare and endpoint with a trace step."""
return (
endpoint.switch.dpid == trace["dpid"]
and endpoint.port_number == trace["port"]
and vlan == trace["vlan"]
)
def load_spec():
"""Validate openapi spec."""
napp_dir = Path(__file__).parent
yml_file = napp_dir / "openapi.yml"
spec_dict, _ = read_from_filename(yml_file)
validate_spec(spec_dict)
return create_spec(spec_dict)
def validate(spec):
"""Decorator to validate a REST endpoint input.
Uses the schema defined in the openapi.yml file
to validate.
"""
def validate_decorator(func):
@functools.wraps(func)
def wrapper_validate(*args, **kwargs):
try:
data = request.get_json()
except BadRequest:
result = "The request body is not a well-formed JSON."
log.debug("create_circuit result %s %s", result, 400)
raise BadRequest(result) from BadRequest
if data is None:
result = "The request body mimetype is not application/json."
log.debug("update result %s %s", result, 415)
raise UnsupportedMediaType(result)
validator = RequestValidator(spec)
openapi_request = FlaskOpenAPIRequest(request)
result = validator.validate(openapi_request)
if result.errors:
errors = result.errors[0]
if hasattr(errors, "schema_errors"):
schema_errors = errors.schema_errors[0]
error_log = {
"error_message": schema_errors.message,
"error_validator": schema_errors.validator,
"error_validator_value": schema_errors.validator_value,
"error_path": list(schema_errors.path),
"error_schema": schema_errors.schema,
"error_schema_path": list(schema_errors.schema_path),
}
log.debug("error response: %s", error_log)
error_response = f"{schema_errors.message} for field"
error_response += (
f" {'/'.join(map(str,schema_errors.path))}."
)
else:
error_response = (
"The request body mimetype is not application/json."
)
raise BadRequest(error_response) from BadRequest
return func(*args, data=data, **kwargs)
return wrapper_validate
return validate_decorator