2 # -*- coding: utf-8 -*-
5 # Copyright 2018 David GarcĂa, University of the Basque Country
6 # Copyright 2018 University of the Basque Country
7 # This file is part of openmano
9 # Contact information at http://i2t.ehu.eus
11 # # Licensed under the Apache License, Version 2.0 (the "License");
12 # you may not use this file except in compliance with the License.
13 # You may obtain a copy of the License at
15 # http://www.apache.org/licenses/LICENSE-2.0
17 # Unless required by applicable law or agreed to in writing, software
18 # distributed under the License is distributed on an "AS IS" BASIS,
19 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
21 # See the License for the specific language governing permissions and
22 # limitations under the License.
29 from wimconn
import WimConnector
, WimConnectorError
33 UNREACHABLE
= 'Unable to reach the WIM.',
34 SERVICE_TYPE_ERROR
= 'Unexpected service_type. Only "L2" is accepted.',
35 CONNECTION_POINTS_SIZE
= \
36 'Unexpected number of connection points: 2 expected.',
37 ENCAPSULATION_TYPE
= \
38 'Unexpected service_endpoint_encapsulation_type. \
39 Only "dotq1" is accepted.',
40 BANDWIDTH
= 'Unable to get the bandwidth.',
41 STATUS
= 'Unable to get the status for the service.',
42 DELETE
= 'Unable to delete service.',
43 CLEAR_ALL
= 'Unable to clear all the services',
44 UNKNOWN_ACTION
= 'Unknown action invoked.',
45 BACKUP
= 'Unable to get the backup parameter.',
46 UNSUPPORTED_FEATURE
= "Unsupported feature",
47 UNAUTHORIZED
= "Failed while authenticating"
50 class WimAPIActions(Enum
):
51 CHECK_CONNECTIVITY
= "CHECK_CONNECTIVITY",
52 CREATE_SERVICE
= "CREATE_SERVICE",
53 DELETE_SERVICE
= "DELETE_SERVICE",
54 CLEAR_ALL
= "CLEAR_ALL",
55 SERVICE_STATUS
= "SERVICE_STATUS",
58 class DynpacConnector(WimConnector
):
59 __supported_service_types
= ["ELINE (L2)", "ELINE"]
60 __supported_encapsulation_types
= ["dot1q"]
61 __WIM_LOGGER
= 'openmano.wimconn.dynpac'
62 __ENCAPSULATION_TYPE_PARAM
= "service_endpoint_encapsulation_type"
63 __ENCAPSULATION_INFO_PARAM
= "service_endpoint_encapsulation_info"
64 __BACKUP_PARAM
= "backup"
65 __BANDWIDTH_PARAM
= "bandwidth"
66 __SERVICE_ENDPOINT_PARAM
= "service_endpoint_id"
67 __WAN_SERVICE_ENDPOINT_PARAM
= "wan_service_endpoint_id"
68 __WAN_MAPPING_INFO_PARAM
= "wan_service_mapping_info"
69 __SW_ID_PARAM
= "wan_switch_dpid"
70 __SW_PORT_PARAM
= "wan_switch_port"
73 # Public functions exposed to the Resource Orchestrator
74 def __init__(self
, wim
, wim_account
, config
):
75 self
.logger
= logging
.getLogger(self
.__WIM
_LOGGER
)
77 self
.__wim
_account
= wim_account
78 self
.__config
= config
79 self
.__wim
_url
= self
.__wim
.get("wim_url")
80 self
.__user
= wim_account
.get("user")
81 self
.__passwd
= wim_account
.get("passwd")
82 self
.logger
.info("Initialized.")
84 def create_connectivity_service(self
,
88 self
.__check
_service
(service_type
, connection_points
, kwargs
)
90 body
= self
.__get
_body
(service_type
, connection_points
, kwargs
)
92 headers
= {'Content-type': 'application/x-www-form-urlencoded'}
93 endpoint
= "{}/service/create".format(self
.__wim
_url
)
96 response
= requests
.post(endpoint
, data
=body
, headers
=headers
)
97 except requests
.exceptions
.RequestException
as e
:
98 self
.__exception
(e
.message
, http_code
=503)
100 if response
.status_code
!= 200:
101 error
= json
.loads(response
.content
)
102 reason
= "Reason: {}. ".format(error
.get("code"))
103 description
= "Description: {}.".format(error
.get("description"))
104 exception
= reason
+ description
105 self
.__exception
(exception
, http_code
=response
.status_code
)
106 uuid
= response
.content
107 self
.logger
.info("Service with uuid {} created.".format(uuid
))
110 def edit_connectivity_service(self
, service_uuid
,
111 conn_info
, connection_points
,
113 self
.__exception
(WimError
.UNSUPPORTED_FEATURE
, http_code
=501)
115 def get_connectivity_service_status(self
, service_uuid
):
116 endpoint
= "{}/service/status/{}".format(self
.__wim
_url
, service_uuid
)
118 response
= requests
.get(endpoint
)
119 except requests
.exceptions
.RequestException
as e
:
120 self
.__exception
(e
.message
, http_code
=503)
122 if response
.status_code
!= 200:
123 self
.__exception
(WimError
.STATUS
, http_code
=response
.status_code
)
124 self
.logger
.info("Status for service with uuid {}: {}"
125 .format(service_uuid
, response
.content
))
126 return response
.content
128 def delete_connectivity_service(self
, service_uuid
, conn_info
):
129 endpoint
= "{}/service/delete/{}".format(self
.__wim
_url
, service_uuid
)
131 response
= requests
.delete(endpoint
)
132 except requests
.exceptions
.RequestException
as e
:
133 self
.__exception
(e
.message
, http_code
=503)
134 if response
.status_code
!= 200:
135 self
.__exception
(WimError
.DELETE
, http_code
=response
.status_code
)
137 self
.logger
.info("Service with uuid: {} deleted".format(service_uuid
))
139 def clear_all_connectivity_services(self
):
140 endpoint
= "{}/service/clearAll".format(self
.__wim
_url
)
142 response
= requests
.delete(endpoint
)
143 http_code
= response
.status_code
144 except requests
.exceptions
.RequestException
as e
:
145 self
.__exception
(e
.message
, http_code
=503)
147 self
.__exception
(WimError
.CLEAR_ALL
, http_code
=http_code
)
149 self
.logger
.info("{} services deleted".format(response
.content
))
150 return "{} services deleted".format(response
.content
)
152 def check_connectivity(self
):
153 endpoint
= "{}/checkConnectivity".format(self
.__wim
_url
)
156 response
= requests
.get(endpoint
)
157 http_code
= response
.status_code
158 except requests
.exceptions
.RequestException
as e
:
159 self
.__exception
(e
.message
, http_code
=503)
162 self
.__exception
(WimError
.UNREACHABLE
, http_code
=http_code
)
163 self
.logger
.info("Connectivity checked")
165 def check_credentials(self
):
166 endpoint
= "{}/checkCredentials".format(self
.__wim
_url
)
167 auth
= (self
.__user
, self
.__passwd
)
170 response
= requests
.get(endpoint
, auth
=auth
)
171 http_code
= response
.status_code
172 except requests
.exceptions
.RequestException
as e
:
173 self
.__exception
(e
.message
, http_code
=503)
176 self
.__exception
(WimError
.UNAUTHORIZED
, http_code
=http_code
)
177 self
.logger
.info("Credentials checked")
180 def __exception(self
, x
, **kwargs
):
181 http_code
= kwargs
.get("http_code")
182 if hasattr(x
, "value"):
186 self
.logger
.error(error
)
187 raise WimConnectorError(error
, http_code
=http_code
)
189 def __check_service(self
, service_type
, connection_points
, kwargs
):
190 if service_type
not in self
.__supported
_service
_types
:
191 self
.__exception
(WimError
.SERVICE_TYPE_ERROR
, http_code
=400)
193 if len(connection_points
) != 2:
194 self
.__exception
(WimError
.CONNECTION_POINTS_SIZE
, http_code
=400)
196 for connection_point
in connection_points
:
197 enc_type
= connection_point
.get(self
.__ENCAPSULATION
_TYPE
_PARAM
)
198 if enc_type
not in self
.__supported
_encapsulation
_types
:
199 self
.__exception
(WimError
.ENCAPSULATION_TYPE
, http_code
=400)
201 # Commented out for as long as parameter isn't implemented
202 # bandwidth = kwargs.get(self.__BANDWIDTH_PARAM)
203 # if not isinstance(bandwidth, int):
204 # self.__exception(WimError.BANDWIDTH, http_code=400)
206 # Commented out for as long as parameter isn't implemented
207 # backup = kwargs.get(self.__BACKUP_PARAM)
208 # if not isinstance(backup, bool):
209 # self.__exception(WimError.BACKUP, http_code=400)
211 def __get_body(self
, service_type
, connection_points
, kwargs
):
212 port_mapping
= self
.__config
.get("service_endpoint_mapping")
214 for connection_point
in connection_points
:
215 endpoint_id
= connection_point
.get(self
.__SERVICE
_ENDPOINT
_PARAM
)
216 port
= filter(lambda x
: x
.get(self
.__WAN
_SERVICE
_ENDPOINT
_PARAM
) == endpoint_id
, port_mapping
)[0]
217 port_info
= port
.get(self
.__WAN
_MAPPING
_INFO
_PARAM
)
218 selected_ports
.append(port_info
)
219 if service_type
== "ELINE (L2)" or service_type
== "ELINE":
222 "connection_points": [{
223 "wan_switch_dpid": selected_ports
[0].get(self
.__SW
_ID
_PARAM
),
224 "wan_switch_port": selected_ports
[0].get(self
.__SW
_PORT
_PARAM
),
225 "wan_vlan": connection_points
[0].get(self
.__ENCAPSULATION
_INFO
_PARAM
).get(self
.__VLAN
_PARAM
)
227 "wan_switch_dpid": selected_ports
[1].get(self
.__SW
_ID
_PARAM
),
228 "wan_switch_port": selected_ports
[1].get(self
.__SW
_PORT
_PARAM
),
229 "wan_vlan": connection_points
[1].get(self
.__ENCAPSULATION
_INFO
_PARAM
).get(self
.__VLAN
_PARAM
)
231 "bandwidth": 100, # Hardcoded for as long as parameter isn't implemented
232 "service_type": service_type
,
233 "backup": False # Hardcoded for as long as parameter isn't implemented
235 return "body={}".format(json
.dumps(body
))