Newer
Older
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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
##
# Copyright 2018 David García, University of the Basque Country
# Copyright 2018 University of the Basque Country
# This file is part of openmano
# All Rights Reserved.
# Contact information at http://i2t.ehu.eus
#
# # 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 requests
import json
import logging
from enum import Enum
from wimconn import WimConnector, WimConnectorError
class WimError(Enum):
UNREACHABLE = 'Unable to reach the WIM.',
SERVICE_TYPE_ERROR = 'Unexpected service_type. Only "L2" is accepted.',
CONNECTION_POINTS_SIZE = \
'Unexpected number of connection points: 2 expected.',
ENCAPSULATION_TYPE = \
'Unexpected service_endpoint_encapsulation_type. \
Only "dotq1" is accepted.',
BANDWIDTH = 'Unable to get the bandwidth.',
STATUS = 'Unable to get the status for the service.',
DELETE = 'Unable to delete service.',
CLEAR_ALL = 'Unable to clear all the services',
UNKNOWN_ACTION = 'Unknown action invoked.',
BACKUP = 'Unable to get the backup parameter.',
UNSUPPORTED_FEATURE = "Unsupported feature",
UNAUTHORIZED = "Failed while authenticating"
class WimAPIActions(Enum):
CHECK_CONNECTIVITY = "CHECK_CONNECTIVITY",
CREATE_SERVICE = "CREATE_SERVICE",
DELETE_SERVICE = "DELETE_SERVICE",
CLEAR_ALL = "CLEAR_ALL",
SERVICE_STATUS = "SERVICE_STATUS",
class DynpacConnector(WimConnector):
__supported_service_types = ["ELINE (L2)", "ELINE"]
__supported_encapsulation_types = ["dot1q"]
__WIM_LOGGER = 'openmano.wimconn.dynpac'
__ENCAPSULATION_TYPE_PARAM = "service_endpoint_encapsulation_type"
__ENCAPSULATION_INFO_PARAM = "service_endpoint_encapsulation_info"
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
__BACKUP_PARAM = "backup"
__BANDWIDTH_PARAM = "bandwidth"
__SERVICE_ENDPOINT_PARAM = "service_endpoint_id"
__WAN_SERVICE_ENDPOINT_PARAM = "wan_service_endpoint_id"
__WAN_MAPPING_INFO_PARAM = "wan_service_mapping_info"
__SW_ID_PARAM = "wan_switch_dpid"
__SW_PORT_PARAM = "wan_switch_port"
__VLAN_PARAM = "vlan"
# Public functions exposed to the Resource Orchestrator
def __init__(self, wim, wim_account, config):
self.logger = logging.getLogger(self.__WIM_LOGGER)
self.__wim = wim
self.__wim_account = wim_account
self.__config = config
self.__wim_url = self.__wim.get("wim_url")
self.__user = wim_account.get("user")
self.__passwd = wim_account.get("passwd")
self.logger.info("Initialized.")
def create_connectivity_service(self,
service_type,
connection_points,
**kwargs):
self.__check_service(service_type, connection_points, kwargs)
body = self.__get_body(service_type, connection_points, kwargs)
headers = {'Content-type': 'application/x-www-form-urlencoded'}
endpoint = "{}/service/create".format(self.__wim_url)
try:
response = requests.post(endpoint, data=body, headers=headers)
except requests.exceptions.RequestException as e:
self.__exception(e.message, http_code=503)
if response.status_code != 200:
error = json.loads(response.content)
reason = "Reason: {}. ".format(error.get("code"))
description = "Description: {}.".format(error.get("description"))
exception = reason + description
self.__exception(exception, http_code=response.status_code)
uuid = response.content
self.logger.info("Service with uuid {} created.".format(uuid))
return (uuid, None)
def edit_connectivity_service(self, service_uuid,
conn_info, connection_points,
**kwargs):
self.__exception(WimError.UNSUPPORTED_FEATURE, http_code=501)
def get_connectivity_service_status(self, service_uuid):
endpoint = "{}/service/status/{}".format(self.__wim_url, service_uuid)
try:
response = requests.get(endpoint)
except requests.exceptions.RequestException as e:
self.__exception(e.message, http_code=503)
if response.status_code != 200:
self.__exception(WimError.STATUS, http_code=response.status_code)
self.logger.info("Status for service with uuid {}: {}"
.format(service_uuid, response.content))
return response.content
def delete_connectivity_service(self, service_uuid, conn_info):
endpoint = "{}/service/delete/{}".format(self.__wim_url, service_uuid)
try:
response = requests.delete(endpoint)
except requests.exceptions.RequestException as e:
self.__exception(e.message, http_code=503)
if response.status_code != 200:
self.__exception(WimError.DELETE, http_code=response.status_code)
self.logger.info("Service with uuid: {} deleted".format(service_uuid))
def clear_all_connectivity_services(self):
endpoint = "{}/service/clearAll".format(self.__wim_url)
try:
response = requests.delete(endpoint)
http_code = response.status_code
except requests.exceptions.RequestException as e:
self.__exception(e.message, http_code=503)
if http_code != 200:
self.__exception(WimError.CLEAR_ALL, http_code=http_code)
self.logger.info("{} services deleted".format(response.content))
return "{} services deleted".format(response.content)
def check_connectivity(self):
endpoint = "{}/checkConnectivity".format(self.__wim_url)
try:
http_code = response.status_code
except requests.exceptions.RequestException as e:
self.__exception(e.message, http_code=503)
if http_code != 200:
self.__exception(WimError.UNREACHABLE, http_code=http_code)
self.logger.info("Connectivity checked")
def check_credentials(self):
endpoint = "{}/checkCredentials".format(self.__wim_url)
auth = (self.__user, self.__passwd)
try:
response = requests.get(endpoint, auth=auth)
http_code = response.status_code
except requests.exceptions.RequestException as e:
self.__exception(e.message, http_code=503)
if http_code != 200:
self.__exception(WimError.UNAUTHORIZED, http_code=http_code)
self.logger.info("Credentials checked")
# Private functions
def __exception(self, x, **kwargs):
http_code = kwargs.get("http_code")
if hasattr(x, "value"):
error = x.value
else:
error = x
self.logger.error(error)
raise WimConnectorError(error, http_code=http_code)
def __check_service(self, service_type, connection_points, kwargs):
if service_type not in self.__supported_service_types:
self.__exception(WimError.SERVICE_TYPE_ERROR, http_code=400)
if len(connection_points) != 2:
self.__exception(WimError.CONNECTION_POINTS_SIZE, http_code=400)
for connection_point in connection_points:
enc_type = connection_point.get(self.__ENCAPSULATION_TYPE_PARAM)
if enc_type not in self.__supported_encapsulation_types:
self.__exception(WimError.ENCAPSULATION_TYPE, http_code=400)
# Commented out for as long as parameter isn't implemented
# bandwidth = kwargs.get(self.__BANDWIDTH_PARAM)
# if not isinstance(bandwidth, int):
# self.__exception(WimError.BANDWIDTH, http_code=400)
# Commented out for as long as parameter isn't implemented
# backup = kwargs.get(self.__BACKUP_PARAM)
# if not isinstance(backup, bool):
# self.__exception(WimError.BACKUP, http_code=400)
def __get_body(self, service_type, connection_points, kwargs):
port_mapping = self.__config.get("service_endpoint_mapping")
selected_ports = []
for connection_point in connection_points:
endpoint_id = connection_point.get(self.__SERVICE_ENDPOINT_PARAM)
port = filter(lambda x: x.get(self.__WAN_SERVICE_ENDPOINT_PARAM) == endpoint_id, port_mapping)[0]
port_info = port.get(self.__WAN_MAPPING_INFO_PARAM)
if service_type == "ELINE (L2)" or service_type == "ELINE":
service_type = "L2"
body = {
"connection_points": [{
"wan_switch_dpid": selected_ports[0].get(self.__SW_ID_PARAM),
"wan_switch_port": selected_ports[0].get(self.__SW_PORT_PARAM),
"wan_vlan": connection_points[0].get(self.__ENCAPSULATION_INFO_PARAM).get(self.__VLAN_PARAM)
}, {
"wan_switch_dpid": selected_ports[1].get(self.__SW_ID_PARAM),
"wan_switch_port": selected_ports[1].get(self.__SW_PORT_PARAM),
"wan_vlan": connection_points[1].get(self.__ENCAPSULATION_INFO_PARAM).get(self.__VLAN_PARAM)
"bandwidth": 100, # Hardcoded for as long as parameter isn't implemented
"backup": False # Hardcoded for as long as parameter isn't implemented