Feeding result data back into a subsequent execution (Pre/Post check)

I have a usage question in a fairly complex setup, but I’ve tried to boil down the actual question to something simple and generic.

Let’s say I have a task that uses netmiko to execute ‘show clock’ on hosts.

from nornir.core.task import Task, Result
from netmiko import ConnectHandler

def show_clock(task: Task) -> Result:

    cmd = 'show clock'
    host = host_data

    connection = {'device_type': host.platform,
                  'host': host.name,
                  'username': host.username,
                  'password': host.password}

    net_connect = ConnectHandler(**connection)
    result = net_connect.send_command(cmd)

    return Result(
        host=task.host,
        result=result)

And when I execute it, it correctly connects and grabs the output for n hosts.

result = nr.run(task=show_clock)
>>> result['host_n'][0].result
'21:44:03.088 gmt Fri Oct 23 2020'

Lets also say I have another task, that will accept a formatted datestamp similar to our previous results, and return the difference between that stamp, and a new execution of show clock.

def show_clock_compare(task: Task, old_stamp: str = None) -> Result:
    ...

Assuming I have n > 1 hosts, how can I feed the current result data back into show_clock_compare dynamically for each host.

To put it another way, how can I have result['host_n'][0].result passed into show_clock_compare as if it were executed like:

nr.run(task=show_clock_compare, old_stamp=result['host_n'][0].result)

I’ve thought about parsing the result data back into each host, so it’s passed into tasks as part of task.host making it accessible, but this feels like a clunky unnecessary step, and I’m hoping something more elegant has to exist.

TIA for the help!

I would pass the timestamp to task.host at the end of your show_clock task. You won’t need to then pass it to the show_clock_compare task but it would still be available in task.host. I know you said this may be clunky but I can’t come up with a better option.

At this point I agree, I’m not seeing a better way of doing it. Since task in show_clock() has the host data (task.host.data: dict) I’m just adding result data to a list of results under task.host.data['task_data'] and then looking for it later.

This is only useful for subsequent re-runs on the same nornir object, but for now its fine.

You have three options IMO:

  1. Create a grouped task so your task owns all the data.
def my_grouped_task(task):
     old_stamp = task.run(task=show_clock)
     # stuff goes here
     new_stamp = task.run(task=show_clock)
     task.run(task=compare, old_stamp=old_stamp, new_stamp=new_stamp)
  1. Store it under host.data
  2. Pass to the second task the result object of the first one and retrieve it (result[task.host.name])