Bug 2217 fixed: modified the cloud-init merge configs and defined the default SSH...
[osm/RO.git] / RO-plugin / osm_ro_plugin / vimconn.py
index bb06037..b251d59 100644 (file)
@@ -293,13 +293,32 @@ class VimConnector:
         userdata = None
         userdata_list = []
 
+        # For more information, check https://cloudinit.readthedocs.io/en/latest/reference/merging.html
+        # Basically, with this, we don't override the provider's cloud config
+        merge_how = yaml.safe_dump(
+            {
+                "merge_how": [
+                    {
+                        "name": "list",
+                        "settings": ["append", "recurse_dict", "recurse_list"],
+                    },
+                    {
+                        "name": "dict",
+                        "settings": ["no_replace", "recurse_list", "recurse_dict"],
+                    },
+                ]
+            },
+            indent=4,
+            default_flow_style=False,
+        )
+
         if isinstance(cloud_config, dict):
             if cloud_config.get("user-data"):
                 if isinstance(cloud_config["user-data"], str):
-                    userdata_list.append(cloud_config["user-data"])
+                    userdata_list.append(cloud_config["user-data"] + f"\n{merge_how}")
                 else:
                     for u in cloud_config["user-data"]:
-                        userdata_list.append(u)
+                        userdata_list.append(u + f"\n{merge_how}")
 
             if cloud_config.get("boot-data-drive") is not None:
                 config_drive = cloud_config["boot-data-drive"]
@@ -314,12 +333,12 @@ class VimConnector:
                 # default user
                 if cloud_config.get("key-pairs"):
                     userdata_dict["ssh-authorized-keys"] = cloud_config["key-pairs"]
