Skip to content

fix: migrate API client HTTP transport from node-fetch to undici#2794

Merged
brendandburns merged 4 commits intomax-regen-genfrom
copilot/sub-pr-2770
Mar 17, 2026
Merged

fix: migrate API client HTTP transport from node-fetch to undici#2794
brendandburns merged 4 commits intomax-regen-genfrom
copilot/sub-pr-2770

Conversation

Copy link
Contributor

Copilot AI commented Mar 12, 2026

The regenerated OpenAPI client switched from node-fetch to undici, but the codebase was never updated to match, causing build failures and broken authentication.

Changes

undici dependency

  • Added undici to package.json — it was imported in generated files but never listed as a dependency.

src/config.ts — dispatcher migration

  • Replaced context.setAgent() (removed in new generated RequestContext) with context.setDispatcher().
  • Added createDispatcher() alongside the existing createAgent(): produces an undici Agent (with TLS connect options) or ProxyAgent (HTTP/HTTPS proxies) using requestTls so TLS options are properly threaded through proxy connections.
  • SOCKS proxy throws a descriptive error — undici has no native SOCKS support.
  • Returns undefined when no TLS options are present, allowing undici to fall through to the global dispatcher (preserves MockAgent behavior in tests).
// Before (node-fetch path, no longer exists on RequestContext)
context.setAgent(this.createAgent(cluster, agentOptions));

// After (undici path)
const dispatcher = this.createDispatcher(cluster, agentOptions);
if (dispatcher !== undefined) {
    context.setDispatcher(dispatcher);
}

src/metrics.ts — fetch migration

  • Migrated from node-fetch to undici fetch by using applySecurityAuthentication on a RequestContext to obtain auth headers and dispatcher.
  • Error messages now include the root cause chain for better debuggability (e.g. ECONNREFUSED surface through fetch failed).

src/util.ts

  • Widened normalizeResponseHeaders to accept any response with a headers.entries() method, removing the hard dependency on the node-fetch Response type.

Test updates

  • config_test.ts, azure_auth_test.ts, gcp_auth_test.ts: switched assertions from getAgent() to getDispatcher(), checking for UndiciAgent/UndiciProxyAgent instances. Restored proxy CA verification via Symbol(request tls settings) and proxy URI verification via Symbol(proxy agent options).
  • Added clusterG/contextG/userG to testdata/kubeconfig-proxy-url.yaml for the "https server, no proxy" test case.
  • integration_test.ts, object_test.ts, metrics_test.ts, top_test.ts: replaced nock with undici MockAgent — nock patches http.ClientRequest which undici bypasses entirely.
  • All tests use mockAgent.assertNoPendingInterceptors() as the equivalent of nock's scope.done() to verify expected HTTP requests were actually made.
  • Body serialization verification in object_test.ts (_from TypeScript field → from JSON key) restored using undici's regex body matching.

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@k8s-ci-robot k8s-ci-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Mar 12, 2026
Copilot AI mentioned this pull request Mar 12, 2026
@k8s-ci-robot k8s-ci-robot added size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Mar 12, 2026
Co-authored-by: brendandburns <5751682+brendandburns@users.noreply.github.com>
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Copilot
Once this PR has been reviewed and has the lgtm label, please ask for approval from brendandburns. 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 size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. labels Mar 12, 2026
Copy link
Contributor Author

Copilot AI commented Mar 12, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • d.i.y
    • Triggering command: /opt/hostedtoolcache/node/24.14.0/x64/bin/node /opt/hostedtoolcache/node/24.14.0/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA (dns block)
    • Triggering command: /opt/hostedtoolcache/node/24.14.0/x64/bin/node /opt/hostedtoolcache/node/24.14.0/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA e/git orig�� 0 (dns block)
    • Triggering command: /opt/hostedtoolcache/node/24.14.0/x64/bin/node /opt/hostedtoolcache/node/24.14.0/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA -RSA-AES128-SHA ascr�� /run/systemd/system ]; then /usr/lib/php/sessionclean; fi credential.helper &#34;token&#34;: &#34;token&#34; } } (dns block)
  • nowhere.foo
    • Triggering command: /opt/hostedtoolcache/node/24.14.0/x64/bin/node /opt/hostedtoolcache/node/24.14.0/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA src/object_test.ts (dns block)
    • Triggering command: /opt/hostedtoolcache/node/24.14.0/x64/bin/node /opt/hostedtoolcache/node/24.14.0/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA (dns block)
    • Triggering command: /opt/hostedtoolcache/node/24.14.0/x64/bin/node /opt/hostedtoolcache/node/24.14.0/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA src/metrics_test.ts conf�� } = require(&#39;undici&#39;); console.log(typeof Agent, typeof ProxyAgent) pull.rebase &#34;token&#34;: &#34;token&#34; } } -AES256-GCM-SHA3node (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title [WIP] Fix code to support undici in openapi generator fix: migrate API client HTTP transport from node-fetch to undici Mar 12, 2026
Copilot AI requested a review from brendandburns March 12, 2026 20:51
@brendandburns
Copy link
Contributor

@copilot I think that many of your unit test changes delete verifications that were present in the original tests. Can you make sure that as you update tests you are retaining all relevant checks and that the tests remain unchanged other than API changes related to the undici library.

Copilot AI and others added 2 commits March 16, 2026 20:54
Co-authored-by: brendandburns <5751682+brendandburns@users.noreply.github.com>
…gent

Co-authored-by: brendandburns <5751682+brendandburns@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 16, 2026

@copilot I think that many of your unit test changes delete verifications that were present in the original tests. Can you make sure that as you update tests you are retaining all relevant checks and ...

Fixed in commit 2e86fcf. Here's what was restored/fixed:

Proxy tests (config_test.ts): Re-added CA and proxy URI verification using undici's internal symbols (Symbol(proxy agent options).uri for proxy URL, Symbol(request tls settings).ca for CA). Also fixed createDispatcher to use requestTls instead of connect for ProxyAgent so TLS options are properly threaded through.

scope.done() equivalents (object_test.ts, metrics_test.ts, top_test.ts): Added mockAgent.assertNoPendingInterceptors() before each mockAgent.close() call — this is the undici equivalent of nock's scope.done().

Body verification (object_test.ts should properly serialize resources on modify): The original nock test used deep-JSON body matching to verify that the TypeScript _from field serializes to JSON from. Restored using undici's regex body matching: body: /"from":/.

metrics.ts and metrics_test.ts: Migrated Metrics class from node-fetch to undici fetch (via applySecurityAuthentication). Converted metrics_test.ts from nock to undici MockAgent.

top_test.ts: Converted from nock to undici MockAgent.

All 343 tests pass with lint and formatter clean.

@brendandburns brendandburns marked this pull request as ready for review March 17, 2026 23:32
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Mar 17, 2026
@brendandburns brendandburns merged commit 0211177 into max-regen-gen Mar 17, 2026
1 of 2 checks passed
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. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants