Example #1
0
    def test_should_warning_about_incompatible_plugins(self):
        class AirflowDeprecatedAdminViewsPlugin(AirflowPlugin):
            name = "test_admin_views_plugin"

            admin_views = [mock.MagicMock()]

        class AirflowDeprecatedAdminMenuLinksPlugin(AirflowPlugin):
            name = "test_menu_links_plugin"

            menu_links = [mock.MagicMock()]

        from airflow import plugins_manager
        plugins_manager.plugins = [
            AirflowDeprecatedAdminViewsPlugin(),
            AirflowDeprecatedAdminMenuLinksPlugin()
        ]
        with self.assertLogs(plugins_manager.log) as cm:
            plugins_manager.initialize_web_ui_plugins()

        self.assertEqual(cm.output, [
            'WARNING:airflow.plugins_manager:Plugin \'test_admin_views_plugin\' may not be '
            'compatible with the current Airflow version. Please contact the author of '
            'the plugin.',
            'WARNING:airflow.plugins_manager:Plugin \'test_menu_links_plugin\' may not be '
            'compatible with the current Airflow version. Please contact the author of '
            'the plugin.'
        ])
Example #2
0
def init_plugins(app):
    """Integrate Flask and FAB with plugins"""
    from airflow import plugins_manager

    plugins_manager.initialize_web_ui_plugins()

    appbuilder = app.appbuilder

    for view in plugins_manager.flask_appbuilder_views:
        log.debug("Adding view %s", view["name"])
        appbuilder.add_view(view["view"],
                            view["name"],
                            category=view["category"])

    for menu_link in sorted(plugins_manager.flask_appbuilder_menu_links,
                            key=lambda x: x["name"]):
        log.debug("Adding menu link %s", menu_link["name"])
        appbuilder.add_link(
            menu_link["name"],
            href=menu_link["href"],
            category=menu_link["category"],
            category_icon=menu_link["category_icon"],
        )

    for blue_print in plugins_manager.flask_blueprints:
        log.debug("Adding blueprint %s:%s", blue_print["name"],
                  blue_print["blueprint"].import_name)
        app.register_blueprint(blue_print["blueprint"])
Example #3
0
def dump_plugins(args):
    """Dump plugins information"""
    plugins_manager.log.setLevel(logging.DEBUG)

    plugins_manager.ensure_plugins_loaded()
    plugins_manager.integrate_dag_plugins()
    plugins_manager.integrate_executor_plugins()
    plugins_manager.initialize_extra_operators_links_plugins()
    plugins_manager.initialize_web_ui_plugins()

    _header("PLUGINS MANGER:", "#")

    for attr_name in PLUGINS_MANAGER_ATTRIBUTES_TO_DUMP:
        attr_value = getattr(plugins_manager, attr_name)
        print(f"{attr_name} = ", end='')
        pprint(attr_value)
    print()

    _header("PLUGINS:", "#")
    if not plugins_manager.plugins:
        print("No plugins loaded")
    else:
        print(f"Loaded {len(plugins_manager.plugins)} plugins")
        for plugin_no, plugin in enumerate(plugins_manager.plugins, 1):
            _header(f"{plugin_no}. {plugin.name}", "=")
            for attr_name in PLUGINS_ATTRIBUTES_TO_DUMP:
                attr_value = getattr(plugin, attr_name)
                print(f"{attr_name} = ", end='')
                pprint(attr_value)
            print()
Example #4
0
    def test_should_warning_about_incompatible_plugins(self, caplog):
        class AirflowAdminViewsPlugin(AirflowPlugin):
            name = "test_admin_views_plugin"

            admin_views = [mock.MagicMock()]

        class AirflowAdminMenuLinksPlugin(AirflowPlugin):
            name = "test_menu_links_plugin"

            menu_links = [mock.MagicMock()]

        with mock_plugin_manager(plugins=[
                AirflowAdminViewsPlugin(),
                AirflowAdminMenuLinksPlugin()
        ]), caplog.at_level(logging.WARNING, logger='airflow.plugins_manager'):
            from airflow import plugins_manager

            plugins_manager.initialize_web_ui_plugins()

        assert caplog.record_tuples == [
            (
                "airflow.plugins_manager",
                logging.WARNING,
                "Plugin 'test_admin_views_plugin' may not be compatible with the current Airflow version. "
                "Please contact the author of the plugin.",
            ),
            (
                "airflow.plugins_manager",
                logging.WARNING,
                "Plugin 'test_menu_links_plugin' may not be compatible with the current Airflow version. "
                "Please contact the author of the plugin.",
            ),
        ]
Example #5
0
def init_plugins(app):
    """Integrate Flask and FAB with plugins"""
    from airflow import plugins_manager

    plugins_manager.initialize_web_ui_plugins()

    appbuilder = app.appbuilder

    for view in plugins_manager.flask_appbuilder_views:
        name = view.get('name')
        if name:
            log.debug("Adding view %s with menu", name)
            appbuilder.add_view(view["view"], name, category=view["category"])
        else:
            # if 'name' key is missing, intent is to add view without menu
            log.debug("Adding view %s without menu", str(type(view["view"])))
            appbuilder.add_view_no_menu(view["view"])

    for menu_link in sorted(plugins_manager.flask_appbuilder_menu_links,
                            key=lambda x: x["name"]):
        log.debug("Adding menu link %s", menu_link["name"])
        appbuilder.add_link(
            menu_link["name"],
            href=menu_link["href"],
            category=menu_link["category"],
            category_icon=menu_link["category_icon"],
        )

    for blue_print in plugins_manager.flask_blueprints:
        log.debug("Adding blueprint %s:%s", blue_print["name"],
                  blue_print["blueprint"].import_name)
        app.register_blueprint(blue_print["blueprint"])
def dump_plugins(args):
    """Dump plugins information"""
    plugins_manager.ensure_plugins_loaded()
    plugins_manager.integrate_macros_plugins()
    plugins_manager.integrate_executor_plugins()
    plugins_manager.initialize_extra_operators_links_plugins()
    plugins_manager.initialize_web_ui_plugins()
    if not plugins_manager.plugins:
        print("No plugins loaded")
        return

    plugins_info: List[Dict[str, str]] = []
    for plugin in plugins_manager.plugins:
        info = {"name": plugin.name}
        info.update(
            {n: getattr(plugin, n)
             for n in PLUGINS_ATTRIBUTES_TO_DUMP})
        plugins_info.append(info)

    # Remove empty info
    if args.output == "table":  # pylint: disable=too-many-nested-blocks
        # We can do plugins_info[0] as the element it will exist as there's
        # at least one plugin at this point
        for col in list(plugins_info[0]):
            if all(not bool(p[col]) for p in plugins_info):
                for plugin in plugins_info:
                    del plugin[col]

    AirflowConsole().print_as(plugins_info, output=args.output)
Example #7
0
    def test_should_not_warning_about_fab_plugins(self):
        class AirflowAdminViewsPlugin(AirflowPlugin):
            name = "test_admin_views_plugin"

            appbuilder_views = [mock.MagicMock()]

        class AirflowAdminMenuLinksPlugin(AirflowPlugin):
            name = "test_menu_links_plugin"

            appbuilder_menu_items = [mock.MagicMock()]

        with mock_plugin_manager(plugins=[AirflowAdminViewsPlugin(), AirflowAdminMenuLinksPlugin()]):
            from airflow import plugins_manager

            # assert not logs
            with self.assertRaises(AssertionError), self.assertLogs(plugins_manager.log):
                plugins_manager.initialize_web_ui_plugins()
Example #8
0
            def integrate_plugins():
                """Integrate plugins to the context"""
                from airflow import plugins_manager

                plugins_manager.initialize_web_ui_plugins()

                for v in plugins_manager.flask_appbuilder_views:
                    log.debug("Adding view %s", v["name"])
                    appbuilder.add_view(v["view"],
                                        v["name"],
                                        category=v["category"])
                for ml in sorted(plugins_manager.flask_appbuilder_menu_links, key=lambda x: x["name"]):
                    log.debug("Adding menu link %s", ml["name"])
                    appbuilder.add_link(ml["name"],
                                        href=ml["href"],
                                        category=ml["category"],
                                        category_icon=ml["category_icon"])
    def test_should_not_warning_about_fab_plugins(self, caplog):
        class AirflowAdminViewsPlugin(AirflowPlugin):
            name = "test_admin_views_plugin"

            appbuilder_views = [mock.MagicMock()]

        class AirflowAdminMenuLinksPlugin(AirflowPlugin):
            name = "test_menu_links_plugin"

            appbuilder_menu_items = [mock.MagicMock()]

        with mock_plugin_manager(
            plugins=[AirflowAdminViewsPlugin(), AirflowAdminMenuLinksPlugin()]
        ), caplog.at_level(logging.WARNING, logger='airflow.plugins_manager'):
            from airflow import plugins_manager

            plugins_manager.initialize_web_ui_plugins()

        assert caplog.record_tuples == []
Example #10
0
def dump_plugins(args):
    """Dump plugins information"""
    plugins_manager.ensure_plugins_loaded()
    plugins_manager.integrate_macros_plugins()
    plugins_manager.integrate_executor_plugins()
    plugins_manager.initialize_extra_operators_links_plugins()
    plugins_manager.initialize_web_ui_plugins()
    if not plugins_manager.plugins:
        print("No plugins loaded")
        return

    console = Console()
    console.print("[bold yellow]SUMMARY:[/bold yellow]")
    console.print(
        f"[bold green]Plugins directory[/bold green]: {conf.get('core', 'plugins_folder')}\n",
        highlight=False)
    console.print(
        f"[bold green]Loaded plugins[/bold green]: {len(plugins_manager.plugins)}\n",
        highlight=False)

    for attr_name in PLUGINS_MANAGER_ATTRIBUTES_TO_DUMP:
        attr_value: Optional[List[Any]] = getattr(plugins_manager, attr_name)
        if not attr_value:
            continue
        table = SimpleTable(title=attr_name.capitalize().replace("_", " "))
        table.add_column(width=100)
        for item in attr_value:  # pylint: disable=not-an-iterable
            table.add_row(f"- {_get_name(item)}", )
        console.print(table)

    console.print("[bold yellow]DETAILED INFO:[/bold yellow]")
    for plugin in plugins_manager.plugins:
        table = SimpleTable(title=plugin.name)
        for attr_name in PLUGINS_ATTRIBUTES_TO_DUMP:
            value = getattr(plugin, attr_name)
            if not value:
                continue
            table.add_row(attr_name.capitalize().replace("_", " "),
                          _join_plugins_names(value))
        console.print(table)