-                    userdata_dict["users"] = [
-                        {
-                            "default": None,
-                            "ssh-authorized-keys": cloud_config["key-pairs"],
+                    userdata_dict["system_info"] = {
+                        "default_user": {
+                            "ssh_authorized_keys": cloud_config["key-pairs"],
                         }
-                    ]
+                    }
+                    userdata_dict["users"] = ["default"]
 
                 if cloud_config.get("users"):
                     if "users" not in userdata_dict:
@@ -358,6 +377,7 @@ class VimConnector:
                 userdata_list.append(
                     "#cloud-config\n"
                     + yaml.safe_dump(userdata_dict, indent=4, default_flow_style=False)
+                    + f"\n{merge_how}"
                 )
             userdata = self._create_mimemultipart(userdata_list)
             self.logger.debug("userdata: %s", userdata)
@@ -822,273 +842,6 @@ class VimConnector:
         """
         raise VimConnNotImplemented("Should have implemented this")
 
-    def new_classification(self, name, ctype, definition):
-        """Creates a traffic classification in the VIM
-        Params:
-            'name': name of this classification
-            'ctype': type of this classification
-            'definition': definition of this classification (type-dependent free-form text)
-        Returns the VIM's classification ID on success or raises an exception on failure
-        """
-        raise VimConnNotImplemented("SFC support not implemented")
-
-    def get_classification(self, classification_id):
-        """Obtain classification details of the VIM's classification with ID='classification_id'
-        Return a dict that contains:
-            'id': VIM's classification ID (same as classification_id)
-            'name': VIM's classification name
-            'type': type of this classification
-            'definition': definition of the classification
-            'status': 'ACTIVE', 'INACTIVE', 'DOWN', 'BUILD', 'ERROR', 'VIM_ERROR', 'OTHER'
-            'error_msg': (optional) text that explains the ERROR status
-            other VIM specific fields: (optional) whenever possible
-        Raises an exception upon error or when classification is not found
-        """
-        raise VimConnNotImplemented("SFC support not implemented")
-
-    def get_classification_list(self, filter_dict={}):
-        """Obtain classifications from the VIM
-        Params:
-            'filter_dict' (optional): contains the entries to filter the classifications on and only return those that
-                match ALL:
-                id:   string => returns classifications with this VIM's classification ID, which implies a return of one
-                    classification at most
-                name: string => returns only classifications with this name
-                type: string => returns classifications of this type
-                definition: string => returns classifications that have this definition
-                tenant_id: string => returns only classifications that belong to this tenant/project
-        Returns a list of classification dictionaries, each dictionary contains:
-            'id': (mandatory) VIM's classification ID
-            'name': (mandatory) VIM's classification name
-            'type': type of this classification
-            'definition': definition of the classification
-            other VIM specific fields: (optional) whenever possible using the same naming of filter_dict param
-        List can be empty if no classification matches the filter_dict. Raise an exception only upon VIM connectivity,
-            authorization, or some other unspecific error
-        """
-        raise VimConnNotImplemented("SFC support not implemented")
-
-    def refresh_classifications_status(self, classification_list):
-        """Get the status of the classifications
-        Params: the list of classification identifiers
-        Returns a dictionary with:
-            vm_id:          #VIM id of this classifier
-                status:     #Mandatory. Text with one of:
-                            #  DELETED (not found at vim)
-                            #  VIM_ERROR (Cannot connect to VIM, VIM response error, ...)
-                            #  OTHER (Vim reported other status not understood)
-                            #  ERROR (VIM indicates an ERROR status)
-                            #  ACTIVE,
-                            #  CREATING (on building process)
-                error_msg:  #Text with VIM error message, if any. Or the VIM connection ERROR
-                vim_info:   #Text with plain information obtained from vim (yaml.safe_dump)
-        """
-        raise VimConnNotImplemented("Should have implemented this")
-
-    def delete_classification(self, classification_id):
-        """Deletes a classification from the VIM
-        Returns the classification ID (classification_id) or raises an exception upon error or when classification is
-           not found
-        """
-        raise VimConnNotImplemented("SFC support not implemented")
-
-    def new_sfi(self, name, ingress_ports, egress_ports, sfc_encap=True):
-        """Creates a service function instance in the VIM
-        Params:
-            'name': name of this service function instance
-            'ingress_ports': set of ingress ports (VIM's port IDs)
-            'egress_ports': set of egress ports (VIM's port IDs)
-            'sfc_encap': boolean stating whether this specific instance supports IETF SFC Encapsulation
-        Returns the VIM's service function instance ID on success or raises an exception on failure
-        """
-        raise VimConnNotImplemented("SFC support not implemented")
-
-    def get_sfi(self, sfi_id):
-        """Obtain service function instance details of the VIM's service function instance with ID='sfi_id'
-        Return a dict that contains:
-            'id': VIM's sfi ID (same as sfi_id)
-            'name': VIM's sfi name
-            'ingress_ports': set of ingress ports (VIM's port IDs)
-            'egress_ports': set of egress ports (VIM's port IDs)
-            'status': 'ACTIVE', 'INACTIVE', 'DOWN', 'BUILD', 'ERROR', 'VIM_ERROR', 'OTHER'
-            'error_msg': (optional) text that explains the ERROR status
-            other VIM specific fields: (optional) whenever possible
-        Raises an exception upon error or when service function instance is not found
-        """
-        raise VimConnNotImplemented("SFC support not implemented")
-
-    def get_sfi_list(self, filter_dict={}):
-        """Obtain service function instances from the VIM
-        Params:
-            'filter_dict' (optional): contains the entries to filter the sfis on and only return those that match ALL:
-                id:   string  => returns sfis with this VIM's sfi ID, which implies a return of one sfi at most
-                name: string  => returns only service function instances with this name
-                tenant_id: string => returns only service function instances that belong to this tenant/project
-        Returns a list of service function instance dictionaries, each dictionary contains:
-            'id': (mandatory) VIM's sfi ID
-            'name': (mandatory) VIM's sfi name
-            'ingress_ports': set of ingress ports (VIM's port IDs)
-            'egress_ports': set of egress ports (VIM's port IDs)
-            other VIM specific fields: (optional) whenever possible using the same naming of filter_dict param
-        List can be empty if no sfi matches the filter_dict. Raise an exception only upon VIM connectivity,
-            authorization, or some other unspecific error
-        """
-        raise VimConnNotImplemented("SFC support not implemented")
-
-    def delete_sfi(self, sfi_id):
-        """Deletes a service function instance from the VIM
-        Returns the service function instance ID (sfi_id) or raises an exception upon error or when sfi is not found
-        """
-        raise VimConnNotImplemented("SFC support not implemented")
-
-    def refresh_sfis_status(self, sfi_list):
-        """Get the status of the service function instances
-        Params: the list of sfi identifiers
-        Returns a dictionary with:
-            vm_id:          #VIM id of this service function instance
-                status:     #Mandatory. Text with one of:
-                            #  DELETED (not found at vim)
-                            #  VIM_ERROR (Cannot connect to VIM, VIM response error, ...)
-                            #  OTHER (Vim reported other status not understood)
-                            #  ERROR (VIM indicates an ERROR status)
-                            #  ACTIVE,
-                            #  CREATING (on building process)
-                error_msg:  #Text with VIM error message, if any. Or the VIM connection ERROR
-                vim_info:   #Text with plain information obtained from vim (yaml.safe_dump)
-        """
-        raise VimConnNotImplemented("Should have implemented this")
-
-    def new_sf(self, name, sfis, sfc_encap=True):
-        """Creates (an abstract) service function in the VIM
-        Params:
-            'name': name of this service function
-            'sfis': set of service function instances of this (abstract) service function
-            'sfc_encap': boolean stating whether this service function supports IETF SFC Encapsulation
-        Returns the VIM's service function ID on success or raises an exception on failure
-        """
-        raise VimConnNotImplemented("SFC support not implemented")
-
-    def get_sf(self, sf_id):
-        """Obtain service function details of the VIM's service function with ID='sf_id'
-        Return a dict that contains:
-            'id': VIM's sf ID (same as sf_id)
-            'name': VIM's sf name
-            'sfis': VIM's sf's set of VIM's service function instance IDs
-            'sfc_encap': boolean stating whether this service function supports IETF SFC Encapsulation
-            'status': 'ACTIVE', 'INACTIVE', 'DOWN', 'BUILD', 'ERROR', 'VIM_ERROR', 'OTHER'
-            'error_msg': (optional) text that explains the ERROR status
-            other VIM specific fields: (optional) whenever possible
-        Raises an exception upon error or when sf is not found
-        """
-
-    def get_sf_list(self, filter_dict={}):
-        """Obtain service functions from the VIM
-        Params:
-            'filter_dict' (optional): contains the entries to filter the sfs on and only return those that match ALL:
-                id:   string  => returns sfs with this VIM's sf ID, which implies a return of one sf at most
-                name: string  => returns only service functions with this name
-                tenant_id: string => returns only service functions that belong to this tenant/project
-        Returns a list of service function dictionaries, each dictionary contains:
-            'id': (mandatory) VIM's sf ID
-            'name': (mandatory) VIM's sf name
-            'sfis': VIM's sf's set of VIM's service function instance IDs
-            'sfc_encap': boolean stating whether this service function supports IETF SFC Encapsulation
-            other VIM specific fields: (optional) whenever possible using the same naming of filter_dict param
-        List can be empty if no sf matches the filter_dict. Raise an exception only upon VIM connectivity,
-            authorization, or some other unspecific error
-        """
-        raise VimConnNotImplemented("SFC support not implemented")
-
-    def delete_sf(self, sf_id):
-        """Deletes (an abstract) service function from the VIM
-        Returns the service function ID (sf_id) or raises an exception upon error or when sf is not found
-        """
-        raise VimConnNotImplemented("SFC support not implemented")
-
-    def refresh_sfs_status(self, sf_list):
-        """Get the status of the service functions
-        Params: the list of sf identifiers
-        Returns a dictionary with:
-            vm_id:          #VIM id of this service function
-                status:     #Mandatory. Text with one of:
-                            #  DELETED (not found at vim)
-                            #  VIM_ERROR (Cannot connect to VIM, VIM response error, ...)
-                            #  OTHER (Vim reported other status not understood)
-                            #  ERROR (VIM indicates an ERROR status)
-                            #  ACTIVE,
-                            #  CREATING (on building process)
-                error_msg:  #Text with VIM error message, if any. Or the VIM connection ERROR
-                vim_info:   #Text with plain information obtained from vim (yaml.safe_dump)
-        """
-        raise VimConnNotImplemented("Should have implemented this")
-
-    def new_sfp(self, name, classifications, sfs, sfc_encap=True, spi=None):
-        """Creates a service function path
-        Params:
-            'name': name of this service function path
-            'classifications': set of traffic classifications that should be matched on to get into this sfp
-            'sfs': list of every service function that constitutes this path , from first to last
-            'sfc_encap': whether this is an SFC-Encapsulated chain (i.e using NSH), True by default
-            'spi': (optional) the Service Function Path identifier (SPI: Service Path Identifier) for this path
-        Returns the VIM's sfp ID on success or raises an exception on failure
-        """
-        raise VimConnNotImplemented("SFC support not implemented")
-
-    def get_sfp(self, sfp_id):
-        """Obtain service function path details of the VIM's sfp with ID='sfp_id'
-        Return a dict that contains:
-            'id': VIM's sfp ID (same as sfp_id)
-            'name': VIM's sfp name
-            'classifications': VIM's sfp's list of VIM's classification IDs
-            'sfs': VIM's sfp's list of VIM's service function IDs
-            'status': 'ACTIVE', 'INACTIVE', 'DOWN', 'BUILD', 'ERROR', 'VIM_ERROR', 'OTHER'
-            'error_msg': (optional) text that explains the ERROR status
-            other VIM specific fields: (optional) whenever possible
-        Raises an exception upon error or when sfp is not found
-        """
-        raise VimConnNotImplemented("SFC support not implemented")
-
-    def get_sfp_list(self, filter_dict={}):
-        """Obtain service function paths from VIM
-        Params:
-            'filter_dict' (optional): contains the entries to filter the sfps on, and only return those that match ALL:
-                id:   string  => returns sfps with this VIM's sfp ID , which implies a return of one sfp at most
-                name: string  => returns only sfps with this name
-                tenant_id: string => returns only sfps that belong to this tenant/project
-        Returns a list of service function path dictionaries, each dictionary contains:
-            'id': (mandatory) VIM's sfp ID
-            'name': (mandatory) VIM's sfp name
-            'classifications': VIM's sfp's list of VIM's classification IDs
-            'sfs': VIM's sfp's list of VIM's service function IDs
-            other VIM specific fields: (optional) whenever possible using the same naming of filter_dict param
-        List can be empty if no sfp matches the filter_dict. Raise an exception only upon VIM connectivity,
-            authorization, or some other unspecific error
-        """
-        raise VimConnNotImplemented("SFC support not implemented")
-
-    def refresh_sfps_status(self, sfp_list):
-        """Get the status of the service function path
-        Params: the list of sfp identifiers
-        Returns a dictionary with:
-            vm_id:          #VIM id of this service function path
-                status:     #Mandatory. Text with one of:
-                            #  DELETED (not found at vim)
-                            #  VIM_ERROR (Cannot connect to VIM, VIM response error, ...)
-                            #  OTHER (Vim reported other status not understood)
-                            #  ERROR (VIM indicates an ERROR status)
-                            #  ACTIVE,
-                            #  CREATING (on building process)
-                error_msg:  #Text with VIM error message, if any. Or the VIM connection ERROR
-                vim_info:   #Text with plain information obtained from vim (yaml.safe_dump)F
-        """
-        raise VimConnNotImplemented("Should have implemented this")
-
-    def delete_sfp(self, sfp_id):
-        """Deletes a service function path from the VIM
-        Returns the sfp ID (sfp_id) or raises an exception upon error or when sf is not found
-        """
-        raise VimConnNotImplemented("SFC support not implemented")
-
     def migrate_instance(self, vm_id, compute_host=None):
         """Migrate a vdu
         Params:
@@ -1106,58 +859,3 @@ class VimConnector:
             flavor_id: flavor_id to resize the vdu to
         """
         raise VimConnNotImplemented("Should have implemented this")
-
-    # NOT USED METHODS in current version. Deprecated
-    @deprecated
-    def host_vim2gui(self, host, server_dict):
-        """Transform host dictionary from VIM format to GUI format,
-        and append to the server_dict
-        """
-        raise VimConnNotImplemented("Should have implemented this")
-
-    @deprecated
-    def get_hosts_info(self):
-        """Get the information of deployed hosts
-        Returns the hosts content"""
-        raise VimConnNotImplemented("Should have implemented this")
-
-    @deprecated
-    def get_hosts(self, vim_tenant):
-        """Get the hosts and deployed instances
-        Returns the hosts content"""
-        raise VimConnNotImplemented("Should have implemented this")
-
-    @deprecated
-    def get_processor_rankings(self):
-        """Get the processor rankings in the VIM database"""
-        raise VimConnNotImplemented("Should have implemented this")
-
-    @deprecated
-    def new_host(self, host_data):
-        """Adds a new host to VIM"""
-        """Returns status code of the VIM response"""
-        raise VimConnNotImplemented("Should have implemented this")
-
-    @deprecated
-    def new_external_port(self, port_data):
-        """Adds a external port to VIM"""
-        """Returns the port identifier"""
-        raise VimConnNotImplemented("Should have implemented this")
-
-    @deprecated
-    def new_external_network(self, net_name, net_type):
-        """Adds a external network to VIM (shared)"""
-        """Returns the network identifier"""
-        raise VimConnNotImplemented("Should have implemented this")
-
-    @deprecated
-    def connect_port_network(self, port_id, network_id, admin=False):
-        """Connects a external port to a network"""
-        """Returns status code of the VIM response"""
-        raise VimConnNotImplemented("Should have implemented this")
-
-    @deprecated
-    def new_vminstancefromJSON(self, vm_data):
-        """Adds a VM instance to VIM"""
-        """Returns the instance identifier"""
-        raise VimConnNotImplemented("Should have implemented this")