Bug 2217 fixed: modified the cloud-init merge configs 15/14315/3 v14.0
authorgarciadeblas <gerardo.garciadeblas@telefonica.com>
Tue, 9 Apr 2024 09:18:12 +0000 (11:18 +0200)
committergarciadeblas <gerardo.garciadeblas@telefonica.com>
Tue, 9 Apr 2024 14:48:40 +0000 (16:48 +0200)
This commit also defines the default SSH keys within the system_info instead of users

This reverts commit 80d2437283d10ae28885638e2940aa58721643fe.

Change-Id: I00f2e01e48951623372b5a7587ee29269aae87a8
Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>
RO-plugin/osm_ro_plugin/vimconn.py
releasenotes/notes/fix_bug_2217_again-43f6d4c55b57c617.yaml [new file with mode: 0644]

index d0162cc..a46f581 100644 (file)
@@ -300,74 +300,107 @@ class VimConnector:
         userdata = None
         userdata_list = []
 
-        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"])
-                else:
-                    for u in cloud_config["user-data"]:
-                        userdata_list.append(u)
+        # 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("boot-data-drive") is not None:
                 config_drive = cloud_config["boot-data-drive"]
-
-            if (
-                cloud_config.get("config-files")
-                or cloud_config.get("users")
-                or cloud_config.get("key-pairs")
-            ):
-                userdata_dict = {}
-
-                # 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"],
+            # If a config drive is needed, userdata is passed directly
+            if config_drive:
+                userdata = cloud_config.get("user-data")
+            # If a config drive is not necessary, then we process userdata and
+            # generate MIME multipart
+            else:
+                if cloud_config.get("user-data"):
+                    if isinstance(cloud_config["user-data"], str):
+                        userdata_list.append(
+                            cloud_config["user-data"] + f"\n{merge_how}"
+                        )
+                    else:
+                        for u in cloud_config["user-data"]:
+                            userdata_list.append(u + f"\n{merge_how}")
+
+                if (
+                    cloud_config.get("config-files")
+                    or cloud_config.get("users")
+                    or cloud_config.get("key-pairs")
+                ):
+                    userdata_dict = {}
+
+                    # default user
+                    if cloud_config.get("key-pairs"):
+                        userdata_dict["ssh-authorized-keys"] = cloud_config["key-pairs"]
+                        userdata_dict["system_info"] = {
+                            "default_user": {
+                                "ssh_authorized_keys": cloud_config["key-pairs"],
+                            }
                         }
-                    ]
-
-                if cloud_config.get("users"):
-                    if "users" not in userdata_dict:
                         userdata_dict["users"] = ["default"]
 
-                    for user in cloud_config["users"]:
-                        user_info = {
-                            "name": user["name"],
-                            "sudo": "ALL = (ALL)NOPASSWD:ALL",
-                        }
+                    if cloud_config.get("users"):
+                        if "users" not in userdata_dict:
+                            userdata_dict["users"] = ["default"]
 
-                        if "user-info" in user:
-                            user_info["gecos"] = user["user-info"]
+                        for user in cloud_config["users"]:
+                            user_info = {
+                                "name": user["name"],
+                                "sudo": "ALL = (ALL)NOPASSWD:ALL",
+                            }
 
-                        if user.get("key-pairs"):
-                            user_info["ssh-authorized-keys"] = user["key-pairs"]
+                            if "user-info" in user:
+                                user_info["gecos"] = user["user-info"]
 
-                        userdata_dict["users"].append(user_info)
+                            if user.get("key-pairs"):
+                                user_info["ssh-authorized-keys"] = user["key-pairs"]
 
-                if cloud_config.get("config-files"):
-                    userdata_dict["write_files"] = []
-                    for file in cloud_config["config-files"]:
-                        file_info = {"path": file["dest"], "content": file["content"]}
+                            userdata_dict["users"].append(user_info)
 
-                        if file.get("encoding"):
-                            file_info["encoding"] = file["encoding"]
+                    if cloud_config.get("config-files"):
+                        userdata_dict["write_files"] = []
+                        for file in cloud_config["config-files"]:
+                            file_info = {
+                                "path": file["dest"],
+                                "content": file["content"],
+                            }
 
-                        if file.get("permissions"):
-                            file_info["permissions"] = file["permissions"]
+                            if file.get("encoding"):
+                                file_info["encoding"] = file["encoding"]
 
-                        if file.get("owner"):
-                            file_info["owner"] = file["owner"]
+                            if file.get("permissions"):
+                                file_info["permissions"] = file["permissions"]
 
-                        userdata_dict["write_files"].append(file_info)
+                            if file.get("owner"):
+                                file_info["owner"] = file["owner"]
 
-                userdata_list.append(
-                    "#cloud-config\n"
-                    + yaml.safe_dump(userdata_dict, indent=4, default_flow_style=False)
-                )
-            userdata = self._create_mimemultipart(userdata_list)
-            self.logger.debug("userdata: %s", userdata)
+                            userdata_dict["write_files"].append(file_info)
+
+                    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)
+            # End if config_drive
         elif isinstance(cloud_config, str):
             userdata = cloud_config
 
diff --git a/releasenotes/notes/fix_bug_2217_again-43f6d4c55b57c617.yaml b/releasenotes/notes/fix_bug_2217_again-43f6d4c55b57c617.yaml
new file mode 100644 (file)
index 0000000..5926b14
--- /dev/null
@@ -0,0 +1,25 @@
+#######################################################################################
+# Copyright ETSI Contributors and Others.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#######################################################################################
+---
+fixes:
+  - |
+    This fixes bug 2217. Modified the cloud-init merge configs and defined
+    the default SSH keys within the system_info instead of users.
+    This bug fix doesn't break the creation of virtual machines that have
+    a config drive. Now the merge_how dictionary is only appended to the user
+    data in those cases where there is no config drive.
+