Add a general ansible validation action#3684
Conversation
ipspace
left a comment
There was a problem hiding this comment.
Mostly nits, the only thing that would be nice to have is a more informative printout on failure.
| return err_value | ||
| command = ' '.join(v_cmd) | ||
|
|
||
| a_module = topology.defaults.devices[node.device].netlab_validate.ansible_module |
There was a problem hiding this comment.
This was my only real questionable point in this PR. On one hand, it would be nice to place this into an existing dictionary (for example, intofeatures, i.e. features.validate.ansible_module or some such). OTOH, we already use the device.netlab_validate dictionary to extend wait times (although netlab_validate is so far never used in device definition).
I don't have a strong opinion either way, so whatever works for you is fine ;)
| # (hosts.yml + ansible.cfg in the lab directory). Pass the command as a single | ||
| # quoted string -- ansible ad-hoc rejects a bare list literal ("does not support | ||
| # raw params"). | ||
| cmd = ['ansible', n_name, '-m', str(a_module), '-a', 'commands=%r' % command, '--one-line'] |
There was a problem hiding this comment.
We might have to support a more generic command format. While most networking "something_command" modules use "commands" argument, the "command" module uses none. However, we can change that later if needed.
| print(f'Preparing to execute {command!r} on {n_name} via Ansible ({a_module})') | ||
|
|
||
| try: | ||
| out = subprocess.run(cmd, capture_output=True, text=True, timeout=60) |
There was a problem hiding this comment.
We have "cli/external_commands/run_command" wrapper around subprocess.run in case you want to use that one. Maybe it's simpler to just go with "subprocess.run" here.
| out = subprocess.run(cmd, capture_output=True, text=True, timeout=60) | ||
| except Exception as ex: # noqa: BLE001 | ||
| report.log_failure(f'Ansible action failed for "{command}" on {n_name}', | ||
| more_data=str(ex), topology=topology) |
There was a problem hiding this comment.
It might make sense to include the actual command executed in "more_data", so the user can run the command manually to see what's wrong -- similar to how we do it in "execute_netlab_config" in devices.py (same directory)
|
|
||
| raw = out.stdout or '' | ||
| # ansible --one-line: "<host> | SUCCESS => { ...json... }" (or FAILED!/UNREACHABLE!) | ||
| if ' => ' not in raw: |
There was a problem hiding this comment.
I knew the output would be messy ;)
6c39574 to
20dfa97
Compare
|
Thanks for the quick review — glad it's mostly nits! All four addressed: 1. More informative failure output. Good call. The failure path now surfaces the exact ad-hoc 2. subprocess wrapper. I looked at 3. Generic command format. Handled the common split now (low-effort): 4. |
Add an `ansible` validation action for `netlab validate`: a validation data source (a peer of the SuzieQ action in netsim/cli/validate/suzieq.py), not a device connection method. It fetches show output by running the command through a device's Ansible module (network_cli), for platforms whose CLI cannot be driven with non-interactive SSH commands. A test selects it with an `ansible` action (or a validation-plugin `ansible_<test>()` function) that supplies the show command; the device names the module to run it through in `defaults.devices.<device>.netlab_validate.ansible_module`. The result is parsed as JSON when the command emits JSON, otherwise the CLI text is returned in `stdout` for a `valid:` expression or a plugin `valid_<test>()` to screen-scrape. - netsim/cli/validate/ansible.py: the action implementation (get_result()). - netsim/cli/validate/tests.py: dispatch arm for the ansible action. - netsim/cli/validate/utils.py, plugin.py: register ansible in the test and plugin action lookups. - netsim/augment/validate.py, netsim/defaults/attributes.yml: make ansible a first-class validation test action in the schema and augment checks, so any topology can use `ansible: <show command>` with `valid:` directly. - netsim/defaults/hints.yml: include ansible in the validation hint messages. - docs/topology/validate.md: document the ansible action. Closes ipspace#3676.
20dfa97 to
9cb0a83
Compare
Add a general
ansiblevalidation actionCloses #3676.
netlab validatereads device state either by running ashow/execcommand over the node connection, or from an external source (suzieq). Both assume the platform can return command output to a non-interactive caller. Some network OSes only expose their operational data through a vendor Ansible module — their interactive CLI rejects non-interactive command execution — so neither existing path can reach them, and today such a device cannot be validated at all.This PR adds an
ansiblevalidation action to close that gap. It is a validation data source, a peer ofnetsim/cli/validate/suzieq.py— not a connection method.netsim/cli/connect.pyis unchanged; interactivenetlab connectis untouched. As discussed on #3676, it is implemented as a first-class, reusable action rather than a device-specific plugin, so any platform in the same situation can adopt it.How it works
validateentry:ansible_<test>()function and assert on the result invalid_<test>().netsim/cli/validate/ansible.pyruns the module ad-hoc against the node using the netlab-generated inventory, and returns parsed JSON when the command emits it (... | json), otherwise the raw CLI text instdoutfor a text assertion to match.The action is registered everywhere a validation action is expected — the topology schema (
attributes.yml), the augment/validation checks and their hint strings (augment/validate.py,hints.yml), and the test/plugin dispatchers — soansible:is accepted and executed like any built-in action, and it's documented indocs/topology/validate.md.Files
netsim/cli/validate/ansible.py— the validation source (peer ofsuzieq.py)netsim/cli/validate/tests.py,utils.py,plugin.py— dispatch + action registrationnetsim/augment/validate.py,netsim/defaults/attributes.yml,netsim/defaults/hints.yml— acceptansible:as a first-class validation action (schema, checks, and user-facing hints)docs/topology/validate.md— documentationtests/coverage/errors/validation-checks.log— updated golden for the new action's error textNotes
The first consumer is the IP Infusion OcNOS device (submitted separately), whose restricted CLI (
cmlsh) returns a non-zero exit on every non-interactive SSH command and so can't be reached by the standardshow/exectransports. The action itself is device-agnostic. Verified live against a real OcNOS lab (OSPFv2/OSPFv3, BGP and IS-IS validators passing through the action).