Merge branch 'contrail' into master 10/9010/1
authortierno <alfonso.tiernosepulveda@telefonica.com>
Mon, 1 Jun 2020 06:23:06 +0000 (06:23 +0000)
committertierno <alfonso.tiernosepulveda@telefonica.com>
Mon, 1 Jun 2020 07:18:54 +0000 (07:18 +0000)
Change-Id: I49a77de6c1d9ade3a932a315f00e59d628367cbe
Signed-off-by: tierno <alfonso.tiernosepulveda@telefonica.com>
RO-SDN-arista/osm_rosdn_arista/aristaSwitch.py [deleted file]
RO-SDN-arista/osm_rosdn_arista/wimconn_arista.py
RO-SDN-arista/requirements.txt
RO-SDN-arista/setup.py
RO-SDN-arista/stdeb.cfg
RO/osm_ro/nfvo.py
RO/osm_ro/vim_thread.py
RO/osm_ro/wim/persistence.py

diff --git a/RO-SDN-arista/osm_rosdn_arista/aristaSwitch.py b/RO-SDN-arista/osm_rosdn_arista/aristaSwitch.py
deleted file mode 100644 (file)
index 840f3a9..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-# -*- coding: utf-8 -*-\r
-##\r
-# Copyright 2019 Atos - CoE Telco NFV Team\r
-# All Rights Reserved.\r
-#\r
-# Contributors: Oscar Luis Peral, Atos\r
-#\r
-# Licensed under the Apache License, Version 2.0 (the "License"); you may\r
-# not use this file except in compliance with the License. You may obtain\r
-# a copy of the License at\r
-#\r
-#         http://www.apache.org/licenses/LICENSE-2.0\r
-#\r
-# Unless required by applicable law or agreed to in writing, software\r
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\r
-# License for the specific language governing permissions and limitations\r
-# under the License.\r
-#\r
-# For those usages not covered by the Apache License, Version 2.0 please\r
-# contact with: <oscarluis.peral@atos.net>\r
-#\r
-# Neither the name of Atos nor the names of its\r
-# contributors may be used to endorse or promote products derived from\r
-# this software without specific prior written permission.\r
-#\r
-# This work has been performed in the context of Arista Telefonica OSM PoC.\r
-##\r
-\r
-from jsonrpclib import Server\r
-import socket\r
-import ssl\r
-\r
-\r
-class AristaSwitch():\r
-    """\r
-    Used to run switch commands through eAPI and check command output\r
-    """\r
-\r
-    def __init__(self, name=None, host=None, user=None, passwd=None,\r
-                 verify_ssl=False, unix_socket=None,\r
-                 logger=None):\r
-\r
-        self.host = host\r
-        self.user = user\r
-        self.passwd = passwd\r
-\r
-        self.unix_socket = unix_socket\r
-        self.local_ep = Server(unix_socket) \\r
-            if unix_socket is not None else None\r
-\r
-        s = "https://{user}:{passwd}@{host}/command-api"\r
-        self.url = s.format(user=user, passwd=passwd, host=host)\r
-        self.ep = Server(self.url)\r
-        self.verify_ssl = verify_ssl\r
-        if not self.verify_ssl:\r
-            try:\r
-                ssl._create_default_https_context = ssl.\\r
-                                                    _create_unverified_context\r
-            except AttributeError:\r
-                # Old python versions do not verify certs by default\r
-                pass\r
-\r
-        self.log = logger\r
-\r
-    def _multilinestr_to_list(self, multilinestr=None):\r
-        """\r
-        Returns a list, each item been one line of a (multi)line string\r
-        Handy for running multiple lines commands through one API call\r
-        """\r
-        mylist = \\r
-            [x.strip() for x in multilinestr.split('\n') if x.strip() != '']\r
-        return mylist\r
-\r
-    def run(self, cmds=None, timeout=10, local_run=False):\r
-        """\r
-        Runs commands through eAPI\r
-\r
-        If local_run is True eAPI call will be done using local unix socket\r
-        If local run is False eAPI call will be done using TCPIP\r
-        """\r
-        socket.setdefaulttimeout(timeout)\r
-\r
-        r = None\r
-\r
-        if type(cmds) is str:\r
-            run_list = self._multilinestr_to_list(cmds)\r
-\r
-        if type(cmds) is list:\r
-            run_list = cmds\r
-\r
-        if local_run:\r
-            ep = self.local_ep\r
-            ep_log = "local unix socket {}".format(str(self.unix_socket))\r
-        else:\r
-            ep = self.ep\r
-            ep_log = "tcpip socket {}".format(str(self.host))\r
-\r
-        self.log.debug("Calling eAPI at {} with commands {}".\r
-                       format(ep_log, str(run_list)))\r
-\r
-        try:\r
-            r = ep.runCmds(1, run_list)\r
-        except Exception as e:\r
-            self.log.error(str(e))\r
-            raise(e)\r
-\r
-        return r\r
index 5c28867..4503275 100644 (file)
@@ -45,7 +45,6 @@ from cvprac.cvp_api import CvpApi
 from cvprac.cvp_client_errors import CvpLoginError,  CvpSessionLogOutError, CvpApiError
 from cvprac import __version__ as cvprac_version
 
-from osm_rosdn_arista.aristaSwitch import AristaSwitch
 from osm_rosdn_arista.aristaConfigLet import AristaSDNConfigLet
 from osm_rosdn_arista.aristaTask import AristaCVPTask
 
@@ -130,6 +129,7 @@ class AristaSdnConnector(SdnConnectorBase):
     __API_REQUEST_TOUT = 60
     __SWITCH_TAG_NAME = 'topology_type'
     __SWITCH_TAG_VALUE = 'leaf'
+    __LOOPBACK_INTF = "Loopback0"
 
 
     def __init__(self, wim, wim_account, config=None, logger=None):
@@ -183,7 +183,13 @@ class AristaSdnConnector(SdnConnectorBase):
         self.allDeviceFacts = []
         self.clC = AristaSDNConfigLet()
         self.taskC = None
-        self.__load_switches()
+        try:
+            self.__load_switches()
+        except SdnConnectorError as sc:
+            raise sc
+        except Exception as e:
+            raise SdnConnectorError(message="Unable to load switches from CVP",
+                                    http_code=500) from e
 
     def __load_switches(self):
         """ Retrieves the switches to configure in the following order
@@ -211,14 +217,20 @@ class AristaSdnConnector(SdnConnectorBase):
                                                   'ip': None,
                                                   'usr': self.__user,
                                                   'lo0': None,
-                                                  'AS': None}
+                                                  'AS': None,
+                                                  'serialNumber': None}
 
         if self.__config and self.__config.get('switches'):
             # Not directly from json, complete one by one
             config_switches = self.__config.get('switches')
             for cs, cs_content in config_switches.items():
                 if cs not in self.switches:
-                    self.switches[cs] = {'passwd': self.__passwd, 'ip': None, 'usr': self.__user, 'lo0': None,'AS': None}
+                    self.switches[cs] = {'passwd': self.__passwd,
+                                         'ip': None,
+                                         'usr': self.__user,
+                                         'lo0': None,
+                                         'AS': None,
+                                         'serialNumber': None}
                 if cs_content:
                     self.switches[cs].update(cs_content)
 
@@ -240,94 +252,32 @@ class AristaSdnConnector(SdnConnectorBase):
                                            'ip': device['ipAddress'],
                                            'usr': self.__user,
                                            'lo0': None,
-                                           'AS': None}
+                                           'AS': None,
+                                           'serialNumber': None}
                             self.switches[device['hostname']] = switch_data
         if len(self.switches) == 0:
             self.logger.error("Unable to load Leaf switches from CVP")
             return
 
-        # self.s_api are switch objects, one for each switch in self.switches,
+        # self.switches are switch objects, one for each switch in self.switches,
         # used to make eAPI calls by using switch.py module
-        self.s_api = {}
         for s in self.switches:
-            if not self.switches[s].get('ip'):
-                for device in self.allDeviceFacts:
-                    if device['hostname'] == s:
+            for device in self.allDeviceFacts:
+                if device['hostname'] == s:
+                    if not self.switches[s].get('ip'):
                         self.switches[s]['ip'] = device['ipAddress']
-            if self.is_valid_destination(self.switches[s].get('ip')):
-                self.s_api[s] = AristaSwitch(host=self.switches[s]['ip'],
-                                             user=self.switches[s]['usr'],
-                                             passwd=self.switches[s]['passwd'],
-                                             logger=self.logger)
+                    self.switches[s]['serialNumber'] = device['serialNumber']
+                    break
+                            
             # Each switch has a different loopback address,
             # so it's a different configLet
             if not self.switches[s].get('lo0'):
-                inf = self.__get_switch_interface_ip(s, 'Loopback0')
-                self.switches[s]["lo0"] = inf.split('/')[0]
+                self.switches[s]["lo0"] = self.__get_interface_ip(self.switches[s]['serialNumber'], self.__LOOPBACK_INTF)
             if not self.switches[s].get('AS'):
-                self.switches[s]["AS"] = self.__get_switch_asn(s)
+                self.switches[s]["AS"] = self.__get_device_ASN(self.switches[s]['serialNumber'])
         self.logger.debug("Using Arista Leaf switches: {}".format(
                 self.delete_keys_from_dict(self.switches, ('passwd',))))
 
-    def __lldp_find_neighbor(self, tlv_name=None, tlv_value=None):
-        """Returns a list of dicts where a mathing LLDP neighbor has been found
-           Each dict has:
-             switch -> switch name
-             interface -> switch interface
-        """
-        r = []
-        lldp_info = {}
-
-        # Get LLDP info from each switch
-        for s in self.s_api:
-            result = self.s_api[s].run("show lldp neighbors detail")
-            lldp_info[s] = result[0]["lldpNeighbors"]
-            # Look LLDP match on each interface
-            # Note that eAPI returns [] for an interface with no LLDP neighbors
-            # in the corresponding interface lldpNeighborInfo field
-            for interface in lldp_info[s]:
-                if lldp_info[s][interface]["lldpNeighborInfo"]:
-                    lldp_nInf = lldp_info[s][interface]["lldpNeighborInfo"][0]
-                    if tlv_name in lldp_nInf:
-                        if lldp_nInf[tlv_name] == tlv_value:
-                            r.append({"name": s, "interface": interface})
-
-        return r
-
-    def __get_switch_asn(self, switch):
-        """Returns switch ASN in default VRF
-        """
-        bgp_info = self.s_api[switch].run("show ip bgp summary")[0]
-        return(bgp_info["vrfs"]["default"]["asn"])
-
-    def __get_switch_po(self, switch, interface=None):
-        """Returns Port-Channels for a given interface
-           If interface is None returns a list with all PO interfaces
-           Note that if specified, interface should be exact name
-           for instance: Ethernet3 and not e3 eth3 and so on
-        """
-        po_inf = self.s_api[switch].run("show port-channel")[0]["portChannels"]
-
-        if interface:
-            r = [x for x in po_inf if interface in po_inf[x]["activePorts"]]
-        else:
-            r = po_inf
-
-        return r
-
-    def __get_switch_interface_ip(self, switch, interface=None):
-        """Returns interface primary ip
-           interface should be exact name
-           for instance: Ethernet3 and not ethernet 3, e3 eth3 and so on
-        """
-        cmd = "show ip interface {}".format(interface)
-        ip_info = self.s_api[switch].run(cmd)[0]["interfaces"][interface]
-
-        ip = ip_info["interfaceAddress"]["primaryIp"]["address"]
-        mask = ip_info["interfaceAddress"]["primaryIp"]["maskLen"]
-
-        return "{}/{}".format(ip, mask)
-
     def __check_service(self, service_type, connection_points,
                         check_vlan=True, check_num_cp=True, kwargs=None):
         """ Reviews the connection points elements looking for semantic errors in the incoming data
@@ -453,7 +403,7 @@ class AristaSdnConnector(SdnConnectorBase):
             t_isFailed = False
             t_isPending = False
             failed_switches = []
-            for s in self.s_api:
+            for s in self.switches:
                 if (len(cls_perSw[s]) > 0):
                     for cl in cls_perSw[s]:
                         # Fix 1030 SDN-ARISTA Key error note when deploy a NS
@@ -610,7 +560,7 @@ class AristaSdnConnector(SdnConnectorBase):
             cls_perSw = {}
             cls_cp = {}
             cl_bgp = {}
-            for s in self.s_api:
+            for s in self.switches:
                 cls_perSw[s] = []
                 cls_cp[s] = []
             vlan_processed = False
@@ -640,18 +590,8 @@ class AristaSdnConnector(SdnConnectorBase):
 
                 encap_type = cp.get(self.__ENCAPSULATION_TYPE_PARAM)
                 switch_id = encap_info.get(self.__SW_ID_PARAM)
-                if not switch_id:
-                    point_mac = encap_info.get(self.__MAC_PARAM)
-                    switches = self.__lldp_find_neighbor("chassisId", point_mac)
-                    self.logger.debug("Found connection point for MAC {}: {}".
-                                      format(point_mac, switches))
-                else:
-                    interface = encap_info.get(self.__SW_PORT_PARAM)
-                    switches = [{'name': switch_id, 'interface': interface}]
-
-                if len(switches) == 0:
-                    raise SdnConnectorError(message="Connection point MAC address {} not found in the switches".format(point_mac),
-                                            http_code=406)
+                interface = encap_info.get(self.__SW_PORT_PARAM)
+                switches = [{'name': switch_id, 'interface': interface}]
 
                 # remove those connections that are equal. This happens when several sriovs are located in the same
                 # compute node interface, that is, in the same switch and interface
@@ -660,13 +600,6 @@ class AristaSdnConnector(SdnConnectorBase):
                     continue
                 processed_connection_points += switches
                 for switch in switches:
-                    if not switch_id:
-                        port_channel = self.__get_switch_po(switch['name'],
-                                                            switch['interface'])
-                        if len(port_channel) > 0:
-                            interface = port_channel[0]
-                        else:
-                            interface = switch['interface']
                     if not interface:
                         raise SdnConnectorError(message="Connection point switch port empty for switch_dpid {}".format(switch_id),
                                                 http_code=406)
@@ -697,7 +630,7 @@ class AristaSdnConnector(SdnConnectorBase):
                 raise SdnConnectorError(message=SdnError.UNSUPPORTED_FEATURE,
                                         http_code=406)
 
-            for s in self.s_api:
+            for s in self.switches:
                 # for cl in cp_configLets:
                 cl_name = (self.__OSM_PREFIX +
                            s +
@@ -760,12 +693,11 @@ class AristaSdnConnector(SdnConnectorBase):
             allLeafConfigured = {}
             allLeafModified = {}
 
-            for s in self.s_api:
+            for s in self.switches:
                 allLeafConfigured[s] = False
                 allLeafModified[s] = False
-            tasks = dict()
             cl_toDelete = []
-            for s in self.s_api:
+            for s in self.switches:
                 toDelete_in_cvp = False
                 if not (cls_perSw.get(s) and cls_perSw[s][0].get('config')):
                     # when there is no configuration, means that there is no interface
@@ -801,7 +733,6 @@ class AristaSdnConnector(SdnConnectorBase):
                 self.logger.info("Device {} modify result {}".format(s, res))
                 for t_id in res[1]['tasks']:
                     if not toDelete_in_cvp:
-                        tasks[t_id] = {'workOrderId': t_id}
                         note_msg = "{}{}{}{}##".format(self.__MANAGED_BY_OSM,
                                                        self.__SEPARATOR,
                                                        t_id,
@@ -810,15 +741,12 @@ class AristaSdnConnector(SdnConnectorBase):
                                 cls_perSw[s][0]['key'],
                                 note_msg)
                         cls_perSw[s][0]['note'] = note_msg
-                    else:
-                        delete_tasks = { t_id : {'workOrderId': t_id} }
-                        self.__exec_task(delete_tasks)
+                    tasks = { t_id : {'workOrderId': t_id} }
+                    self.__exec_task(tasks, self.__EXC_TASK_EXEC_WAIT)
                 # with just one configLet assigned to a device,
                 # delete all if there are errors in next loops
                 if not toDelete_in_cvp:
                     allLeafModified[s] = True
-            if len(tasks) > 0:
-                self.__exec_task(tasks, self.__EXC_TASK_EXEC_WAIT)
             if len(cl_toDelete) > 0:
                 self.__configlet_modify(cl_toDelete, delete=True)
 
@@ -839,7 +767,7 @@ class AristaSdnConnector(SdnConnectorBase):
                              allLeafModified):
         """ Removes the given configLet from the devices and then remove the configLets
         """
-        for s in self.s_api:
+        for s in self.switches:
             if allLeafModified[s]:
                 try:
                     res = self.__device_modify(
@@ -856,7 +784,7 @@ class AristaSdnConnector(SdnConnectorBase):
                 except Exception as e:
                     self.logger.error('Error removing configlets from device {}: {}'.format(s, e))
                     pass
-        for s in self.s_api:
+        for s in self.switches:
             if allLeafConfigured[s]:
                 self.__configlet_modify(cls_perSw[s], delete=True)
 
@@ -1104,7 +1032,7 @@ class AristaSdnConnector(SdnConnectorBase):
         return [changed, data]
 
     def __get_configletsDevices(self, configlets):
-        for s in self.s_api:
+        for s in self.switches:
             configlet = configlets[s]
             # Add applied Devices
             if len(configlet) > 0:
@@ -1116,14 +1044,14 @@ class AristaSdnConnector(SdnConnectorBase):
 
     def __get_serviceData(self, service_uuid, service_type, vlan_id, conn_info=None):
         cls_perSw = {}
-        for s in self.s_api:
+        for s in self.switches:
             cls_perSw[s] = []
         if not conn_info:
             srv_cls = self.__get_serviceConfigLets(service_uuid,
                                                    service_type,
                                                    vlan_id)
             self.__get_configletsDevices(srv_cls)
-            for s in self.s_api:
+            for s in self.switches:
                 cl = srv_cls[s]
                 if len(cl) > 0:
                     for dev in cl['devices']:
@@ -1160,11 +1088,11 @@ class AristaSdnConnector(SdnConnectorBase):
                                                c_info)
             allLeafConfigured = {}
             allLeafModified = {}
-            for s in self.s_api:
+            for s in self.switches:
                 allLeafConfigured[s] = True
                 allLeafModified[s] = True
             found_in_cvp = False
-            for s in self.s_api:
+            for s in self.switches:
                 if cls_perSw[s]:
                     found_in_cvp = True
             if found_in_cvp:
@@ -1397,7 +1325,7 @@ class AristaSdnConnector(SdnConnectorBase):
         connectivity service
         """
         srv_cls = {}
-        for s in self.s_api:
+        for s in self.switches:
             srv_cls[s] = []
             found_in_cvp = False
             name = (self.__OSM_PREFIX +
@@ -1552,6 +1480,25 @@ class AristaSdnConnector(SdnConnectorBase):
                     self.cvp_tags.append(elem)
         self.logger.debug('Available devices with tag_name {} - value {}: {} '.format(name, value, self.cvp_tags))
 
+    def __get_interface_ip(self, device_id, interface):
+        ip = None
+        url = '/api/v1/rest/{}/Sysdb/ip/config/ipIntfConfig/{}/'.format(device_id, interface)
+        self.logger.debug('get_interface_ip: URL {}'.format(url))
+        try:
+            data = self.client.get(url, timeout=self.__API_REQUEST_TOUT)
+            return data['notifications'][0]['updates']['addrWithMask']['value'].split('/')[0]
+        except Exception:
+            raise SdnConnectorError("Invalid response from url {}: data {}".format(url, data))
+
+    def __get_device_ASN(self, device_id):
+        url = '/api/v1/rest/{}/Sysdb/routing/bgp/config/'.format(device_id)
+        self.logger.debug('get_device_ASN: URL {}'.format(url))
+        try:
+            data = self.client.get(url, timeout=self.__API_REQUEST_TOUT)
+            return data['notifications'][0]['updates']['asNumber']['value']['value']['int']
+        except Exception:
+            raise SdnConnectorError("Invalid response from url {}: data {}".format(url, data))
+
     def is_valid_destination(self, url):
         """ Check that the provided WIM URL is correct
         """
@@ -1587,6 +1534,8 @@ class AristaSdnConnector(SdnConnectorBase):
         return True
 
     def delete_keys_from_dict(self, dict_del, lst_keys):
+        if dict_del is None:
+            return dict_del
         dict_copy = {k: v for k, v in dict_del.items() if k not in lst_keys}
         for k, v in dict_copy.items():
             if isinstance(v, dict):
index e0aac53..cd1edfe 100644 (file)
@@ -14,7 +14,6 @@
 ##
 
 requests
-jsonrpclib-pelix
 uuid
 cvprac
 git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro
index 4532078..d974aad 100644 (file)
@@ -46,7 +46,6 @@ setup(
     include_package_data=True,
     install_requires=["requests",
                       "uuid",
-                      "jsonrpclib-pelix",
                       "cvprac",
                       "osm-ro @ git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro&subdirectory=RO"],
     setup_requires=['setuptools-version-command'],
index d5d358a..0c718e4 100644 (file)
@@ -15,5 +15,5 @@
 
 [DEFAULT]
 X-Python3-Version : >= 3.5
-Depends3: python3-requests, python3-osm-ro, python3-jsonrpclib-pelix
+Depends3: python3-requests, python3-osm-ro
 
index f06bce4..2efd610 100644 (file)
@@ -3311,31 +3311,6 @@ def create_instance(mydb, tenant_id, instance_dict):
                 involved_datacenters.append(default_datacenter_id)
             target_wim_account = sce_net.get("wim_account", default_wim_account)
 
-            # --> WIM
-            # TODO: use this information during network creation
-            wim_account_id = wim_account_name = None
-            if len(involved_datacenters) > 1 and 'uuid' in sce_net:
-                urls = [myvims[v].url for v in involved_datacenters]
-                if len(set(urls)) < 2:
-                    wim_usage[sce_net['uuid']] = False
-                elif target_wim_account is None or target_wim_account is True:  # automatic selection of WIM
-                    # OBS: sce_net without uuid are used internally to VNFs
-                    # and the assumption is that VNFs will not be split among
-                    # different datacenters
-                    wim_account = wim_engine.find_suitable_wim_account(
-                        involved_datacenters, tenant_id)
-                    wim_account_id = wim_account['uuid']
-                    wim_account_name = wim_account['name']
-                    wim_usage[sce_net['uuid']] = wim_account_id
-                elif isinstance(target_wim_account, str):     # manual selection of WIM
-                    wim_account.persist.get_wim_account_by(target_wim_account, tenant_id)
-                    wim_account_id = wim_account['uuid']
-                    wim_account_name = wim_account['name']
-                    wim_usage[sce_net['uuid']] = wim_account_id
-                else:  # not WIM usage
-                    wim_usage[sce_net['uuid']] = False
-            # <-- WIM
-
             descriptor_net = {}
             if instance_dict.get("networks"):
                 if sce_net.get("uuid") in instance_dict["networks"]:
@@ -3368,14 +3343,39 @@ def create_instance(mydb, tenant_id, instance_dict):
                 )
                 if not target_instance_nets:
                     raise NfvoException(
-                        "Cannot find the target network at instance:networks[{}]:use-network".format(descriptor_net_name),
-                        httperrors.Bad_Request)
+                        "Cannot find the target network at instance:networks[{}]:use-network".format(
+                            descriptor_net_name), httperrors.Bad_Request)
                 else:
                     use_network = target_instance_nets[0]["related"]
 
             if sce_net["external"]:
                 number_mgmt_networks += 1
 
+            # --> WIM
+            # TODO: use this information during network creation
+            wim_account_id = wim_account_name = None
+            if len(involved_datacenters) > 1 and 'uuid' in sce_net:
+                urls = [myvims[v].url for v in involved_datacenters]
+                if len(set(urls)) < 2:
+                    wim_usage[sce_net['uuid']] = False
+                elif target_wim_account is None or target_wim_account is True:  # automatic selection of WIM
+                    # OBS: sce_net without uuid are used internally to VNFs
+                    # and the assumption is that VNFs will not be split among
+                    # different datacenters
+                    wim_account = wim_engine.find_suitable_wim_account(
+                        involved_datacenters, tenant_id)
+                    wim_account_id = wim_account['uuid']
+                    wim_account_name = wim_account['name']
+                    wim_usage[sce_net['uuid']] = wim_account_id
+                elif isinstance(target_wim_account, str):     # manual selection of WIM
+                    wim_account.persist.get_wim_account_by(target_wim_account, tenant_id)
+                    wim_account_id = wim_account['uuid']
+                    wim_account_name = wim_account['name']
+                    wim_usage[sce_net['uuid']] = wim_account_id
+                else:  # not WIM usage
+                    wim_usage[sce_net['uuid']] = False
+            # <-- WIM
+
             for datacenter_id in involved_datacenters:
                 netmap_use = None
                 netmap_create = None
@@ -5265,12 +5265,13 @@ def create_vim_account(mydb, nfvo_tenant, datacenter_id, name=None, vim_id=None,
         else: #if vim_tenant==None:
             #create tenant at VIM if not provided
             try:
-                _, myvim = get_datacenter_by_name_uuid(mydb, None, datacenter, vim_user=vim_username,
-                                                                   vim_passwd=vim_password)
+                _, myvim = get_datacenter_by_name_uuid(mydb, None, datacenter_id, vim_user=vim_username,
+                                                       vim_passwd=vim_password)
                 datacenter_name = myvim["name"]
                 vim_tenant = myvim.new_tenant(vim_tenant_name, "created by openmano for datacenter "+datacenter_name)
             except vimconn.vimconnException as e:
-                raise NfvoException("Not possible to create vim_tenant {} at VIM: {}".format(vim_tenant_id, str(e)), httperrors.Internal_Server_Error)
+                raise NfvoException("Not possible to create vim_tenant {} at VIM: {}".format(vim_tenant_name, e),
+                                    httperrors.Internal_Server_Error)
             datacenter_tenants_dict = {}
             datacenter_tenants_dict["created"]="true"
 
index 622cccb..380bd6a 100644 (file)
@@ -126,7 +126,7 @@ class vim_thread(threading.Thread):
         self.error_status = None
         self.wim_account_id = wim_account_id
         self.datacenter_tenant_id = datacenter_tenant_id
-        self.port_mapping = None
+        self.port_mappings = None
         if self.wim_account_id:
             self.target_k = "wim_account_id"
             self.target_v = self.wim_account_id
index f4945bb..27a87c4 100644 (file)
@@ -870,10 +870,7 @@ def _preprocess_wim_account(wim_account):
     """
     wim_account = preprocess_record(wim_account)
 
-    created = wim_account.get('created')
-    wim_account['created'] = (
-        'true' if created is True or created == 'true' else 'false')
-
+    wim_account['sdn'] = False
     return wim_account