Skip to content

Add gNMI-style JSON remediation rendering (#287) - #292

Merged
jtdub merged 3 commits into
nextfrom
issue-287-gnmi-json-remediation
Aug 5, 2026
Merged

Add gNMI-style JSON remediation rendering (#287)#292
jtdub merged 3 commits into
nextfrom
issue-287-gnmi-json-remediation

Conversation

@jtdub

@jtdub jtdub commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #287.

Completes the "remediation output matches input format" story from #232 for OpenConfig/gNMI pipelines: WorkflowRemediation.remediation_json() (and the standalone hier_config.formats.hconfig_to_gnmi_json()) render a remediation between HConfig.from_json() trees as a gNMI-SetRequest-style structure:

workflow.remediation_json()
# {
#     "update": {"system": {"config": {"hostname": "new"}}},
#     "delete": ["interfaces/interface[name=eth1]"],
# }

Design notes, mirroring the NETCONF renderer (#280) throughout:

  • Delete paths: negated nodes become xpath-ish paths. Keyed list entries get [key=value] selectors using the same running-config key-leaf discrimination as _netconf_delete_element; scalar leaves delete by their bare path (system/config/hostname); without a running config, keyed deletes degrade to bare paths (same fallback contract as the NETCONF renderer). Selector values escape \ and ]; attribute-level changes raise InvalidConfigError.
  • Update object: non-negated subtrees render through the existing JSON mapping, so the output is re-ingestible by from_json(). Branches emptied by deletions are pruned, and a modified keyed entry re-gains its identity leaf (e.g. "name": "eth0") so the update stays valid OpenConfig.
  • Unlike the XML renderer there is no single-root requirement — top-level JSON members are multiple roots.
  • Additive only; no breaking change, no new dependencies, nothing new exported from hier_config/__init__.py.

Self-Review Checklist

  • poetry run ./scripts/build.py lint-and-test passes locally (lint + 95% test coverage).
  • Tests were written first (TDD) and cover the change, following the testing conventions.
  • CHANGELOG.md has an entry under ## [Unreleased] referencing this issue/PR ((#NNN)).
  • Documentation is updated if public API or driver behavior changed (and mkdocs build --strict passes if docs were touched).
  • Commit messages follow the contributing guide: imperative mood, subject ≤72 characters, body explains why.

AI-Assisted Contributions

Written with Claude Code; reviewed with the hier-config-review skill (no blockers).

Complete the remediation-output-matches-input-format story from #232
for OpenConfig/gNMI pipelines: WorkflowRemediation.remediation_json()
(and hier_config.formats.hconfig_to_gnmi_json()) render a remediation
between HConfig.from_json() trees as a gNMI-SetRequest-style structure.

Negations become xpath-ish delete paths with [key=value] selectors for
keyed list entries, resolved against the running config via the same
key-leaf discrimination as the NETCONF renderer. Additions render into
an update object through the existing JSON mapping; modified keyed
entries re-gain their identity leaf so the update stays valid
OpenConfig, and branches emptied by deletions are pruned.
@jtdub
jtdub requested a review from aedwardstx as a code owner August 4, 2026 23:53
jtdub added 2 commits August 4, 2026 18:59
Post-review cleanup: the NETCONF and gNMI delete renderers and the gNMI
identity lookup each carried their own copy of the running-entry key
probe, letting the single definition of keyed-list-entry identity drift
across three sites. Extract _matching_list_key/_running_entry_key so
both output formats share it. Also collapse single-name deferred
imports and drop a delete-path assertion already owned by the
nested-delete test.
Review flagged the fallback branch as untested: when a modified keyed
entry is rendered without a running config, its remediation subtree
lacks the identity leaf, so the key name cannot be resolved. Pin both
consequences — the delete-path selector guesses the first list_keys
name, and identity injection into the update is skipped so a guessed
key never becomes applied config.
@jtdub
jtdub merged commit 28eaded into next Aug 5, 2026
6 checks passed
@jtdub
jtdub deleted the issue-287-gnmi-json-remediation branch August 5, 2026 00:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant