Beispiel #1
0
 def _generate_vni(self):
     """
      Method to get unused VxLAN Network Identifier (VNI)
         Args:
             None
         Returns:
             VNI
     """
     # find unused VLAN ID
     for vlanID_range in self.vni_range:
         try:
             start_vni, end_vni = map(
                 int,
                 vlanID_range.replace(" ", "").split("-"))
             for i in range(start_vni, end_vni + 1):
                 vni = random.randrange(start_vni, end_vni, 1)
                 if vni not in self.used_vni:
                     return vni
         except Exception as exp:
             raise SdnConnectorError(
                 "Exception {} occurred while searching a free VNI.".format(
                     exp))
     else:
         raise SdnConnectorError(
             "Unable to create the virtual network."
             " All VNI in VNI range {} are in use.".format(self.vni_range))
Beispiel #2
0
 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)
         if "status" in response:
             self.logger.debug(
                 "Connectivity service {} reset".format(service_uuid))
         else:
             raise SdnConnectorError(
                 "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)
     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
             })
             # "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)
     except Exception as e:
         raise SdnConnectorError(
             "Failed to edit connectivity service | text: {}".format(e),
             500)
     self.logger.debug(
         "Edited connectivity service {}".format(service_uuid))
     return conn_info
Beispiel #3
0
 def post(self, function, url_params="", data=None, get_response=True):
     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))
         if get_response:
             return response.json()
     except Exception as e:
         raise SdnConnectorError("REST request failed | text: {}".format(e),
                                 500)
Beispiel #4
0
 def __build_private_key_obj(self):
     try:
         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))
             elif self.__auth_data.get("key_type") == "ECDSA":
                 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)
Beispiel #5
0
 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)
Beispiel #6
0
    def __init__(self, wim, wim_account, config):
        self.logger = logging.getLogger(self.__LOGGER_NAME)

        self.__wim = wim
        self.__account = wim_account
        self.__config = config
        self.__cli_config = self.__account.pop("config", None)

        self.__url = self.__wim.get("wim_url", "")
        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.__port = self.__cli_config.get(
            "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)
        elif self.__connection_type == "REST":
            interface = DpbRestInterface(self.__url, self.__port,
                                         self.__network, self.__LOGGER_NAME)
        else:
            raise SdnConnectorError(
                "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")
Beispiel #7
0
 def create_virtual_network(self, name, vni):
     self.logger.debug("create vname, name: {}, vni: {}".format(name, vni))
     routetarget = '{}:{}'.format(self.asn, vni)
     vnet_dict = {
         "virtual-network": {
             "virtual_network_properties": {
                 "vxlan_network_identifier": vni,
             },
             "parent_type": "project",
             "fq_name": [self.domain, self.project, name],
             "route_target_list": {
                 "route_target": ["target:" + routetarget]
             }
         }
     }
     endpoint = self.controller_url + 'virtual-networks'
     resp = self.http.post_cmd(url=endpoint,
                               headers=self.http_header,
                               post_fields_dict=vnet_dict)
     if not resp:
         raise SdnConnectorError(
             'Error creating virtual network: empty response')
     vnet_info = json.loads(resp)
     self.logger.debug("created vnet, vnet_info: {}".format(vnet_info))
     return vnet_info.get("virtual-network").get('uuid'), vnet_info.get(
         "virtual-network")
Beispiel #8
0
    def delete_connectivity_service(self, service_uuid, conn_info=None):
        self.logger.debug(
            "delete_connectivity_service uuid: {}".format(service_uuid))

        conn_info = conn_info or {}
        created_ifs = conn_info.get("interfaces", [])
        # Obtain current config
        onos_config = self._get_onos_netconfig()

        try:
            # Removes ports used by network from onos config
            for vpls in onos_config.get('apps', {}).get(
                    'org.onosproject.vpls', {}).get('vpls',
                                                    {}).get('vplsList', {}):
                if vpls['name'] == service_uuid:
                    # iterate interfaces to check if must delete them
                    for interface in vpls['interfaces']:
                        for port in onos_config['ports'].values():
                            for port_interface in port['interfaces']:
                                if port_interface['name'] == interface:
                                    # Delete only created ifzs
                                    if port_interface['name'] in created_ifs:
                                        self.logger.debug(
                                            "Delete ifz: {}".format(
                                                port_interface['name']))
                                        port['interfaces'].remove(
                                            port_interface)
                    onos_config['apps']['org.onosproject.vpls']['vpls'][
                        'vplsList'].remove(vpls)
                    break
            else:
                raise SdnConnectorError(
                    "service uuid: {} does not exist".format(service_uuid))

            self._pop_last_update_time(onos_config)
            self._post_onos_netconfig(onos_config)
            self.logger.debug(
                "deleted connectivity service uuid: {}".format(service_uuid))
        except SdnConnectorError:
            raise
        except Exception as e:
            self.logger.error('Exception delete connection_service: %s',
                              e,
                              exc_info=True)
            raise SdnConnectorError(
                "Exception delete connectivity service: {}".format(str(e)))
Beispiel #9
0
    def check_credentials(self):
        """Check if the connector itself can access the SDN/WIM with the provided url (wim.wim_url),
            user (wim_account.user), and password (wim_account.password)

        Raises:
            SdnConnectorError: Issues regarding authorization, access to
                external URLs, etc are detected.
        """
        self.logger.debug("")
        try:
            resp = self.underlay_api.check_auth()
            if not resp:
                raise SdnConnectorError('Empty response')
        except Exception as e:
            self.logger.error('Error checking credentials')
            raise SdnConnectorError('Error checking credentials: {}'.format(
                str(e)))
Beispiel #10
0
 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 SdnConnectorError(error, http_code=http_code)
Beispiel #11
0
 def create_vmi(self, switch_id, switch_port, network, vlan):
     self.logger.debug(
         "create vmi, switch_id: {}, switch_port: {}, network: {}, vlan: {}"
         .format(switch_id, switch_port, network, vlan))
     vmi_name = self.get_vmi_name(switch_id, switch_port, vlan)
     vpg_name = self.get_vpg_name(switch_id, switch_port)
     profile_dict = {
         "local_link_information": [{
             "port_id":
             switch_port.replace(":", "_"),
             "switch_id":
             switch_port.replace(":", "_"),
             "switch_info":
             switch_id,
             "fabric":
             self.fabric
         }]
     }
     vmi_dict = {
         "virtual-machine-interface": {
             "parent_type":
             "project",
             "fq_name": [self.domain, self.project, vmi_name],
             "virtual_network_refs": [{
                 "to": [self.domain, self.project, network]
             }],
             "virtual_machine_interface_properties": {
                 "sub_interface_vlan_tag": vlan
             },
             "virtual_machine_interface_bindings": {
                 "key_value_pair": [{
                     "key": "vnic_type",
                     "value": "baremetal"
                 }, {
                     "key": "vif_type",
                     "value": "vrouter"
                 }, {
                     "key": "vpg",
                     "value": vpg_name
                 }, {
                     "key": "profile",
                     "value": json.dumps(profile_dict)
                 }]
             }
         }
     }
     endpoint = self.controller_url + 'virtual-machine-interfaces'
     self.logger.debug("vmi_dict: {}".format(vmi_dict))
     resp = self.http.post_cmd(url=endpoint,
                               headers=self.http_header,
                               post_fields_dict=vmi_dict)
     if not resp:
         raise SdnConnectorError('Error creating vmi: empty response')
     vmi_info = json.loads(resp)
     self.logger.debug("created vmi, info: {}".format(vmi_info))
     return vmi_info.get("virtual-machine-interface").get(
         'uuid'), vmi_info.get("virtual-machine-interface")
Beispiel #12
0
 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"]}
     try:
         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)
     except Exception as e:
         raise SdnConnectorError(
             "Failed to check service status | text: {}".format(e), 500)
Beispiel #13
0
    def delete_connectivity_service(self, service_uuid, conn_info=None):
        """
        Disconnect multi-site endpoints previously connected

        :param service_uuid: The one returned by create_connectivity_service
        :param conn_info: The one returned by last call to 'create_connectivity_service' or 'edit_connectivity_service'
            if they do not return None
        :return: None
        :raises: SdnConnectorException: In case of error. The parameter http_code must be filled
        """
        self.logger.info(
            "delete_connectivity_service vnet_name: {}, connection_points: {}".
            format(service_uuid, conn_info))

        try:
            vnet_uuid = service_uuid
            # vnet_name = conn_info["vnet"]["name"]   # always should exist as the network is the first thing created
            work_cps = conn_info["connection_points"]

            # 1: For each connection point delete vlan from vpg and it is is the
            # last one, delete vpg
            for cp in work_cps.values():
                self._delete_port(cp.get("switch_dpid"), cp.get("switch_port"),
                                  cp.get("vlan"))

            # 2: Delete vnet
            self.underlay_api.delete_virtual_network(vnet_uuid)
            self.logger.info(
                "deleted connectivity_service vnet_uuid: {}, connection_points: {}"
                .format(service_uuid, conn_info))
        except SdnConnectorError:
            raise
        except HttpException as e:
            self.logger.error(
                "Error deleting connectivity service: {}".format(e))
            raise SdnConnectorError(
                "Exception deleting connectivity service: {}".format(str(e)))
        except Exception as e:
            self.logger.error(
                "Error deleting connectivity service: {}".format(e),
                exc_info=True)
            raise SdnConnectorError(
                "Exception deleting connectivity service: {}".format(str(e)))
Beispiel #14
0
    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)
            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
                })
                # "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))
            return (str(service_id), None)
        except Exception as e:
            raise SdnConnectorError(
                "Connectivity service could not be made | text: {}".format(e),
                500)
Beispiel #15
0
    def delete_connectivity_service(self, service_uuid, conn_info=None):
        """Disconnect multi-site endpoints previously connected

        """
        self.logger.debug(
            "delete_connectivity_service: service_uuid='{}' conn_info='{}'".
            format(service_uuid, conn_info))
        if service_uuid not in self.connections:
            raise SdnConnectorError(
                "connectivity {} not found".format(service_uuid),
                http_code=HTTPStatus.NOT_FOUND.value)
        self.connections.pop(service_uuid, None)
        return None
Beispiel #16
0
 def _post_onos_netconfig(self, onos_config):
     try:
         onos_config_resp = requests.post(self.url,
                                          json=onos_config,
                                          auth=HTTPBasicAuth(
                                              self.user, self.password))
         status_code = onos_config_resp.status_code
         if status_code != requests.codes.ok:
             self.logger.info(
                 "Error updating network config, status code: {}".format(
                     status_code))
             raise SdnConnectorError(
                 "Error obtaining network config status code: {}".format(
                     status_code),
                 http_code=status_code)
     except requests.exceptions.ConnectionError as e:
         self.logger.info('Exception connecting to onos: %s', e)
         raise SdnConnectorError("Error connecting to onos: {}".format(e))
     except Exception as e:
         self.logger.info('Exception posting onos network config: %s', e)
         raise SdnConnectorError(
             "Exception posting onos network config: {}".format(e))
Beispiel #17
0
 def _get_onos_netconfig(self):
     try:
         onos_config_req = requests.get(self.url,
                                        auth=HTTPBasicAuth(
                                            self.user, self.password))
         status_code = onos_config_req.status_code
         if status_code == requests.codes.ok:
             return onos_config_req.json()
         else:
             self.logger.info(
                 "Error obtaining network config, status code: {}".format(
                     status_code))
             raise SdnConnectorError(
                 "Error obtaining network config status code: {}".format(
                     status_code),
                 http_code=status_code)
     except requests.exceptions.ConnectionError as e:
         self.logger.info('Exception connecting to onos: %s', e)
         raise SdnConnectorError("Error connecting to onos: {}".format(e))
     except Exception as e:
         self.logger.error('Exception getting onos network config: %s', e)
         raise SdnConnectorError(
             "Exception getting onos network config: {}".format(e))
Beispiel #18
0
 def __init__(self, wim, wim_account, config=None, logger=None):
     self.logger = logger or logging.getLogger(self._WIM_LOGGER)
     super().__init__(wim, wim_account, config, logger)
     self.user = wim_account.get("user")
     self.password = wim_account.get("password")
     url = wim.get("wim_url")
     if not url:
         raise SdnConnectorError("'url' must be provided")
     if not url.startswith("http"):
         url = "http://" + url
     if not url.endswith("/"):
         url = url + "/"
     self.url = url + "onos/v1/network/configuration"
     self.logger.info("ONOS VPLS Connector Initialized.")
Beispiel #19
0
 def delete_connectivity_service(self, service_uuid, conn_info=None):
     self.logger.info(
         "Deleting connectivity service id: {}".format(service_uuid))
     try:
         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))
     return None
