Loading src/nbi/service/ietf_l3vpn/Handlers.py +59 −3 Original line number Diff line number Diff line Loading @@ -215,3 +215,59 @@ def process_site(site : Dict, errors : List[Dict]) -> None: network_accesses : List[Dict] = site['site-network-accesses']['site-network-access'] for network_access in network_accesses: process_site_network_access(site_id, network_access, site_static_routing, errors) def update_vpn(site : Dict, errors : List[Dict]) -> None: if site['management']['type'] != 'ietf-l3vpn-svc:provider-managed': MSG = 'Site Management Type: {:s}' raise NotImplementedError(MSG.format(str(site['management']['type']))) network_accesses : List[Dict] = site['site-network-accesses']['site-network-access'] for network_access in network_accesses: update_site_network_access(network_access, errors) def update_site_network_access( network_access : Dict, errors : List[Dict] ) -> None: if network_access['site-network-access-type'] != 'ietf-l3vpn-svc:multipoint': MSG = 'Site Network Access Type: {:s}' raise NotImplementedError(MSG.format(str(network_access['site-network-access-type']))) service_uuid = network_access['vpn-attachment']['vpn-id'] service_input_bandwidth = network_access['service']['svc-input-bandwidth'] service_output_bandwidth = network_access['service']['svc-output-bandwidth'] service_bandwidth_bps = max(service_input_bandwidth, service_output_bandwidth) service_bandwidth_gbps = service_bandwidth_bps / 1.e9 max_e2e_latency_ms = None availability = None exc = update_site_endpoint( service_uuid, capacity_gbps=service_bandwidth_gbps, e2e_latency_ms=max_e2e_latency_ms, availability=availability, ) if exc is not None: errors.append({'error': str(exc)}) def update_site_endpoint( service_uuid : str, capacity_gbps : Optional[float] = None, e2e_latency_ms : Optional[float] = None, availability : Optional[float] = None, context_uuid : Optional[str] = DEFAULT_CONTEXT_NAME ) -> Optional[Exception]: context_client = ContextClient() service = get_service_by_uuid(context_client, service_uuid, context_uuid=context_uuid, rw_copy=True) if service is None: raise Exception('VPN({:s}) not found in database'.format(str(service_uuid))) constraints = service.service_constraints if capacity_gbps is not None: update_constraint_sla_capacity (constraints, capacity_gbps) if e2e_latency_ms is not None: update_constraint_sla_latency (constraints, e2e_latency_ms) if availability is not None: update_constraint_sla_availability(constraints, 1, True, availability) try: service_client = ServiceClient() service_client.UpdateService(service) return None except Exception as e: # pylint: disable=broad-except LOGGER.exception('Unhandled exception updating Service') return e src/nbi/service/ietf_l3vpn/L3VPN_Service.py +40 −2 Original line number Diff line number Diff line Loading @@ -20,8 +20,12 @@ from common.proto.context_pb2 import ServiceStatusEnum from common.tools.context_queries.Service import get_service_by_uuid from context.client.ContextClient import ContextClient from service.client.ServiceClient import ServiceClient from nbi.service._tools.Authentication import HTTP_AUTH from nbi.service._tools.HttpStatusCodes import HTTP_GATEWAYTIMEOUT, HTTP_NOCONTENT, HTTP_OK, HTTP_SERVERERROR from typing import Dict, List from ..tools.Authentication import HTTP_AUTH from ..tools.HttpStatusCodes import HTTP_GATEWAYTIMEOUT, HTTP_NOCONTENT, HTTP_OK, HTTP_SERVERERROR, HTTP_CREATED from .Handlers import update_vpn from werkzeug.exceptions import UnsupportedMediaType from .YangValidator import YangValidator LOGGER = logging.getLogger(__name__) Loading Loading @@ -76,3 +80,37 @@ class L3VPN_Service(Resource): response = jsonify({'error': str(e)}) response.status_code = HTTP_SERVERERROR return response def put(self, vpn_id : str): #TODO: check vpn_id with request service_id in body if not request.is_json: raise UnsupportedMediaType('JSON payload is required') request_data: Dict = request.json LOGGER.debug('PUT Request: {:s}'.format(str(request_data))) errors = list() if 'ietf-l3vpn-svc:l3vpn-services' in request_data: for l3vpn_svc in request_data['ietf-l3vpn-svc:l3vpn-services']['l3vpn-svc']: l3vpn_svc.pop('service-id', None) l3vpn_svc_request_data = {'ietf-l3vpn-svc:l3vpn-svc': l3vpn_svc} errors.extend(self._update_l3vpn(l3vpn_svc_request_data)) elif 'ietf-l3vpn-svc:l3vpn-svc' in request_data: errors.extend(self._update_l3vpn(request_data)) else: errors.append('Unexpected request format: {:s}'.format(str(request_data))) response = jsonify(errors) response.status_code = HTTP_CREATED if len(errors) == 0 else HTTP_SERVERERROR return response def _update_l3vpn(self, request_data: Dict) -> List[Dict]: yang_validator = YangValidator('ietf-l3vpn-svc') request_data = yang_validator.parse_to_dict(request_data) yang_validator.destroy() errors = list() for site in request_data['l3vpn-svc']['sites']['site']: update_vpn(site, errors) return errors Loading
src/nbi/service/ietf_l3vpn/Handlers.py +59 −3 Original line number Diff line number Diff line Loading @@ -215,3 +215,59 @@ def process_site(site : Dict, errors : List[Dict]) -> None: network_accesses : List[Dict] = site['site-network-accesses']['site-network-access'] for network_access in network_accesses: process_site_network_access(site_id, network_access, site_static_routing, errors) def update_vpn(site : Dict, errors : List[Dict]) -> None: if site['management']['type'] != 'ietf-l3vpn-svc:provider-managed': MSG = 'Site Management Type: {:s}' raise NotImplementedError(MSG.format(str(site['management']['type']))) network_accesses : List[Dict] = site['site-network-accesses']['site-network-access'] for network_access in network_accesses: update_site_network_access(network_access, errors) def update_site_network_access( network_access : Dict, errors : List[Dict] ) -> None: if network_access['site-network-access-type'] != 'ietf-l3vpn-svc:multipoint': MSG = 'Site Network Access Type: {:s}' raise NotImplementedError(MSG.format(str(network_access['site-network-access-type']))) service_uuid = network_access['vpn-attachment']['vpn-id'] service_input_bandwidth = network_access['service']['svc-input-bandwidth'] service_output_bandwidth = network_access['service']['svc-output-bandwidth'] service_bandwidth_bps = max(service_input_bandwidth, service_output_bandwidth) service_bandwidth_gbps = service_bandwidth_bps / 1.e9 max_e2e_latency_ms = None availability = None exc = update_site_endpoint( service_uuid, capacity_gbps=service_bandwidth_gbps, e2e_latency_ms=max_e2e_latency_ms, availability=availability, ) if exc is not None: errors.append({'error': str(exc)}) def update_site_endpoint( service_uuid : str, capacity_gbps : Optional[float] = None, e2e_latency_ms : Optional[float] = None, availability : Optional[float] = None, context_uuid : Optional[str] = DEFAULT_CONTEXT_NAME ) -> Optional[Exception]: context_client = ContextClient() service = get_service_by_uuid(context_client, service_uuid, context_uuid=context_uuid, rw_copy=True) if service is None: raise Exception('VPN({:s}) not found in database'.format(str(service_uuid))) constraints = service.service_constraints if capacity_gbps is not None: update_constraint_sla_capacity (constraints, capacity_gbps) if e2e_latency_ms is not None: update_constraint_sla_latency (constraints, e2e_latency_ms) if availability is not None: update_constraint_sla_availability(constraints, 1, True, availability) try: service_client = ServiceClient() service_client.UpdateService(service) return None except Exception as e: # pylint: disable=broad-except LOGGER.exception('Unhandled exception updating Service') return e
src/nbi/service/ietf_l3vpn/L3VPN_Service.py +40 −2 Original line number Diff line number Diff line Loading @@ -20,8 +20,12 @@ from common.proto.context_pb2 import ServiceStatusEnum from common.tools.context_queries.Service import get_service_by_uuid from context.client.ContextClient import ContextClient from service.client.ServiceClient import ServiceClient from nbi.service._tools.Authentication import HTTP_AUTH from nbi.service._tools.HttpStatusCodes import HTTP_GATEWAYTIMEOUT, HTTP_NOCONTENT, HTTP_OK, HTTP_SERVERERROR from typing import Dict, List from ..tools.Authentication import HTTP_AUTH from ..tools.HttpStatusCodes import HTTP_GATEWAYTIMEOUT, HTTP_NOCONTENT, HTTP_OK, HTTP_SERVERERROR, HTTP_CREATED from .Handlers import update_vpn from werkzeug.exceptions import UnsupportedMediaType from .YangValidator import YangValidator LOGGER = logging.getLogger(__name__) Loading Loading @@ -76,3 +80,37 @@ class L3VPN_Service(Resource): response = jsonify({'error': str(e)}) response.status_code = HTTP_SERVERERROR return response def put(self, vpn_id : str): #TODO: check vpn_id with request service_id in body if not request.is_json: raise UnsupportedMediaType('JSON payload is required') request_data: Dict = request.json LOGGER.debug('PUT Request: {:s}'.format(str(request_data))) errors = list() if 'ietf-l3vpn-svc:l3vpn-services' in request_data: for l3vpn_svc in request_data['ietf-l3vpn-svc:l3vpn-services']['l3vpn-svc']: l3vpn_svc.pop('service-id', None) l3vpn_svc_request_data = {'ietf-l3vpn-svc:l3vpn-svc': l3vpn_svc} errors.extend(self._update_l3vpn(l3vpn_svc_request_data)) elif 'ietf-l3vpn-svc:l3vpn-svc' in request_data: errors.extend(self._update_l3vpn(request_data)) else: errors.append('Unexpected request format: {:s}'.format(str(request_data))) response = jsonify(errors) response.status_code = HTTP_CREATED if len(errors) == 0 else HTTP_SERVERERROR return response def _update_l3vpn(self, request_data: Dict) -> List[Dict]: yang_validator = YangValidator('ietf-l3vpn-svc') request_data = yang_validator.parse_to_dict(request_data) yang_validator.destroy() errors = list() for site in request_data['l3vpn-svc']['sites']['site']: update_vpn(site, errors) return errors