Building a button
A button belongs to a set, and a set is what you export and share. Start with a set — “Cisco IOS basics”, “Site survey”, whatever describes the job.
The simplest useful button
One send block with show ip int brief in it and “append Enter”
ticked. That is a real button and there is nothing wrong with it. Most of the ones you
end up using every day look exactly like this.
Waiting for the device
Firing three commands at a device that has not finished answering the first one is how
you end up with half a command in the buffer. An expect block waits for a
pattern — usually the prompt — before the script goes on:
send conf t
expect \(config\)#\s*$ timeout 10s
send interface Gi1/0/1
Asking for input
A form block pops a dialog part way through the script. Each field has a
name, and the answers fill {{NAME}} placeholders in later steps:
form INTERFACE ("Which interface?"), VLAN ("VLAN ID")
send interface {{INTERFACE}}
send switchport access vlan {{VLAN}}
One button now covers every port on every switch, instead of one button per port.
Values you never want to type
Some values are the same every time you press the button but different on every engineer's machine: your syslog collector, your TFTP host, your jump box, your site code. Those are global variables — set once, used by every button, and never asked for:
send logging host {{SYSLOG_HOST}}
send copy running-config tftp://{{TFTP_HOST}}/{{HOSTNAME}}-backup
Nothing on the button declares those names. That is what makes the button shareable: the value stays on your machine, and whoever downloads the set supplies their own.
Running a script from your library
A runScript block copies a script out of your script library onto the host,
runs it — optionally through an interpreter — and deletes the staged copy afterwards. The
path is relative to your library root, so the block still resolves on somebody else's
machine, as long as they have a script at that path. The script itself is not part of an
exported set.
Gates before something irreversible
A confirm block asks a yes/no question and stops the script if the answer
is no. Put one in front of anything that reboots, erases or writes:
confirm "Reload {{HOST}} now? Everything on it drops."
send reload
There is also a “confirm before run” flag on the button itself, which asks once before
anything happens at all. Use the flag for buttons that are dangerous end to end, and a
confirm block for the one step in the middle that is.
Branching
An if block runs one list of steps or another depending on what came back.
Handy for kit that might already be in the state you want, or for coping with two
firmware generations from one button.
Building from pieces
callMacro runs another button. callSet runs a whole set in order.
A long procedure becomes “log in, take a backup, make the change, verify” — four buttons
you already trust, called by a fifth.
A call can also hand values down. The keys are the names the called button uses; the values are text from the caller, so they can contain the caller's own placeholders. That is how one generic “back up to TFTP” button gets used by five different callers, each passing its own filename.
Do not make two buttons call each other. The exchange rejects bundles whose calls form a loop, because on the downloader's machine that is a script that never ends.
Firing across every session
With broadcast on, a button runs against every connected session rather than the focused one. Read that sentence again before pressing a reload button.
Next: sharing a set.