Network create/update requests were sending empty strings for unset fields
(firewall_zone_id, radiusprofile_id, usergroup_id, dhcpd_dns_*, wan_dns*,
and 20+ others) because their JSON struct tags lacked omitempty. The UniFi
controller interprets an explicit empty firewall_zone_id as a zone
disassociation, which triggers a global zone rebuild that causes all zone
policies to disappear from the UI.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add NetworkIDs and MatchOppositeNetworks fields to destination struct
- Add NETWORK to MatchingTarget validation for destination
- Update codegen schema to include destination network targeting
- Add AggregateNumPorts to DevicePortOverrides (compatibility fix)
This enables firewall zone policies to target specific destination
networks, matching the existing source.network_ids functionality.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: support Zone-Based Firewalls
* chore: add usage example of zone-based firewall
* chore: add note to readme to support unifi controller v2
* fix: invalid path for reordering firewall zone policies
feat: allow creating own http.RoundTripper for http.Client with `HttpRoundTripperProvider` when customizing pre-configured http.Transport with `HttpTransportCustomizer` is not sufficient
* feat: generate fields validation and use it when issuing requests to API with soft (default) or hard modes
* chore: apply linter fixes
* feat: enable field validation on int fields
* feat: add validation for ^[\w]+$ fields
* feat: add validation for MAC address fields
* fix: trim wrappers for all comments
* feat: add validation for IPv4, IPv6 and IP(IPv4/IPv6) fields
* feat: add validation for numeric, non-zero based fields
* fix: one of validation can contain dot (.) sign in values
* feat: add second notation of MAC address validation
* fix: one of validation can start with ^( and end with )$
* feat: add option to disable validation and use soft validation by default
* chore: fix test
* docs: add readme about client-side validation
* feat: remove -latest flag and instead support latest version marker
* refactor: move determining unifi version, download URL and downloading resources and field definitions to dedicated files
* refactor: move writing version file to version.go file
* refactor: move code generation code to dedicated generator.go file
* chore: fix linting issues
* chore: add version tests
This method supports doing "errors.Is" checks so downstream can handle API errors more specifically.
In my case, since I copied your lazyClient example, but I'm using it in a server, the Login needs to be refreshed if an API call errors out with "api.err.LoginRequired".
There was no clean way to check for this specific error in order to refresh the login and retry.