def InitNornir(
    config_file: str = "",
    dry_run: bool = False,
    **kwargs: Any,
) -> Nornir:
    """
    Arguments:
        config_file(str): Path to the configuration file (optional)
        dry_run(bool): Whether to simulate changes or not
        configure_logging: Whether to configure logging or not. This argument is being
            deprecated. Please use logging.enabled parameter in the configuration
            instead.
        **kwargs: Extra information to pass to the
            :obj:`nornir.core.configuration.Config` object

    Returns:
        :obj:`nornir.core.Nornir`: fully instantiated and configured
    """
    ConnectionPluginRegister.auto_register()

    if config_file:
        config = Config.from_file(config_file, **kwargs)
    else:
        config = Config.from_dict(**kwargs)

    data = GlobalState(dry_run=dry_run)

    config.logging.configure()

    return Nornir(
        inventory=load_inventory(config),
        runner=load_runner(config),
        config=config,
        data=data,
    )
Пример #2
0
 def setup_class(cls):
     ConnectionPluginRegister.deregister_all()
     ConnectionPluginRegister.register("dummy", DummyConnectionPlugin)
     ConnectionPluginRegister.register("dummy2", DummyConnectionPlugin)
     ConnectionPluginRegister.register("dummy_no_overrides",
                                       DummyConnectionPlugin)
     ConnectionPluginRegister.register(FailedConnectionPlugin.name,
                                       FailedConnectionPlugin)
Пример #3
0
def cli(ctx, pg_bar, print_result, print_stat, *args, **kwargs):
    ConnectionPluginRegister.auto_register()

    # 'None' = None
    kwargs.update({k: v for k, v in zip(kwargs, _json_loads(kwargs.values()))})

    current_func_params = next(ctx.obj["queue_functions_generator"])

    # try to pass not all arguments, but only the necessary ones
    if kwargs == list(current_func_params.values())[0]:
        function, parameters = list(current_func_params.items())[0]
    else:
        param_iterator = iter(current_func_params.values())
        params = list(next(param_iterator).items())
        function, parameters = list(current_func_params)[0], {
            key: value
            for key, value in kwargs.items() if (key, value) not in params
        }

    # get the current Nornir object from Commands chain or from temp.pkl file
    try:
        nr = ctx.obj["nornir"]
    except KeyError:
        nr = _pickle_to_hidden_file("temp.pkl", mode="rb", dump=False)

    nr.config.logging.configure()

    # pg_bar option
    if pg_bar:
        with tqdm(
                total=len(nr.inventory.hosts),
                desc="processing: ",
        ) as pb:
            result = nr.run(
                task=multiple_progress_bar,
                method=function,
                pg_bar=pb,
                **parameters,
            )
        print()
    else:
        result = nr.run(
            task=function,
            **parameters,
        )

    ctx.obj["result"] = result

    # print_result option
    if print_result:
        pr(result)
        print()

    # print statistic
    if print_stat:
        ps(nr, result)
Пример #4
0
def default_nr_init(pytester):
    """Create initial Nornir files and expose the location
    as nornir_config_file fixture."""
    hosts_path = pytester.path / f"hosts{YAML_EXTENSION}"
    config = f"""inventory:
                          plugin: SimpleInventory
                          options:
                              host_file: {hosts_path}"""
    arguments = {
        "nr-config": config,
        "hosts": """
            R1:
              hostname: 1.1.1.1
            R2:
              hostname: 2.2.2.2
            R3:
              hostname: 3.3.3.3
            L1:
              hostname: 11.11.11.11
            L2:
              hostname: 22.22.22.22
            S1:
              hostname: 111.111.111.111
            S2:
              hostname: 222.222.222.222""",
    }
    pytester.makefile(YAML_EXTENSION, **arguments)

    # We need to have the test tmpdir in sys.path, so NUTS can import the test
    # modules (e.g. basic_task.py).
    pytester.syspathinsert()

    yield

    # Cleanup Nornir's PluginRegisters.
    # This is necessary as InitNornir is initiated for every test case, but the
    # PluginRegisters are (somehow) shared. This results in a
    # PluginAlreadyRegistered Exception as the plugins are registered multiple
    # times.
    ConnectionPluginRegister.deregister_all()
    InventoryPluginRegister.deregister_all()
    RunnersPluginRegister.deregister_all()
Пример #5
0
 def _get_trusted_untrusted(task):
     ConnectionPluginRegister.auto_register()
     # Get parameters in format:
     #    [ { 'description': 'NNI',
     #        'mac_address': 'xxxx-yyyy-zzzz',
     #        'mtu': '',
     #        'name': 'Ethernet0/0/1'},]
     intfs = task.run(
         task=netmiko_send_command,
         name="interfaces list",
         command_string="disp int",
         use_textfsm=True,
         textfsm_template=os.path.join(
             os.getcwd(),
             "nornir_cli/custom_commands/templates/disp_int.template"),
     )
     # Get trusted interfaces
     task.host["trusted"] = [
         i["name"] for i in intfs.result if "NNI" in i["description"]
     ]
     # Get untrusted interfaces
     task.host["untrusted"] = [
         i["name"] for i in intfs.result
         if "NNI" not in i["description"] and not i["mtu"]
     ]
     # Render j2 template
     template = task.run(
         task=template_file,
         path="nornir_cli/custom_commands/templates",
         template="dhcp_snooping.j2",
     )
     # Configure commands from j2 template
     task.host["template"] = template.result
     task.run(
         task=netmiko_send_config,
         name="Configure dhcp snooping",
         config_commands=template.result,
         cmd_verify=False,
         exit_config_mode=False,
     )
Пример #6
0
    def open_connection(
        self,
        connection: str,
        configuration: Config,
        hostname: Optional[str] = None,
        username: Optional[str] = None,
        password: Optional[str] = None,
        port: Optional[int] = None,
        platform: Optional[str] = None,
        extras: Optional[Dict[str, Any]] = None,
        default_to_host_attributes: bool = True,
    ) -> ConnectionPlugin:
        """
        Open a new connection.

        If ``default_to_host_attributes`` is set to ``True`` arguments will default to host
        attributes if not specified.

        Raises:
            AttributeError: if it's unknown how to establish a connection for the given type

        Returns:
            An already established connection
        """
        conn_name = connection
        existing_conn = self.connections.get(conn_name)
        if existing_conn is not None:
            raise ConnectionAlreadyOpen(conn_name)

        plugin = ConnectionPluginRegister.get_plugin(conn_name)
        conn_obj = plugin()
        if default_to_host_attributes:
            conn_params = self.get_connection_parameters(conn_name)
            hostname = hostname if hostname is not None else conn_params.hostname
            username = username if username is not None else conn_params.username
            password = password if password is not None else conn_params.password
            port = port if port is not None else conn_params.port
            platform = platform if platform is not None else conn_params.platform
            extras = extras if extras is not None else conn_params.extras

        conn_obj.open(
            hostname=hostname,
            username=username,
            password=password,
            port=port,
            platform=platform,
            extras=extras,
            configuration=configuration,
        )
        self.connections[conn_name] = conn_obj
        return conn_obj
Пример #7
0
 def test_register_already_registered_same(self):
     ConnectionPluginRegister.register("dummy", DummyConnectionPlugin)
     assert ConnectionPluginRegister.available[
         "dummy"] == DummyConnectionPlugin
Пример #8
0

19 Dec 2020 Ported to nornir 3 by paketb0te

"""

# Imports
from rich import print as rprint
from nornir import InitNornir
from nornir.core.task import Task
from nornir.core.plugins.connections import ConnectionPluginRegister
from nornir_netmiko.tasks import netmiko_send_command
from netaddr import EUI

# Register Plugins
ConnectionPluginRegister.register("connection-name", netmiko_send_command)


def get_interface_info(task: Task, target: EUI) -> None:
    """
    Get MAC addresses of all interfaces and compare to target.
    If present, identify Device and Interface
    """
    interfaces = task.run(task=netmiko_send_command,
                          command_string="show interfaces",
                          use_genie=True).result

    for intf in interfaces:
        mac_addr = EUI(interfaces[intf]["mac_address"])
        if target == mac_addr:
            print_info(task, intf, target)
Пример #9
0
from nornir_pyez.plugins.tasks import pyez_get_config
import os
from nornir import InitNornir
from nornir_utils.plugins.functions import print_result
from rich import print
from nornir.core.plugins.connections import ConnectionPluginRegister
from nornir_pyez.plugins.connections import Pyez

ConnectionPluginRegister.register("pyez", Pyez)

script_dir = os.path.dirname(os.path.realpath(__file__))

nr = InitNornir(config_file=f"{script_dir}/config.yml")

# xpath = 'interfaces/interface'
# xml = '<interfaces></interfaces>'
# database = 'committed'

response = nr.run(task=pyez_get_config)

# response is an AggregatedResult, which behaves like a list
# there is a response object for each device in inventory
devices = []
for dev in response:
    print(response[dev].result)
Пример #10
0
 def test_nonexistent_plugin(self):
     with pytest.raises(PluginNotRegistered):
         ConnectionPluginRegister.get_plugin("nonexistent_dummy")
Пример #11
0
 def test_get_plugin(self):
     assert ConnectionPluginRegister.get_plugin(
         "dummy") == DummyConnectionPlugin
     assert (ConnectionPluginRegister.get_plugin("another_dummy") ==
             AnotherDummyConnectionPlugin)
     assert len(ConnectionPluginRegister.available) == 2
Пример #12
0
 def test_deregister_all(self):
     ConnectionPluginRegister.deregister_all()
     assert ConnectionPluginRegister.available == {}
Пример #13
0
 def test_deregister_nonexistent(self):
     with pytest.raises(PluginNotRegistered):
         ConnectionPluginRegister.deregister("nonexistent_dummy")
Пример #14
0
 def test_deregister_existing(self):
     ConnectionPluginRegister.deregister("dummy")
     assert len(ConnectionPluginRegister.available) == 1
     assert "dummy" not in ConnectionPluginRegister.available
Пример #15
0
 def test_register_already_registered_new(self):
     with pytest.raises(PluginAlreadyRegistered):
         ConnectionPluginRegister.register("dummy",
                                           AnotherDummyConnectionPlugin)
Пример #16
0
 def test_register_new(self):
     ConnectionPluginRegister.register("new_dummy", DummyConnectionPlugin)
     assert "new_dummy" in ConnectionPluginRegister.available
Пример #17
0
 def teardown_method(self, method):
     ConnectionPluginRegister.deregister_all()
     ConnectionPluginRegister.auto_register()
Пример #18
0
 def setup_method(self, method):
     ConnectionPluginRegister.deregister_all()
     ConnectionPluginRegister.register("dummy", DummyConnectionPlugin)
     ConnectionPluginRegister.register("another_dummy",
                                       AnotherDummyConnectionPlugin)
Пример #19
0
def cli(ctx, pg_bar, show_result, *args, **kwargs):
    ConnectionPluginRegister.auto_register()

    # 'None' = None
    kwargs.update({k: v for k, v in zip(kwargs, _json_loads(kwargs.values()))})

    current_func_params = next(ctx.obj["queue_functions_generator"])

    # try to pass not all arguments, but only the necessary ones
    if kwargs == list(current_func_params.values())[0]:
        function, parameters = list(current_func_params.items())[0]
    else:
        param_iterator = iter(current_func_params.values())
        params = list(next(param_iterator).items())
        function, parameters = list(current_func_params)[0], {
            key: value
            for key, value in kwargs.items() if (key, value) not in params
        }

    # get the current Nornir object from Commands chain or from temp.pkl file
    try:
        nr = ctx.obj["nornir"]
    except KeyError:
        nr = _pickle_to_hidden_file("temp.pkl", mode="rb", dump=False)

    nr.config.logging.configure()

    # pg_bar option
    if pg_bar:
        with tqdm(
                total=len(nr.inventory.hosts),
                desc="processing: ",
        ) as pb:
            task = nr.run(
                task=multiple_progress_bar,
                method=function,
                pg_bar=pb,
                **parameters,
            )
        print()
    else:
        task = nr.run(
            task=function,
            **parameters,
        )

    # show_result option
    if show_result:
        print_result(task, severity_level=logging.DEBUG)
        print()

    # show statistic
    ch_sum = 0
    for host in nr.inventory.hosts:
        f, ch = (task[host].failed, task[host].changed)
        ch_sum += int(ch)
        click.secho(
            f"{host:<50}: ok={not f:<15} changed={ch:<15} failed={f:<15}",
            fg=_get_color(f, ch),
            bold=True,
        )
    print()
    f_sum = len(nr.data.failed_hosts)
    ok_sum = len(nr.inventory.hosts) - f_sum
    for state, summary, color in zip(("OK", "CHANGED", "FAILED"),
                                     (ok_sum, ch_sum, f_sum),
                                     ("green", "yellow", "red")):
        click.secho(
            f"{state:<8}: {summary}",
            fg=color,
            bold=True,
        )
    print()