* feat(metrics): add source wrapper metrics for invalid and deduplicated endpoints
Add GaugeVecMetric.Reset() to clear stale label combinations between cycles.
Introduce invalidEndpoints and deduplicatedEndpoints gauge vectors in the
source wrappers package, partitioned by record_type and source_type. The
dedup source wrapper now tracks rejected (invalid) and de-duplicated
endpoints per collection cycle.
Update the metrics documentation and bump the known metrics count.
Signed-off-by: Seena Fallah <seenafallah@gmail.com>
* feat(source): add PTR source wrapper for automatic reverse DNS
Implement ptrSource, a source wrapper that generates PTR endpoints from
A/AAAA records. The wrapper supports:
- Global default via WithCreatePTR (maps to --create-ptr flag)
- Per-endpoint override via record-type provider-specific property
- Grouping multiple hostnames sharing an IP into a single PTR endpoint
- Skipping wildcard DNS names
Add WithPTRSupported and WithCreatePTR options to the wrapper Config
and wire the PTR wrapper into the WrapSources chain when PTR is in
managed-record-types.
Signed-off-by: Seena Fallah <seenafallah@gmail.com>
* feat(config): add --create-ptr flag and deprecate --rfc2136-create-ptr
Add the generic --create-ptr boolean flag to Config, enabling automatic
PTR record creation for any provider. Add IsPTRSupported() helper that
checks whether PTR is included in --managed-record-types.
Add validation: --create-ptr (or legacy --rfc2136-create-ptr) now
requires PTR in --managed-record-types, preventing misconfiguration.
Mark --rfc2136-create-ptr as deprecated in the flag description.
Signed-off-by: Seena Fallah <seenafallah@gmail.com>
* refactor(rfc2136): remove inline PTR logic in favor of PTR source wrapper
Remove the createPTR field, AddReverseRecord, RemoveReverseRecord, and
GenerateReverseRecord methods from the rfc2136 provider. PTR record
generation is now handled generically by the PTR source wrapper before
records reach the provider.
Update the PTR creation test to supply pre-generated PTR endpoints
(simulating what the source wrapper produces) instead of relying on
the provider to create them internally.
Signed-off-by: Seena Fallah <seenafallah@gmail.com>
* feat(controller): wire PTR source wrapper into buildSource
Pass the top-level Config to buildSource so it can read IsPTRSupported()
and the CreatePTR / RFC2136CreatePTR flags. When PTR is in
managed-record-types, the PTR source wrapper is installed in the
wrapper chain with the combined create-ptr default.
Signed-off-by: Seena Fallah <seenafallah@gmail.com>
* chore(pdns): remove stale comment and fix whitespace
Remove an outdated comment about a single-target-per-tuple assumption
that no longer applies.
Signed-off-by: Seena Fallah <seenafallah@gmail.com>
* docs: add PTR records documentation and update existing guides
Add docs/advanced/ptr-records.md covering the --create-ptr flag,
per-resource annotation overrides, prerequisites, and usage examples.
Update:
- annotations.md: document record-type annotation
- flags.md: add --create-ptr, mark --rfc2136-create-ptr as deprecated
- tutorials/rfc2136.md: point to generic --create-ptr flag
- contributing/source-wrappers.md: add PTR wrapper to the chain
- mkdocs.yml: add PTR Records navigation entry
Signed-off-by: Seena Fallah <seenafallah@gmail.com>
* feat(rfc2136)!: remove rfc2136-create-ptr in favor of create-ptr
Signed-off-by: Seena Fallah <seenafallah@gmail.com>
---------
Signed-off-by: Seena Fallah <seenafallah@gmail.com>
* perf(source/istio): replace API calls with indexed informer cache for gateway and virtualservice sources
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* perf(source/istio): replace API calls with indexed informer cache for gateway and virtualservice sources
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
---------
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
Without AddRateLimited the failed item was marked Done but never
put back into the queue, so transient API errors silently dropped
the event instead of retrying up to maxTriesPerEvent.
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
* refactor(registry): introduce factory with uniform New constructors
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactor(registry): introduce factory with uniform New constructors
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactor(registry): introduce factory with uniform New constructors
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactor(registry): introduce factory with uniform New constructors
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactor(registry): introduce factory with uniform New constructors
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
---------
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactor(controller): move provider construction to provider/factory package
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactor(controller): move provider construction to provider/factory package
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactor(provider): introduce factory package with per-provider New constructors
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactor(provider): introduce factory package with per-provider New constructors
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactor(provider): introduce factory package with per-provider New constructors
* refactor(provider): introduce factory package with per-provider New constructors
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactor(provider): introduce factory package with per-provider New constructors
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
---------
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactore(kubeclient): consolidate duplicate code to ensure consistent client creation
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactore(kubeclient): consolidate duplicate code to ensure consistent client creation
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactore(kubeclient): consolidate duplicate code to ensure consistent client creation
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactore(kubeclient): consolidate duplicate code to ensure consistent client creation
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactore(kubeclient): consolidate duplicate code to ensure consistent client creation
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactore(kubeclient): consolidate duplicate code to ensure consistent client creation
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactore(kubeclient): consolidate duplicate code to ensure consistent client creation
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactore(kubeclient): consolidate duplicate code to ensure consistent client creation
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactore(kubeclient): consolidate duplicate code to ensure consistent client creation
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node,crd
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node,crd
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node,crd
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node,crd
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node,crd
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node,crd
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node,crd
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node,crd
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node,crd
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node,crd
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node,crd
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node,crd
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node,crd
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node,crd
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactore(source): move SuitableType to endpiont package
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node,crd
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(event): add support for svc,ingress,pod,node,crd
Co-authored-by: vflaux <38909103+vflaux@users.noreply.github.com>
* feat(event): add support for svc,ingress,pod,node,crd
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
---------
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
Co-authored-by: vflaux <38909103+vflaux@users.noreply.github.com>
* linter(goimports): Mixed import groups (internal before external)
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* inter(goimports): Mixed import groups (internal before external)
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
---------
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(cloudflare): add --batch-change-size and --batch-change-interval flags
Adds two new global CLI flags for controlling batch DNS change behaviour:
- --batch-change-size (default 200): maximum number of DNS operations per batch
- --batch-change-interval (default 1s): pause between consecutive batch chunks
Wires the flags through Config into the Cloudflare provider's DNSRecordsConfig.
* feat(cloudflare): implement batch DNS records API with automatic fallback
Uses Cloudflare's Batch DNS Records API to submit all creates, updates, and
deletes for a zone in a single transactional API call per chunk, significantly
reducing the total number of requests made against the Cloudflare API.
- Batch size and interval are controlled via --batch-change-size / --batch-change-interval
- Record types unsupported by the batch PUT endpoint (e.g. SRV, CAA) are
submitted individually via the standard API
- If a batch chunk is rejected by Cloudflare, ExternalDNS automatically retries
each record change in that chunk individually so no changes are silently lost
- Adds cloudflare_batch.go with the core batching logic and full test coverage
* feat(cloudflare): soft retry for 'unexpected EOF' (issue 3798)
* feat(cloudflare): soft retry for 'unexpected EOF' (issue 3798)
* feat(cloudflare): debug logs for intentional invididual-updates
* feat(cloudflare): improved code coverage
* feat(cloudflare): handle json.Encoder error in test helper
* test: add tests for pkg/events/fake package
Add comprehensive test coverage for the fake EventEmitter implementation.
Tests cover:
- NewFakeEventEmitter() initialization
- Add() method with single and multiple events
- Different event types (Create, Update, Delete, Failed)
- Mock verification with specific events and any event type
- Edge case: empty events (panics as documented)
Improves code coverage from 0% to 100% for pkg/events/fake package.
Related to issue #5150
* fix: update copyright year to 2026
* chore(source): remove cloudfoundry support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* chore(source): remove cloudfoundry support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* chore(source): remove cloudfoundry support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* chore(source): remove cloudfoundry support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* chore(source): remove cloudfoundry support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* chore(source): remove cloudfoundry support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* chore(source): remove cloudfoundry support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* chore(source): remove cloudfoundry support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
---------
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(cli): rollbak to kingpin
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(cli): rollbak to kingpin
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(cli): rollbak to kingpin
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* chore(lint): configure modernize linter
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(cli): rollbak to kingpin
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
---------
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(coredns): use managed-by to separate records
Signed-off-by: Jan Jansen <jan.jansen@gdata.de>
* feat(coredns): use txt-owner-id to strictly separated external-dns instances
Signed-off-by: Jan Jansen <jan.jansen@gdata.de>
* fix tests
Signed-off-by: Jan Jansen <jan.jansen@gdata.de>
* fix reviewer comments
Signed-off-by: Jan Jansen <jan.jansen@gdata.de>
* answer review comments
* fix deletion behavior and remove extra function
* fix markdown
* fix tests again
---------
Signed-off-by: Jan Jansen <jan.jansen@gdata.de>
* feat(annotations): add custom annotation prefix support for split horizon DNS
Add --annotation-prefix flag to allow customizing the annotation prefix
used by external-dns. This enables split horizon DNS scenarios where
multiple instances process different sets of annotations from the same
Kubernetes resources.
Changes:
- Add AnnotationPrefix field to Config with validation
- Convert annotation constants to variables that can be reconfigured
- Add SetAnnotationPrefix() function to rebuild annotation keys
- Integrate annotation prefix setting in controller startup
- Update Helm chart with annotationPrefix value
- Add comprehensive split horizon DNS documentation
- Update FAQ with annotation prefix examples
This maintains full backward compatibility - the default prefix remains
"external-dns.alpha.kubernetes.io/".
Co-Authored-By: Claude <noreply@anthropic.com>
* docs(advanced): fix markdown formatting in split-horizon guide
Add blank lines before code blocks to improve markdown rendering
and comply with markdownlint rules.
Co-Authored-By: Claude <noreply@anthropic.com>
* docs(advanced): fix markdown formatting in split-horizon guide
Co-Authored-By: Claude <noreply@anthropic.com>
* docs(charts): regenerate Helm chart documentation
Co-Authored-By: Claude <noreply@anthropic.com>
* test: add AnnotationPrefix field to test configs
Add missing AnnotationPrefix field to minimalConfig and overriddenConfig
test configurations to match the new default value set in NewConfig().
Co-Authored-By: Claude <noreply@anthropic.com>
* test(charts): update error pattern in json-schema test
Update expected error message pattern to match current Helm validation
output format.
Co-Authored-By: Claude <noreply@anthropic.com>
* refactor(annotations): remove init() for explicit initialization
- Remove init() function from annotations package
- Add explicit SetAnnotationPrefix() call in controller/execute.go
- Remove annotation key aliases from source/source.go
- Replace all alias usages with annotations.* references (348 changes in 28 files)
- Add TestMain to existing test files (service_test.go, cloudflare_test.go)
This change makes annotation initialization explicit and predictable,
avoiding hidden global state initialization at import time.
Co-Authored-By: Claude <noreply@anthropic.com>
* docs: update changelog and mkdocs to include annotationPrefix and split horizon DNS
Signed-off-by: Aleksei Sviridkin <f@lex.la>
* docs(split-horizon): fix linting
Signed-off-by: Aleksei Sviridkin <f@lex.la>
* refactor(annotations): replace hardcoded annotation prefix with constant
Replace all hardcoded "external-dns.alpha.kubernetes.io/" strings
with annotations.DefaultAnnotationPrefix constant to establish
a single source of truth.
Changes:
- Add DefaultAnnotationPrefix constant in source/annotations/annotations.go
- Replace hardcoded string in controller/execute.go with constant reference
- Replace hardcoded strings in pkg/apis/externaldns/types.go (2 occurrences)
- Add helm unit tests for annotationPrefix value
This eliminates string duplication and makes future changes easier.
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Co-authored-by: Claude <noreply@anthropic.com>
* refactor(source/wrappers): move wrappers away from
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactor(source/wrappers): move wrappers away from
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactor(source/wrappers): move wrappers away from
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* refactor(source/wrappers): move wrappers away from
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
---------
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* Reintroduce base config for txt owner migration
# Conflicts:
# controller/execute.go
# registry/txt.go
# Conflicts:
# pkg/apis/externaldns/types.go
* Added label update logic and fixed existing tests
* Fixed existing declaration in tests, re introduced tests for new flag, regened flags.md from make
* Fixed tests logic and target expression evaluation, fixed update of label in the TXT registry process
* Set Old owner id var down the plan to calculate changes correctly
* Lint fixes
* (wip) Code cleaning and test coverage
* Simplified label overwriting on migration and implem tests for coverage
* Fix tests
* Update txt registry doc
* Fix rebase issues in txt test
* Update docs/registry/txt.md
Co-authored-by: Michel Loiseleur <97035654+mloiseleur@users.noreply.github.com>
* Update docs/registry/txt.md
Co-authored-by: Michel Loiseleur <97035654+mloiseleur@users.noreply.github.com>
* Update docs/registry/txt.md
Co-authored-by: Michel Loiseleur <97035654+mloiseleur@users.noreply.github.com>
* Fix label overriding in TXT record generation when migration is enabled
* Make linter happy
* Regen flags, fix types tests after types updates
* Removed boolean flag that enabled migration, evaluate only against old owner flag instead
---------
Co-authored-by: Michel Loiseleur <97035654+mloiseleur@users.noreply.github.com>
* feat(cli): add Cobra binder and backend switch
* add FlagBinder with Kingpin and Cobra implementations
* support --cli-backend and EXTERNAL_DNS_CLI (default: kingpin)
* add tests for binders and CLI switch
Refs: #5379
Signed-off-by: Tobias Harnickell <tobias.harnickell@bedag.ch>
* feat(cli): centralize flag registration and add Cobra parity
Started moving CLI flag registration into a common binder function,
avoiding duplication between Kingpin and Cobra.
Refs: #5820
Signed-off-by: Tobias Harnickell <tobias.harnickell@bedag.ch>
* feat(cli): enforce Cobra parity with Kingpin
* Add `regexpValue` and `RegexpVar` to Cobra binder with
`setRegexpDefault`
* Enforce `--provider` presence and validate against `providerNames
* require at least one `--source` and validate against new
`allowedSources`
* Expand tests for Kingpin and Cobra
Refs: #5379
Signed-off-by: Tobias Harnickell <tobias.harnickell@bedag.ch>
* feat(cli): Commit go-lint edits
Signed-off-by: Tobias Harnickell <tobias.harnickell@bedag.ch>
* feat(cli): add kingpin vs cobra binder parity
* Test parity assertion across binders
* Test Cobra-specific incapabilities (`--no-<flag>` and env vars)
* Deduplicate regexp flag handling
Refs: #5379
Signed-off-by: Tobias Harnickell <tobias.harnickell@bedag.ch>
* feat(cli): Rebuild flags documentation
Signed-off-by: Tobias Harnickell <tobias.harnickell@bedag.ch>
---------
Signed-off-by: Tobias Harnickell <tobias.harnickell@bedag.ch>
* feat(source/min-ttl): added min-ttl support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(source/min-ttl): added min-ttl support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(source/min-ttl): added min-ttl support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(source/min-ttl): added min-ttl support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(source/min-ttl): added min-ttl support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(source/min-ttl): added min-ttl support
Co-authored-by: Michel Loiseleur <97035654+mloiseleur@users.noreply.github.com>
* feat(source/min-ttl): added min-ttl support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(source/min-ttl): added min-ttl support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(source/min-ttl): added min-ttl support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(source/min-ttl): added min-ttl support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(source/min-ttl): added min-ttl support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(source/min-ttl): added min-ttl support
Co-authored-by: Michel Loiseleur <97035654+mloiseleur@users.noreply.github.com>
* feat(source): add min-ttl support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(source): add min-ttl support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
* feat(source/min-ttl): added min-ttl support
Co-authored-by: Michel Loiseleur <97035654+mloiseleur@users.noreply.github.com>
* feat(source): add min-ttl support
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
---------
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
Co-authored-by: Michel Loiseleur <97035654+mloiseleur@users.noreply.github.com>
* add FlagBinder with Kingpin and Cobra implementations
* support --cli-backend and EXTERNAL_DNS_CLI (default: kingpin)
* add tests for binders and CLI switch
Refs: #5379
Signed-off-by: Tobias Harnickell <tobias.harnickell@bedag.ch>
* chore(tests): Adding in missing tests for CustomRoundTrip struct.
* chore(tests): Adding in missing unit test.
* chore(tests): Refactored and addressed missing coverage in models.go