Skip to main content

netbox-kea-ng

PyPI PyPI - Downloads CI Coverage CodeQL REUSE License Python NetBox

Fork notice: This is netbox-kea-ng, an independently maintained fork of netbox-kea by Devon Mar. It is published to PyPI as netbox-kea-ng and tracked in this repository. Upstream changes are periodically merged where applicable.

NetBox plugin for the Kea DHCP server. Manage your DHCP infrastructure directly from NetBox — view daemon status, search and manage leases, manage host reservations, configure subnets/pools/options, and keep your NetBox IPAM synchronized with live Kea data via a background job.

Features

Core (from upstream)

  • View Kea daemon status (DHCPv4/DHCPv6 daemons — and the Control Agent on Kea < 3.0)
  • Full DHCPv4 and DHCPv6 support
  • Search, view, delete and export DHCP leases
  • Search for NetBox devices/VMs directly from DHCP leases
  • View DHCP subnets from Kea configuration
  • REST API and GraphQL support for Server objects

Additions in this fork

Host Reservations

  • Full CRUD for DHCPv4 and DHCPv6 reservations via host_cmds and subnet_cmds hooks
  • Identifier types: hw-address (v4), DUID (v6), client-id, flex-id, circuit-id, remote-id
  • Reservations that reserve no address — an identifier-only host (hostname, options or client classes only) and a DHCPv6 host that only delegates prefixes. Both are listed, created, edited and deleted by client identifier instead of by IP, and the IPAM sync reports them as skipped: there is no address to record in NetBox. Their Lease column matches the client identifier against the leases of the reservation's own subnet, there being no reserved address to match on
  • Per-reservation DHCP options
  • Journal entries on add/edit/delete
  • Validated YAML or JSON bulk transfer. Export a Complete Snapshot from one server or the combined view, then import it from the matching DHCPv4 or DHCPv6 Reservations page

Subnet Management

  • Add, edit and delete subnets (requires subnet_cmds or config-set)
  • Pool management (add/delete pools per subnet)
  • Shared network management (add/edit/delete)
  • Per-subnet and global DHCP option editing

IPAM Sync

  • Sync active leases → NetBox IPAddress (status active)
  • Sync reservations → NetBox IPAddress (status reserved)
  • Sync button on individual leases and reservations
  • Bulk sync for entire lease tables
  • Pending-change detection: badge on leases where a reservation exists at a different IP
  • MAC address sync → NetBox MACAddress
  • Sets dns_name on IPAddress for automatic DNS sync via netbox-dns IPAMDNSsync

Periodic Background Sync (requires rqworker)

  • Automatic Kea→NetBox IPAM sync on a configurable interval (default 5 minutes)
  • Syncs all leases and reservations from all configured servers
  • Visible in NetBox System → Background Jobs

DHCP Control

  • Enable/disable DHCPv4 and DHCPv6 daemons from the NetBox UI

Dual-URL Server

  • Optional separate URLs for the DHCPv4 and DHCPv6 endpoints
  • Supports Kea 3.0+ (each daemon exposes its own HTTP control socket) and split v4/v6 deployments

Global / Cross-Server Views

  • Combined dashboard, lease, reservation, subnet and shared-network views across all servers

Lease Add / Edit / Bulk Import

  • Add and edit individual leases
  • Bulk import leases from CSV

Requirements

  • NetBox 4.3 – 4.7
  • Kea 3.0+ (recommended) — the plugin connects directly to each daemon's built-in HTTP control socket (kea-dhcp4 / kea-dhcp6). The Kea Control Agent was deprecated in Kea 2.7 and removed in 3.0; on Kea < 3.0, point the server URL at the Control Agent instead.
  • lease_cmds hook library (for lease search and management)
  • stat_cmds hook library (for guarded Subnet lease searches unless lease_query_max_unpaged_leases is 0)
  • Kea 3.1.5+ for state-filtered Subnet lease searches. Earlier releases do not provide the scoped state commands, so these searches fail closed.
  • host_cmds hook library (optional, for reservation management — also requires subnet_cmds to resolve a reservation's subnet from its CIDR)
  • subnet_cmds hook library (optional, for subnet add/edit/delete, reservation management, and the subnet suggestions on the lease search and reservation forms)

The plugin degrades gracefully when optional hooks are absent — tabs for unavailable features are hidden automatically. Two pages offer the server's configured subnets as suggestions and read them through subnet_cmds; without that hook each says so in a banner rather than silently offering nothing:

  • Lease search keeps working: the Search field offers no subnet suggestions, so type an exact configured subnet CIDR or ID.
  • Add reservation cannot save, because resolving the entered CIDR to a Kea subnet ID needs subnet_cmds. Load the hook first.

Compatibility

netbox-kea-ng NetBox Kea
1.x 4.3 – 4.7 3.0+ recommended (2.4+ via Control Agent)

On Kea 3.0+ the plugin talks directly to each DHCP daemon's HTTP control socket; on Kea < 3.0 it connects through the (now-deprecated) Control Agent. CI tests against Kea 3.2.0 using the memfile lease database.

netbox-branching

In a netbox-branching branch, the plugin is read-only. CI tests NetBox 4.7 with netbox-branching 1.2.1. List netbox_branching last in PLUGINS.

  • Kea servers, sync settings, DHCP plugin links and IPAM ownership links stay in main. A branch has no copy of them, so it shows main's values.
  • Kea data is live, in main and in every branch.
  • In a branch, the plugin refuses every change that comes through its web pages or its REST API, before it sends anything to Kea or writes to the database. A page shows HTTP 409 with a link to main; the REST API answers 409 with the code branch_write_refused. Plugin pages show a banner, and plugin and GraphQL responses carry an X-NetBox-Kea-Sources header.
  • A change request that still selects a branch that you can no longer use changes nothing. A _branch query that names a merged, archived, or not ready branch, and an active_branch cookie that names such a branch or a deleted one, get HTTP 409 with the code branch_selection_unusable. netbox-branching answers HTTP 400 first when a _branch query names a deleted branch, and when an API X-NetBox-Branch header names a deleted or unusable branch. Select main (?_branch=) and try again.
  • Code that runs outside a web request (a custom script, for example) is also refused in a branch. A save or a delete of a Kea server, the sync settings or a DHCP plugin link raises BranchActive, and so does a Kea command that changes Kea, from a client that Server.get_client() returns. The periodic IPAM sync job fails when it runs in a branch.
  • A merge fails, and changes nothing, when the branch deletes a VRF that a Kea server in main now syncs into. Clear or change that server's Sync VRF, then merge again.
  • In a branch, a delete of an IP address, Prefix or IP Range that a Kea server owns is refused, and so is a delete of a device or virtual machine that holds such an IP address, because the ownership data exists in main only. NetBox shows the refusal as an error message; the REST API answers 400.

Upgrade with open branches. Earlier releases let netbox-branching copy the Kea servers table into each new branch. Nothing removes that copy: branch sync no longer updates it, and branch migrate does not drop it. NetBox still reads Kea servers from main, but a VRF delete in the branch checks the old copy, not main. A merge also applies to main every Kea server change that the branch recorded before the upgrade. Before you upgrade, merge or delete every branch that is not yet merged, and create new branches after the upgrade. If a branch changed a Kea server password, delete it and make the change again in main: the change log holds a placeholder, not the password, so a merge can write the placeholder to main. A merged branch keeps its schema until you archive it; archive it when you no longer need to revert it.


Installation

1. Install the package

Add netbox-kea-ng to your local_requirements.txt (or install with pip):

pip install netbox-kea-ng

2. Enable the plugin

In configuration.py:

PLUGINS = ["netbox_kea"]

Optionally configure plugin settings (see Configuration):

PLUGINS_CONFIG = {
    "netbox_kea": {
        "kea_timeout": 30,
        "lease_query_max_unpaged_leases": 1000,
        "sync_interval_minutes": 5,
        "sync_leases_enabled": True,
        "sync_reservations_enabled": True,
        "sync_prefixes_enabled": True,
        "sync_ip_ranges_enabled": True,
        "sync_max_leases_per_server": 50000,
        "stale_ip_cleanup": "remove",
    }
}

3. Run migrations

./manage.py migrate

4. Start the background worker (required for periodic sync)

The periodic IPAM sync job runs via NetBox's built-in rqworker. If you're not already running it:

./manage.py rqworker

The Kea IPAM Sync job will appear under System → Background Jobs and runs on the configured interval.


Configuration

All settings are under PLUGINS_CONFIG["netbox_kea"]:

Setting Default Description
kea_timeout 30 HTTP request timeout in seconds for Kea API calls
lease_query_max_unpaged_leases 1000 Reject an unpaged Subnet lease query when its Kea statistics count exceeds this limit. Set to 0 to disable this safety check
stale_ip_cleanup "remove" What to do with stale IPs after sync: "remove" (delete), "deprecate" (set status=deprecated), "none" (skip)
sync_interval_minutes 5 Initial interval of the background sync job (minutes). Edit it later on the Sync Jobs page
sync_enabled True Initial state of the global sync switch. Edit it later on the Sync Jobs page
sync_leases_enabled True Sync active DHCP leases to NetBox IPAM
sync_reservations_enabled True Sync Kea reservations to NetBox IPAM
sync_prefixes_enabled True Sync Kea subnets to NetBox IPAM as IP Prefixes
sync_ip_ranges_enabled True Sync Kea pools to NetBox IPAM as IP Ranges
sync_max_leases_per_server 50000 Hard cap on leases fetched per server per sync run. Set to 0 for no limit

NetBox refuses to start when one of these settings has a value of the wrong type or outside its range. The error names the setting, the allowed values, and the given value. A number must be an integer, not a string or a boolean. kea_timeout must be at least 1, sync_interval_minutes must be from 1 to 1440, and the other numbers must be at least 0.

./manage.py migrate reads sync_interval_minutes, sync_enabled and the four sync_*_enabled toggles once, when it creates the Sync Configuration. After that, the Sync Jobs page holds these values, and a later change to these settings in PLUGINS_CONFIG has no effect.

Subnet lease searches use stat-lease4-get or stat-lease6-get before an unpaged lease command. Kea statistics can reject a query that is already too large. They cannot prove that an unqualified query is below the limit because stored expired states are not included in all statistics. Select Active or Declined to narrow a large query. Other states require an exact IP address or client identifier search. The guard fails closed when the stat_cmds hook is not available. State-filtered searches also fail closed when Kea does not support the scoped state commands. Set the limit to 0 only when you accept unbounded responses.

A Configuration Change holds a PostgreSQL advisory lock in an open transaction for all of its Kea requests, up to and including the save to disk. A PostgreSQL idle_in_transaction_session_timeout or a connection pooler timeout shorter than the longest Configuration Change ends that transaction and releases the lock while the change runs, so set these timeouts longer.


Server Configuration

Single-URL (Control Agent, or a single-protocol daemon)

Point one Server URL at a Kea endpoint that serves every enabled protocol — a Control Agent (Kea < 3.0, which fronts both DHCPv4 and DHCPv6), or a single DHCP daemon's HTTP control socket (Kea 3.0+) when the server runs only DHCPv4 or only DHCPv6. A dual-stack Kea 3.0+ deployment needs one URL per daemon — see Dual-URL below.

Field Description
CA / Server URL (ca_url) URL of the Kea HTTP endpoint — a DHCP daemon control socket (Kea 3.0+) or the Control Agent (Kea < 3.0), e.g. https://kea.example.com:8000
DHCPv4 Enable DHCPv4 lease/reservation/subnet management
DHCPv6 Enable DHCPv6 lease/reservation/subnet management
CA Username (ca_username) / CA Password (ca_password) HTTP Basic Auth credentials (if required)
CA File Path Path to a custom CA certificate file for TLS verification
SSL Verification Enable/disable TLS certificate verification (enabled by default)

Dual-URL (separate v4/v6 processes)

When DHCPv4 and DHCPv6 have separate endpoints — the norm on Kea 3.0+, where each daemon exposes its own HTTP control socket:

Field Description
DHCPv4 URL URL of the DHCPv4 daemon's HTTP control socket (or its Control Agent on Kea < 3.0)
DHCPv6 URL URL of the DHCPv6 daemon's HTTP control socket (or its Control Agent on Kea < 3.0)

The main CA URL (ca_url) is required and acts as a fallback for any protocol without a dedicated URL. By default, both DHCPv4 URL and DHCPv6 URL use CA-level credentials; see Per-protocol credentials below for optional overrides.


Per-protocol credentials

When connecting directly to DHCP daemons (bypassing the Control Agent), you can configure separate credentials per protocol:

Field Description
dhcp4_username Username for the DHCPv4 daemon (overrides ca_username for DHCPv4)
dhcp4_password Password for the DHCPv4 daemon (overrides ca_password for DHCPv4)
dhcp6_username Username for the DHCPv6 daemon (overrides ca_username for DHCPv6)
dhcp6_password Password for the DHCPv6 daemon (overrides ca_password for DHCPv6)

If per-protocol credentials are not set, the CA-level credentials (ca_username/ca_password) are used as the default for all connections.


Per-server IPAM sync settings

Each server has optional overrides for the IPAM sync job:

Field Default Description
IPAM Sync Enabled (sync_enabled) True Include this server in the periodic sync job
Sync Leases (sync_leases_enabled) True Sync active DHCP leases as NetBox IP Addresses
Sync Reservations (sync_reservations_enabled) True Sync DHCP reservations as NetBox IP Addresses
Sync Prefixes (sync_prefixes_enabled) True Sync Kea subnets as NetBox IP Prefixes
Sync IP Ranges (sync_ip_ranges_enabled) True Sync Kea pools as NetBox IP Ranges
Deprecate stale Prefixes and IP Ranges (sync_deprecate_prefixes_and_ranges) False Deprecate an owned Prefix or IP Range when this server drops its last ownership link as stale. These objects are never deleted
Sync VRF (sync_vrf) None (global routing table) VRF to assign when syncing Prefixes, IP Ranges, and lease and reservation IP Addresses. There is no global fallback: leave blank to use the global routing table (no VRF). NetBox refuses to delete a VRF while a server syncs into it
First complete IPAM observation (ipam_first_complete_at) None Read-only time when this server first completed all enabled job and DHCP import observations after the ownership upgrade
Persist configuration (persist_config) True Automatically save Kea config after each change via config-write. Disable when Kea config is managed externally (e.g. Ansible)

These fields override the global PLUGINS_CONFIG values for that specific server.


Background IPAM Sync

The Kea IPAM Sync job runs automatically when rqworker is active:

  1. Iterates all configured Server objects
  2. For each server: fetches all active leases (v4 + v6) and all reservations
  3. Creates or updates NetBox IPAddress objects in the server's sync_vrf, and links each one to the server and its source (lease or reservation):
    • Leases → status=dhcp, dns_name set from the Kea hostname
    • In-subnet reservations → status=reserved, dns_name set from the Kea hostname
    • An address with both a lease and a reservation → status=active; the reservation hostname wins
    • Global reservations create and change no IP address
    • The description starts with the sync marker [kea-sync: <kind>]. Text after the marker is an operator note, and the sync keeps it. To release an address from the sync, remove the marker or move it away from the start.
  4. Cleans up stale IPs (configurable via stale_ip_cleanup). A server's lease or reservation that Kea no longer reports loses its link. When the last link of every server to an address goes, stale_ip_cleanup applies, but only after a complete lease sync and a complete reservation sync. If the server disables reservation sync, a complete lease sync is sufficient. An unavailable host_cmds hook leaves the reservation source incomplete, because config-file reservations can still exist. Failed or truncated lease reads keep their stale links.
  5. Links Subnets to Prefixes and Pools to IP Ranges in the server's sync_vrf. A complete Subnet or Pool phase drops its own stale links. These objects stay unchanged by default and are never deleted. The server that drops the last link can opt in to deprecation with sync_deprecate_prefixes_and_ranges. A deprecated object's last link stays marked stale until an applied report restores its active status, or another owner supersedes the stale link. Removing the description marker releases every link without deprecation. DHCP plugin references prevent deprecation.
  6. One server failing does not block others
  7. Summary logged per server and in total

Each execution groups its native changelog records under one request ID, including MAC address changes. Sync now records the initiating user. Scheduled runs use the reserved user netbox-kea-sync. A job whose initiating user was deleted also uses system attribution.

The job creates this attribution account inactive, with an unusable password and no permissions. Keep it inactive and without access grants. If an existing account with that name has login access or permissions, the job fails before synchronization and leaves the account unchanged.

Each server's summary reports created, updated, errors, prefix_errors, conflicts, disagreements, skipped and waiting. The job total also reports unowned:

  • skipped: reservations the sync deliberately did not write: global reservations and reservations that reserve no address. They are not errors and do not fail the job.
  • errors: lease and reservation rows that failed to sync, snapshots that could not be read, and reservations that the snapshot could not read. Any error fails the job. A failed snapshot and the first 10 failed rows of each server and IP version are logged at warning level, with the source (lease or reservation), the address and the exception.
  • conflicts: IPAM objects that the sync left unchanged: the description of the object does not start with the sync marker (it was created by hand, or an operator removed the marker), or the new marker and the note after it do not fit in the 200-character description. They are deduplicated per server across its phases. Up to 20 of them are named in the summary and the log, so the addresses to look at are visible without trawling debug output.
  • disagreements: addresses that two Kea servers report with different facts (the hostname or the prefix length), or that one server reports twice with different facts, for example from two reservations in overlapping subnets. A lease and a reservation disagree only on the prefix length, and an empty hostname makes no claim. The address keeps its values until the reports agree, or until one of them goes.
  • unowned: marker objects with no ownership link, including objects left by a deleted server. Only the job total reports this count, because these objects have no owning server. It counts each object once.
  • waiting: adopted objects whose cleanup this server held during the run while a potential owner had not completed its initial observations. The job total counts objects still waiting after all servers finish. Counts include each object once across sources and address families.

View job history, next scheduled time and logs under System → Background Jobs → Kea IPAM Sync.

The first observations adopt marker objects that Kea still reports. No data migration assigns owners. An object with a blank description stays unchanged unless an operator forces a claim. When every configured server uses the same non-global sync_vrf, an unowned marker IP address in the global VRF moves into that VRF with its primary key and changelog intact. A row already owned by another server does not move. A destination address collision keeps the global row unowned and reports a conflict. Servers with different VRFs keep the global row and create their own scoped rows. A global-VRF server adopts it in place.

Adopted objects keep their last link until every potential owner completes all relevant enabled observations. Periodic jobs and DHCP imports record completion separately. An incomplete phase or missing family does not count as complete. Disabled sources and families do not hold the barrier. The read-only ipam_first_complete_at field shows when a server first completed its enabled observations. Newly enabled sources still require complete observations, even when that timestamp is already set.

stale_ip_cleanup = "remove" now also removes the rows of expired leases, deleted Reservations and hostless leases after their final ownership link becomes stale. On upgrade, lease removal applies only to leases that expire after adoption. Rows already stale before the upgrade get no link, stay unchanged and count as unowned. Review these rows before removing them manually.

To change the sync interval, edit it on the Sync Jobs page. You do not need to restart the worker: the new interval applies after the next scheduled run.


DNS Integration

When netbox-dns with IPAMDNSsync is installed:

  1. The IPAM sync sets dns_name on IPAddress objects from the Kea hostname
  2. IPAMDNSsync picks up dns_name changes via Django signals
  3. A/AAAA/PTR records are created automatically (provided matching DNS views + zones exist)

No additional configuration is required — the integration is automatic when both plugins are present.


Add custom links to NetBox models to navigate directly to Kea lease searches.

Replace <Kea Server ID> with your server's object ID (visible in the top-right corner of the server detail page as netbox_kea.server:<ID>).

Show DHCP leases for a prefix

Content type: IPAM > Prefix

URL: https://netbox.example.com/plugins/kea/servers/<Kea Server ID>/leases{{ object.prefix.version }}/?q={{ object.prefix }}&by=subnet

Show DHCP leases for a device/VM interface (by MAC)

Content types: DCIM > Interface, Virtualization > Interface

DHCPv4 URL: https://netbox.example.com/plugins/kea/servers/<Kea Server ID>/leases4/?q={{ object.mac_address }}&by=hw

DHCPv6 URL: https://netbox.example.com/plugins/kea/servers/<Kea Server ID>/leases6/?q={{ object.mac_address }}&by=hw

Show DHCP leases for a device/VM (by hostname)

Content types: DCIM > Device, Virtualization > Virtual Machine

DHCPv4 URL: https://netbox.example.com/plugins/kea/servers/<Kea Server ID>/leases4/?q={{ object.name|lower }}&by=hostname

DHCPv6 URL: https://netbox.example.com/plugins/kea/servers/<Kea Server ID>/leases6/?q={{ object.name|lower }}&by=hostname

You can substitute {{ object.name|lower }} with a custom field: {{ object.cf.<your_field>|lower }}.


Development

# Install dev dependencies
uv sync

# Lint
uv run ruff check .
uv run ruff format --check .

# REUSE compliance check
uv run reuse lint

# Format
uv run ruff format .

# Install pre-commit hooks
uv run pre-commit install

# Build wheel (required before integration tests)
uv build

# Run unit tests; both variables are required (see AGENTS.md for picking values)
TEST_DB_NAME=test_netbox_kea_local TEST_REDIS_HOST=localhost \
  uv run --native-tls pytest --reuse-db -n auto --maxschedchunk=1 -q

# Run integration tests (requires Docker — see tests/test_setup.sh)
./tests/test_setup.sh
uv run --native-tls pytest -p no:django tests/ --tracing=retain-on-failure -v --cov=netbox_kea --cov-report=xml

See CHANGELOG for version history.


License

Apache-2.0 — original code by Devon Mar, fork maintained by Marcin Zieba.

Metadata

Release files for netbox-kea-ng 1.13.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for netbox-kea-ng 1.13.0
File Size Uploaded Provenance
netbox_kea_ng-1.13.0.tar.gz 765.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for netbox-kea-ng 1.13.0
File Interpreter ABI Platform
netbox_kea_ng-1.13.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.1 MB

Release files / netbox_kea_ng-1.13.0.tar.gz

Download URL netbox_kea_ng-1.13.0.tar.gz
Size 765.7 kB
Tags Source
SHA-256 checksum
How to use checksums
90e689ad383d0d195b701b2d99d2199e8754f3c7edafa588475bb98bde169214
BLAKE2b-256 checksum
How to use checksums
894ae066d78120a92c74b04ca31a38d4c528d1b2971a8b1e80a2540154cbd72e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / netbox_kea_ng-1.13.0-py3-none-any.whl

Download URL netbox_kea_ng-1.13.0-py3-none-any.whl
Size 340.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4cdf12cd980b040ad830e391826fa5b4c0eeb38bd27ebd048629d043af449a23
BLAKE2b-256 checksum
How to use checksums
db9675ec54aa68336ba599cc8d32b261d9e72a9414b54aaa00cc4cb5ffe3501b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for netbox-kea-ng 1.13.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.13.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page