5 Commits
Author SHA1 Message Date
Jack CarterandClaude Opus 4.7 27595eee61 fix: raise on unresolved group/peer/posture-check references instead of silent drop
The configure role's name resolver previously used dict.get(name, name)
fallbacks, so any unresolvable reference in YAML config was silently
passed through to the API as if it were a valid ID. On the server side,
the reference was discarded — producing half-applied policies whose
rules ended up with sources: null (or destinations/auto_groups wiped).

Common failure mode: a typo in a group name ships a broken firewall
rule that reports changed=true but has no source constraint.

This change makes the resolver strict:

- Unknown name that is ALSO not an existing ID -> AnsibleFilterError
  with a message naming the resource, field, and unresolved value.
- Known name -> resolves to ID (unchanged).
- Value that matches an existing ID -> passes through (preserves
  backward compatibility for YAML configs that use raw IDs).

Applies to groups in policy sources/destinations, setup_key auto_groups,
policy source_posture_checks, peer refs in policy source_resource/
destination_resource, and network router.peer / resource.groups.

Also: the /api/networks/{id}/routers endpoint returns router.peer as
the peer's HOSTNAME rather than its canonical name. The peer_ids map
(configure role) and peer_id_map (export role) now include hostname
aliases so round-trips stay idempotent.

Files:
- plugins/filter/netbird_resolve.py: strict _resolve_names,
  _resolve_resource_ref, new _resolve_peer_id helper
- roles/configure/tasks/main.yml: peer_ids merges hostname->id
  aliases with name->id
- roles/export/tasks/main.yml: peer_id_map merges hostname->name
  aliases with id->name

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 16:59:52 +02:00
Jack Carter 02e2c94ddb fix: resolve peer-type source/destination resources on roundtrip
PR#31 fixed export silently dropping peer-based policy sources, but
collapsed them into sources: [peer_name]. The configure role resolver
only maps sources against group_ids, so peer names fell through
unresolved. The netbird_policy module then sent literal peer names to
the API, which silently accepted them and wiped sourceResource --
turning the exported YAML into a policy with no source at all (reported
as changed: true).

Changes:
- Export template emits source_resource: {name, type: peer} for
  peer-type resources (keeps host/domain/subnet as {id, type}).
- _resolve_policy in netbird_resolve accepts peer_ids and converts
  {name, type: peer} to {id, type: peer}; non-peer refs pass through.
- configure/tasks/main.yml passes peer_ids to the policy resolve call
  (the map is already built on line 214 for networks).

Roundtrip verified on live NetBird: sourceResource preserved; apply
reports ok (idempotent) instead of false changed: true.
2026-04-17 10:28:50 +02:00
Tomas Kloda ec2a4f1ec9 normalization 2026-03-31 23:08:46 +02:00
Tomas Kloda da74682398 fixing false diff 2026-03-31 22:49:24 +02:00
Tomas Kloda 4045d39929 moving to plugins 2026-03-31 22:20:40 +02:00