예제 #1
0
    def _platform_attach_volume(self, volume, instance):
        """
        Attach a volume using the Google Cloud Platform API
        Some specific steps are performed here:
            - Device name (the name assigned to this device visible through the VM OS)
            - Mount mode (read only or read write)
            - Disk interface (SCSI or NVME)

        Args:
            volume (<volume>): The volume to attach
            instance (<instance>): The instance where the volume is to be attached

        Returns:
            bool: True if the volume is attached successfully, False otherwise
        """
        # Ask for mount ro/rw
        ro_rw = SimpleTUI.input_dialog(
            "Mount mode",
            question="Specify a mount mode (READ_WRITE, READ_ONLY)",
            return_type=str,
            regex="^(READ_WRITE|READ_ONLY)$")
        if ro_rw is None:
            return
        # Ask for disk interface
        interface = SimpleTUI.input_dialog(
            "Disk interface",
            question="Specify disk interface (SCSI, NVME)",
            return_type=str,
            regex="^(SCSI|NVME)$")
        return self.gcp_client.attach_volume(node=instance,
                                             volume=volume,
                                             device=volume.name,
                                             ex_boot=False,
                                             ex_auto_delete=False,
                                             ex_interface=interface)
예제 #2
0
    def _platform_detach_volume(self, volume):
        """
        Detach a volume using the Google Cloud Platform API
        Some specific steps are performed here:
            - Check if the selected volume is a boot disk

        Args:
            volume (<volume>): The volume to detach

        Returns:
            bool: True if the volume is successfully detached, False otherwise
        """
        # Search for the instance the volume is attached to
        instance = self._get_instance_from_volume(volume)
        if instance is None:
            return False
        if not self._is_volume_removable(volume):
            SimpleTUI.msg_dialog(
                "Detaching status",
                "This volume is mounted as boot disk and cannot be detached until the VM is stopped!",
                SimpleTUI.DIALOG_ERROR)
            return
        result = self.gcp_client.detach_volume(volume, instance)
        if result:
            while True:
                # No direct way to refresh a Volume status, so we look if
                # it is still attached to its previous instance
                updated_volume = self.gcp_client.ex_get_volume(volume.name)
                if not self._platform_is_volume_attached(updated_volume):
                    break
                time.sleep(3)
        return result
예제 #3
0
    def close(self, code):
        """
        Close the application

        Args:
            code (int): an exit code (0 for normal termination)
        """
        SimpleTUI.clear_console()
        exit(code)
예제 #4
0
 def print_global_floating_ips(self):
     """
     Print ip and other useful information of all floating ip available in each region
     """
     table_header = [
         "ID", "Public Ip", "Floating IP ID", "Associated Instance",
         "Region"
     ]
     table_body = self._list_global_floating_ips()
     SimpleTUI.print_table(table_header, table_body)
     if len(self.global_floating_ips) == 0:
         SimpleTUI.info("There are no floating IPs available")
     return len(self.global_floating_ips)
예제 #5
0
 def print_global_instances(self):
     """
     Print instance id, image id, IP address and state for each active instance in each region
     """
     table_header = [
         "ID", "Instance Name", "Instance ID", "IP address", "Status",
         "Key Name", "Avail. Zone"
     ]
     table_body = self._list_global_instances()
     SimpleTUI.print_table(table_header, table_body)
     if len(self.global_instances) == 0:
         SimpleTUI.info("There are no running or pending instances")
     return len(self.global_instances)
예제 #6
0
 def print_global_volumes(self):
     """
     Print all the available volumes for each region and some informations
     """
     table_header = [
         "ID", "Volume Name", "Volume ID", "Creation", "Size (GB)",
         "Attached To", "Status", "Avail. Zone"
     ]
     table_body = self._list_global_volumes()
     SimpleTUI.print_table(table_header, table_body)
     if len(self.global_volumes) == 0:
         SimpleTUI.info("There are no volumes available")
     return len(self.global_volumes)
예제 #7
0
 def promote_ephimeral_ip(self):
     """
     Promote an Ephimeral IP to a Static one
     For more infos about Ephimeral/Static IPs on GCP, please visit
     https://cloud.google.com/compute/docs/ip-addresses/
     """
     # Select an instance
     floating_ip = None
     while (True):
         instance_index = SimpleTUI.list_dialog(
             "Instances available",
             self.print_all_instances,
             question=
             "Select the instance which floating IP has to be promoted to \"static\""
         )
         if instance_index is None:
             return
         instance = self.instances[instance_index - 1]
         # Check if the instance has an IP assigned (e.g. no IP is assigned while stopped)
         if len(instance.public_ips) == 0 or None in instance.public_ips:
             SimpleTUI.msg_dialog(
                 "Promotion status",
                 "This instance has no available floating IPs to promote!",
                 SimpleTUI.DIALOG_ERROR)
         # Check if the instance has already a static IP assigned
         elif self._is_instance_floating_ip_static(instance):
             SimpleTUI.msg_dialog(
                 "Promotion status",
                 "This instance floating IP is already promoted to \"static\"!",
                 SimpleTUI.DIALOG_ERROR)
         # Continue the ephimeral to static conversion
         else:
             floating_ip = instance.public_ips[0]
             break
     # Specify address name
     address_name = SimpleTUI.input_dialog(
         "Static Floating IP Name",
         question="Specify a name for the new Static Floating IP",
         return_type=str,
         regex="^[a-zA-Z0-9-]+$")
     if address_name is None:
         return
     if self._promote_ephimeral_ip_to_static(floating_ip, address_name):
         SimpleTUI.msg_dialog("Static Floating IP Promotion",
                              "Floating IP promoted!",
                              SimpleTUI.DIALOG_SUCCESS)
     else:
         SimpleTUI.msg_dialog(
             "Static Floating IP Promotion",
             "There was an error while promoting this Floating IP!",
             SimpleTUI.DIALOG_ERROR)
예제 #8
0
    def print_all_nics(self):
        """
        Print instance id, image id, IP address and state for each active instance
        ! NOTE: before using this method, please set an instance using self.instance = <instance> !

        Returns:
            int: the number of items printed
        """
        table_header = ["ID", "NIC Name"]
        table_body = self._list_all_nics()
        SimpleTUI.print_table(table_header, table_body)
        if len(self.instances) == 0:
            SimpleTUI.info("There are no NICs available for this instance")
        return len(self.instances)
예제 #9
0
    def _platform_override_menu(self, menu, choice):
        """
        Override a menu voice

        Args:
            menu (str): a menu identifier
            choice (int): a menu entry index

        Returns:
            int: 0 for normal, 1 for going back to the main menu of EasyCloud,
                 2 for closing the whole application
        """
        if menu == "floating_ips":
            if choice == 5:  # Detach floating ip
                SimpleTUI.msg_dialog(
                    "Detach Floating IP",
                    "Detaching an IP address from an instance is not supported on GCP: \n"
                    +
                    "an instance must always have an IP associated while running.\n"
                    +
                    "However, you can assign another address to the desired instance to\n"
                    + "replace the current one.", SimpleTUI.DIALOG_INFO)
                return 0
            SimpleTUI.error("Unavailable choice!")
            SimpleTUI.pause()
            SimpleTUI.clear_console()
        pass
예제 #10
0
 def load_all_modules(self, no_libs_check):
     """
     Loads all the Modules from the modules folder
     """
     _all_modules = list(iter_modules(modules.__path__))
     for _module in _all_modules:
         module_object = Module(_module[1])
         try:
             if no_libs_check or self.check_dependencies(module_object):
                 module_object.load_manager_class()
                 self.loaded_modules.append(module_object)
         except ImportError as e:
             SimpleTUI.msg_dialog("Missing packages", "There was an error while importing a package for the\n" +
                                  module_object.platform_name + " module: \n\n" + str(e) + "\n\n" +
                                  "This module won't be loaded.", SimpleTUI.DIALOG_ERROR)
예제 #11
0
 def _platform_extra_menu(self):
     """
     Print the extra Functions Menu (specific for each platform)
     """
     while (True):
         menu_header = self.platform_name + " Extra Commands"
         menu_subheader = [
             "Region: \033[1;94m" + self._platform_get_region() + "\033[0m"
         ]
         menu_items = [
             "Promote ephimeral IP to static", "Demote a static IP",
             "List instances for all the regions",
             "List volumes for all the regions",
             "List floating ips for all the regions",
             "Back to the Main Menu"
         ]
         choice = SimpleTUI.print_menu(menu_header, menu_items,
                                       menu_subheader)
         if choice == 1:  # Promote IP
             self.promote_ephimeral_ip()
         elif choice == 2:  # Demote IP
             answer = SimpleTUI.yn_dialog(
                 "Demotion status",
                 "You can demote a static IP easily deleting it through \"Manage floating IPs\" > \"Release a reserved Floating IP\".\n"
                 +
                 "NOTE: the static IP won't be removed from the associated instance until the latter is stopped/rebooted/deleted.\n"
                 +
                 "For more infos about Ephimeral/Static IPs on GCP, please visit https://cloud.google.com/compute/docs/ip-addresses/.\n"
                 +
                 "Would you like to start the \"Release a reserved Floating IP\" wizard now?",
                 SimpleTUI.DIALOG_INFO)
             if answer:
                 self.release_floating_ip()
         elif choice == 3:  # List all the instances (Global)
             SimpleTUI.list_dialog("Instances available (Global view)",
                                   list_printer=self.print_global_instances)
         elif choice == 4:  # List all the volumes (Global)
             SimpleTUI.list_dialog("Volumes available (Global view)",
                                   list_printer=self.print_global_volumes)
         elif choice == 5:  # List all the floating ips (Global)
             SimpleTUI.list_dialog(
                 "Floating IPs available (Global view)",
                 list_printer=self.print_global_floating_ips)
         elif choice == 6:
             break
         else:
             SimpleTUI.msg_dialog("Error", "Unimplemented functionality",
                                  SimpleTUI.DIALOG_ERROR)
예제 #12
0
    def _platform_create_new_instance(self,
                                      instance_name,
                                      image,
                                      instance_type,
                                      monitor_cmd_queue=None):
        """
        Create a new instance using the Google Cloud Platform API

        Args:
            instance_name (str): The name of the instance
            image (<image_type>): The image to be used as a base system
            instance_type (<instance_type>): The VM flavor
            monitor_cmd_queue: the monitor commands Quue
        """

        # Creation summary
        print("\n--- Creating a new instance with the following properties:")
        print("- %-20s %-30s" % ("Name", instance_name))
        print("- %-20s %-30s" % ("Image", image.name))
        print("- %-20s %-30s" % ("Instance Type", instance_type.name))

        # ask for confirm
        print("")
        if (SimpleTUI.user_yn("Are you sure?")):
            instance = self.gcp_client.create_node(name=instance_name,
                                                   size=instance_type,
                                                   image=image)
            if instance is None:
                return False
            if monitor_cmd_queue is not None and self.is_monitor_running():
                monitor_cmd_queue.put({
                    "command": "add",
                    "instance_id": instance.id
                })
            return True
예제 #13
0
    def ask_for_data(self,
                     section_name,
                     param_name,
                     return_type=None,
                     regex=None):
        """
        Ask for user input if a parameter is not defined

        Args:
            param_name (str): the name of the missing parameter
            return_type (<return_type>, optional): the return type assigned to user input
            regex (str): the regular expression the input must follow

        Returns:
            <return_type>: user input of type <return_type>
        """
        return SimpleTUI.input_dialog(
            "Missing value",
            question=
            "A parameter required by this module has not been defined in settings.cfg!\n"
            "Please, define a value to assign to \"" + param_name + "\" (\"" +
            section_name + "\" section)",
            return_type=return_type,
            regex=regex,
            pause_on_exit=False,
            cannot_quit=True)
예제 #14
0
    def _platform_create_volume(self, volume_name, volume_size):
        """
        Create a new volume using the Google Cloud Platform API
        Some specific steps are performed here:
            - Volume type (pd-standard or pd-ssd)

        Args:
            volume_name (str): Volume name
            volume_size (int): Volume size in GB

        Returns:
            bool: True if the volume is successfully created, False otherwise
        """
        # Volume type
        volume_type = SimpleTUI.input_dialog(
            "Volume type",
            question="Specify the volume type (pd-standard, pd-ssd)",
            return_type=str,
            regex="^(pd-standard|pd-ssd)$")
        if volume_type is None:
            return
        # Volume creation
        return self.gcp_client.create_volume(size=volume_size,
                                             name=volume_name,
                                             ex_disk_type=volume_type)
