Commits (50)
......@@ -22,6 +22,7 @@ class DeviceTypeEnum(Enum):
# Emulated device types
EMULATED_CLIENT = 'emu-client'
EMULATED_DATACENTER = 'emu-datacenter'
EMULATED_IP_SDN_CONTROLLER = 'emu-ip-sdn-controller'
EMULATED_MICROWAVE_RADIO_SYSTEM = 'emu-microwave-radio-system'
EMULATED_OPEN_LINE_SYSTEM = 'emu-open-line-system'
EMULATED_OPTICAL_ROADM = 'emu-optical-roadm'
......@@ -36,6 +37,7 @@ class DeviceTypeEnum(Enum):
# Real device types
CLIENT = 'client'
DATACENTER = 'datacenter'
IP_SDN_CONTROLLER = 'ip-sdn-controller'
MICROWAVE_RADIO_SYSTEM = 'microwave-radio-system'
OPEN_LINE_SYSTEM = 'open-line-system'
OPTICAL_ROADM = 'optical-roadm'
......
......@@ -46,7 +46,7 @@ from slice.client.SliceClient import SliceClient
from .Tools import (
format_device_custom_config_rules, format_service_custom_config_rules, format_slice_custom_config_rules,
get_descriptors_add_contexts, get_descriptors_add_services, get_descriptors_add_slices,
get_descriptors_add_topologies, split_devices_by_rules)
get_descriptors_add_topologies, split_controllers_and_network_devices, split_devices_by_rules)
LOGGER = logging.getLogger(__name__)
LOGGERS = {
......@@ -56,9 +56,10 @@ LOGGERS = {
}
ENTITY_TO_TEXT = {
# name => singular, plural
# name => singular, plural
'context' : ('Context', 'Contexts' ),
'topology' : ('Topology', 'Topologies' ),
'controller': ('Controller', 'Controllers'),
'device' : ('Device', 'Devices' ),
'link' : ('Link', 'Links' ),
'service' : ('Service', 'Services' ),
......@@ -68,8 +69,8 @@ ENTITY_TO_TEXT = {
ACTION_TO_TEXT = {
# action => infinitive, past
'add' : ('Add', 'Added'),
'update' : ('Update', 'Updated'),
'add' : ('Add', 'Added' ),
'update' : ('Update', 'Updated' ),
'config' : ('Configure', 'Configured'),
}
......@@ -231,10 +232,12 @@ class DescriptorLoader:
def _load_dummy_mode(self) -> None:
# Dummy Mode: used to pre-load databases (WebUI debugging purposes) with no smart or automated tasks.
controllers, network_devices = split_controllers_and_network_devices(self.__devices)
self.__ctx_cli.connect()
self._process_descr('context', 'add', self.__ctx_cli.SetContext, Context, self.__contexts_add )
self._process_descr('topology', 'add', self.__ctx_cli.SetTopology, Topology, self.__topologies_add)
self._process_descr('device', 'add', self.__ctx_cli.SetDevice, Device, self.__devices )
self._process_descr('controller', 'add', self.__ctx_cli.SetDevice, Device, controllers )
self._process_descr('device', 'add', self.__ctx_cli.SetDevice, Device, network_devices )
self._process_descr('link', 'add', self.__ctx_cli.SetLink, Link, self.__links )
self._process_descr('service', 'add', self.__ctx_cli.SetService, Service, self.__services )
self._process_descr('slice', 'add', self.__ctx_cli.SetSlice, Slice, self.__slices )
......@@ -262,20 +265,23 @@ class DescriptorLoader:
self.__services_add = get_descriptors_add_services(self.__services)
self.__slices_add = get_descriptors_add_slices(self.__slices)
controllers_add, network_devices_add = split_controllers_and_network_devices(self.__devices_add)
self.__ctx_cli.connect()
self.__dev_cli.connect()
self.__svc_cli.connect()
self.__slc_cli.connect()
self._process_descr('context', 'add', self.__ctx_cli.SetContext, Context, self.__contexts_add )
self._process_descr('topology', 'add', self.__ctx_cli.SetTopology, Topology, self.__topologies_add)
self._process_descr('device', 'add', self.__dev_cli.AddDevice, Device, self.__devices_add )
self._process_descr('device', 'config', self.__dev_cli.ConfigureDevice, Device, self.__devices_config)
self._process_descr('link', 'add', self.__ctx_cli.SetLink, Link, self.__links )
self._process_descr('service', 'add', self.__svc_cli.CreateService, Service, self.__services_add )
self._process_descr('service', 'update', self.__svc_cli.UpdateService, Service, self.__services )
self._process_descr('slice', 'add', self.__slc_cli.CreateSlice, Slice, self.__slices_add )
self._process_descr('slice', 'update', self.__slc_cli.UpdateSlice, Slice, self.__slices )
self._process_descr('context', 'add', self.__ctx_cli.SetContext, Context, self.__contexts_add )
self._process_descr('topology', 'add', self.__ctx_cli.SetTopology, Topology, self.__topologies_add)
self._process_descr('controller', 'add', self.__dev_cli.AddDevice, Device, controllers_add )
self._process_descr('device', 'add', self.__dev_cli.AddDevice, Device, network_devices_add )
self._process_descr('device', 'config', self.__dev_cli.ConfigureDevice, Device, self.__devices_config)
self._process_descr('link', 'add', self.__ctx_cli.SetLink, Link, self.__links )
self._process_descr('service', 'add', self.__svc_cli.CreateService, Service, self.__services_add )
self._process_descr('service', 'update', self.__svc_cli.UpdateService, Service, self.__services )
self._process_descr('slice', 'add', self.__slc_cli.CreateSlice, Slice, self.__slices_add )
self._process_descr('slice', 'update', self.__slc_cli.UpdateSlice, Slice, self.__slices )
# By default the Context component automatically assigns devices and links to topologies based on their
# endpoints, and assigns topologies, services, and slices to contexts based on their identifiers.
......
......@@ -14,6 +14,7 @@
import copy, json
from typing import Dict, List, Optional, Tuple, Union
from common.DeviceTypes import DeviceTypeEnum
def get_descriptors_add_contexts(contexts : List[Dict]) -> List[Dict]:
contexts_add = copy.deepcopy(contexts)
......@@ -103,3 +104,24 @@ def split_devices_by_rules(devices : List[Dict]) -> Tuple[List[Dict], List[Dict]
devices_config.append(device)
return devices_add, devices_config
CONTROLLER_DEVICE_TYPES = {
DeviceTypeEnum.EMULATED_IP_SDN_CONTROLLER.value,
DeviceTypeEnum.EMULATED_MICROWAVE_RADIO_SYSTEM.value,
DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value,
DeviceTypeEnum.IP_SDN_CONTROLLER.value,
DeviceTypeEnum.MICROWAVE_RADIO_SYSTEM.value,
DeviceTypeEnum.OPEN_LINE_SYSTEM.value,
DeviceTypeEnum.TERAFLOWSDN_CONTROLLER.value,
}
def split_controllers_and_network_devices(devices : List[Dict]) -> Tuple[List[Dict], List[Dict]]:
controllers : List[Dict] = list()
network_devices : List[Dict] = list()
for device in devices:
device_type = device.get('device_type')
if device_type in CONTROLLER_DEVICE_TYPES:
controllers.append(device)
else:
network_devices.append(device)
return controllers, network_devices
......@@ -18,11 +18,12 @@
import json
from typing import Any, Dict, List, Optional, Tuple
from common.proto.context_pb2 import Constraint, EndPointId
from common.proto.context_pb2 import Constraint, ConstraintActionEnum, EndPointId
from common.tools.grpc.Tools import grpc_message_to_json_string
def update_constraint_custom_scalar(
constraints, constraint_type : str, value : Any, raise_if_differs : bool = False
constraints, constraint_type : str, value : Any, raise_if_differs : bool = False,
new_action : ConstraintActionEnum = ConstraintActionEnum.CONSTRAINTACTION_SET
) -> Constraint:
for constraint in constraints:
......@@ -36,6 +37,8 @@ def update_constraint_custom_scalar(
constraint.custom.constraint_type = constraint_type
json_constraint_value = None
constraint.action = new_action
if (json_constraint_value is None) or not raise_if_differs:
# missing or raise_if_differs=False, add/update it
json_constraint_value = value
......@@ -47,7 +50,10 @@ def update_constraint_custom_scalar(
constraint.custom.constraint_value = json.dumps(json_constraint_value, sort_keys=True)
return constraint
def update_constraint_custom_dict(constraints, constraint_type : str, fields : Dict[str, Tuple[Any, bool]]) -> Constraint:
def update_constraint_custom_dict(
constraints, constraint_type : str, fields : Dict[str, Tuple[Any, bool]],
new_action : ConstraintActionEnum = ConstraintActionEnum.CONSTRAINTACTION_SET
) -> Constraint:
# fields: Dict[field_name : str, Tuple[field_value : Any, raise_if_differs : bool]]
for constraint in constraints:
......@@ -61,6 +67,8 @@ def update_constraint_custom_dict(constraints, constraint_type : str, fields : D
constraint.custom.constraint_type = constraint_type
json_constraint_value = {}
constraint.action = new_action
for field_name,(field_value, raise_if_differs) in fields.items():
if (field_name not in json_constraint_value) or not raise_if_differs:
# missing or raise_if_differs=False, add/update it
......@@ -75,7 +83,8 @@ def update_constraint_custom_dict(constraints, constraint_type : str, fields : D
def update_constraint_endpoint_location(
constraints, endpoint_id : EndPointId,
region : Optional[str] = None, gps_position : Optional[Tuple[float, float]] = None
region : Optional[str] = None, gps_position : Optional[Tuple[float, float]] = None,
new_action : ConstraintActionEnum = ConstraintActionEnum.CONSTRAINTACTION_SET
) -> Constraint:
# gps_position: (latitude, longitude)
if region is not None and gps_position is not None:
......@@ -103,6 +112,8 @@ def update_constraint_endpoint_location(
_endpoint_id.topology_id.topology_uuid.uuid = topology_uuid
_endpoint_id.topology_id.context_id.context_uuid.uuid = context_uuid
constraint.action = new_action
location = constraint.endpoint_location.location
if region is not None:
location.region = region
......@@ -111,7 +122,10 @@ def update_constraint_endpoint_location(
location.gps_position.longitude = gps_position[1]
return constraint
def update_constraint_endpoint_priority(constraints, endpoint_id : EndPointId, priority : int) -> Constraint:
def update_constraint_endpoint_priority(
constraints, endpoint_id : EndPointId, priority : int,
new_action : ConstraintActionEnum = ConstraintActionEnum.CONSTRAINTACTION_SET
) -> Constraint:
endpoint_uuid = endpoint_id.endpoint_uuid.uuid
device_uuid = endpoint_id.device_id.device_uuid.uuid
topology_uuid = endpoint_id.topology_id.topology_uuid.uuid
......@@ -134,10 +148,15 @@ def update_constraint_endpoint_priority(constraints, endpoint_id : EndPointId, p
_endpoint_id.topology_id.topology_uuid.uuid = topology_uuid
_endpoint_id.topology_id.context_id.context_uuid.uuid = context_uuid
constraint.action = new_action
constraint.endpoint_priority.priority = priority
return constraint
def update_constraint_sla_capacity(constraints, capacity_gbps : float) -> Constraint:
def update_constraint_sla_capacity(
constraints, capacity_gbps : float,
new_action : ConstraintActionEnum = ConstraintActionEnum.CONSTRAINTACTION_SET
) -> Constraint:
for constraint in constraints:
if constraint.WhichOneof('constraint') != 'sla_capacity': continue
break # found, end loop
......@@ -145,10 +164,15 @@ def update_constraint_sla_capacity(constraints, capacity_gbps : float) -> Constr
# not found, add it
constraint = constraints.add() # pylint: disable=no-member
constraint.action = new_action
constraint.sla_capacity.capacity_gbps = capacity_gbps
return constraint
def update_constraint_sla_latency(constraints, e2e_latency_ms : float) -> Constraint:
def update_constraint_sla_latency(
constraints, e2e_latency_ms : float,
new_action : ConstraintActionEnum = ConstraintActionEnum.CONSTRAINTACTION_SET
) -> Constraint:
for constraint in constraints:
if constraint.WhichOneof('constraint') != 'sla_latency': continue
break # found, end loop
......@@ -156,11 +180,14 @@ def update_constraint_sla_latency(constraints, e2e_latency_ms : float) -> Constr
# not found, add it
constraint = constraints.add() # pylint: disable=no-member
constraint.action = new_action
constraint.sla_latency.e2e_latency_ms = e2e_latency_ms
return constraint
def update_constraint_sla_availability(
constraints, num_disjoint_paths : int, all_active : bool, availability : float
constraints, num_disjoint_paths : int, all_active : bool, availability : float,
new_action : ConstraintActionEnum = ConstraintActionEnum.CONSTRAINTACTION_SET
) -> Constraint:
for constraint in constraints:
if constraint.WhichOneof('constraint') != 'sla_availability': continue
......@@ -169,12 +196,17 @@ def update_constraint_sla_availability(
# not found, add it
constraint = constraints.add() # pylint: disable=no-member
constraint.action = new_action
constraint.sla_availability.num_disjoint_paths = num_disjoint_paths
constraint.sla_availability.all_active = all_active
constraint.sla_availability.availability = availability
return constraint
def update_constraint_sla_isolation(constraints, isolation_levels : List[int]) -> Constraint:
def update_constraint_sla_isolation(
constraints, isolation_levels : List[int],
new_action : ConstraintActionEnum = ConstraintActionEnum.CONSTRAINTACTION_SET
) -> Constraint:
for constraint in constraints:
if constraint.WhichOneof('constraint') != 'sla_isolation': continue
break # found, end loop
......@@ -182,6 +214,8 @@ def update_constraint_sla_isolation(constraints, isolation_levels : List[int]) -
# not found, add it
constraint = constraints.add() # pylint: disable=no-member
constraint.action = new_action
for isolation_level in isolation_levels:
if isolation_level in constraint.sla_isolation.isolation_level: continue
constraint.sla_isolation.isolation_level.append(isolation_level)
......
......@@ -73,6 +73,13 @@ class DeviceServiceServicerImpl(DeviceServiceServicer):
device.device_operational_status = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_UNDEFINED
device.device_drivers.extend(request.device_drivers) # pylint: disable=no-member
device.device_config.CopyFrom(request.device_config) # pylint: disable=no-member
if request.HasField('controller_id'):
controller_id = request.controller_id
if controller_id.HasField('device_uuid'):
controller_device_uuid = controller_id.device_uuid.uuid
device.controller_id.device_uuid.uuid = controller_device_uuid
device_id = context_client.SetDevice(device)
device = get_device(context_client, device_id.device_uuid.uuid, rw_copy=True)
......
......@@ -16,7 +16,7 @@ import json, logging, requests, threading
from typing import Any, Iterator, List, Optional, Tuple, Union
from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method
from common.type_checkers.Checkers import chk_string, chk_type
from device.service.driver_api._Driver import _Driver, RESOURCE_SERVICES
from device.service.driver_api._Driver import _Driver, RESOURCE_ENDPOINTS, RESOURCE_SERVICES
from .handlers.EthtServiceHandler import EthtServiceHandler
from .handlers.OsuTunnelHandler import OsuTunnelHandler
from .handlers.RestApiClient import RestApiClient
......@@ -25,6 +25,7 @@ from .Tools import get_etht_services, get_osu_tunnels, parse_resource_key
LOGGER = logging.getLogger(__name__)
ALL_RESOURCE_KEYS = [
RESOURCE_ENDPOINTS,
RESOURCE_SERVICES,
]
......@@ -78,7 +79,12 @@ class IetfActnDriver(_Driver):
try:
_results = list()
if resource_key == RESOURCE_SERVICES:
if resource_key == RESOURCE_ENDPOINTS:
# Add mgmt endpoint by default
resource_key = '/endpoints/endpoint[mgmt]'
resource_value = {'uuid': 'mgmt', 'name': 'mgmt', 'type': 'mgmt'}
results.append((resource_key, resource_value))
elif resource_key == RESOURCE_SERVICES:
get_osu_tunnels(self._handler_osu_tunnel, _results)
get_etht_services(self._handler_etht_service, _results)
else:
......
......@@ -31,10 +31,6 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
interface = {}
interface_name = xml_interface.find('oci:name', namespaces=NAMESPACES)
if interface_name is None or interface_name.text is None: continue
add_value_from_tag(interface, 'name', interface_name)
#interface_type = xml_interface.find('oci:config/oci:type', namespaces=NAMESPACES)
#add_value_from_tag(interface, 'type', interface_type)
......@@ -42,8 +38,11 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
interface_type = xml_interface.find('oci:config/oci:type', namespaces=NAMESPACES)
elif xml_interface.find('oci:state/oci:type', namespaces=NAMESPACES) is not None:
interface_type = xml_interface.find('oci:state/oci:type', namespaces=NAMESPACES)
else:
interface_type = ''
else: continue
interface_name = xml_interface.find('oci:name', namespaces=NAMESPACES)
if interface_name is None or interface_name.text is None: continue
add_value_from_tag(interface, 'name', interface_name)
# Get the type of interface according to the vendor's type
if 'ianaift:' in interface_type.text:
......
......@@ -54,7 +54,6 @@ XPATH_PORTS = "//ocp:components/ocp:component"
def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
response = []
LOGGER.debug("InventoryPrueba")
parent_types = {}
for xml_component in xml_data.xpath(XPATH_PORTS, namespaces=NAMESPACES):
LOGGER.info('xml_component inventario = {:s}'.format(str(ET.tostring(xml_component))))
......@@ -78,9 +77,9 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
add_value_from_tag(inventory['attributes'], 'location', component_location)
component_type = xml_component.find('ocp:state/ocp:type', namespaces=NAMESPACES)
component_type.text = component_type.text.replace('oc-platform-types:','')
if component_type is None: continue
add_value_from_tag(inventory, 'class', component_type)
if component_type is not None:
component_type.text = component_type.text.replace('oc-platform-types:','')
add_value_from_tag(inventory, 'class', component_type)
if inventory['class'] == 'CPU' or inventory['class'] == 'STORAGE': continue
......
......@@ -35,7 +35,7 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
#LOGGER.info('xml_policy_definition = {:s}'.format(str(ET.tostring(xml_policy_definition))))
policy_definition = {}
statement_name = ''
policy_name = xml_policy_definition.find('ocrp:name', namespaces=NAMESPACES)
if policy_name is None or policy_name.text is None: continue
add_value_from_tag(policy_definition, 'policy_name', policy_name)
......
......@@ -26,7 +26,7 @@
["128.32.20.5", 24, "128.32.33.5"]
],
"dst_node_id": "10.0.30.1", "dst_tp_id": "200", "dst_vlan_tag": 201, "dst_static_routes": [
["172.1.101.22", 24, "172.10.33.5"]
["172.1.201.22", 24, "172.10.33.5"]
]
}}}
]
......@@ -139,7 +139,7 @@
"is-terminal": true,
"static-route-list": [
{
"destination": "172.1.101.22",
"destination": "172.1.201.22",
"destination-mask": 24,
"next-hop": "172.10.33.5"
}
......
......@@ -151,6 +151,11 @@ def test_device_ietf_actn_configure(
retrieved_driver_config_rules = sorted(driver.GetConfig(), key=operator.itemgetter(0))
LOGGER.info('driver_config = {:s}'.format(str(retrieved_driver_config_rules)))
assert isinstance(retrieved_driver_config_rules, list)
retrieved_driver_config_rules = [
(resource_key, resource_value)
for resource_key, resource_value in retrieved_driver_config_rules
if resource_key != '/endpoints/endpoint[mgmt]'
]
if len(retrieved_driver_config_rules) > 0:
LOGGER.error('PRE DRIVER CONFIG RULES - Differences:\n{:s}'.format(str(retrieved_driver_config_rules)))
assert len(retrieved_driver_config_rules) == 0
......@@ -186,6 +191,7 @@ def test_device_ietf_actn_configure(
retrieved_driver_config_rules = [
{'action': 1, 'custom': {'resource_key': resource_key, 'resource_value': resource_value}}
for resource_key, resource_value in retrieved_driver_config_rules
if resource_key != '/endpoints/endpoint[mgmt]'
]
with open(DATA_FILE_CONFIG_RULES, 'r', encoding='UTF-8') as f:
expected_driver_config_rules = sorted(json.load(f), key=lambda cr: cr['custom']['resource_key'])
......@@ -231,6 +237,7 @@ def test_device_ietf_actn_deconfigure(
retrieved_driver_config_rules = [
{'action': 1, 'custom': {'resource_key': resource_key, 'resource_value': resource_value}}
for resource_key, resource_value in retrieved_driver_config_rules
if resource_key != '/endpoints/endpoint[mgmt]'
]
with open(DATA_FILE_CONFIG_RULES, 'r', encoding='UTF-8') as f:
expected_driver_config_rules = sorted(json.load(f), key=lambda cr: cr['custom']['resource_key'])
......@@ -266,6 +273,11 @@ def test_device_ietf_actn_deconfigure(
retrieved_driver_config_rules = sorted(driver.GetConfig(), key=operator.itemgetter(0))
LOGGER.info('retrieved_driver_config_rules = {:s}'.format(str(retrieved_driver_config_rules)))
assert isinstance(retrieved_driver_config_rules, list)
retrieved_driver_config_rules = [
(resource_key, resource_value)
for resource_key, resource_value in retrieved_driver_config_rules
if resource_key != '/endpoints/endpoint[mgmt]'
]
if len(retrieved_driver_config_rules) > 0:
LOGGER.error('POST DRIVER CONFIG RULES - Differences:\n{:s}'.format(str(retrieved_driver_config_rules)))
assert len(retrieved_driver_config_rules) == 0
......
......@@ -55,7 +55,7 @@ def process_vpn_service(
def update_service_endpoint(
service_uuid : str, site_id : str, device_uuid : str, endpoint_uuid : str,
vlan_tag : int, ipv4_address : str, ipv4_prefix_length : int,
vlan_tag : int, ipv4_address : str, neighbor_ipv4_address : str, ipv4_prefix_length : int,
capacity_gbps : Optional[float] = None, e2e_latency_ms : Optional[float] = None,
availability : Optional[float] = None, mtu : Optional[int] = None,
static_routing : Optional[Dict[Tuple[str, str], str]] = None,
......@@ -91,12 +91,15 @@ def update_service_endpoint(
for (ip_range, ip_prefix_len, lan_tag), next_hop in static_routing.items()
})
ENDPOINT_SETTINGS_KEY = '/device[{:s}]/endpoint[{:s}]/vlan[{:d}]/settings'
endpoint_settings_key = ENDPOINT_SETTINGS_KEY.format(device_uuid, endpoint_uuid, vlan_tag)
#ENDPOINT_SETTINGS_KEY = '/device[{:s}]/endpoint[{:s}]/vlan[{:d}]/settings'
#endpoint_settings_key = ENDPOINT_SETTINGS_KEY.format(device_uuid, endpoint_uuid, vlan_tag)
ENDPOINT_SETTINGS_KEY = '/device[{:s}]/endpoint[{:s}]/settings'
endpoint_settings_key = ENDPOINT_SETTINGS_KEY.format(device_uuid, endpoint_uuid)
field_updates = {}
if vlan_tag is not None: field_updates['vlan_tag' ] = (vlan_tag, True)
if ipv4_address is not None: field_updates['ip_address' ] = (ipv4_address, True)
if ipv4_prefix_length is not None: field_updates['prefix_length'] = (ipv4_prefix_length, True)
if vlan_tag is not None: field_updates['vlan_tag' ] = (vlan_tag, True)
if ipv4_address is not None: field_updates['ip_address' ] = (ipv4_address, True)
if neighbor_ipv4_address is not None: field_updates['neighbor_address'] = (neighbor_ipv4_address, True)
if ipv4_prefix_length is not None: field_updates['prefix_length' ] = (ipv4_prefix_length, True)
update_config_rule_custom(config_rules, endpoint_settings_key, field_updates)
try:
......@@ -131,7 +134,7 @@ def process_site_network_access(
raise NotImplementedError(MSG.format(str(ipv4_allocation['address-allocation-type'])))
ipv4_allocation_addresses = ipv4_allocation['addresses']
ipv4_provider_address = ipv4_allocation_addresses['provider-address']
#ipv4_customer_address = ipv4_allocation_addresses['customer-address']
ipv4_customer_address = ipv4_allocation_addresses['customer-address']
ipv4_prefix_length = ipv4_allocation_addresses['prefix-length' ]
vlan_tag = None
......@@ -176,7 +179,8 @@ def process_site_network_access(
availability = qos_profile_class['bandwidth']['guaranteed-bw-percent']
exc = update_service_endpoint(
service_uuid, site_id, device_uuid, endpoint_uuid, vlan_tag, ipv4_provider_address, ipv4_prefix_length,
service_uuid, site_id, device_uuid, endpoint_uuid,
vlan_tag, ipv4_customer_address, ipv4_provider_address, ipv4_prefix_length,
capacity_gbps=service_bandwidth_gbps, e2e_latency_ms=max_e2e_latency_ms, availability=availability,
mtu=service_mtu, static_routing=site_static_routing
)
......
......@@ -13,7 +13,7 @@
# limitations under the License.
import logging
from typing import Dict
from typing import Dict, List
from flask import request
from flask.json import jsonify
from flask_restful import Resource
......@@ -36,11 +36,40 @@ class L3VPN_Services(Resource):
request_data : Dict = request.json
LOGGER.debug('Request: {:s}'.format(str(request_data)))
errors = list()
if 'ietf-l3vpn-svc:l3vpn-services' in request_data:
# processing multiple L3VPN service requests formatted as:
#{
# "ietf-l3vpn-svc:l3vpn-services": {
# "l3vpn-svc": [
# {
# "service-id": "vpn1",
# "vpn-services": {
# "vpn-service": [
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._process_l3vpn(l3vpn_svc_request_data))
elif 'ietf-l3vpn-svc:l3vpn-svc' in request_data:
# processing single (standard) L3VPN service request formatted as:
#{
# "ietf-l3vpn-svc:l3vpn-svc": {
# "vpn-services": {
# "vpn-service": [
errors.extend(self._process_l3vpn(request_data))
else:
errors.append('unexpected request: {:s}'.format(str(request_data)))
response = jsonify(errors)
response.status_code = HTTP_CREATED if len(errors) == 0 else HTTP_SERVERERROR
return response
def _process_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 = []
errors = list()
for vpn_service in request_data['l3vpn-svc']['vpn-services']['vpn-service']:
process_vpn_service(vpn_service, errors)
......@@ -48,6 +77,4 @@ class L3VPN_Services(Resource):
for site in request_data['l3vpn-svc']['sites']['site']:
process_site(site, errors)
response = jsonify(errors)
response.status_code = HTTP_CREATED if len(errors) == 0 else HTTP_SERVERERROR
return response
return errors
......@@ -28,9 +28,11 @@ IGNORE_DEVICE_TYPES = {
DeviceTypeEnum.DATACENTER.value,
DeviceTypeEnum.EMULATED_CLIENT.value,
DeviceTypeEnum.EMULATED_DATACENTER.value,
DeviceTypeEnum.EMULATED_IP_SDN_CONTROLLER,
DeviceTypeEnum.EMULATED_MICROWAVE_RADIO_SYSTEM.value,
DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value,
DeviceTypeEnum.EMULATED_XR_CONSTELLATION.value,
DeviceTypeEnum.IP_SDN_CONTROLLER,
DeviceTypeEnum.MICROWAVE_RADIO_SYSTEM.value,
DeviceTypeEnum.NETWORK.value,
DeviceTypeEnum.OPEN_LINE_SYSTEM.value,
......@@ -39,10 +41,10 @@ IGNORE_DEVICE_TYPES = {
IGNORE_DEVICE_NAMES = {
NetworkTypeEnum.TE_OTN_TOPOLOGY: {
'128.32.10.1', '128.32.33.5', '128.32.20.5', '128.32.20.1', '128.32.10.5', 'nce-t'
'nce-t', '128.32.10.1', '128.32.33.5', '128.32.20.5', '128.32.20.1', '128.32.10.5',
},
NetworkTypeEnum.TE_ETH_TRAN_TOPOLOGY: {
'nce-t',
},
}
......
......@@ -39,12 +39,12 @@
{
"lan": "128.32.10.1/24",
"lan-tag": "vlan21",
"next-hop": "128.32.33.5"
"next-hop": "128.32.33.2"
},
{
"lan": "128.32.20.1/24",
"lan-tag": "vlan21",
"next-hop": "128.32.33.5"
"next-hop": "128.32.33.2"
}
]
}
......@@ -82,7 +82,7 @@
{
"lan": "172.1.101.1/24",
"lan-tag": "vlan21",
"next-hop": "10.0.10.1"
"next-hop": "128.32.33.254"
}
]
}
......@@ -147,7 +147,7 @@
{
"lan": "172.1.101.1/24",
"lan-tag": "vlan101",
"next-hop": "172.10.33.5"
"next-hop": "172.10.33.2"
}
]
}
......@@ -185,12 +185,12 @@
{
"lan": "128.32.10.1/24",
"lan-tag": "vlan101",
"next-hop": "10.0.30.1"
"next-hop": "172.10.33.254"
},
{
"lan": "128.32.20.1/24",
"lan-tag": "vlan101",
"next-hop": "10.0.30.1"
"next-hop": "172.10.33.254"
}
]
}
......
......@@ -39,12 +39,12 @@
{
"lan": "128.32.10.1/24",
"lan-tag": "vlan31",
"next-hop": "128.32.33.5"
"next-hop": "128.32.33.2"
},
{
"lan": "128.32.20.1/24",
"lan-tag": "vlan31",
"next-hop": "128.32.33.5"
"next-hop": "128.32.33.2"
}
]
}
......@@ -80,9 +80,9 @@
"cascaded-lan-prefixes": {
"ipv4-lan-prefixes": [
{
"lan": "172.1.101.1/24",
"lan": "172.1.201.1/24",
"lan-tag": "vlan31",
"next-hop": "10.0.10.1"
"next-hop": "128.32.33.254"
}
]
}
......@@ -145,9 +145,9 @@
"cascaded-lan-prefixes": {
"ipv4-lan-prefixes": [
{
"lan": "172.1.101.1/24",
"lan": "172.1.201.1/24",
"lan-tag": "vlan201",
"next-hop": "172.10.33.1"
"next-hop": "172.10.33.2"
}
]
}
......@@ -185,12 +185,12 @@
{
"lan": "128.32.10.1/24",
"lan-tag": "vlan201",
"next-hop": "10.0.30.1"
"next-hop": "172.10.33.254"
},
{
"lan": "128.32.20.1/24",
"lan-tag": "vlan201",
"next-hop": "10.0.30.1"
"next-hop": "172.10.33.254"
}
]
}
......
......@@ -73,6 +73,6 @@ def test_detect_attack(
request.service_id.service_uuid.uuid = str(uuid.uuid4())
request.kpi_id.kpi_id.uuid = "1"
optical_attack_detector_client.DetectAttack(request)
dbscanserving.assert_called_once()
monitoring.assert_called_once()
dbscanserving.assert_called()
monitoring.assert_called()
mitigator.NotifyAttack.assert_called()
......@@ -15,12 +15,16 @@
import json, logging, requests, uuid
from typing import Dict, List, Optional, Tuple, Union
from common.proto.context_pb2 import (
Connection, Device, DeviceList, EndPointId, Link, LinkList, Service, ServiceStatusEnum, ServiceTypeEnum)
ConfigRule, Connection, Device, DeviceList, EndPointId, Link, LinkList, Service, ServiceStatusEnum, ServiceTypeEnum
)
from common.proto.pathcomp_pb2 import PathCompReply, PathCompRequest
from common.tools.grpc.Tools import grpc_message_list_to_json
from pathcomp.frontend.Config import BACKEND_URL
from .tools.EroPathToHops import eropath_to_hops
from .tools.ComposeConfigRules import (
compose_device_config_rules, compose_l2nm_config_rules, compose_l3nm_config_rules, compose_tapi_config_rules)
compose_device_config_rules, compose_l2nm_config_rules, compose_l3nm_config_rules, compose_tapi_config_rules,
generate_neighbor_endpoint_config_rules
)
from .tools.ComposeRequest import compose_device, compose_link, compose_service
from .tools.ComputeSubServices import (
convert_explicit_path_hops_to_connections, convert_explicit_path_hops_to_plain_connection)
......@@ -227,12 +231,25 @@ class _Algorithm:
continue
orig_config_rules = grpc_orig_service.service_config.config_rules
json_orig_config_rules = grpc_message_list_to_json(orig_config_rules)
for service_path_ero in response['path']:
self.logger.debug('service_path_ero["devices"] = {:s}'.format(str(service_path_ero['devices'])))
_endpoint_to_link_dict = {k:v[0] for k,v in self.endpoint_to_link_dict.items()}
self.logger.debug('self.endpoint_to_link_dict = {:s}'.format(str(_endpoint_to_link_dict)))
path_hops = eropath_to_hops(service_path_ero['devices'], self.endpoint_to_link_dict)
json_generated_config_rules = generate_neighbor_endpoint_config_rules(
json_orig_config_rules, path_hops, self.device_name_mapping, self.endpoint_name_mapping
)
json_extended_config_rules = list()
json_extended_config_rules.extend(json_orig_config_rules)
json_extended_config_rules.extend(json_generated_config_rules)
extended_config_rules = [
ConfigRule(**json_extended_config_rule)
for json_extended_config_rule in json_extended_config_rules
]
self.logger.debug('path_hops = {:s}'.format(str(path_hops)))
try:
_device_dict = {k:v[0] for k,v in self.device_dict.items()}
......@@ -256,7 +273,7 @@ class _Algorithm:
if service_key in grpc_services: continue
grpc_service = self.add_service_to_reply(
reply, context_uuid, service_uuid, service_type, path_hops=path_hops,
config_rules=orig_config_rules)
config_rules=extended_config_rules)
grpc_services[service_key] = grpc_service
for connection in connections:
......