Beispiel #20
0
 def check_credentials(self):
     status_code = 503
     onos_config_req = None
     try:
         onos_config_req = requests.get(self.url,
                                        auth=HTTPBasicAuth(
                                            self.user, self.password))
         onos_config_req.raise_for_status()
     except Exception as e:
         if onos_config_req:
             status_code = onos_config_req.status_code
         self.logger.exception('Error checking credentials: {}'.format(e))
         raise SdnConnectorError('Error checking credentials: {}'.format(e),
                                 http_code=status_code)
Beispiel #21
0
    def post(self, function, url_params="", data=None, get_response=True):
        """post request to dpb via ssh

        notes:
        - 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('/')
        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["type"] = function[self.__FUNCTION_MAP_POS]
        data = {"session": self.__session_id, "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)
            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)

        try:
            data_len = struct.unpack(">I", self.__stdout.read(4))[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)
Beispiel #22
0
    def edit_connectivity_service(self,
                                  service_uuid,
                                  conn_info=None,
                                  connection_points=None,
                                  **kwargs):
        """Change an existing connectivity service.

        This method's arguments and return value follow the same convention as
        :meth:`~.create_connectivity_service`.
        """
        self.logger.debug(
            "edit_connectivity_service: service_uuid='{}' conn_info='{}', connection_points='{}'"
            "kwargs='{}'".format(service_uuid, conn_info, connection_points,
                                 kwargs))
        if service_uuid not in self.connections:
            raise SdnConnectorError(
                "connectivity {} not found".format(service_uuid),
                http_code=HTTPStatus.NOT_FOUND.value)
        self.connections[service_uuid] = connection_points.copy()
        return None
Beispiel #23
0
 def create_vpg(self, switch_id, switch_port):
     self.logger.debug("create vpg, switch_id: {}, switch_port: {}".format(
         switch_id, switch_port))
     vpg_name = self.get_vpg_name(switch_id, switch_port)
     vpg_dict = {
         "virtual-port-group": {
             "parent_type": "fabric",
             "fq_name":
             ["default-global-system-config", self.fabric, vpg_name]
         }
     }
     endpoint = self.controller_url + 'virtual-port-groups'
     resp = self.http.post_cmd(url=endpoint,
                               headers=self.http_header,
                               post_fields_dict=vpg_dict)
     if not resp:
         raise SdnConnectorError(
             'Error creating virtual port group: empty response')
     vpg_info = json.loads(resp)
     self.logger.debug("created vpg, vpg_info: {}".format(vpg_info))
     return vpg_info.get("virtual-port-group").get('uuid'), vpg_info.get(
         "virtual-port-group")
Beispiel #24
0
    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)
            stdin, stdout, stderr = self.__ssh_client.exec_command(
                command=self.__network)
        except paramiko.BadHostKeyException as e:
            raise SdnConnectorError(
                "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)
        except paramiko.SSHException as e:
            raise SdnConnectorError(
                "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)

        try:
            data_len = struct.unpack(">I", stdout.read(4))[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)
        if "error" in data:
            raise SdnConnectorError(
                data.get("msg", data.get("error", "ERROR")), 500)
        self.logger.info("SSH connection to DPB established OK")
        return stdin, stdout
Beispiel #25
0
 def get_all_active_connectivity_services(self):
     raise SdnConnectorError('Impossible to use WIM: {}'.format(self.error_msg))
Beispiel #26
0
 def edit_connectivity_service(self, service_uuid, *args, **kwargs):
     raise SdnConnectorError('Impossible to change connection {}: {}'
                             .format(service_uuid, self.error_msg))
Beispiel #27
0
 def delete_connectivity_service(self, service_uuid, _conn_info=None):
     raise SdnConnectorError('Impossible to delete {}: {}'
                             .format(service_uuid, self.error_msg))
Beispiel #28
0
 def create_connectivity_service(self, service_uuid, *args, **kwargs):
     raise SdnConnectorError('Impossible to create connectivity: {}'
                             .format(self.error_msg))
Beispiel #29
0
 def get_connectivity_service_status(self, service_uuid, _conn_info=None):
     raise SdnConnectorError('Impossible to retrieve status for {}: {}'
                             .format(service_uuid, self.error_msg))
Beispiel #30
0
 def check_credentials(self):
     raise SdnConnectorError('Impossible to use WIM:\n' + self.error_msg)