Skip to content

NM-291: feat(egress): add preset catalog API and server-side CIDR res…#4006

Open
abhishek9686 wants to merge 9 commits into
developfrom
NM-291
Open

NM-291: feat(egress): add preset catalog API and server-side CIDR res…#4006
abhishek9686 wants to merge 9 commits into
developfrom
NM-291

Conversation

@abhishek9686
Copy link
Copy Markdown
Member

…olution

Introduce GET /api/v1/egress/presets with embedded extras plus generated AWS region presets. Support optional preset_id on egress create/update to apply catalog defaults and resolve CIDRs from AWS ip-ranges, GitHub meta, and Fastly when available.

Add preset_id and static_domain_ans on schema.Egress; skip overwriting domain_ans from host EgressUpdate when static_domain_ans is set. Add Jenkins to extras catalog and tests for apply/resolvers and host guard.

Update swagger for preset_id, static fields, and presets endpoint.

Describe your changes

Provide Issue ticket number if applicable/not in title

Provide testing steps

Checklist before requesting a review

  • My changes affect only 10 files or less.
  • I have performed a self-review of my code and tested it.
  • If it is a new feature, I have added thorough tests, my code is <= 1450 lines.
  • If it is a bugfix, my code is <= 200 lines.
  • My functions are <= 80 lines.
  • I have had my code reviewed by a peer.
  • My unit tests pass locally.
  • Netmaker is awesome.

…olution

Introduce GET /api/v1/egress/presets with embedded extras plus generated AWS
region presets. Support optional preset_id on egress create/update to apply
catalog defaults and resolve CIDRs from AWS ip-ranges, GitHub meta, and Fastly
when available.

Add preset_id and static_domain_ans on schema.Egress; skip overwriting
domain_ans from host EgressUpdate when static_domain_ans is set. Add Jenkins
to extras catalog and tests for apply/resolvers and host guard.

Update swagger for preset_id, static fields, and presets endpoint.
@tenki-reviewer
Copy link
Copy Markdown
Contributor

tenki-reviewer Bot commented May 6, 2026

Tenki Code Review - Complete

Files Reviewed: 15
Findings: 2

By Severity:

  • 🟠 Medium: 2

This PR introduces a well-structured egress preset catalog with sensible allowlisting, but two medium-severity issues warrant attention: preset CIDR resolution failures are silently swallowed (degrading behavior with no operator visibility), and the resolution is performed synchronously in HTTP handlers with a 45-second independent timeout that ignores request cancellation.

Files Reviewed (15 files)
controllers/egress.go
controllers/hosts.go
controllers/hosts_egress_test.go
logic/egress_preset_extras.json
logic/egress_presets.go
logic/egress_presets_aws.go
logic/egress_presets_catalog.go
logic/egress_presets_public_ip.go
logic/egress_presets_test.go
logic/testdata/aws-ip-ranges-sample.json
logic/testdata/github-meta-sample.json
models/egress.go
models/egress_preset.go
schema/egress.go
swagger.yaml

Copy link
Copy Markdown
Contributor

@tenki-reviewer tenki-reviewer Bot left a comment

Choose a reason for hiding this comment

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

Overview

The PR adds an egress preset catalog (GET /api/v1/egress/presets) and allows creating/updating egress resources from a preset ID. The implementation is well-structured: a compile-time–embedded catalog, an allowlist-gated CIDR resolver, sync.Once for lazy initialization, and a StaticDomainAns flag to prevent host check-in from overwriting server-resolved CIDRs.

Issues Found

1. Silent CIDR resolution failure

In both createEgress and updateEgress, the error from logic.ResolveEgressPresetCIDRs is silently discarded:

if c, err := logic.ResolveEgressPresetCIDRs(http.DefaultClient, p); err == nil && len(c) > 0 {
    resolvedCIDRs = c
}

When the upstream (AWS, GitHub, Fastly) returns an error or non-200, the egress is created with StaticDomainAns=false and an empty DomainAns. The client receives a 200 OK with no indication that the preset CIDRs were not applied. This silent fallback to host-resolved behavior may confuse operators who expect static routing rules from the preset.

2. Synchronous outbound HTTP fetch blocks the handler

ResolveEgressPresetCIDRs is called synchronously in the HTTP handler for POST and PUT /api/v1/egress. Each resolver internally uses context.WithTimeout(context.Background(), 45s)not the incoming r.Context(). Consequences:

  • A slow or unreachable upstream stalls the handler goroutine for up to 45 seconds.
  • Client cancellation (connection close, client-side timeout) does not cancel the outbound fetch.
  • The HTTP server in controllers/controller.go has no WriteTimeout, so the connection stays open the entire duration.
  • The AWS ip-ranges.json payload is ~1.5 MB, adding latency from download and JSON decode.

Positive Observations

  • The isFetchableCIDRSource allowlist correctly prevents arbitrary URL fetches even if the embedded catalog were somehow tampered with.
  • The StaticDomainAns guard in shouldApplyEgressDomainAnsUpdate correctly protects server-resolved CIDRs from being overwritten during host check-in.
  • The sync.Once pattern for catalog initialization is correct and thread-safe.
  • Test coverage for the new helpers is solid, including fixture-based tests for AWS and GitHub resolvers.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant