def create_fake_task(output, vendor_vars, vrf_name, nos, test_obj, effect=None): '''Create instance of nornir.core.task.Task and nornir.core.task.Host, assign latter to former, but mocking Host get_connection method to not really connect to hosts and return files outputs. Can use single return value or side effect with list of files. Arguments: * output - string with CLI output of some command, if we need single output * vendor_vars - dict with NOS CLI commands * vrf_name - name of VRF to test upon * nos - NOS name * test_obj - instance of nornir.core.task.Task which we will test * effect (defaults to None) - Mock.side_effect to provide different outputs Returns: * instance of nornir.core.task.Task with mocked internals ''' connection = Mock() if effect is None: connection.send_command = Mock(return_value=output) else: connection.send_command = Mock(side_effect=effect) host = OvercomeHostSlots('test-host') host['vendor_vars'] = vendor_vars host['vrf_name'] = vrf_name host.platform = nos host.get_connection = Mock(return_value=connection) fake_task = Task(test_obj) fake_task.host = host return fake_task
def _run_parallel(self, task, hosts, num_workers, **kwargs): result = AggregatedResult(kwargs.get("name") or task.__name__) pool = Pool(processes=num_workers) result_pool = [ pool.apply_async(Task(task, **kwargs).start, args=(h, self)) for h in hosts ] pool.close() pool.join() for rp in result_pool: r = rp.get() result[r.host.name] = r return result
def _run_serial(self, task, hosts, **kwargs): result = AggregatedResult(kwargs.get("name") or task.__name__) for host in hosts: result[host.name] = Task(task, **kwargs).start(host, self) return result
def run( self, task, raise_on_error=None, on_good=True, on_failed=False, name: Optional[str] = None, **kwargs, ): """ Run task over all the hosts in the inventory. Arguments: task (``callable``): function or callable that will be run against each device in the inventory raise_on_error (``bool``): Override raise_on_error behavior on_good(``bool``): Whether to run or not this task on hosts marked as good on_failed(``bool``): Whether to run or not this task on hosts marked as failed **kwargs: additional argument to pass to ``task`` when calling it Raises: :obj:`nornir.core.exceptions.NornirExecutionError`: if at least a task fails and self.config.core.raise_on_error is set to ``True`` Returns: :obj:`nornir.core.task.AggregatedResult`: results of each execution """ task = Task( task, self, global_dry_run=self.data.dry_run, name=name, processors=self.processors, **kwargs, ) self.processors.task_started(task) run_on = [] if on_good: for name, host in self.inventory.hosts.items(): if name not in self.data.failed_hosts: run_on.append(host) if on_failed: for name, host in self.inventory.hosts.items(): if name in self.data.failed_hosts: run_on.append(host) num_hosts = len(self.inventory.hosts) if num_hosts: logger.info( "Running task %r with args %s on %d hosts", task.name, kwargs, num_hosts, ) else: logger.warning("Task %r has not been run – 0 hosts selected", task.name) result = self.runner.run(task, run_on) raise_on_error = (raise_on_error if raise_on_error is not None else self.config.core.raise_on_error) # noqa if raise_on_error: result.raise_on_error() else: self.data.failed_hosts.update(result.failed_hosts.keys()) self.processors.task_completed(task, result) return result