Repository navigation
connections: ?move=true moves the matched NetBox entry with its credentials - #268
jseifeddine wants to merge 1 commit into
Conversation
7b116d8 to
19e3a71
Compare
|
Thanks Jad. Can't take this one as is, two problems:
Could it match the device by a stored NetBox ID rather than the name, and move the existing entry with the server-side move from v1.10.3 ( Also, since the PRs are stacked, could you rebase this onto main on its own so it can be taken separately? |
19e3a71 to
1e25d34
Compare
|
Thanks Dave, both points were fair and this version does it the way you suggested. Entries now carry a stored external_id (the webhook sends netbox:device:) and ?move=true matches on that only, so tenant B's fw01 is never touched by tenant A's webhook and nothing is ever deleted by name. When the id is found in another folder or under another name, the entry goes through the same copy-then-delete move as the v1.10.3 move endpoint, so its password, key, jump host credentials and $variable references come along, and only then is the webhook payload merged on top, keeping every secret it lacks. A name already held by a different device, or an id stored on two entries, is a 409 with nothing changed. It is rebased onto main on its own now; the matching rules are under PUT .../entries/:entry in docs/api.md and the updated webhook template is in docs/netbox.md. The CI audit failure on this branch is the new quinn-proto advisories, not this change; #283 bumps the lockfile and the run goes green once that is in. |
…ntials
PUT /api/addressbook/folders/{scope}/{folder}/entries/{entry}?move=true
is for sync sources such as the NetBox webhook, where the folder (one
per tenant) or the name is computed from the device and can change.
Entries get a stored external_id (the webhook sends netbox:device:<id>)
and the flag matches the device on that, never on its name:
- already at folder/entry with that id, or with no id (an entry made by
hand before syncing began): updated in place;
- stored elsewhere in the scope under that id: moved to folder/entry by
the same server-side move as POST .../move (full entry copied, then
the original removed), so its password, key, jump host credentials
and credential variable references come along, and the update is
applied on top;
- stored nowhere: created.
Same-named entries in other folders are never touched: two tenants can
each have a fw01, and tenant A's webhook must not delete tenant B's. A
name held by a different device in the target folder, or an id stored
on more than one entry, is a 409 and nothing is changed. Without the
flag the PUT is the plain name upsert it always was.
The merge keeps every secret the request omits (the edit form never
receives them, a sync source never has them) and now keeps external_id
the same way, so a form edit does not cut a synced entry loose. A
failed read of the existing entry is a 502 rather than a blind write,
so a payload without secrets can no longer replace an entry that has
them.
Compared with the first version of this change: nothing is deleted by
name and there is no name matching across folders; the match is on the
stored NetBox id, and a moved entry goes through the existing
copy-then-delete path, so no credential is lost (sol1#232).
The locate / move / merge sequence sits behind a small EntryStore
trait with an in-memory store in the tests, which cover: the same name
in two folders is untouched, a move carries credentials, a rename
within the folder, an update without secrets keeps them, an untagged
entry is adopted in place, a missing id is refused, a name clash and an
ambiguous id are refused with nothing changed, and an unfinished move
is reported as such.
Part 1/3 of sol1#253.
1e25d34 to
a9bfaa7
Compare
Based on current
mainon its own: one commit, nothing from any other open PR. Part 1/3 of #253.What it does
PUT /api/addressbook/folders/{scope}/{folder}/entries/{entry}?move=trueis for sync sources such as the NetBox webhook, where the folder (one per tenant) or the name is computed from the device and can change. Entries now carry a storedexternal_id(the webhook body sendsnetbox:device:{{ data.id }}), and the flag matches the device on that, never on its name.Matching rule
folder/entryexists with the sameexternal_id, or with none (an entry made by hand before syncing began): updated in place.external_id, and it is moved tofolder/entryby the existing server-side move (move_stored_entry, the copy-then-delete path behindPOST .../entries/{entry}/movefrom v1.10.3), so its password, key, jump host credentials and$variablereferences come along; the update is then merged on top. Response:{"ok": true, "moved_from": {"folder": "...", "name": "..."}}.Same-named entries in other folders are never touched.
400withoutexternal_id;409iffolder/entrybelongs to a different id, or the id is stored on more than one entry (nothing is changed either way);502with"copied": trueif the move copied the entry but could not remove the original. Without the flag the PUT is the plain name upsert it always was. The scan only runs when the entry is not already where the request says (first sight of a device, a tenant change, a rename), so a routine update is one read and one write as before.Two smaller things in the same merge:
external_idis kept when the request omits it (the edit form never sends it, and it must not cut a synced entry loose from its source), and a failed read of the existing entry is now a502instead of a blind write, so a payload without secrets can no longer replace an entry that has them.Review changes
external_id. Tests:move_upsert_leaves_a_same_named_entry_in_another_folder_alone,move_upsert_refuses_a_name_held_by_another_device,move_upsert_needs_an_external_id,plain_upsert_never_moves.move_stored_entry, the same code as the move endpoint (full entry copied withput_entry_if_absent, original removed only after), and the payload is merged onto the moved entry afterwards, so every secret the payload lacks is kept. Tests:move_upsert_moves_the_matched_entry_with_its_credentials,move_upsert_follows_a_rename_within_the_folder,upsert_without_secrets_keeps_the_stored_ones,move_upsert_reports_a_move_it_could_not_finish.external_idtoAddressBookEntry(src/vault.rs, also returned inEntryInfo), populated by the webhook body indocs/netbox.md;relocate_by_external_idinsrc/api.rsdoes the matching,upsert_entrythe sequence.origin/mainplus this commit.Tests
11 unit tests in
src/api.rsrun the locate / move / merge sequence against an in-memoryEntryStore(the handler's Vault access sits behind that trait, like the existingFolderSource): the eight named above plusmove_upsert_adopts_a_hand_made_entry_of_that_name,move_upsert_refuses_an_ambiguous_external_idandentry_put_query_parses_the_move_flag.cargo fmtclean,cargo clippy --all-targetsno warnings.cargo test: 342 passed, 2 failed, the twovault::tests::test_build_client_mtls_*tests, which fail identically onmainin the same container (UnsupportedCertVersionfrom the locally generated test certificate) and are unrelated to this change.Docs
docs/api.md: theexternal_idfield and the?move=truerules and responses underPUT .../entries/:entry.docs/netbox.md: the create/update webhook is nowPUT ...?move=truewithexternal_idin the body, with the per-tenant folder example.