Example #1
0
 def test_get_extension_modname_file_with_prefix(self):
     # We should only file a module if it's a directory and not a file even if it has the prefix
     tmp_dir = tempfile.mkdtemp()
     filename = EXTENSIONS_MOD_PREFIX + 'helloworld'
     open(os.path.join(tmp_dir, filename), 'a').close()
     with self.assertRaises(AssertionError):
         get_extension_modname(ext_dir=tmp_dir)
Example #2
0
 def test_get_extension_modname_too_many_mods_with_prefix(self):
     tmp_dir = tempfile.mkdtemp()
     modname1 = EXTENSIONS_MOD_PREFIX + 'helloworldmod1'
     modname2 = EXTENSIONS_MOD_PREFIX + 'helloworldmod2'
     os.makedirs(os.path.join(tmp_dir, modname1))
     os.makedirs(os.path.join(tmp_dir, modname2))
     with self.assertRaises(AssertionError):
         get_extension_modname(ext_dir=tmp_dir)
Example #3
0
 def _filter_modname(extensions):
     # Extension's name may not be the same as its modname. eg. name: virtual-wan, modname: azext_vwan
     filtered_extensions = []
     for ext in extensions:
         ext_mod = get_extension_modname(ext.name, ext.path)
         # Filter the extensions according to the index
         if ext_mod in extension_modname:
             filtered_extensions.append(ext)
             extension_modname.remove(ext_mod)
     if extension_modname:
         logger.debug(
             "These extensions are not installed and will be skipped: %s",
             extension_modname)
     return filtered_extensions
Example #4
0
        def _update_command_table_from_extensions(ext_suppressions):
            def _handle_extension_suppressions(extensions):
                filtered_extensions = []
                for ext in extensions:
                    should_include = True
                    for suppression in ext_suppressions:
                        if should_include and suppression.handle_suppress(ext):
                            should_include = False
                    if should_include:
                        filtered_extensions.append(ext)
                return filtered_extensions

            extensions = get_extensions()
            if extensions:
                logger.debug("Found %s extensions: %s", len(extensions),
                             [e.name for e in extensions])
                allowed_extensions = _handle_extension_suppressions(extensions)
                module_commands = set(self.command_table.keys())
                for ext in allowed_extensions:
                    ext_name = ext.name
                    ext_dir = get_extension_path(ext_name)
                    sys.path.append(ext_dir)
                    try:
                        ext_mod = get_extension_modname(ext_name,
                                                        ext_dir=ext_dir)
                        # Add to the map. This needs to happen before we load commands as registering a command
                        # from an extension requires this map to be up-to-date.
                        # self._mod_to_ext_map[ext_mod] = ext_name
                        start_time = timeit.default_timer()
                        extension_command_table, extension_group_table = \
                            _load_extension_command_loader(self, args, ext_mod)

                        for cmd_name, cmd in extension_command_table.items():
                            cmd.command_source = ExtensionCommandSource(
                                extension_name=ext_name,
                                overrides_command=cmd_name in module_commands,
                                preview=ext.preview)

                        self.command_table.update(extension_command_table)
                        self.command_group_table.update(extension_group_table)
                        elapsed_time = timeit.default_timer() - start_time
                        logger.debug("Loaded extension '%s' in %.3f seconds.",
                                     ext_name, elapsed_time)
                    except Exception:  # pylint: disable=broad-except
                        self.cli_ctx.raise_event(EVENT_FAILED_EXTENSION_LOAD,
                                                 extension_name=ext_name)
                        logger.warning(
                            "Unable to load extension '%s'. Use --debug for more information.",
                            ext_name)
                        logger.debug(traceback.format_exc())
Example #5
0
def start_shell(cmd, update=None, style=None):
    from importlib import import_module
    try:
        get_extension(INTERACTIVE_EXTENSION_NAME)
        if update:
            logger.warning("Updating the Interactive extension to the latest available..")
            update_extension(INTERACTIVE_EXTENSION_NAME)
            reload_extension(INTERACTIVE_EXTENSION_NAME)
    except ExtensionNotInstalledException:
        logger.warning("Installing the Interactive extension..")
        add_extension(extension_name=INTERACTIVE_EXTENSION_NAME)

    add_extension_to_path(INTERACTIVE_EXTENSION_NAME)
    interactive_module = get_extension_modname(ext_name=INTERACTIVE_EXTENSION_NAME)
    azext_interactive = import_module(interactive_module)
    azext_interactive.start_shell(cmd, style=style)
Example #6
0
        def _update_command_table_from_extensions(ext_suppressions):

            def _handle_extension_suppressions(extensions):
                filtered_extensions = []
                for ext in extensions:
                    should_include = True
                    for suppression in ext_suppressions:
                        if should_include and suppression.handle_suppress(ext):
                            should_include = False
                    if should_include:
                        filtered_extensions.append(ext)
                return filtered_extensions

            extensions = get_extensions()
            if extensions:
                logger.debug("Found %s extensions: %s", len(extensions), [e.name for e in extensions])
                allowed_extensions = _handle_extension_suppressions(extensions)
                module_commands = set(self.command_table.keys())
                for ext in allowed_extensions:
                    ext_name = ext.name
                    ext_dir = ext.path or get_extension_path(ext_name)
                    sys.path.append(ext_dir)
                    try:
                        ext_mod = get_extension_modname(ext_name, ext_dir=ext_dir)
                        # Add to the map. This needs to happen before we load commands as registering a command
                        # from an extension requires this map to be up-to-date.
                        # self._mod_to_ext_map[ext_mod] = ext_name
                        start_time = timeit.default_timer()
                        extension_command_table, extension_group_table = \
                            _load_extension_command_loader(self, args, ext_mod)

                        for cmd_name, cmd in extension_command_table.items():
                            cmd.command_source = ExtensionCommandSource(
                                extension_name=ext_name,
                                overrides_command=cmd_name in module_commands,
                                preview=ext.preview)

                        self.command_table.update(extension_command_table)
                        self.command_group_table.update(extension_group_table)
                        elapsed_time = timeit.default_timer() - start_time
                        logger.debug("Loaded extension '%s' in %.3f seconds.", ext_name, elapsed_time)
                    except Exception:  # pylint: disable=broad-except
                        self.cli_ctx.raise_event(EVENT_FAILED_EXTENSION_LOAD, extension_name=ext_name)
                        logger.warning("Unable to load extension '%s'. Use --debug for more information.", ext_name)
                        logger.debug(traceback.format_exc())
Example #7
0
def start_shell(cmd, update=None, style=None):
    from importlib import import_module
    try:
        get_extension(INTERACTIVE_EXTENSION_NAME)
        if update:
            logger.warning(
                "Updating the Interactive extension to the latest available..")
            update_extension(INTERACTIVE_EXTENSION_NAME)
            reload_extension(INTERACTIVE_EXTENSION_NAME)
    except ExtensionNotInstalledException:
        logger.warning("Installing the Interactive extension..")
        add_extension(extension_name=INTERACTIVE_EXTENSION_NAME)

    add_extension_to_path(INTERACTIVE_EXTENSION_NAME)
    interactive_module = get_extension_modname(
        ext_name=INTERACTIVE_EXTENSION_NAME)
    azext_interactive = import_module(interactive_module)
    azext_interactive.start_shell(cmd, style=style)
Example #8
0
def get_extension_modules():
    from importlib import import_module
    import pkgutil
    from azure.cli.core.extension import get_extensions, get_extension_path, get_extension_modname
    extension_whls = get_extensions()
    ext_modules = []
    if extension_whls:
        for ext_name in [e.name for e in extension_whls]:
            ext_dir = get_extension_path(ext_name)
            sys.path.append(ext_dir)
            try:
                ext_mod = get_extension_modname(ext_name, ext_dir=ext_dir)
                module = import_module(ext_mod)
                setattr(module, 'path', module.__path__[0])
                ext_modules.append((module, ext_mod))
            except Exception as ex:
                display("Error importing '{}' extension: {}".format(ext_mod, ex))
    return ext_modules
Example #9
0
def get_extension_modules():
    from importlib import import_module
    import pkgutil
    from azure.cli.core.extension import get_extensions, get_extension_path, get_extension_modname
    extension_whls = get_extensions()
    ext_modules = []
    if extension_whls:
        for ext_name in [e.name for e in extension_whls]:
            ext_dir = get_extension_path(ext_name)
            sys.path.append(ext_dir)
            try:
                ext_mod = get_extension_modname(ext_name, ext_dir=ext_dir)
                module = import_module(ext_mod)
                setattr(module, 'path', module.__path__[0])
                ext_modules.append((module, ext_mod))
            except Exception as ex:
                display("Error importing '{}' extension: {}".format(
                    ext_mod, ex))
    return ext_modules
def update_cmd_tree(ext_name):
    print(f"Processing {ext_name}")

    ext_dir = get_extension_path(ext_name)
    ext_mod = get_extension_modname(ext_name, ext_dir=ext_dir)

    invoker = az_cli.invocation_cls(
        cli_ctx=az_cli,
        commands_loader_cls=az_cli.commands_loader_cls,
        parser_cls=az_cli.parser_cls,
        help_cls=az_cli.help_cls)
    az_cli.invocation = invoker

    sys.path.append(ext_dir)
    extension_command_table, _ = _load_extension_command_loader(
        invoker.commands_loader, None, ext_mod)

    EXT_CMD_TREE_TO_UPLOAD = Session()
    EXT_CMD_TREE_TO_UPLOAD.load(
        os.path.expanduser(os.path.join('~', '.azure', file_name)))
    root = {}
    for cmd_name, ext_cmd in extension_command_table.items():
        try:
            # do not include hidden deprecated command
            if ext_cmd.deprecate_info.hide:
                print(f"Skip hidden deprecated command: {cmd_name}")
                continue
        except AttributeError:
            pass
        parts = cmd_name.split()
        parent = root
        for i, part in enumerate(parts):
            if part in parent:
                pass
            elif i == len(parts) - 1:
                parent[part] = ext_name
            else:
                parent[part] = {}
            parent = parent[part]
    print(root)
    for k, v in root.items():
        merge(EXT_CMD_TREE_TO_UPLOAD.data, k, v)
    EXT_CMD_TREE_TO_UPLOAD.save_with_retry()
Example #11
0
def _get_command_table_from_extensions():
    extensions = get_extension_names()
    if extensions:
        logger.debug("Found {} extensions: {}".format(len(extensions), extensions))
        for ext_name in extensions:
            ext_dir = get_extension_path(ext_name)
            sys.path.append(ext_dir)
            try:
                ext_mod = get_extension_modname(ext_dir=ext_dir)
                # Add to the map. This needs to happen before we load commands as registering a command
                # from an extension requires this map to be up-to-date.
                mod_to_ext_map[ext_mod] = ext_name
                start_time = timeit.default_timer()
                import_module(ext_mod).load_commands()
                elapsed_time = timeit.default_timer() - start_time
                logger.debug("Loaded extension '%s' in %.3f seconds.", ext_name, elapsed_time)
            except Exception:  # pylint: disable=broad-except
                logger.warning("Unable to load extension '%s'. Use --debug for more information.", ext_name)
                logger.debug(traceback.format_exc())
Example #12
0
def _get_command_table_from_extensions():
    extensions = get_extension_names()
    if extensions:
        logger.debug("Found {} extensions: {}".format(len(extensions), extensions))
        for ext_name in extensions:
            ext_dir = get_extension_path(ext_name)
            sys.path.append(ext_dir)
            try:
                ext_mod = get_extension_modname(ext_dir=ext_dir)
                # Add to the map. This needs to happen before we load commands as registering a command
                # from an extension requires this map to be up-to-date.
                mod_to_ext_map[ext_mod] = ext_name
                start_time = timeit.default_timer()
                import_module(ext_mod).load_commands()
                elapsed_time = timeit.default_timer() - start_time
                logger.debug("Loaded extension '%s' in %.3f seconds.", ext_name, elapsed_time)
            except Exception:  # pylint: disable=broad-except
                logger.warning("Unable to load extension '%s'. Use --debug for more information.", ext_name)
                logger.debug(traceback.format_exc())
Example #13
0
        def _update_command_table_from_extensions(ext_suppressions,
                                                  extension_modname=None):
            """Loads command tables from extensions and merge into the main command table.

            :param ext_suppressions: Extension suppression information.
            :param extension_modname: Command modules to load, in the format like ['azext_timeseriesinsights'].
             If None, will do extension discovery and load all extensions.
             If [], only ALWAYS_LOADED_EXTENSIONS will be loaded.
             Otherwise, the list will be extended using ALWAYS_LOADED_EXTENSIONS.
             If the extensions in the list are not installed, it will be skipped.
            """
            def _handle_extension_suppressions(extensions):
                filtered_extensions = []
                for ext in extensions:
                    should_include = True
                    for suppression in ext_suppressions:
                        if should_include and suppression.handle_suppress(ext):
                            should_include = False
                    if should_include:
                        filtered_extensions.append(ext)
                return filtered_extensions

            def _filter_modname(extensions):
                # Extension's name may not be the same as its modname. eg. name: virtual-wan, modname: azext_vwan
                filtered_extensions = []
                for ext in extensions:
                    ext_mod = get_extension_modname(ext.name, ext.path)
                    # Filter the extensions according to the index
                    if ext_mod in extension_modname:
                        filtered_extensions.append(ext)
                        extension_modname.remove(ext_mod)
                if extension_modname:
                    logger.debug(
                        "These extensions are not installed and will be skipped: %s",
                        extension_modname)
                return filtered_extensions

            extensions = get_extensions()
            if extensions:
                if extension_modname is not None:
                    extension_modname.extend(ALWAYS_LOADED_EXTENSIONS)
                    extensions = _filter_modname(extensions)
                allowed_extensions = _handle_extension_suppressions(extensions)
                module_commands = set(self.command_table.keys())

                count = 0
                cumulative_elapsed_time = 0
                cumulative_group_count = 0
                cumulative_command_count = 0
                logger.debug("Loading extensions:")
                logger.debug(self.header_ext)

                for ext in allowed_extensions:
                    try:
                        # Import in the `for` loop because `allowed_extensions` can be []. In such case we
                        # don't need to import `check_version_compatibility` at all.
                        from azure.cli.core.extension.operations import check_version_compatibility
                        check_version_compatibility(ext.get_metadata())
                    except CLIError as ex:
                        # issue warning and skip loading extensions that aren't compatible with the CLI core
                        logger.warning(ex)
                        continue
                    ext_name = ext.name
                    ext_dir = ext.path or get_extension_path(ext_name)
                    sys.path.append(ext_dir)
                    try:
                        ext_mod = get_extension_modname(ext_name,
                                                        ext_dir=ext_dir)
                        # Add to the map. This needs to happen before we load commands as registering a command
                        # from an extension requires this map to be up-to-date.
                        # self._mod_to_ext_map[ext_mod] = ext_name
                        start_time = timeit.default_timer()
                        extension_command_table, extension_group_table = \
                            _load_extension_command_loader(self, args, ext_mod)

                        for cmd_name, cmd in extension_command_table.items():
                            cmd.command_source = ExtensionCommandSource(
                                extension_name=ext_name,
                                overrides_command=cmd_name in module_commands,
                                preview=ext.preview,
                                experimental=ext.experimental)

                        self.command_table.update(extension_command_table)
                        self.command_group_table.update(extension_group_table)

                        elapsed_time = timeit.default_timer() - start_time
                        logger.debug(self.item_ext_format_string, ext_name,
                                     elapsed_time, len(extension_group_table),
                                     len(extension_command_table), ext_dir)
                        count += 1
                        cumulative_elapsed_time += elapsed_time
                        cumulative_group_count += len(extension_group_table)
                        cumulative_command_count += len(
                            extension_command_table)
                    except Exception as ex:  # pylint: disable=broad-except
                        self.cli_ctx.raise_event(EVENT_FAILED_EXTENSION_LOAD,
                                                 extension_name=ext_name)
                        logger.warning(
                            "Unable to load extension '%s: %s'. Use --debug for more information.",
                            ext_name, ex)
                        logger.debug(traceback.format_exc())
                # Summary line
                logger.debug(self.item_ext_format_string,
                             "Total ({})".format(count),
                             cumulative_elapsed_time, cumulative_group_count,
                             cumulative_command_count, "")
Example #14
0
def reload_extension(extension_name, extension_module=None):
    return reload_module(
        extension_module if extension_module else get_extension_modname(
            ext_name=extension_name))
Example #15
0
 def test_get_extension_modname_no_mods_with_prefix(self):
     tmp_dir = tempfile.mkdtemp()
     with self.assertRaises(AssertionError):
         get_extension_modname(ext_dir=tmp_dir)
Example #16
0
 def test_get_extension_modname_okay(self):
     tmp_dir = tempfile.mkdtemp()
     expected_modname = EXTENSIONS_MOD_PREFIX + 'helloworldmod'
     os.makedirs(os.path.join(tmp_dir, expected_modname))
     actual_modname = get_extension_modname(ext_dir=tmp_dir)
     self.assertEqual(expected_modname, actual_modname)
Example #17
0
def reload_extension(extension_name, extension_module=None):
    return reload_module(extension_module if extension_module else get_extension_modname(ext_name=extension_name))
Example #18
0
 def test_get_extension_modname_no_mods_with_prefix(self):
     tmp_dir = tempfile.mkdtemp()
     with self.assertRaises(AssertionError):
         get_extension_modname(ext_dir=tmp_dir)
Example #19
0
 def test_get_extension_modname_okay(self):
     tmp_dir = tempfile.mkdtemp()
     expected_modname = EXTENSIONS_MOD_PREFIX + 'helloworldmod'
     os.makedirs(os.path.join(tmp_dir, expected_modname))
     actual_modname = get_extension_modname(ext_dir=tmp_dir)
     self.assertEqual(expected_modname, actual_modname)