Skip to content
Snippets Groups Projects
Commit 9c83759f authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Device - IETF ACTN Driver:

- Intermediate backup
- Added example messages
- Implemented request message composers
- Implemented handlers (work in progress)
parent d0bbc4e7
No related branches found
No related tags found
2 merge requests!235Release TeraFlowSDN 3.0,!188Resolve "(CTTC) Implement SBI Driver ACTN"
Showing
with 635 additions and 117 deletions
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import enum
from typing import Dict
OSU_TUNNEL_URL = '/restconf/data/ietf-te:tunnel'
class EndpointProtectionRoleEnum(enum.Enum):
WORK = 'work'
class LspProtectionTypeEnum(enum.Enum):
UNPROTECTED = 'ietf-te-types:lsp-protection-unprotected'
class LspRestorationTypeEnum(enum.Enum):
NOT_APPLICABLE = 'ietf-te-types:lsp-restoration-not-applicable'
class TunnelAdminStateEnum(enum.Enum):
UP = 'ietf-te-types:tunnel-admin-state-up'
class OduTypeEnum(enum.Enum):
OSUFLEX = 'osuflex'
def compose_osu_tunnel_endpoint(
node_id : str, tp_id : str, ttp_channel_name : str,
protection_role : EndpointProtectionRoleEnum = EndpointProtectionRoleEnum.WORK
) -> Dict:
return {
'node-id': node_id, 'tp-id': tp_id, 'ttp-channel-name': ttp_channel_name,
'protection-role': protection_role.value
}
def compose_osu_tunnel_te_bandwidth_odu(odu_type : OduTypeEnum, number : int) -> Dict:
return {'layer': 'odu', 'odu-type': odu_type.value, 'number': number}
def compose_osu_tunnel_protection(
type_ : LspProtectionTypeEnum = LspProtectionTypeEnum.UNPROTECTED, reversion_disable : bool = True
) -> Dict:
return {'protection-type': type_.value, 'protection-reversion-disable': reversion_disable}
def compose_osu_tunnel_restoration(
type_ : LspRestorationTypeEnum = LspRestorationTypeEnum.NOT_APPLICABLE, restoration_lock : bool = False
) -> Dict:
return {'restoration-type': type_.value, 'restoration-lock': restoration_lock}
def compose_osu_tunnel(
name : str,
src_node_id : str, src_tp_id : str, src_ttp_channel_name : str,
dst_node_id : str, dst_tp_id : str, dst_ttp_channel_name : str,
odu_type : OduTypeEnum, osuflex_number : int,
delay : int, bidirectional : bool = True,
admin_state : TunnelAdminStateEnum = TunnelAdminStateEnum.UP
) -> Dict:
return {'ietf-te:tunnel': [{
'name': name.lower(),
'title': name.upper(),
'admin-state': admin_state.value,
'delay': delay,
'te-bandwidth': compose_osu_tunnel_te_bandwidth_odu(odu_type, osuflex_number),
'bidirectional': bidirectional,
'source-endpoints': {'source-endpoint': [
compose_osu_tunnel_endpoint(src_node_id, src_tp_id, src_ttp_channel_name),
]},
'destination-endpoints': {'destination-endpoint': [
compose_osu_tunnel_endpoint(dst_node_id, dst_tp_id, dst_ttp_channel_name),
]},
'restoration': compose_osu_tunnel_restoration(),
'protection': compose_osu_tunnel_protection(),
}]}
......@@ -140,40 +140,7 @@ def create_resource(
url = '{:s}/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context'.format(base_url)
headers = {'content-type': 'application/json'}
data = {
'tapi-connectivity:connectivity-service': [
{
'uuid': uuid,
'connectivity-constraint': {
'requested-capacity': {
'total-size': {
'value': capacity_value,
'unit': capacity_unit
}
},
'connectivity-direction': direction
},
'end-point': [
{
'service-interface-point': {
'service-interface-point-uuid': input_sip
},
'layer-protocol-name': layer_protocol_name,
'layer-protocol-qualifier': layer_protocol_qualifier,
'local-id': input_sip
},
{
'service-interface-point': {
'service-interface-point-uuid': output_sip
},
'layer-protocol-name': layer_protocol_name,
'layer-protocol-qualifier': layer_protocol_qualifier,
'local-id': output_sip
}
]
}
]
}
data = compose_...
results = []
try:
LOGGER.info('Connectivity service {:s}: {:s}'.format(str(uuid), str(data)))
......@@ -194,9 +161,9 @@ def delete_resource(
base_url : str, resource_key : str, resource_value : Dict,
auth : Optional[HTTPBasicAuth] = None, timeout : Optional[int] = None
):
uuid = find_key(resource, 'uuid')
uuid = find_key(resource_value, 'uuid')
url = '{:s}/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connectivity-service={:s}'
url = '{:s}/tapi-common:context/tapi-connectivity:connectivity-context/connectivity-service={:s}'
url = url.format(base_url, uuid)
results = []
try:
......
{
"ietf-eth-tran-service:etht-svc": {
"etht-svc-instances": [
{
"etht-svc-name": "etht_service_1",
"etht-svc-title": "ETHT_SVC_1",
"etht-svc-type": "op-mp2mp-svc?",
"source-endpoints": {
"source-endpoint": [
{
"node-id": "10.0.10.1",
"tp-id": "200",
"protection-role": "work?",
"layer-specific": {
"access-type": "port"
},
"is-extendable": false,
"is-terminal": true,
"static-route-list": [
{
"destination": "128.32.10.5",
"destination-mask": 24,
"next-hop": "128.32.33.5"
},
{
"destination": "128.32.20.5",
"destination-mask": 24,
"next-hop": "128.32.33.5"
}
],
"outer-tag": {
"tag-type": "ietf-eth-tran-types:classify-c-vlan",
"vlan-value": 21
},
"service-classification-type": "ietf-eth-tran-type:vlan-classification",
"ingress-egress-bandwidth-profile" : {
"bandwidth-profile-type": "ietf-eth-tran-types:mef-10-bwp",
"CIR": 10000000,
"EIR": 10000000
}
}
]
},
"destination-endpoints": {
"destination-endpoint": [
{
"node-id": "10.0.30.1",
"tp-id": "200",
"protection-role": "work?",
"layer-specific": {
"access-type": "port"
},
"is-extendable": false,
"is-terminal": true,
"static-route-list": [
{
"destination": "172.1.101.22",
"destination-mask": 24,
"next-hop": "172.10.33.5"
}
],
"outer-tag": {
"tag-type": "ietf-eth-tran-types:classify-c-vlan",
"vlan-value": 101
},
"service-classification-type": "ietf-eth-tran-type:vlan-classification",
"ingress-egress-bandwidth-profile" : {
"bandwidth-profile-type": "ietf-eth-tran-types:mef-10-bwp",
"CIR": 10000000,
"EIR": 10000000
}
}
]
},
"svc-tunnel": [
{
"tunnel-name": "osu_tunnel_1"
}
],
"optimizations": {
"optimization-metric": [
{
"metric-role": "work?",
"metric-type": "ietf-te-types:path-metric-te"
}
]
}
}
]
}
}
\ No newline at end of file
{
"ietf-eth-tran-service:etht-svc": {
"etht-svc-instances": [
{
"etht-svc-name": "etht_service_2",
"etht-svc-title": "ETHT_SVC_2",
"etht-svc-type": "op-p2mp-svc?",
"source-endpoints": {
"source-endpoint": [
{
"node-id": "10.0.10.1",
"tp-id": "200",
"protection-role": "work?",
"layer-specific": {
"access-type": "port"
},
"is-extendable": false,
"is-terminal": true,
"static-route-list": [
{
"destination": "128.32.10.5",
"destination-mask": 24,
"next-hop": "128.32.33.5"
},
{
"destination": "128.32.20.5",
"destination-mask": 24,
"next-hop": "128.32.33.5"
}
],
"outer-tag": {
"tag-type": "ietf-eth-tran-types:classify-c-vlan",
"vlan-value": 31
},
"service-classification-type": "ietf-eth-tran-type:vlan-classification",
"ingress-egress-bandwidth-profile" : {
"bandwidth-profile-type": "ietf-eth-tran-types:mef-10-bwp",
"CIR": 10000000,
"EIR": 10000000
}
}
]
},
"destination-endpoints": {
"destination-endpoint": [
{
"node-id": "10.0.30.1",
"tp-id": "200",
"protection-role": "work?",
"layer-specific": {
"access-type": "port"
},
"is-extendable": false,
"is-terminal": true,
"static-route-list": [
{
"destination": "172.1.101.22",
"destination-mask": 24,
"next-hop": "172.10.33.5"
}
],
"outer-tag": {
"tag-type": "ietf-eth-tran-types:classify-c-vlan",
"vlan-value": 201
},
"service-classification-type": "ietf-eth-tran-type:vlan-classification",
"ingress-egress-bandwidth-profile" : {
"bandwidth-profile-type": "ietf-eth-tran-types:mef-10-bwp",
"CIR": 10000000,
"EIR": 10000000
}
}
]
},
"svc-tunnel": [
{
"tunnel-name": "osu_tunnel_2"
}
],
"optimizations": {
"optimization-metric": [
{
"metric-role": "work?",
"metric-type": "ietf-te-types:path-metric-te"
}
]
}
}
]
}
}
\ No newline at end of file
{
"ietf-te:tunnel": [
{
"name": "osu_tunnel_1",
"title": "OSU_TUNNEL_1",
"admin-state": "ietf-te-types:tunnel-admin-state-up",
"delay": 20,
"te-bandwidth": {
"layer": "odu",
"odu-type": "osuflex",
"number": 1
},
"bidirectional": true,
"destination-endpoints": {
"destination-endpoint": [
{
"node-id": "10.0.30.1",
"tp-id": "200",
"ttp-channel-name": "och:1-odu2:1-oduflex:3-osuflex:1?",
"protection-role": "work"
}
]
},
"source-endpoints": {
"source-endpoint": [
{
"node-id": "10.0.10.1",
"tp-id": "200",
"ttp-channel-name": "och:1-odu2:1-oduflex:1-osuflex:2?",
"protection-role": "work"
}
]
},
"restoration": {
"restoration-type": "ietf-te-types:lsp-restoration-not-applicable",
"restoration-lock": false
},
"protection": {
"protection-type": "ietf-te-types:lsp-protection-unprotected",
"protection-reversion-disable": true
}
}
]
}
\ No newline at end of file
{
"ietf-te:tunnel": [
{
"name": "osu_tunnel_2",
"title": "OSU_TUNNEL_2",
"admin-state": "ietf-te-types:tunnel-admin-state-up",
"delay": 20,
"te-bandwidth": {
"layer": "odu",
"odu-type": "osuflex",
"number": 1
},
"bidirectional": true,
"destination-endpoints": {
"destination-endpoint": [
{
"node-id": "10.0.30.1",
"tp-id": "200",
"ttp-channel-name": "och:1-odu2:1-oduflex:3-osuflex:1?",
"protection-role": "work"
}
]
},
"source-endpoints": {
"source-endpoint": [
{
"node-id": "10.0.10.1",
"tp-id": "200",
"ttp-channel-name": "och:1-odu2:1-oduflex:1-osuflex:2?",
"protection-role": "work"
}
]
},
"restoration": {
"restoration-type": "ietf-te-types:lsp-restoration-not-applicable",
"restoration-lock": false
},
"protection": {
"protection-type": "ietf-te-types:lsp-protection-unprotected",
"protection-reversion-disable": true
}
}
]
}
\ No newline at end of file
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import enum
from typing import Dict, List, Tuple
OSU_TUNNEL_URL = '/restconf/data/ietf-te:tunnel'
class BandwidthProfileTypeEnum(enum.Enum):
MEF_10_BWP = 'ietf-eth-tran-types:mef-10-bwp'
class EndpointLayerSpecificAccessTypeEnum(enum.Enum):
PORT = 'port'
class EndpointProtectionRoleEnum(enum.Enum):
WORK = 'work'
class OptimizationMetricRole(enum.Enum):
WORK = 'work'
class OptimizationMetricType(enum.Enum):
PATH_METRIC_TE = 'ietf-te-types:path-metric-te'
class OuterTagTypeEnum(enum.Enum):
CLASSIFY_C_VLAN = 'ietf-eth-tran-types:classify-c-vlan'
class ServiceClassificationTypeEnum(enum.Enum):
VLAN_CLASSIFICATION = 'ietf-eth-tran-type:vlan-classification'
class ServiceTypeEnum(enum.Enum):
MP2MP = 'op-mp2mp-svc'
P2MP = 'op-p2mp-svc'
def compose_outer_tag(tag_type : OuterTagTypeEnum, vlan_value : int) -> Dict:
return {'tag-type': tag_type.value, 'vlan-value': vlan_value}
def compose_ingress_egress_bandwidth_profile() -> Dict:
return {
'bandwidth-profile-type': BandwidthProfileTypeEnum.MEF_10_BWP.value,
'CIR': 10_000_000,
'EIR': 10_000_000,
}
def compose_layer_specific_access_type() -> Dict:
return {'access-type': EndpointLayerSpecificAccessTypeEnum.PORT.value}
def compose_static_route(prefix : str, mask : int, next_hop : str) -> Dict:
return {'destination': prefix, 'destination-mask': mask, 'next-hop': next_hop}
def compose_static_route_list(static_routes : List[Tuple[str, int, str]]) -> List[Dict]:
return [
compose_static_route(prefix, mask, next_hop)
for prefix, mask, next_hop in static_routes
]
def compose_etht_service_endpoint(
node_id : str, tp_id : str, vlan_value : int, static_routes : List[Tuple[str, int, str]] = list()
) -> Dict:
return {
'node-id' : node_id,
'tp-id' : tp_id,
'protection-role' : EndpointProtectionRoleEnum.WORK.value,
'layer-specific' : compose_layer_specific_access_type,
'is-extendable' : False,
'is-terminal' : True,
'static-route-list' : compose_static_route_list(static_routes),
'outer-tag' : compose_outer_tag(OuterTagTypeEnum.CLASSIFY_C_VLAN, vlan_value),
'service-classification-type' : ServiceClassificationTypeEnum.VLAN_CLASSIFICATION.value,
'ingress-egress-bandwidth-profile': compose_ingress_egress_bandwidth_profile(),
}
def compose_optimizations() -> Dict:
return {'optimization-metric': [{
'metric-role': OptimizationMetricRole.WORK.value,
'metric-type': OptimizationMetricType.PATH_METRIC_TE.value,
}]}
def compose_etht_service(
name : str, service_type : ServiceTypeEnum, osu_tunnel_name : str,
src_node_id : str, src_tp_id : str, src_vlan_tag : int, dst_node_id : str, dst_tp_id : str, dst_vlan_tag : int,
src_static_routes : List[Tuple[str, int, str]] = list(), dst_static_routes : List[Tuple[str, int, str]] = list()
) -> Dict:
return {'ietf-eth-tran-service:etht-svc': {'etht-svc-instances': [{
'etht-svc-name' : name.lower(),
'etht-svc-title': name.upper(),
'etht-svc-type' : service_type.value,
'source-endpoints': {'source-endpoint': [
compose_etht_service_endpoint(src_node_id, src_tp_id, src_vlan_tag, src_static_routes),
]},
'destination-endpoints': {'destination-endpoint': [
compose_etht_service_endpoint(dst_node_id, dst_tp_id, dst_vlan_tag, dst_static_routes),
]},
'svc-tunnel': [{'tunnel-name': osu_tunnel_name}],
'optimizations': compose_optimizations(),
}]}}
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import enum, json, logging, operator, requests
from requests.auth import HTTPBasicAuth
from typing import Dict, List, Optional
from device.service.driver_api._Driver import RESOURCE_ENDPOINTS, RESOURCE_SERVICES
from .Tools import HTTP_OK_CODES
LOGGER = logging.getLogger(__name__)
BASE_URL_OSU_TUNNEL = '{:s}/ietf-te:tunnel'
class EndpointProtectionRoleEnum(enum.Enum):
WORK = 'work'
class LspProtectionTypeEnum(enum.Enum):
UNPROTECTED = 'ietf-te-types:lsp-protection-unprotected'
class LspRestorationTypeEnum(enum.Enum):
NOT_APPLICABLE = 'ietf-te-types:lsp-restoration-not-applicable'
class TunnelAdminStateEnum(enum.Enum):
UP = 'ietf-te-types:tunnel-admin-state-up'
class OduTypeEnum(enum.Enum):
OSUFLEX = 'osuflex'
def compose_osu_tunnel_endpoint(
node_id : str, tp_id : str, ttp_channel_name : str,
protection_role : EndpointProtectionRoleEnum = EndpointProtectionRoleEnum.WORK
) -> Dict:
return {
'node-id': node_id, 'tp-id': tp_id, 'ttp-channel-name': ttp_channel_name,
'protection-role': protection_role.value
}
def compose_osu_tunnel_te_bandwidth_odu(odu_type : OduTypeEnum, number : int) -> Dict:
return {'layer': 'odu', 'odu-type': odu_type.value, 'number': number}
def compose_osu_tunnel_protection(
type_ : LspProtectionTypeEnum = LspProtectionTypeEnum.UNPROTECTED, reversion_disable : bool = True
) -> Dict:
return {'protection-type': type_.value, 'protection-reversion-disable': reversion_disable}
def compose_osu_tunnel_restoration(
type_ : LspRestorationTypeEnum = LspRestorationTypeEnum.NOT_APPLICABLE, restoration_lock : bool = False
) -> Dict:
return {'restoration-type': type_.value, 'restoration-lock': restoration_lock}
def compose_osu_tunnel(
name : str,
src_node_id : str, src_tp_id : str, src_ttp_channel_name : str,
dst_node_id : str, dst_tp_id : str, dst_ttp_channel_name : str,
odu_type : OduTypeEnum, osuflex_number : int,
delay : int, bidirectional : bool = True,
admin_state : TunnelAdminStateEnum = TunnelAdminStateEnum.UP
) -> Dict:
return {'ietf-te:tunnel': [{
'name': name.lower(),
'title': name.upper(),
'admin-state': admin_state.value,
'delay': delay,
'te-bandwidth': compose_osu_tunnel_te_bandwidth_odu(odu_type, osuflex_number),
'bidirectional': bidirectional,
'source-endpoints': {'source-endpoint': [
compose_osu_tunnel_endpoint(src_node_id, src_tp_id, src_ttp_channel_name),
]},
'destination-endpoints': {'destination-endpoint': [
compose_osu_tunnel_endpoint(dst_node_id, dst_tp_id, dst_ttp_channel_name),
]},
'restoration': compose_osu_tunnel_restoration(),
'protection': compose_osu_tunnel_protection(),
}]}
class OsuTunnel:
def __init__(self, base_url : str, auth : Optional[HTTPBasicAuth] = None, timeout : Optional[int] = None) -> None:
self._base_url = base_url
self._auth = auth
self._timeout = timeout
def get(self, resource_key : str) -> None:
url = '{:s}/restconf/data/tapi-common:context'.format(base_url)
result = []
try:
response = requests.get(url, timeout=timeout, verify=False, auth=auth)
except requests.exceptions.Timeout:
LOGGER.exception('Timeout connecting {:s}'.format(url))
return result
except Exception as e: # pylint: disable=broad-except
LOGGER.exception('Exception retrieving {:s}'.format(resource_key))
result.append((resource_key, e))
return result
try:
context = json.loads(response.content)
except Exception as e: # pylint: disable=broad-except
LOGGER.warning('Unable to decode reply: {:s}'.format(str(response.content)))
result.append((resource_key, e))
return result
if resource_key == RESOURCE_ENDPOINTS:
if 'tapi-common:context' in context:
context = context['tapi-common:context']
elif 'context' in context:
context = context['context']
for sip in context['service-interface-point']:
layer_protocol_name = sip.get('layer-protocol-name', '?')
supportable_spectrum = sip.get('tapi-photonic-media:media-channel-service-interface-point-spec', {})
supportable_spectrum = supportable_spectrum.get('mc-pool', {})
supportable_spectrum = supportable_spectrum.get('supportable-spectrum', [])
supportable_spectrum = supportable_spectrum[0] if len(supportable_spectrum) == 1 else {}
grid_type = supportable_spectrum.get('frequency-constraint', {}).get('grid-type')
granularity = supportable_spectrum.get('frequency-constraint', {}).get('adjustment-granularity')
direction = sip.get('direction', '?')
endpoint_type = [layer_protocol_name, grid_type, granularity, direction]
str_endpoint_type = ':'.join(filter(lambda i: operator.is_not(i, None), endpoint_type))
sip_uuid = sip['uuid']
sip_names = sip.get('name', [])
sip_name = next(iter([
sip_name['value']
for sip_name in sip_names
if sip_name['value-name'] == 'local-name'
]), sip_uuid)
endpoint_url = '/endpoints/endpoint[{:s}]'.format(sip_uuid)
endpoint_data = {'uuid': sip_uuid, 'name': sip_name, 'type': str_endpoint_type}
result.append((endpoint_url, endpoint_data))
elif resource_key == RESOURCE_SERVICES:
if 'tapi-common:context' in context:
context = context['tapi-common:context']
elif 'context' in context:
context = context['context']
if 'tapi-connectivity:connectivity-context' in context:
context = context['tapi-connectivity:connectivity-context']
elif 'connectivity-context' in context:
context = context['connectivity-context']
for conn_svc in context['connectivity-service']:
service_uuid = conn_svc['uuid']
constraints = conn_svc.get('connectivity-constraint', {})
total_req_cap = constraints.get('requested-capacity', {}).get('total-size', {})
service_url = '/services/service[{:s}]'.format(service_uuid)
service_data = {
'uuid': service_uuid,
'direction': constraints.get('connectivity-direction', 'UNIDIRECTIONAL'),
'capacity_unit': total_req_cap.get('unit', '<UNDEFINED>'),
'capacity_value': total_req_cap.get('value', '<UNDEFINED>'),
}
for i,endpoint in enumerate(conn_svc.get('end-point', [])):
layer_protocol_name = endpoint.get('layer-protocol-name')
if layer_protocol_name is not None:
service_data['layer_protocol_name'] = layer_protocol_name
layer_protocol_qualifier = endpoint.get('layer-protocol-qualifier')
if layer_protocol_qualifier is not None:
service_data['layer_protocol_qualifier'] = layer_protocol_qualifier
sip = endpoint['service-interface-point']['service-interface-point-uuid']
service_data['input_sip' if i == 0 else 'output_sip'] = sip
result.append((service_url, service_data))
return result
def update(self, resource_value : Dict) -> None:
name = resource_value['name' ]
src_node_id = resource_value['src_node_id' ]
src_tp_id = resource_value['src_tp_id' ]
src_ttp_channel_name = resource_value['src_ttp_channel_name']
dst_node_id = resource_value['dst_node_id' ]
dst_tp_id = resource_value['dst_tp_id' ]
dst_ttp_channel_name = resource_value['dst_ttp_channel_name']
odu_type = resource_value.get('odu_type', OduTypeEnum.OSUFLEX.value)
osuflex_number = resource_value.get('osuflex_number', 1 )
delay = resource_value.get('delay', 20 )
bidirectional = resource_value.get('bidirectional', True )
odu_type = OduTypeEnum._value2member_map_[odu_type]
headers = {'content-type': 'application/json'}
data = compose_osu_tunnel(
name, src_node_id, src_tp_id, src_ttp_channel_name, dst_node_id, dst_tp_id, dst_ttp_channel_name,
odu_type, osuflex_number, delay, bidirectional=bidirectional
)
results = []
try:
LOGGER.info('OSU Tunnel {:s}: {:s}'.format(str(name), str(data)))
response = requests.post(
self._base_url, data=json.dumps(data), timeout=self._timeout,
headers=headers, verify=False, auth=self._auth
)
LOGGER.info('Response: {:s}'.format(str(response)))
except Exception as e: # pylint: disable=broad-except
LOGGER.exception('Exception creating OsuTunnel(name={:s}, data={:s})'.format(str(name), str(data)))
results.append(e)
else:
if response.status_code not in HTTP_OK_CODES:
msg = 'Could not create OsuTunnel(name={:s}, data={:s}). status_code={:s} reply={:s}'
LOGGER.error(msg.format(str(name), str(data), str(response.status_code), str(response)))
results.append(response.status_code in HTTP_OK_CODES)
return results
def delete(self, osu_tunnel_name : str) -> List[]:
url = '{:s}[name={:s}]'.format(self._base_url, osu_tunnel_name)
results = []
try:
response = requests.delete(url=url, timeout=self._timeout, verify=False, auth=self._auth)
except Exception as e: # pylint: disable=broad-except
LOGGER.exception('Exception deleting OsuTunnel(name={:s})'.format(str(osu_tunnel_name)))
results.append(e)
else:
if response.status_code not in HTTP_OK_CODES:
msg = 'Could not delete OsuTunnel(name={:s}). status_code={:s} reply={:s}'
LOGGER.error(msg.format(str(osu_tunnel_name), str(response.status_code), str(response)))
results.append(response.status_code in HTTP_OK_CODES)
return results
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
HTTP_OK_CODES = {
200, # OK
201, # Created
202, # Accepted
204, # No Content
}
......@@ -11,4 +11,3 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment