Defdo.Cloudflare.DDNS (defdo_ddns v0.5.0)

Copy Markdown

We fetch the current domain ip in order to set your ip on cloudflare

Summary

Functions

Applies to cloudflare the record update.

Creates a new DNS record in Cloudflare with a promotional comment.

Check if a domain is configured for a specific mapping key.

Evaluate domain posture to quickly detect risky edge configurations.

Same listing as list_dns_records/2, but reports failure instead of hiding it.

Get combined configured domains from A and AAAA mappings.

Get all configured domains from domain mappings.

By parsing the Application config retrieves a list of domains defined.

Get the key from the the Application.

Retrieve configured CNAME records normalized for a specific zone/domain.

Backward compatible helper for public IPv4 retrieval.

Get current public IPv4 for the running service.

Get current public IPv6 for the running service.

Retrieve normalized proxy exclusion patterns from configuration.

Get subdomains specifically configured for a domain.

Retrieve the zone id for specific domain

Retrieve current SSL mode configured in Cloudflare for a zone.

Check CNAME records that must be updated to match a desired record definition.

Check the records which must be updated

Get the List of DNS records

Check if a record name matches any exclusion pattern from CLOUDFLARE_PROXY_EXCLUDE.

Retrieve the records to be used to monitor for a specific domain.

Retrieve records to monitor for a specific domain and mapping key.

Returns true when a hostname is deeper than one label under the zone.

Resolve if DNS record should be proxied.

Functions

apply_update(zone_id, arg)

@spec apply_update(
  String.t(),
  {String.t(), String.t()}
) :: tuple()

Applies to cloudflare the record update.

create_dns_record(zone_id, record_data)

@spec create_dns_record(String.t(), map()) :: tuple()

Creates a new DNS record in Cloudflare with a promotional comment.

domain_configured?(domain, mapping_key \\ :domain_mappings)

Check if a domain is configured for a specific mapping key.

evaluate_domain_posture(records, ssl_mode, expected_proxied)

@spec evaluate_domain_posture(list(), String.t() | nil, boolean()) :: map()

Evaluate domain posture to quickly detect risky edge configurations.

Returned map is intended for monitor logs and lightweight health checks.

fetch_dns_records(zone_id, params \\ [])

@spec fetch_dns_records(String.t(), list()) :: {:ok, list()} | {:error, term()}

Same listing as list_dns_records/2, but reports failure instead of hiding it.

list_dns_records/2 answers [] for both "this zone has no records" and "the call failed", which is fine for the monitor — it simply has nothing to sync — and dangerous for anything that reasons about absence. Reconciliation reads an empty list as "every declared record is missing" and an edge error as "nothing is declared upstream", so a single transient Cloudflare 521 would otherwise manufacture a zone's worth of false conclusions.

get_all_cloudflare_config_domains()

Get combined configured domains from A and AAAA mappings.

get_cloudflare_config_domains()

Get all configured domains from domain mappings.

get_cloudflare_config_domains(mapping_key)

get_cloudflare_config_subdomains(subdomain \\ get_cloudflare_key(:subdomains))

By parsing the Application config retrieves a list of domains defined.

get_cloudflare_key(key, default \\ "")

@spec get_cloudflare_key(atom(), any()) :: any()

Get the key from the the Application.

get_cname_records_for_domain(domain)

@spec get_cname_records_for_domain(String.t()) :: [map()]

Retrieve configured CNAME records normalized for a specific zone/domain.

Records come from the configured DDNS record store. The store may be bootstrapped from a snapshot file, init file, or legacy env JSON seed. Supported keys per entry:

  • provider
  • domain
  • type
  • name
  • content
  • ttl
  • proxied
  • metadata

get_current_ip()

@spec get_current_ip() :: String.t() | nil

Backward compatible helper for public IPv4 retrieval.

get_current_ipv4()

@spec get_current_ipv4() :: String.t() | nil

Get current public IPv4 for the running service.

get_current_ipv6()

@spec get_current_ipv6() :: String.t() | nil

Get current public IPv6 for the running service.

get_proxy_exclude_patterns()

@spec get_proxy_exclude_patterns() :: [String.t()]

Retrieve normalized proxy exclusion patterns from configuration.

Values come from CLOUDFLARE_PROXY_EXCLUDE and support exact names or wildcard suffixes using *..

get_subdomains_for_domain(domain)

Get subdomains specifically configured for a domain.

get_subdomains_for_domain(domain, mapping_key)

get_zone_id(domain)

@spec get_zone_id(bitstring()) :: String.t() | nil

Retrieve the zone id for specific domain

iex> Defdo.Cloudflare.DDNS.get_zone_id("defdo.de")

get_zone_ssl_mode(zone_id)

@spec get_zone_ssl_mode(String.t()) :: String.t() | nil

Retrieve current SSL mode configured in Cloudflare for a zone.

Typical values:

  • "strict"
  • "full"
  • "flexible"
  • "off"

input_for_update_cname_records(records, desired_record)

@spec input_for_update_cname_records(list(), map()) :: list()

Check CNAME records that must be updated to match a desired record definition.

input_for_update_dns_records(records, local_ip)

@spec input_for_update_dns_records(list(), String.t() | map()) :: list()

Check the records which must be updated

We filter the updatable records and transform them to give the input to apply_update/2

In fact this give the second parameter to execute the update.

list_dns_records(zone_id, params \\ [])

@spec list_dns_records(String.t(), list()) :: list()

Get the List of DNS records

use the params to filter the result and get only which are interested

Note: As of 2025-02-21, Cloudflare deprecated comma-separated name filtering. Use separate API calls for multiple DNS records.

iex> Defdo.Cloudflare.DDNS.list_dns_records(zone_id, [name: "defdo.de"])
iex> Defdo.Cloudflare.DDNS.list_dns_records(zone_id, [name: "h.defdo.de"])

proxy_excluded?(record_name, patterns \\ get_proxy_exclude_patterns())

@spec proxy_excluded?(String.t(), [String.t()]) :: boolean()

Check if a record name matches any exclusion pattern from CLOUDFLARE_PROXY_EXCLUDE.

records_to_monitor(domain)

Retrieve the records to be used to monitor for a specific domain.

records_to_monitor(domain, mapping_key)

Retrieve records to monitor for a specific domain and mapping key.

requires_advanced_certificate?(record_name, domain)

@spec requires_advanced_certificate?(String.t(), String.t()) :: boolean()

Returns true when a hostname is deeper than one label under the zone.

Example for zone example.com:

  • api.example.com => false (covered by Universal wildcard)
  • foo.bar.example.com => true (usually requires ACM for proxied edge cert)

resolve_proxied_value(record)

@spec resolve_proxied_value(map()) :: boolean()

Resolve if DNS record should be proxied.

By default, keep current Cloudflare proxied value. Set CLOUDFLARE_PROXY_A_RECORDS=true to force proxied mode, except for hostnames matched by CLOUDFLARE_PROXY_EXCLUDE.

resolve_ttl(record, desired_proxied)

@spec resolve_ttl(map(), boolean()) :: integer()

Resolve record TTL.

Cloudflare proxied records should use Auto TTL (1).