Skip to content

CLOUDFLAREAPI: Add per-record CNAME flattening support#4020

Merged
tlimoncelli merged 1 commit intoStackExchange:mainfrom
allixsenos:feature/per-record-cname-flattening
Jan 27, 2026
Merged

CLOUDFLAREAPI: Add per-record CNAME flattening support#4020
tlimoncelli merged 1 commit intoStackExchange:mainfrom
allixsenos:feature/per-record-cname-flattening

Conversation

@allixsenos
Copy link
Copy Markdown
Contributor

Add support for Cloudflare's per-record CNAME flattening feature using CF_CNAME_FLATTEN_ON and CF_CNAME_FLATTEN_OFF modifiers, similar to the existing CF_PROXY_ON/OFF pattern.

CNAME flattening resolves CNAME targets to their IP addresses at Cloudflare's edge, which can improve performance and compatibility. This feature requires a paid Cloudflare plan (Pro, Business, or Enterprise).

New record modifiers for CNAME records:

  • CF_CNAME_FLATTEN_ON: Enable CNAME flattening for the record
  • CF_CNAME_FLATTEN_OFF: Disable CNAME flattening (default)

Example usage:

D("example.com", REG, DSP,
    CNAME("cdn", "cdn.provider.com.", CF_CNAME_FLATTEN_ON),
    CNAME("www", "www.example.com.", CF_CNAME_FLATTEN_OFF),
);
  • Uses Cloudflare API's settings.flatten_cname field

  • Stores state in record metadata as cloudflare_cname_flatten

  • Only applies to CNAME record types

  • Integrated with diff detection via genComparable()

  • pkg/js/helpers.js: Add CF_CNAME_FLATTEN_ON/OFF constants

  • commands/types/others.d.ts: Add TypeScript declarations for IDE support

  • providers/cloudflare/cloudflareProvider.go:

    • Add metaCNAMEFlatten constant
    • Add checkCNAMEFlattenVal() validation function
    • Update preprocessConfig() to validate CNAME flatten setting
    • Update nativeToRecord() to read settings.flatten_cname from API
    • Update genComparable() to include flatten state in diff comparison
  • providers/cloudflare/rest.go:

    • Update createRecDiff2() to set Settings.FlattenCNAME
    • Update modifyRecord() to set Settings.FlattenCNAME
  • commands/getZones.go:

    • Update TSV export to include cloudflare_cname_flatten metadata
    • Update JS/DJS export to include CF_CNAME_FLATTEN_ON modifier
  • pkg/prettyzone/prettyzone.go:

    • Update zone file export to include CF_CNAME_FLATTEN_ON comment

Added gated integration tests that are disabled by default since CNAME flattening requires a paid plan:

  • integrationTest/helpers_test.go: Add -cfflatten flag (default false)
  • integrationTest/helpers_integration_test.go: Add test helper functions
  • integrationTest/integration_test.go: Add CF_CNAME_FLATTEN test groups

Run tests on paid zones with: go test -v -provider=CLOUDFLAREAPI -cfflatten=true

Updated documentation/provider/cloudflareapi.md with:

  • New CNAME flattening section with usage examples
  • Warning about paid plan requirement
  • Integration test flag documentation

Add support for Cloudflare's per-record CNAME flattening feature using
CF_CNAME_FLATTEN_ON and CF_CNAME_FLATTEN_OFF modifiers, similar to the
existing CF_PROXY_ON/OFF pattern.

CNAME flattening resolves CNAME targets to their IP addresses at
Cloudflare's edge, which can improve performance and compatibility.
This feature requires a paid Cloudflare plan (Pro, Business, or
Enterprise).

New record modifiers for CNAME records:
- CF_CNAME_FLATTEN_ON: Enable CNAME flattening for the record
- CF_CNAME_FLATTEN_OFF: Disable CNAME flattening (default)

Example usage:
```javascript
D("example.com", REG, DSP,
    CNAME("cdn", "cdn.provider.com.", CF_CNAME_FLATTEN_ON),
    CNAME("www", "www.example.com.", CF_CNAME_FLATTEN_OFF),
);
```

- Uses Cloudflare API's `settings.flatten_cname` field (not tags, as
  the `cf-flatten-cname` tag is reserved by Cloudflare)
- Stores state in record metadata as `cloudflare_cname_flatten`
- Only applies to CNAME record types
- Integrated with diff detection via genComparable()

- pkg/js/helpers.js: Add CF_CNAME_FLATTEN_ON/OFF constants
- commands/types/others.d.ts: Add TypeScript declarations for IDE support
- providers/cloudflare/cloudflareProvider.go:
  - Add metaCNAMEFlatten constant
  - Add checkCNAMEFlattenVal() validation function
  - Update preprocessConfig() to validate CNAME flatten setting
  - Update nativeToRecord() to read settings.flatten_cname from API
  - Update genComparable() to include flatten state in diff comparison
- providers/cloudflare/rest.go:
  - Update createRecDiff2() to set Settings.FlattenCNAME
  - Update modifyRecord() to set Settings.FlattenCNAME
- commands/getZones.go:
  - Update TSV export to include cloudflare_cname_flatten metadata
  - Update JS/DJS export to include CF_CNAME_FLATTEN_ON modifier
- pkg/prettyzone/prettyzone.go:
  - Update zone file export to include CF_CNAME_FLATTEN_ON comment

Added gated integration tests that are disabled by default since CNAME
flattening requires a paid plan:
- integrationTest/helpers_test.go: Add -cfflatten flag (default false)
- integrationTest/helpers_integration_test.go: Add test helper functions
- integrationTest/integration_test.go: Add CF_CNAME_FLATTEN test groups

Run tests on paid zones with: go test -v -provider=CLOUDFLAREAPI -cfflatten=true

Updated documentation/provider/cloudflareapi.md with:
- New CNAME flattening section with usage examples
- Warning about paid plan requirement
- Integration test flag documentation
@allixsenos
Copy link
Copy Markdown
Contributor Author

Loosely related to #1862 which was asking about tags and comments, I started implementing this with tags but alas you cannot write cf- prefixed tags, so I abandoned that approach.

I cannot see a way of achieving this functionality with an additional tool without dropping dnscontrol altogether. I hope it's acceptable quality :D

Copy link
Copy Markdown
Contributor

@tlimoncelli tlimoncelli left a comment

Choose a reason for hiding this comment

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

This looks great! Thanks for adding this feature (and great job with the flag for the integration tests!)

I think a similar pattern would be useful for implementing the labels/comments. If you want to take that on, I would super appreciate it!

@tlimoncelli tlimoncelli merged commit d0a0a02 into StackExchange:main Jan 27, 2026
2 checks passed
@allixsenos allixsenos deleted the feature/per-record-cname-flattening branch January 27, 2026 23:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants