Commit Graph

9175 Commits

Author SHA1 Message Date
Paul Lorenz 8b6289cabf Gate the smoke test's SDK paths on routers that handle OIDC sessions
- turns the oidc capability from a config switch into a test gate: OIDC stays on, as a 2.x
  controller runs it by default, and tests skip SDK client and SDK-hosted paths through routers older
  than 1.6, whose OIDC handling had many bugs that 1.6 fixed
- stops defaulting the oidc flag off for old routers, which did nothing once the controller started
  binding OIDC by default
- requires OIDC on the client routers for SDK clients, and on the hosting routers alongside SDK hosting
  for SDK-hosted services; ERT client and ERT-hosted paths always run
- adds Support.And for checks that span both ends of a path
2026-10-19 20:21:16 -04:00
Paul Lorenz 6bfcacdb49 Let a manual backward compatibility run pass extra fablab labels
- adds an optional labels input to the compat workflow's manual dispatch, appended to every job's
  fablab labels, so a run can set capability overrides such as capability_oidc=on
- passes the input to the script through the environment rather than interpolating it
2026-10-19 19:28:12 -04:00
Paul Lorenz c514f3a0f3 Gate the smoke test's config and tests on what each router version supports
- adds a router capability table to the smoke model: controller-managed link config, SDK hosting
  against a 2.x controller, and OIDC api sessions, each with the first release that has it
- keeps link config local on routers without managed link config, and defaults OIDC off when any
  edge router lacks it, though an oidc label still decides
- adds capability_<name>=on|off labels that override the version check for every router, so a run
  can test a floor or exercise the skips on the local build
- skips the SDK-hosted file, iperf, scp and sim tests with the reason when the hosting routers lack
  SDK hosting, and leaves those services out of the terminator waits
- tests the version and override checks
2026-10-19 19:20:43 -04:00
Paul Lorenz 2d6573eb30 Reclaim the AWS resources that cancelled CI fablab runs leave behind
- adds a scheduled sweeper that terminates CI fablab instances (Name gh-*) launched more than 7 hours
  ago in every enabled region and deletes their VPCs; EC2 records no VPC creation time, so it ages
  each VPC from a tag it writes on first sight, and it reports every find as a workflow warning
- adds a stop-fablab action that interrupts the fablab command and terraform a cancelled step left
  running, and waits for terraform to save its state; the smoketest, validation, upgrade and
  backward compatibility jobs run it before they archive or tear down their environment
- moves the housekeeper's VPC teardown into a file the sweeper shares, and waits on instances already
  shutting down before deleting the subnet they hold
- fixes the HA smoketest teardown's skip condition, which named a job that doesn't exist
2026-10-16 18:20:30 -04:00
Paul Lorenz e459fe3d6f Run the backward compatibility smoke test as part of Validation (All)
- runs the compat matrix against the 2.0 and 1.6 lines, with the old routers on the client side
  and, separately, on the hosting side
- resolves each line's newest stable release at run time instead of pinning versions
- makes the compat workflow callable and runs it first in Validation (All); the soak validations
  start once it finishes, whatever its result, so the two sets of environments don't share
  us-east-1's VPC quota
- keeps link config local on smoke test routers older than the first release that applies
  controller-managed link config, since they ignore it and would start with no links
2026-10-15 17:17:55 -04:00
Andrew Martinez 8415a7dbf6 Merge commit from fork
* The controller and the router wrote the complete service session token, an OIDC
  service session JWT or a legacy session token, into structured log fields during
  edge control operations. Several of the sites logged at Error or Info, so the
  values reached logs at default verbosity during ordinary operation.
* Adds LoggingFields to the session and api session types in common, controller/model
  and router/state, so a logging site asks for the session fields or the api session
  fields instead of picking values by hand. Ids, type, identity, service and the
  token's validity window go in; the token does not. Empty values are dropped, so the
  sets merge over each other.
* AddLoggingFields in router/state now delegates to LoggingFields. Its output moves
  from a nested field to flat prefixed keys.
* The edge control handlers log the session field set on the shared returnError and
  logResult paths, on circuit setup and on terminator update. The terminator removal
  paths log the terminator id, since they never load a session.
* Adds unit tests over returnError and logResult that fail if a session token reaches
  a log entry, covering the loaded-session, failed-to-load and JWT-claims cases.
2026-10-14 13:53:50 -04:00
Paul Lorenz a24e17af2a Merge pull request #4588 from openziti/illumos-build
Fix compilation on illumos. Fixes #3482
2026-10-14 12:45:35 -04:00
Paul Lorenz 5a36030e9b Fix compilation on illumos. Fixes #3482
- constrains the cpu profiler and router signal monitor to `unix` instead of a list of operating
  systems, and turns their windows stubs into `!unix` fallbacks
- replaces the per-OS tproxy and geneve listener stubs with one fallback each, covering every
  operating system without an implementation
- replaces survey with local stdin prompts for the pki pickers, since survey's terminal package does
  not build on solaris or illumos; an exact name takes precedence over a list number
- limits the interactive database explorer to the platforms its prompt library builds on, and
  reports it as unsupported elsewhere
- removes the survey dependency and syncs zititest's go.mod
- tests the pickers
- notes the fix in the changelog
2026-10-14 10:38:49 -04:00
Shawn Carey 8ab2bf0860 add l2 config types (#4051) 2026-10-13 14:25:41 -04:00
Paul Lorenz 98ebab22e6 Merge pull request #4544 from openziti/disable-connected-router-deadlock
Fix deadlocks disabling a connected router and resyncing router subscribers
2026-10-07 09:41:27 -04:00
Paul Lorenz 4958f76fab Stop the router deadlocking when syncing subscribers to a replaced data model. Fixes #4543
- collects the subscribed identity ids under IterCb when syncing all subscribers and checks each one
  after the iteration returns, rather than inside the callback; a deleted or disabled identity closes
  its SDK channel, whose close handler unsubscribes through RemoveCb on the same key and
  self-deadlocked on the shard lock
- clears each identity's update flag before looking up its live subscription, so a subscription
  replaced and updated mid-sync is checked instead of the one collected
- clears the update flag before the subscription lookup in syncSubscriptionIfRequired, for the same
  reason
- tests that a subscriber unsubscribing from inside its deleted notification lets the sync complete
- tests that a subscription replaced and updated during the sync delivers the update to its new
  listener
- notes the fix in the changelog
2026-10-06 14:05:12 -04:00
Paul Lorenz e0a0945042 Stop disabling a connected router from deadlocking the controller. Fixes #4542
- closes a disabled router's control channel after the connected map's RemoveCb returns, rather than
  inside its callback; the channel's close handler runs DisconnectRouter synchronously, which reads
  and removes the same map entry and self-deadlocked on the shard lock, wedging the raft apply
  goroutine and every path selection behind it
- logs any error from closing the channel
- adds godoc for UpdateCachedRouter
- tests that disabling a connected router completes and tears the connection down
- notes the fix in the changelog
2026-10-06 11:23:46 -04:00
Paul Lorenz 98ae32f2ca Merge pull request #4473 from openziti/link-fixes
Fix link reporting gaps found by links-test and the HA smoketest
2026-09-29 16:19:27 -04:00
Paul Lorenz b7bc3e129f Set the zititest link dial timeout with a key the router parses
- replaces the link dialer connectTimeout duration, which older channel options parsers do not recognize, with connectTimeoutMs so dials get 30s instead of the 5s default
2026-09-29 15:23:46 -04:00
Paul Lorenz 797f6b4d5d Document that ziti-edge-tunnel LogVerbosity must be shell-quoted
- updates the LogVerbosity godoc example to the quoted form the start command needs
2026-09-29 15:23:46 -04:00
Paul Lorenz bbfd87501e Run links-test mixed-version routers on the 1.6 LTS instead of 1.5
- moves the older-version links-test routers from v1.5.4 to v1.6.21
2026-09-29 15:23:46 -04:00
Paul Lorenz 75049cf8a1 Run circuit-test with an HA controller cluster again
- restores the circuit-test ha default to true, so circuits are created and validated across three raft controllers
2026-09-29 15:23:46 -04:00
Paul Lorenz b88ab2f98b Validate circuit-test throughput on the whole-transfer rate
- reads the sim's tx.byterate gauge, which was previously dropped as an unknown metric
- asserts throughput on the last non-zero byterate per service instead of the tx.bytes meter's one-minute EWMA, which never converges for a transfer shorter than a minute and reads low depending on where the burst lands against the sampling ticks
- fails a throughput service that reports no transfer rate
- logs the byterate alongside the EWMA per service, and includes it in the failure dump
- tests the gauge parsing and the last non-zero selection
2026-09-29 15:23:45 -04:00
Paul Lorenz e33b057481 Fix links-test validation diagnostics and error handling
- diagnoses a short link count by unordered router pair, since links are single-dialer, so only pairs with no link in either direction are reported missing and duplicates are found in either direction
- caps missing-pair log output and summarizes link, pair, duplicate and missing counts
- retries a failed link count query until the deadline instead of treating it as success, extending the deadline while the controller host is unreachable
- collects routers the controller could not reach during link validation instead of failing on the first, reporting inconsistent links ahead of unreachable routers
- names the expected link count as a constant
2026-09-29 15:23:45 -04:00
Paul Lorenz a4285af743 Deliver link listeners to every controller until written. Fixes #4456
- tracks the link listener set owed to each controller in the link registry, marked on a listener change and after each reconnect
- sends the listener set from the registry loop with wait-for-wire once the controller's reconnect link announcement is written, retrying every tick until the write succeeds, replacing the fire-and-forget send to controllers connected at the time of the change
- fences listener completions with the reconnect generation so a send that reached an earlier connection does not count for a later one
- keeps sync state for controllers absent from a controller snapshot while they still owe the listener set
- stamps the listener set sent to controllers with the config generation read in the same snapshot, matching the hello
- makes the controller skip the peer fan-out for an UpdateLinkListeners message whose set matches the one it replaced, still recording the message generation
- makes Router.SetLinkListeners return the set it held, read under the same lock as the update
2026-09-29 15:23:45 -04:00
Paul Lorenz 043912dd47 Close a dialed link the registry cannot account for. Fixes #4455
- closes a dialed link whose destination or link state is absent from the registry, where it was previously only logged, so a link this router can never report, fault or close does not survive
- skips dialing a queued link state whose destination is no longer registered, since removing a destination leaves its linkMap intact and the existing liveness check cannot see the removal
- leaves an accepted link alone, as the listener side holds no state for one, and leaves the existing fault path for a closed detached link unchanged
- logs each link pairing detached during listener reconciliation, with the reporting controller and whether a peer update or local rescan caused it
- passes the reporting controller id through UpdateLinkDest from the peer state handler
- tests the close, the accepted-link exemption, and the removed destination not being dialed
2026-09-29 10:30:48 -04:00
Paul Lorenz 02093821af Treat an unbound channel as open when checking a split link. Fixes #4454
- treats an unbound payload or ack channel as open in splitImpl.IsClosed, matching Close, which has always skipped a nil channel
- fixes a nil dereference on a split link whose channels are still being bound, since the listener sets the two independently as each arrives
- tests that checking a link with neither channel bound does not panic
2026-09-29 10:30:48 -04:00
Paul Lorenz f37ab93389 Retry the reconnect link announcement until it is written. Fixes #4453
- tracks a full link refresh owed to each controller after a reconnect, sent from the link registry loop through the rate limiter pool and retried every tick until written, instead of giving up after three attempts
- holds incremental new-link reports and faults to a connected controller until its refresh is written, so they cannot be pruned by or race ahead of the refresh, while disconnected controllers keep their existing skip and fault expiry handling
- fences refresh completions with a reconnect generation so a refresh written to an earlier connection does not satisfy a later one
- keeps sync state for controllers absent from a controller snapshot while they still owe a refresh
- snapshots the link set under the registry lock and sends outside it
- stops raft before closing the controller database on shutdown, so an in-flight apply cannot fail against a closed store and halt the process
2026-09-29 10:30:48 -04:00
Paul Lorenz bd9c4d1e4e Merge pull request #4472 from openziti/fix-triage-workflow
Fix triage workflow
2026-09-29 10:14:28 -04:00
Paul Lorenz 839abd3859 Merge pull request #4443 from openziti/fix.4442.controller-panics
Stop the controller panicking on a tunnel v2 dial to an unknown service. Fixes #4442
2026-09-29 10:07:16 -04:00
Paul Lorenz 667436b3b6 Stop the controller panicking on a tunnel v2 dial to an unknown service. Fixes #4442
- uses the nil-safe getApiSessionId() in loadServiceForName, matching loadServiceForId; the v2
  tunnel circuit handler never establishes an api session, so the lookup-failure branch
  dereferenced a nil apiSession and took the controller down on any unresolvable service name
- makes the default admin check log a read failure and return instead of panicking; the check is
  advisory and runs in a goroutine that can observe a datastore the shutdown path has closed,
  turning a controlled exit into exit 2
- adds godoc for checkEdgeInitialized covering the advisory contract and the remaining fatal case
- notes both in the changelog
2026-09-28 20:51:28 -04:00
Paul Lorenz c4b5a96ab5 Merge pull request #4215 from openziti/router-link-runtime-config
Apply managed link heartbeat and queue settings at runtime
2026-09-28 17:46:38 -04:00
Clint Dovholuk b47022c403 Merge pull request #4452 from openziti/issue-4402-fix-ziti-login
ziti-login using cert/key/file should persist after logging in
2026-09-24 22:59:41 -04:00
dovholuknf 2e4964c392 when using cert-based auth, present the client certificate on every path that reuses a cached login 2026-09-24 16:57:16 -04:00
Paul Lorenz 6348984dd2 Update triage skip list
- adds CLBRITTON2 to the skip list
- corrects scarey to scareything, the actual GitHub login
2026-09-24 15:05:49 -04:00
Paul Lorenz a3229aca55 Fix triage workflow permissions 2026-09-24 14:58:06 -04:00
Paul Lorenz a14e67b539 Merge pull request #4159 from openziti/fix-sdk-terminator-congestion-collapse
Fix SDK terminator remove-path congestion collapse
2026-09-24 13:50:19 -04:00
Paul Lorenz e0475768ee Make the ert-hosting-test bootstrap tolerate transient controller errors
- moves the identity and service id lookups in createServicePolicies inside the
  parallel task, so a transient failure is retried by the shared retry policy
  rather than ending the action; they previously ran serially ahead of the tasks
  with no retry, so one expired API session failed the whole run
- records why the create concurrency is left low, since a wider fan-out draws
  429s and timeouts from this model's controller that the retry policy cannot
  absorb
- corrects the service policy task type and label, which reported policy creation
  as service creation
- sets the model defaults through the promoted field rather than naming the
  embedded scope
2026-09-24 13:26:14 -04:00
Paul Lorenz be50068800 Tidy the zititest module
- syncs zititest's go.mod and go.sum, which dependency update automation does not
  reach, so the module had drifted from the versions it actually resolves
2026-09-24 13:26:14 -04:00
Paul Lorenz 444999bc5b Break the SDK terminator removal retry storm. Fixes #4156
- adds RemoveTerminatorsV2, an asynchronous control-channel removal, so a router
  no longer holds a request slot open waiting for a synchronous reply; gated on a
  new capability so routers fall back to the synchronous path against controllers
  that do not advertise it
- paces establish and remove retries with a per-terminator exponential backoff
  after a controller rejection, so a rejected operation is not re-sent on the next
  event-loop tick, which is what let a rate-limited removal sustain itself
- routes v2 removes to the leader and skips the ordered delete for a terminator the
  router confirms it created that no longer exists, so a storm of no-op retries
  cannot consume the command rate limiter
- gates that skip on the leader having applied everything committed when it took
  leadership, since a leader reports itself elected before those applies finish and
  would otherwise read a committed create as absent and drop its delete
- guards the leader term and every write to the caught-up flag with a dedicated
  lock, so a barrier completing alongside a leadership change cannot record a result
  for a term that has already ended
- scopes v2 removals to the requesting router, so a router can only remove
  terminators it owns on the asynchronous path as well as the synchronous one
- tracks in-flight removal batches on the router, resolving or requeueing them when
  the response arrives; lost responses self-heal via rate-limiter expiry and the
  retry scan
- waits for an outstanding operation before sending a terminator delete, and checks
  that before dequeuing, so a delete neither races a create the controller has
  committed but not applied nor falls out of the queue until the retry scan finds it
  minutes later
- matches a create response to the attempt that produced it, by control channel and
  reply sequence, since attempts overlap once one overruns the establishment timeout
  and every attempt carries the same terminator id; only the outstanding attempt's
  response may confirm the create or report the terminator idle
- records the attempt as the sender assigns its sequence, so a response cannot be
  processed before the request it answers is known, and withdraws an attempt whose
  send never queued
- reports a removal that succeeds past the establishment timeout as congestion
  rather than success, matching how the establish path classifies its own latency,
  since both resolve into the same limiter
- extracts the transient-error test both remove handlers share, so the v2 path
  treats a leaderless cluster as busy like v1 does instead of as a permanent
  failure, and the two cannot drift again
- applies the same delete sequencing and response correlation to the router-hosted
  (ER/T) registry, which cleared the same in-flight marker unguarded and dropped a
  deferred delete from its queue rather than leaving it there
- bounds the v2 response send with a timeout, so a router that stops draining its
  send queue cannot accumulate blocked responder goroutines on the controller
2026-09-24 13:24:51 -04:00
Paul Lorenz f4f1993fd9 Merge pull request #4158 from openziti/terminator-congestion-signaling
Signal congestion on terminator establish/remove timeouts
2026-09-23 17:34:16 -04:00
dovholuknf e6cd1afce8 skip the token refresh test when the session is not OIDC 2026-09-23 16:25:34 -04:00
Paul Lorenz 4ea4342092 Merge pull request #4451 from openziti/docs.quickstart-readme-release-flow
Correct quickstart release docs
2026-09-23 14:21:25 -04:00
Paul Lorenz 6c20e68038 Apply managed link heartbeat and queue settings at runtime. For #3743
- applies the router.link.v1 heartbeat settings (sendInterval, checkInterval,
  closeUnresponsiveTimeout) and payload/ack sender queue sizes at runtime,
  replacing the hardcoded 10s/1s link heartbeat intervals and the ignored fields;
  new links take them at bind time, established links are re-tuned in place
  through the channel HeartbeatControl, and queue sizes reach new links only
- publishes heartbeat settings as an immutable generation in one atomic swap, so
  no reader pairs one generation's interval with another's timeout, and has each
  link enforce the timeout belonging to its own intervals
- pushes a generation and its intervals as one step under the link's lock and
  ignores a generation at or below the one applied, so an overtaken update cannot
  roll a link back; reconciles every channel of a link, including a split link
  whose channels bind on either side of a config change, to the newest generation
- adopts the first registered settings explicitly, since a router with no managed
  link config publishes its defaults at generation 0
- re-arms a link's liveness deadline when its generation changes, so age
  accumulated under the previous intervals cannot close a healthy link when a
  timeout is shortened
- honors a closeUnresponsiveTimeout below 30s, which previously sat behind the
  unhealthy threshold; treats a zero timeout as closing nothing, and reports a
  closing link unhealthy
- scales the unhealthy threshold with the intervals, to max(30s, 2 x (send +
  check)): reporting unhealthy poisons the latency metric the controller routes
  on, so a fixed 30s priced healthy links with a long send interval out of
  routing every cycle
- validates heartbeat timing on the controller and the router: durations must be
  positive, their sum representable, and the timeout at least 10s and greater
  than sendInterval + checkInterval; a timeout under two heartbeat cycles is
  accepted with a warning
- adds a per-config-type semantic validator registry to ConfigManager, run after
  schema validation, and moves the router.link config definition to
  common/config/routerlink so the controller applies the same rules
- treats a link section in router YAML, of any content, as local config that
  takes precedence over the controller's for the whole router.link type, since
  the loader defaults every field and so now records presence separately; warns
  at startup when that section has no listeners or dialers
- translates local heartbeat timing leniently, since a local failure stops the
  router from starting: keeps an explicit zero, raises a timeout below the floor
  to it, and falls back to the defaults for other invalid timing, each with a
  warning
- stamps UpdateLinkListeners with the config generation it came from and has the
  controller drop superseded sets, which a multi-underlay control channel can
  deliver out of order and which would otherwise send peers to withdrawn
  addresses
- logs every successful link config apply, including those that dispatch no work,
  and pins that a queue-size-only change triggers no GC pass
- deprecates split links, documents the feature in the changelog and the router
  config design doc, and brings both up to date

Builds on the channel/v5 HeartbeatControl from openziti/channel#265.
2026-09-23 13:35:30 -04:00
dovholuknf 9c0637b12d present the client certificate when refreshing an expired token 2026-09-23 12:51:56 -04:00
dovholuknf 4a9a97278e persist the client certificate so cert logins survive into the next command 2026-09-23 12:27:22 -04:00
Paul Lorenz 8f9494fad6 Correct quickstart release docs
- documents the release: edited trigger that re-points :latest without rebuilding
- documents that :latest and CloudFront only follow GitHub's Latest release, and the force_latest/force_cloudfront overrides
- corrects the image tag format to X.Y.Z (no leading v)
- notes that each release branch must carry the workflow
2026-09-23 11:29:58 -04:00
Paul Lorenz eb43f60911 Allow a ctrl rateLimiter stanza that does not set minSize
- removes the minSize lower bound that rejected the router's own default of 1,
  which made any ctrl.rateLimiter stanza omitting minSize fail config load
- leaves CtrlRateLimiterMinSizeValue alone, since it also bounds maxSize, and
  documents that it does not bound minSize
- relies on AdaptiveRateLimiterConfig.Load, which already rejects minSize below 1
  or above maxSize
- tests the stanza shapes that used to fail and the bounds that must still reject
2026-09-22 20:29:36 -04:00
Paul Lorenz d895239272 Correct and complete the terminator congestion signaling. For #4155
- adds edgeTerminator.establishStart so the post-establish inspect is timed from
  the bind the sdk is waiting on rather than the last create re-send, which reset
  the clock and skipped the re-inspect for exactly the stalled binds it covers
- gives that gate its own threshold, anchored to the sdk's one minute bind
  deadline rather than to controller load
- brings router-hosted terminators to parity: they resolve a superseded rate
  limit control instead of orphaning its slot, classify establishment latency
  rather than reporting success regardless, and treat a send timeout on the
  remove reply as congestion
- shares one establishment timeout between both registries, which resolve into
  the same limiter and would otherwise feed one window inconsistent signals
- warns at config load when ctrl.rateLimiter.timeout undercuts that threshold,
  where the limiter expires work as congestion before the router can classify it
- describes the remove-path classification accurately: a send-queue timeout is a
  busy channel and it backs off
- tests markEstablishedEvent.handle at the call site, pinning the two clocks
  against each other
2026-09-22 20:29:36 -04:00
Paul Lorenz 928d7a7348 Signal congestion on terminator establish/remove timeouts. Fixes #4155
- measures terminator establishment latency from the last attempt, reporting Backoff to the controller rate limiter at or over the establishment timeout and Success below it, so a stalled establish shrinks the window instead of counting as a success
- resolves a superseded establishment's outstanding rate-limit control with Backoff when a stalled attempt is re-sent, rather than orphaning it
- treats a synchronous terminator-removal reply timeout as congestion (Backoff) instead of a neutral failure, so removals shed load when the controller is slow to respond
2026-09-22 20:29:36 -04:00
Paul Lorenz de01dd226f Merge pull request #4381 from openziti/fix/api-session-enforcer-delete-meter
Mark the api session enforcer delete meter on every delete attempt
2026-09-22 13:52:53 -04:00
Paul Lorenz d2a6631c4c Merge pull request #4435 from openziti/update-to-go-1.27
Update to Go 1.27
2026-09-22 10:42:54 -04:00
Paul Lorenz b6e3cdb95a Update to Go 1.27. Fixes #4434
- bumps the CI toolchain pin from 1.26.x to 1.27.x
- bumps the go directive in go.mod and zititest/go.mod to 1.27.1
2026-09-18 17:35:29 -04:00
Stephen D. Spencer 0294d2f181 fix openziti/ziti#4413 debian package post-install hang (#4414)
* fix openziti/ziti#4413

replaces simple stdin check in the current router and controller postinstall
scripts with typical debconf mechanisms

* change default response for the Configure? diaglog to "true" to maintain
behavioral consistency
2026-09-17 14:00:54 -04:00
Paul Lorenz 7b4cd3d5f0 Merge pull request #4412 from openziti/fix.4410.responder-code-method-value
Log the REST error responder's application code, not a method value
2026-09-17 13:37:33 -04:00