# Port forwards move from `firewall.rules` (dnat, toPort, hairpin) to # `firewall.nat`; the allow rule that went with them stays as a rule of its # own, limited to translated connections (natOnly). The rest of a rule # (rateLimit, log, sources) stays on the allow rule. def natRow: {type: "dnat", from: .from, to: .to, protocol: .protocol, ports: .ports, toAddress: .destination} + (if .toPort != null then {toPort: .toPort} else {} end) + (if ((.sources // []) | length) > 0 then {sources: .sources} else {} end) + (if .hairpin == true then {hairpin: true} else {} end); def allowRule: del(.dnat, .hairpin, .toPort) + {natOnly: true} + (if .toPort != null then {ports: [.toPort]} else {} end); if ((.router.firewall.rules // []) | any(.dnat == true or .hairpin != null or .toPort != null)) then .router.firewall.nat = ((.router.firewall.nat // []) + [.router.firewall.rules[] | select(.dnat == true) | natRow]) | .router.firewall.rules |= map(if .dnat == true then allowRule else del(.dnat, .hairpin, .toPort) end) else . end