예제 #15
0
    def _platform_create_volume(self, volume_name, volume_size):
        """
        Create a new volume using the Amazon Web Services API
        Some specific steps are performed here:
            - Volume type (standard or io1)
            - IOPS (only if io1 is selected)
            - Zone selection (required)

        Args:
            volume_name (str): Volume name
            volume_size (int): Volume size in GB

        Returns:
            bool: True if the volume is successfully created, False otherwise
        """
        # Volume type
        volume_type = SimpleTUI.input_dialog(
            "Volume type",
            question="Specify the volume type (standard, io1)",
            return_type=str,
            regex="^(standard|io1)$")
        if volume_type is None:
            return
        # IOPS
        iops = None
        if volume_type == "io1":
            iops = SimpleTUI.input_dialog(
                "IOPS limit",
                question=
                "Specify the number of IOPS (I/O operations per second) the volume has to support",
                return_type=int)
            if iops is None:
                return
        # Zone selection
        zone_index = SimpleTUI.list_dialog(
            "Zones available",
            self.print_all_availability_zones,
            question="Select a zone where the volume will be created")
        if zone_index is None:
            return
        zone = self.avail_zones[zone_index - 1]
        # Volume creation
        return self.ec2_client.create_volume(name=volume_name,
                                             size=volume_size,
                                             location=zone,
                                             ex_volume_type=volume_type,
                                             ex_iops=iops)
예제 #16
0
 def _platform_extra_menu(self):
     """
     Print the extra Functions Menu (specific for each platform)
     """
     while (True):
         menu_header = self.platform_name + " Extra Commands"
         menu_subheader = [
             "Region: \033[1;94m" + self._platform_get_region() + "\033[0m"
         ]
         menu_items = ["Back to the Main Menu"]
         choice = SimpleTUI.print_menu(menu_header, menu_items,
                                       menu_subheader)
         # if choice == 1 and self._is_barebone():  # Blazar menu
         if choice == 1:
             break
         else:
             SimpleTUI.msg_dialog("Error", "Unimplemented functionality",
                                  SimpleTUI.DIALOG_ERROR)
예제 #17
0
    def _platform_delete_volume(self, volume):
        """
        Delete a volume using the Google Cloud Platform API
        Some specific steps are performed here:
            - Check if the selected volume is a boot disk

        Args:
            volume (<volume>): The volume to delete

        Returns:
            bool: True if the volume is successfully deleted, False otherwise
        """
        if not self._is_volume_removable(volume):
            SimpleTUI.msg_dialog(
                "Volume deletion",
                "This volume is mounted as boot disk and cannot be detached until the VM is stopped!",
                SimpleTUI.DIALOG_ERROR)
            return
        return self.gcp_client.destroy_volume(volume)
예제 #18
0
    def get_instance(self, manager_class):
        """
        Returns an existing instance of the manager_class provided in input
        if previously instantiated or creates a new instance.

        Args:
            manager_class (<manager_class>): class of the module manager

        Returns:
            <manager_class_instance>: an instance of <manager_class>
        """
        for _instance in self.loaded_instances:
            if isinstance(_instance, manager_class):
                return _instance
        try:
            _new_instance = manager_class()
            self.loaded_instances.append(_new_instance)
            return _new_instance
        except Exception as e:
            SimpleTUI.exception_dialog(e)
            return None
예제 #19
0
    def menu(self):
        """
        Prints the modules menu
        """
        global kill

        while True:
            # Header creation
            menu_header = "******************** EasyCloud ********************"
            # Subheader creation
            disclaimer = "\033[34;1mThis is a proof-of-concept build, not suitable\nfor production use.\033[0m\n"
            debug_status = None
            hffr_status = None
            if "LIBCLOUD_DEBUG" in environ:
                debug_status = "\033[93mLibcloud Debug Mode ON\033[0m"
            else:
                debug_status = "\033[90mLibcloud Debug Mode OFF\033[0m"
            if "LIBCLOUD_DEBUG_PRETTY_PRINT_RESPONSE" in environ and environ["LIBCLOUD_DEBUG_PRETTY_PRINT_RESPONSE"] == "1":
                hffr_status = "\033[93mLibcloud Human friendly formatted response ON\033[0m"
            else:
                hffr_status = "\033[90mLibcloud Human friendly formatted response OFF\033[0m"
            menu_subheader = [disclaimer, debug_status, hffr_status]
            # Menu items creation
            menu_items = []
            for module in self.loaded_modules:
                menu_items.append(module.platform_name)
            menu_items.append("Close application")
            # Menu print
            choice = SimpleTUI.print_menu(menu_header, menu_items,
                                          subheader_items=menu_subheader,
                                          custom_question="Select a platform")
            try:
                if(choice >= 1 and choice <= len(self.loaded_modules)):
                    return self.loaded_modules[choice - 1]  # Load a module
                elif(choice == len(self.loaded_modules) + 1):  # Close application
                    self.close(0)
                else:
                    SimpleTUI.msg_dialog("Error", "Unimplemented functionality", SimpleTUI.DIALOG_ERROR)
            except Exception as e:
                SimpleTUI.exception_dialog(e)
예제 #20
0
 def start(self, no_libs_check=False):
     """
     Main application loop
     """
     # Resize the console window
     SimpleTUI.resize_console(30, 120)
     # Load all the modules
     self.load_all_modules(no_libs_check=no_libs_check)
     # Loop
     exit = False
     while(not exit):
         SimpleTUI.set_console_title("EasyCloud")
         platform = self.menu()
         manager = self.get_instance(platform.manager_class)
         try:
             close = False
             while(not close):
                 action = manager.menu()
                 # if action == 0:  # Ignore this value
                 #     pass
                 if action == 1:  # Close current manager menu
                     close = True
                 elif action == 2:  # Close this application
                     close = True
                     exit = True
         except Exception as e:
             SimpleTUI.exception_dialog(e)
     self.close(0)
예제 #21
0
 def _platform_reserve_floating_ip(self):
     """
     Reserve a floating IP using the Google Cloud Platform API
     """
     address_name = SimpleTUI.input_dialog(
         "Floating IP Name",
         question="Specify a name for the new Floating IP",
         return_type=str,
         regex="^[a-zA-Z0-9-]+$")
     if address_name is None:
         return
     if self.gcp_client.ex_create_address(name=address_name):
         return True
     return False
예제 #22
0
    def check_dependencies(self, module):
        """
        Check if all the dependencies (pip packages) are satisfied for
        a certain module, and can install them if the user approves

        Args:
            module (Module): a module object (no manager class must be loaded
                             through load_manager_class method of this object)

        Returns:
            bool: the result of the check
        """
        required_packages = getattr(module, "dependencies")
        installed_packages = subprocess.check_output(['pip3', 'list', '--format=json'], stderr=subprocess.STDOUT).decode()
        missing_packages_names = []  # package names displayed to the user
        missing_packages_commands = []  # packages names/urls passed to pip3
        for required_package in required_packages:
            # Format: pip-package-name:package-url|package-git (the latter is optional)
            #
            # Symbolic: pip package name (the one you see with "pip3 list")
            # Package URL (optional): package url from where pip3 will download the library
            # Package Git (optional): package git url in the form git+git://github.com/my_user/my_project.git(@branch)
            #
            # e.g. libcloud:apache-libcloud
            required_package_data = required_package.split(":", 1)
            if required_package_data[0] not in installed_packages:
                missing_packages_names.append(required_package_data[0])
                if len(required_package_data) == 2:
                    missing_packages_commands.append(required_package_data[1])
                else:
                    missing_packages_commands.append(required_package_data[0])
        if len(missing_packages_names) > 0:
            packages_list = ""
            for missing_package_name in missing_packages_names:
                packages_list += "- " + missing_package_name + "\n"
            choice = SimpleTUI.yn_dialog("Missing packages", "The following packages are required by the " + module.platform_name + " module:\n" +
                                         "\n" + packages_list + "\nIf these packages are not installed, this module won't be loaded.\n" +
                                         "Do you want to install them through pip?", warning=True)
            if choice:
                SimpleTUI.msg_dialog("Library installer", "Installing the required libraries, this can take a bit...",
                                     SimpleTUI.DIALOG_INFO, pause_on_exit=False, clear_on_exit=False)
                if self.install_libraries(missing_packages_commands):
                    SimpleTUI.msg_dialog("Library installer", "All the packages for " + module.platform_name + "\n" +
                                         "were successfully installed!\n\n" + packages_list, SimpleTUI.DIALOG_SUCCESS)
                    return True
                else:
                    SimpleTUI.msg_dialog("Library installer", "There was an error while installing the missing packages\n" +
                                         "for " + module.platform_name + ".\n"
                                         "Please check logs" + sep + "installer.log in the main directory for details.", SimpleTUI.DIALOG_ERROR)
                    return False
            return False
        return True
예제 #23
0
    def _platform_attach_volume(self, volume, instance):
        """
        Attach a volume using the Amazon Web Services API
        Some specific steps are performed here:
            - Exposure point (e.g. /dev/sdb)

        Args:
            volume (<volume>): The volume to attach
            instance (<instance>): The instance where the volume is to be attached

        Returns:
            bool: True if the volume is attached successfully, False otherwise
        """
        # Ask for exposure point (the GNU/Linux device where this volume will
        # be available)
        exposure_point = SimpleTUI.input_dialog(
            "Exposure point",
            question="Specify where the device is exposed, e.g. ‘/dev/sdb’",
            return_type=str,
            regex="^(/[^/ ]*)+/?$")
        if exposure_point is None:
            return
        return self.ec2_client.attach_volume(instance, volume, exposure_point)
예제 #24
0
    def _platform_create_new_instance(self,
                                      instance_name,
                                      image,
                                      instance_type,
                                      monitor_cmd_queue=None):
        """
        Create a new instance using the Amazon Web Services API
        Some specific steps are performed here:
            - Ask for security group
            - Ask for key pair
            - Instance creation summary

        Args:
            instance_name (str): The name of the instance
            image (<image_type>): The image to be used as a base system
            instance_type (<instance_type>): The VM flavor
            monitor_cmd_queue: the monitor commands Quue
        """
        # 5. Security Group
        security_group_index = SimpleTUI.list_dialog(
            "Security Groups available",
            self.print_all_security_groups,
            question="Select security group")
        if security_group_index is None:
            return
        security_group = self.security_groups[security_group_index - 1]
        # 6. Key Pair
        key_pair_index = SimpleTUI.list_dialog("Key Pairs available",
                                               self.print_all_key_pairs,
                                               question="Select key pair")
        if key_pair_index is None:
            return
        key_pair = self.key_pairs[key_pair_index - 1]

        # Creation summary
        print("\n--- Creating a new instance with the following properties:")
        print("- %-20s %-30s" % ("Name", instance_name))
        print("- %-20s %-30s" % ("Image", image.name))
        print("- %-20s %-30s" % ("Instance Type", instance_type.name))
        print("- %-20s %-30s" % ("Key Pair", key_pair.name))
        print("- %-20s %-30s" % ("Security Group", security_group))

        # ask for confirm
        print("")
        if (SimpleTUI.user_yn("Are you sure?")):
            instance = self.ec2_client.create_node(
                name=instance_name,
                image=image,
                size=instance_type,
                ex_keyname=key_pair.name,
                ex_security_groups=[security_group],
                ex_monitoring=True,
                ex_mincount=1,
                ex_maxcount=1)
            if instance is None:
                return False
            if monitor_cmd_queue is not None and self.is_monitor_running():
                monitor_cmd_queue.put({
                    "command": "add",
                    "instance_id": instance.id
                })
            return True
예제 #25
0
    def _platform_associate_floating_ip(self, floating_ip, instance):
        """
        Associate a floating IP to an instance using the Google Cloud Platform API
        Some specific steps are performed here:
            - NIC (Network interface controller) selection
            - Access config name

        Args:
            floating_ip (GCEAddress): The floating IP to attach
            instance (Node): The instance where the floating IP is to be assigned

        Returns:
            bool: True if the floating IP is successfully associated, False otherwise
        """
        # Set an instance, as required by print_all_nics()
        self.current_instance = instance
        nic_index = SimpleTUI.list_dialog(
            "NICs available",
            self.print_all_nics,
            question="Select the VM NIC to assign this IP")
        if nic_index is None:
            return
        nic = instance.extra["networkInterfaces"][
            nic_index - 1]  # serve nome per rimuovere
        # Check if there's already an active Access Configuration and ask the user for confirm
        remove_old_access_config = False
        if self._nic_has_access_config(nic):
            choice = SimpleTUI.yn_dialog(
                "Access Configuration Overwrite",
                "Warning: there's already an access configuration associated to this NIC.\n"
                +
                "Do you really want to continue (the current access configuration will be overwritten)?",
                warning=True)
            if not choice:
                return
            remove_old_access_config = True
        # Access Configuration name
        access_config_name = SimpleTUI.input_dialog(
            "Access configuration",
            question="Specify an access configuration name",
            return_type=str,
            regex="^[a-zA-Z0-9-]+$")
        if access_config_name is None:
            return
        # Remove the old access configuration if it's already existing
        if remove_old_access_config:
            SimpleTUI.msg_dialog("Access Configuration Overwrite",
                                 "Removing old access configuration...",
                                 SimpleTUI.DIALOG_INFO,
                                 pause_on_exit=False,
                                 clear_on_exit=False)
            if not self._delete_access_config(instance, nic):
                SimpleTUI.msg_dialog(
                    "Access Configuration Overwrite",
                    "There was an error while removing the current access configuration!",
                    SimpleTUI.DIALOG_ERROR)
                return
        # Associate the Access Configuration to the NIC
        if self.gcp_client.ex_add_access_config(node=instance,
                                                name=access_config_name,
                                                nic=nic,
                                                nat_ip=floating_ip.address,
                                                config_type="ONE_TO_ONE_NAT"):
            return True
        return False