Skip to content

feat(source/fake): extend fake source to emit all supported record types#6308

Open
ivankatliarchuk wants to merge 9 commits intokubernetes-sigs:masterfrom
gofogo:feat/fake-source-all-record-types
Open

feat(source/fake): extend fake source to emit all supported record types#6308
ivankatliarchuk wants to merge 9 commits intokubernetes-sigs:masterfrom
gofogo:feat/fake-source-all-record-types

Conversation

@ivankatliarchuk
Copy link
Copy Markdown
Member

@ivankatliarchuk ivankatliarchuk commented Mar 24, 2026

What does it do ?

  • source/fake.go — generates one endpoint per type in KnownRecordTypes (A, AAAA, CNAME, TXT, SRV, NS, PTR, MX, NAPTR); adds ResourceLabelKey label mirroring service source; honours --fqdn-template via Config.TemplateEngine; caps fake Pod name at 253 chars
  • pkg/events/types.go - sets event.Regarding from Name (not gated on UID), so fake source endpoints produce valid Kubernetes events; Related still requires UID
  • docs/sources/fake.md - new page covering use cases, generated endpoints table, --managed-record-types, --emit-events, and --fqdn-template
  • 100% coverage

Motivation

Fixes #6042

Webhook providers (3rd-party DNS backends) had no way to test all supported record types without a live Kubernetes cluster. The fake source only emitted A records, making it impossible to verify AAAA, SRV, MX, NAPTR, etc. handling. Additionally, Kubernetes events were silently skipped for fake endpoints because Regarding was never populated (UID gated), and the domain was hardcoded to example.com.

More

  • Yes, this PR title follows Conventional Commits
  • Yes, I added unit tests
  • Yes, I updated end user documentation accordingly

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
@k8s-ci-robot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign szuecs for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added docs source size/L Denotes a PR that changes 100-499 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Mar 24, 2026
@coveralls
Copy link
Copy Markdown

coveralls commented Mar 24, 2026

Pull Request Test Coverage Report for Build 23734458438

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • 4 unchanged lines in 1 file lost coverage.
  • Overall coverage increased (+0.04%) to 80.515%

Files with Coverage Reduction New Missed Lines %
fake.go 4 95.96%
Totals Coverage Status
Change from base Build 23734434195: 0.04%
Covered Lines: 16987
Relevant Lines: 21098

💛 - Coveralls

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
@ivankatliarchuk
Copy link
Copy Markdown
Member Author

Hi @frittentheke . Have a look, I'm not sure where all records supported, but yeah, make sense to use fake source as some sort of contract/issue tracker.

@frittentheke
Copy link
Copy Markdown
Contributor

frittentheke commented Mar 24, 2026

Hi @frittentheke . Have a look, I'm not sure where all records supported, but yeah, make sense to use fake source as some sort of contract/issue tracker.

Awesome thank you @ivankatliarchuk .
I started a little on a PR adding IPv6/AAAA and MX ...
But fake providing the more complex records is what helps.

I'll push my code as draft later for you to take ans maybe make use of ....

Edit:

I see you already have lots of code including the use of managed-record-types which I added as well.

Cool 😎

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
@ivankatliarchuk
Copy link
Copy Markdown
Member Author

ivankatliarchuk commented Mar 26, 2026

Lgtm is enough. We could incorporate other code changes in follow up PRs ;-)

Copy link
Copy Markdown
Contributor

@frittentheke frittentheke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM @ivankatliarchuk

... just dropped a few thoughts on making the test-data even more "valuable" or "challenging" for the consumer.

Comment thread source/fake.go
case endpoint.RecordTypePTR:
name := generateDNSName(4, sc.dnsName)
var err error
ep, err = endpoint.NewPTREndpoint(generateIPv4Address(), endpoint.TTL(0), name)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe randomly generate IPv6 PTR records (ip6.arpa) as well?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure. We going to have a flag for that #6232. But in reality it should be done with DNSEndpoint

Comment thread source/fake.go Outdated
case endpoint.RecordTypeSRV:
// SRV target format: "priority weight port target." (target must end with a dot per RFC 2782)
name := generateDNSName(4, sc.dnsName)
ep = endpoint.NewEndpoint(fmt.Sprintf("_sip._udp.%s", sc.dnsName), endpoint.RecordTypeSRV, fmt.Sprintf("10 20 5060 %s.", name))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since SRV records are quite complex, maybe a bit more variety makes sense?
Just to ensure that

I have something like

	case endpoint.RecordTypeSRV:
		// SRV syntax:
		// SPEC: _service._proto.name. ttl IN SRV priority weight port target.
		// EXAMPLE: _sip._tcp.example.com. 86400 IN SRV 0 5 5060 sipserver.example.com.

		var priority int = rand.Intn(100) + 1
		var weight int = rand.Intn(100) + 1
		var target string = generateDNSName(6, sc.dnsName) + "."
		var service string = "_" + generateDNSName(5, "")
		var protocol []string = []string{"_tcp", "_udp"}

		serviceName = fmt.Sprintf("%s%s ", service, protocol[rand.Intn(2)])
		address = fmt.Sprintf("%d %d %s", priority, weight, target)

in mind.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure. Better to use DNSEndpoint, fake source is to verity handling of these types.

Comment thread source/fake.go Outdated
}

// Endpoints returns endpoint objects.
// Endpoints returns one endpoint per supported DNS record type.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe sticking with creating 10 each makes sense?
Since Fake is used for testing webhooks or other integrations have a "bigger" set might be helpful to cover more ground?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've change it sligthtly. Updated docs, high level - user could have FQDN template to increase number of endpoints

Comment thread source/fake.go
ep.WithLabel(endpoint.ResourceLabelKey, fmt.Sprintf("%s/%s/%s", types.Fake, pod.Namespace, ep.DNSName))
ep.WithRefObject(events.NewObjectReference(&pod, types.Fake))
}
return ep, nil
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add some (debug) logging the Record generated?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

Comment thread source/fake.go
var ep *endpoint.Endpoint

switch recordType {
case endpoint.RecordTypeA:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe adding a record containing more than one IP address makes sense?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

Comment thread source/fake.go
switch recordType {
case endpoint.RecordTypeA:
ep = endpoint.NewEndpoint(generateDNSName(4, sc.dnsName), endpoint.RecordTypeA, generateIPv4Address())
case endpoint.RecordTypeAAAA:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as with IPv4 having a record contain more than one address might make for sensible test data?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

@ivankatliarchuk
Copy link
Copy Markdown
Member Author

ivankatliarchuk commented Mar 26, 2026

LGTM @ivankatliarchuk

... just dropped a few thoughts on making the test-data even more "valuable" or "challenging" for the consumer.

I'm a bit on the edge to overload Fake source. Updated docs to better frame the fake source's scope.

The fake source is a smoke-test tool - it answers "does the provider connect and accept records?" without needing a cluster. It is not a substitute for a contract test. For predictable, stable integration test fixtures (specific record types, exact counts, known values), the right approach is DNSEndpoint resources with --source=crd, where the user has full control.

A few things worth noting:

  • SRV, PTR, and NAPTR are emitted by the fake source, but in practice they are only reachable via the CRD source. The fake source lets webhook providers verify handling of those types, but a passing result doesn't mean any real source will produce them.
  • The --fqdn-template comma-separated list adds volume (useful for load/stress testing) but not gurantee predictability

Documentation updated accordingly.

  ┌───────────────────┬──────────────────────────────────────────────────────────────┬───────────────────────────────────────────────────────────────┐
  │                   │                         Fake source                          │                        DNSEndpoint CRD                        │
  ├───────────────────┼──────────────────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────┤
  │ Purpose           │ Smoke test — "does the provider connect and accept records?" │ Integration test — predictable, exact record types and counts │
  ├───────────────────┼──────────────────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────┤
  │ Record types      │ Whatever fake emits                                          │ You decide                                                    │
  ├───────────────────┼──────────────────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────┤
  │ Volume            │ FQDN template hack                                           │ You decide                                                    │
  ├───────────────────┼──────────────────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────┤
  │ PTR / SRV / NAPTR │ Fake emits them, but real sources only CRD                  │ Explicitly supported                                          │
  ├───────────────────┼──────────────────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────┤
  │ Predictability    │ Random names, random IPs, changes every reconciliation       │ Stable, declarative                                           │
  └───────────────────┴──────────────────────────────────────────────────────────────┴───────────────────────────────────────────────────────────────┘

@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Mar 26, 2026
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
@frittentheke
Copy link
Copy Markdown
Contributor

frittentheke commented Mar 27, 2026

Thanks @ivankatliarchuk ! You are right, this PR is big enough, but it's also more than a leap forward.
Yes, before doing even more, the question about the actual role and intention of the Fake source should be discussed.

In the end it's not about creating and maintaining all possible values for all sorts of records and to validate a consumer does accept them. But I thank you again for picking up on the idea of providing just "a little" more test data for webhook authors to ensure their part works and to allow for some lightweight CI testing.

@ivankatliarchuk
Copy link
Copy Markdown
Member Author

ivankatliarchuk commented Mar 29, 2026

We don't hold any sessions where we discuss things ;-). I've added a doc, to clarify them

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. docs size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. source

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extend FakeSource to all supported record types

4 participants