import json
import logging
-import paramiko
-import requests
import struct
-# import sys
+
from osm_ro_plugin.sdnconn import SdnConnectorBase, SdnConnectorError
+import paramiko
+import requests
-class DpbSshInterface():
- """ Communicate with the DPB via SSH """
+class DpbSshInterface:
+ """Communicate with the DPB via SSH"""
__LOGGER_NAME_EXT = ".ssh"
__FUNCTION_MAP_POS = 1
- def __init__(self, username, password, wim_url, wim_port, network, auth_data, logger_name):
+ def __init__(
+ self, username, password, wim_url, wim_port, network, auth_data, logger_name
+ ):
self.logger = logging.getLogger(logger_name + self.__LOGGER_NAME_EXT)
self.__username = username
self.__password = password
"""post request to dpb via ssh
notes:
- - session_id need only be unique per ssh session, thus is currently safe if
+ - session_id need only be unique per ssh session, thus is currently safe if
ro is restarted
"""
self._check_connection()
+
if data is None:
data = {}
- url_ext_info = url_params.split('/')
+
+ url_ext_info = url_params.split("/")
+
for i in range(0, len(url_ext_info)):
if url_ext_info[i] == "service":
- data["service-id"] = int(url_ext_info[i+1])
+ data["service-id"] = int(url_ext_info[i + 1])
+
data["type"] = function[self.__FUNCTION_MAP_POS]
data = {
"session": self.__session_id,
- "content": data
+ "content": data,
}
self.__session_id += 1
try:
data = json.dumps(data).encode("utf-8")
- data_packed = struct.pack(
- ">I" + str(len(data)) + "s", len(data), data)
+ data_packed = struct.pack(">I" + str(len(data)) + "s", len(data), data)
self.__stdin.write(data_packed)
self.logger.debug("Data sent to DPB via SSH")
except Exception as e:
- raise SdnConnectorError(
- "Failed to write via SSH | text: {}".format(e), 500)
+ raise SdnConnectorError("Failed to write via SSH | text: {}".format(e), 500)
try:
data_len = struct.unpack(">I", self.__stdout.read(4))[0]
- data = struct.unpack(str(data_len) + "s",
- self.__stdout.read(data_len))[0]
+ data = struct.unpack(str(data_len) + "s", self.__stdout.read(data_len))[0]
+
return json.loads(data).get("content", {})
except Exception as e:
raise SdnConnectorError(
- "Could not get response from WIM | text: {}".format(e), 500)
+ "Could not get response from WIM | text: {}".format(e), 500
+ )
def get(self, function, url_params=""):
raise SdnConnectorError("SSH Get not implemented", 500)
def __create_client(self):
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+
return ssh_client
def __connect(self):
private_key = None
password = None
+
if self.__auth_data.get("auth_type", "PASS") == "KEY":
private_key = self.__build_private_key_obj()
+
if self.__auth_data.get("auth_type", "PASS") == "PASS":
password = self.__password
try:
- self.__ssh_client.connect(hostname=self.__url,
- port=self.__port,
- username=self.__username,
- password=password,
- pkey=private_key,
- look_for_keys=False,
- compress=False)
+ self.__ssh_client.connect(
+ hostname=self.__url,
+ port=self.__port,
+ username=self.__username,
+ password=password,
+ pkey=private_key,
+ look_for_keys=False,
+ compress=False,
+ )
stdin, stdout, stderr = self.__ssh_client.exec_command(
- command=self.__network)
+ command=self.__network
+ )
except paramiko.BadHostKeyException as e:
raise SdnConnectorError(
- "Could not add SSH host key | text: {}".format(e), 500)
+ "Could not add SSH host key | text: {}".format(e), 500
+ )
except paramiko.AuthenticationException as e:
raise SdnConnectorError(
- "Could not authorize SSH connection | text: {}".format(e), 400)
+ "Could not authorize SSH connection | text: {}".format(e), 400
+ )
except paramiko.SSHException as e:
raise SdnConnectorError(
- "Could not establish the SSH connection | text: {}".format(e), 500)
+ "Could not establish the SSH connection | text: {}".format(e), 500
+ )
except Exception as e:
raise SdnConnectorError(
- "Unknown error occurred when connecting via SSH | text: {}".format(e), 500)
+ "Unknown error occurred when connecting via SSH | text: {}".format(e),
+ 500,
+ )
try:
data_len = struct.unpack(">I", stdout.read(4))[0]
- data = json.loads(struct.unpack(
- str(data_len) + "s", stdout.read(data_len))[0])
+ data = json.loads(
+ struct.unpack(str(data_len) + "s", stdout.read(data_len))[0]
+ )
except Exception as e:
raise SdnConnectorError(
- "Failed to get response from DPB | text: {}".format(e), 500)
+ "Failed to get response from DPB | text: {}".format(e), 500
+ )
+
if "error" in data:
- raise SdnConnectorError(
- data.get("msg", data.get("error", "ERROR")), 500)
+ raise SdnConnectorError(data.get("msg", data.get("error", "ERROR")), 500)
+
self.logger.info("SSH connection to DPB established OK")
+
return stdin, stdout
def __build_private_key_obj(self):
try:
- with open(self.__auth_data.get("key_file"), 'r') as key_file:
+ with open(self.__auth_data.get("key_file"), "r") as key_file:
if self.__auth_data.get("key_type") == "RSA":
- return paramiko.RSAKey.from_private_key(key_file,
- password=self.__auth_data.get("key_pass", None))
+ return paramiko.RSAKey.from_private_key(
+ key_file, password=self.__auth_data.get("key_pass", None)
+ )
elif self.__auth_data.get("key_type") == "ECDSA":
- return paramiko.ECDSAKey.from_private_key(key_file,
- password=self.__auth_data.get("key_pass", None))
+ return paramiko.ECDSAKey.from_private_key(
+ key_file, password=self.__auth_data.get("key_pass", None)
+ )
else:
raise SdnConnectorError("Key type not supported", 400)
except Exception as e:
raise SdnConnectorError(
- "Could not load private SSH key | text: {}".format(e), 500)
+ "Could not load private SSH key | text: {}".format(e), 500
+ )
-class DpbRestInterface():
- """ Communicate with the DPB via the REST API """
+class DpbRestInterface:
+ """Communicate with the DPB via the REST API"""
__LOGGER_NAME_EXT = ".rest"
__FUNCTION_MAP_POS = 0
def __init__(self, wim_url, wim_port, network, logger_name):
self.logger = logging.getLogger(logger_name + self.__LOGGER_NAME_EXT)
self.__base_url = "http://{}:{}/network/{}".format(
- wim_url, str(wim_port), network)
+ wim_url, str(wim_port), network
+ )
self.logger.info("REST defined OK")
def post(self, function, url_params="", data=None, get_response=True):
- url = self.__base_url + url_params + \
- "/" + function[self.__FUNCTION_MAP_POS]
+ url = self.__base_url + url_params + "/" + function[self.__FUNCTION_MAP_POS]
+
try:
self.logger.info(data)
response = requests.post(url, json=data)
+
if response.status_code != 200:
raise SdnConnectorError(
- "REST request failed (status code: {})".format(response.status_code))
+ "REST request failed (status code: {})".format(response.status_code)
+ )
+
if get_response:
return response.json()
except Exception as e:
- raise SdnConnectorError(
- "REST request failed | text: {}".format(e), 500)
+ raise SdnConnectorError("REST request failed | text: {}".format(e), 500)
def get(self, function, url_params=""):
url = self.__base_url + url_params + function[self.__FUNCTION_MAP_POS]
+
try:
return requests.get(url)
except Exception as e:
- raise SdnConnectorError(
- "REST request failed | text: {}".format(e), 500)
+ raise SdnConnectorError("REST request failed | text: {}".format(e), 500)
class DpbConnector(SdnConnectorBase):
- """ Use the DPB to establish multipoint connections """
+ """Use the DPB to establish multipoint connections"""
- __LOGGER_NAME = "openmano.rosdnconn.dpb"
+ __LOGGER_NAME = "ro.sdn.dpb"
__SUPPORTED_SERV_TYPES = ["ELAN (L2)", "ELINE (L2)"]
__SUPPORTED_CONNECTION_TYPES = ["REST", "SSH"]
__SUPPORTED_SSH_AUTH_TYPES = ["KEY", "PASS"]
__SUPPORTED_SSH_KEY_TYPES = ["ECDSA", "RSA"]
- __STATUS_MAP = {
- "ACTIVE": "ACTIVE",
- "ACTIVATING": "BUILD",
- "FAILED": "ERROR"}
+ __STATUS_MAP = {"ACTIVE": "ACTIVE", "ACTIVATING": "BUILD", "FAILED": "ERROR"}
__ACTIONS_MAP = {
"CREATE": ("create-service", "new-service"),
"DEFINE": ("define", "define-service"),
"DEACTIVATE": ("deactivate", "deactivate-service"),
"CHECK": ("await-status", "await-service-status"),
"GET": ("services", "NOT IMPLEMENTED"),
- "RESET": ("reset", "NOT IMPLEMENTED")
+ "RESET": ("reset", "NOT IMPLEMENTED"),
}
def __init__(self, wim, wim_account, config):
self.__password = self.__account.get("passwd", "")
self.__username = self.__account.get("user", "")
self.__network = self.__cli_config.get("network", "")
- self.__connection_type = self.__cli_config.get(
- "connection_type", "REST")
+ self.__connection_type = self.__cli_config.get("connection_type", "REST")
self.__port = self.__cli_config.get(
- "port", (80 if self.__connection_type == "REST" else 22))
+ "port", (80 if self.__connection_type == "REST" else 22)
+ )
self.__ssh_auth = self.__cli_config.get("ssh_auth", None)
if self.__connection_type == "SSH":
- interface = DpbSshInterface(self.__username,
- self.__password,
- self.__url,
- self.__port,
- self.__network,
- self.__ssh_auth,
- self.__LOGGER_NAME)
+ interface = DpbSshInterface(
+ self.__username,
+ self.__password,
+ self.__url,
+ self.__port,
+ self.__network,
+ self.__ssh_auth,
+ self.__LOGGER_NAME,
+ )
elif self.__connection_type == "REST":
- interface = DpbRestInterface(self.__url,
- self.__port,
- self.__network,
- self.__LOGGER_NAME)
+ interface = DpbRestInterface(
+ self.__url, self.__port, self.__network, self.__LOGGER_NAME
+ )
else:
raise SdnConnectorError(
- "Connection type not supported (must be SSH or REST)", 400)
+ "Connection type not supported (must be SSH or REST)", 400
+ )
+
self.__post = interface.post
self.__get = interface.get
self.logger.info("DPB WimConn Init OK")
def create_connectivity_service(self, service_type, connection_points, **kwargs):
self.logger.info("Creating a connectivity service")
+
try:
response = self.__post(self.__ACTIONS_MAP.get("CREATE"))
+
if "service-id" in response:
service_id = int(response.get("service-id"))
self.logger.debug("created service id {}".format(service_id))
else:
raise SdnConnectorError(
- "Invalid create service response (could be an issue with the DPB)", 500)
+ "Invalid create service response (could be an issue with the DPB)",
+ 500,
+ )
+
data = {"segment": []}
+
for point in connection_points:
- data["segment"].append({
- "terminal-name": point.get("service_endpoint_id"),
- "label": int((point.get("service_endpoint_encapsulation_info")).get("vlan")),
- "ingress-bw": 10.0,
- "egress-bw": 10.0})
+ data["segment"].append(
+ {
+ "terminal-name": point.get("service_endpoint_id"),
+ "label": int(
+ (point.get("service_endpoint_encapsulation_info")).get(
+ "vlan"
+ )
+ ),
+ "ingress-bw": 10.0,
+ "egress-bw": 10.0,
+ }
+ )
# "ingress-bw": (bandwidth.get(point.get("service_endpoint_id"))).get("ingress"),
# "egress-bw": (bandwidth.get(point.get("service_endpoint_id"))).get("egress")}
- self.__post(self.__ACTIONS_MAP.get("DEFINE"),
- "/service/"+str(service_id), data, get_response=False)
- self.__post(self.__ACTIONS_MAP.get("ACTIVATE"),
- "/service/"+str(service_id), get_response=False)
- self.logger.debug(
- "Created connectivity service id:{}".format(service_id))
+ self.__post(
+ self.__ACTIONS_MAP.get("DEFINE"),
+ "/service/" + str(service_id),
+ data,
+ get_response=False,
+ )
+ self.__post(
+ self.__ACTIONS_MAP.get("ACTIVATE"),
+ "/service/" + str(service_id),
+ get_response=False,
+ )
+ self.logger.debug("Created connectivity service id:{}".format(service_id))
+
return (str(service_id), None)
except Exception as e:
raise SdnConnectorError(
- "Connectivity service could not be made | text: {}".format(e), 500)
+ "Connectivity service could not be made | text: {}".format(e), 500
+ )
def get_connectivity_service_status(self, service_uuid, conn_info=None):
self.logger.info(
- "Checking connectivity service status id:{}".format(service_uuid))
- data = {
- "timeout-millis": 10000,
- "acceptable": ["ACTIVE", "FAILED"]
- }
+ "Checking connectivity service status id:{}".format(service_uuid)
+ )
+ data = {"timeout-millis": 10000, "acceptable": ["ACTIVE", "FAILED"]}
+
try:
- response = self.__post(self.__ACTIONS_MAP.get(
- "CHECK"), "/service/"+service_uuid, data)
+ response = self.__post(
+ self.__ACTIONS_MAP.get("CHECK"),
+ "/service/" + service_uuid,
+ data,
+ )
+
if "status" in response:
status = response.get("status", None)
self.logger.info("CHECKED CONNECTIVITY SERVICE STATUS")
+
return {"wim_status": self.__STATUS_MAP.get(status)}
else:
raise SdnConnectorError(
- "Invalid status check response (could be an issue with the DPB)", 500)
+ "Invalid status check response (could be an issue with the DPB)",
+ 500,
+ )
except Exception as e:
raise SdnConnectorError(
- "Failed to check service status | text: {}".format(e), 500)
+ "Failed to check service status | text: {}".format(e), 500
+ )
def delete_connectivity_service(self, service_uuid, conn_info=None):
- self.logger.info(
- "Deleting connectivity service id: {}".format(service_uuid))
+ self.logger.info("Deleting connectivity service id: {}".format(service_uuid))
+
try:
- self.__post(self.__ACTIONS_MAP.get("RELEASE"),
- "/service/"+service_uuid, get_response=False)
+ self.__post(
+ self.__ACTIONS_MAP.get("RELEASE"),
+ "/service/" + service_uuid,
+ get_response=False,
+ )
except Exception as e:
raise SdnConnectorError(
- "Could not delete service id:{} (could be an issue with the DPB): {}".format(service_uuid, e), 500)
- self.logger.debug(
- "Deleted connectivity service id:{}".format(service_uuid))
+ "Could not delete service id:{} (could be an issue with the DPB): {}".format(
+ service_uuid, e
+ ),
+ 500,
+ )
+
+ self.logger.debug("Deleted connectivity service id:{}".format(service_uuid))
+
return None
- def edit_connectivity_service(self, service_uuid, conn_info=None, connection_points=None, **kwargs):
- self.logger.info(
- "Editing connectivity service id: {}".format(service_uuid))
- data = {
- "timeout-millis": 10000,
- "acceptable": ["DORMANT"]
- }
+ def edit_connectivity_service(
+ self, service_uuid, conn_info=None, connection_points=None, **kwargs
+ ):
+ self.logger.info("Editing connectivity service id: {}".format(service_uuid))
+ data = {"timeout-millis": 10000, "acceptable": ["DORMANT"]}
+
try:
- self.__post(self.__ACTIONS_MAP.get("RESET"),
- "/service/"+service_uuid, get_response=False)
- response = self.__post(self.__ACTIONS_MAP.get(
- "CHECK"), "/service/"+service_uuid, data)
+ self.__post(
+ self.__ACTIONS_MAP.get("RESET"),
+ "/service/" + service_uuid,
+ get_response=False,
+ )
+ response = self.__post(
+ self.__ACTIONS_MAP.get("CHECK"),
+ "/service/" + service_uuid,
+ data,
+ )
+
if "status" in response:
- self.logger.debug(
- "Connectivity service {} reset".format(service_uuid))
+ self.logger.debug("Connectivity service {} reset".format(service_uuid))
else:
raise SdnConnectorError(
- "Invalid status check response (could be an issue with the DPB)", 500)
+ "Invalid status check response (could be an issue with the DPB)",
+ 500,
+ )
except Exception as e:
- raise SdnConnectorError(
- "Failed to reset service | text: {}".format(e), 500)
+ raise SdnConnectorError("Failed to reset service | text: {}".format(e), 500)
+
try:
data = {"segment": []}
+
for point in connection_points:
- data["segment"].append({
- "terminal-name": point.get("service_endpoint_id"),
- "label": int((point.get("service_endpoint_encapsulation_info")).get("vlan")),
- "ingress-bw": 10.0,
- "egress-bw": 10.0})
+ data["segment"].append(
+ {
+ "terminal-name": point.get("service_endpoint_id"),
+ "label": int(
+ (point.get("service_endpoint_encapsulation_info")).get(
+ "vlan"
+ )
+ ),
+ "ingress-bw": 10.0,
+ "egress-bw": 10.0,
+ }
+ )
# "ingress-bw": (bandwidth.get(point.get("service_endpoint_id"))).get("ingress"),
# "egress-bw": (bandwidth.get(point.get("service_endpoint_id"))).get("egress")}
- self.__post(self.__ACTIONS_MAP.get("DEFINE"), "/service/" +
- str(service_uuid), data, get_response=False)
- self.__post(self.__ACTIONS_MAP.get("ACTIVATE"),
- "/service/"+str(service_uuid), get_response=False)
+
+ self.__post(
+ self.__ACTIONS_MAP.get("DEFINE"),
+ "/service/" + str(service_uuid),
+ data,
+ get_response=False,
+ )
+ self.__post(
+ self.__ACTIONS_MAP.get("ACTIVATE"),
+ "/service/" + str(service_uuid),
+ get_response=False,
+ )
except Exception as e:
raise SdnConnectorError(
- "Failed to edit connectivity service | text: {}".format(e), 500)
- self.logger.debug(
- "Edited connectivity service {}".format(service_uuid))
+ "Failed to edit connectivity service | text: {}".format(e), 500
+ )
+
+ self.logger.debug("Edited connectivity service {}".format(service_uuid))
+
return conn_info
def __check_service(self, serv_type, points, kwargs):