Skip to main content

tare uninstall

Tear down the TARS dataplane from a Kubernetes cluster.


Synopsis

tare uninstall <identity-file> [flags]

Description

tare uninstall reverses tare install in a single command. After a successful run, the Helm release is gone, the tars-system and tars-dataplane namespaces have been removed, and the CRDs the install brought have been deleted.

This is mostly a cluster-only operation, with one management-plane side channel: after helm uninstall runs (phase 2), the CLI reports the uninstall event to MP so the workspace's deployment history reflects it. See Management-plane event reporting below.

tare uninstall does not:

  • Deregister the dataplane URL from your workspace.
  • Revoke the service-account identity.
  • Touch the management-plane database directly (beyond the install-event side channel, which is bounded to the dataplane_install_events table).

If you need to clean up the dataplane URL registration or the SA identity, use the dashboard or the tars sa command.

helm and kubectl are downloaded automatically on first run into ~/.tare/tools/ if they are not already on PATH.

Phases

[1/6] Preflight (Helm 3+, kubectl, cluster)
[2/6] helm uninstall <release> -n <system-namespace>
└── after helm uninstall: sync-POST uninstall event to MP
(CM fallback on 5xx; see "Management-plane event reporting" below)
[3/6] Patch finalizers in tars-system / tars-dataplane + delete GatewayClass tars-egress
[4/6] Delete namespaces (system, dataplane)
[5/6] Wait for namespaces to disappear
[6/6] Delete TARS-owned CRDs (skipped under the multi-DP guard; see --force)

Phase ordering is deliberate:

  • Phase 3 runs before phase 4 so the namespace delete in phase 4 has no blockers. We enumerate the namespaced resource kinds in the chart's API groups (aigateway.envoyproxy.io, tars.tetrate.ai, gateway.networking.k8s.io, gateway.envoyproxy.io), list any in both tars-system and tars-dataplane that carry finalizers, and patch metadata.finalizers: [] on them. Both namespaces are covered: tars-system holds the bulk of the chart's CRs and controllers, but tars-dataplane can also hold finalizer-bearing resources such as EnvoyPatchPolicy.
  • Phase 4 deletes the namespaces which sweeps every namespaced resource in one stroke. Immediately after issuing each delete, we clear the namespace's .spec.finalizers via the /finalize subresource: the standard "force a stuck namespace through" technique. Safe here because we have already patched all resource finalizers and the goal of the command is to tear the namespaces down.
  • Phase 5 polls for the namespaces to disappear.
  • Phase 6 deletes CRDs, by which point no CRs of any owned kind exist, so CRD deletion has nothing left to wait on.

Examples

# Standard teardown with confirmation prompt.
tare uninstall identity.json

# Non-interactive (CI).
tare uninstall identity.json --yes

# Stuck finalizers: bypass controller cleanup and patch them empty.
tare uninstall identity.json --yes --force

# Multi-DP cluster: leave CRDs in place so other releases keep working.
tare uninstall identity.json --yes --keep-crds

# Preview without touching the cluster.
tare uninstall identity.json --dry-run

Flags

FlagDefaultDescription
--keep-crdsfalseLeave CRDs in place. Use on shared / multi-DP clusters.
--forcefalseOverride the multi-DP guard and delete CRDs even when other releases share them.
--yesfalseSkip the typed-confirmation prompt.
--timeout5mPer-phase wait timeout.
--dry-runfalsePrint the plan and run helm uninstall --dry-run; no cluster mutation.
--skip-preflight (hidden)falseSkip Helm/kubectl/cluster preflight (also TARE_SKIP_PREFLIGHT=1).
--release-name (hidden)tarsHelm release name.
--system-namespace (hidden)tars-systemKubernetes system namespace.
--dataplane-namespace (hidden)tars-dataplaneKubernetes dataplane namespace.

Inherited from root: --verbose, --quiet.

What gets deleted

Namespaced resources (cleared via the namespace delete in phase 4):

  • All objects in tars-system and tars-dataplane, including the image-pull secret created by tare install --image-pull-secret-stdin.

Cluster-scoped resources (explicit deletes):

  • GatewayClass/tars-egress
  • CRDs in groups aigateway.envoyproxy.io and tars.tetrate.ai

What is preserved

  • CRDs in gateway.networking.k8s.io (commonly platform-managed; GKE, distro bundles, etc.).
  • CRDs in gateway.envoyproxy.io (Envoy Gateway distribution, often shared).
  • Any namespaces, secrets, or ConfigMaps outside tars-system and tars-dataplane that an operator created independently.
  • Management-plane state, except for the single new row appended to dataplane_install_events (one row per uninstall, see Management-plane event reporting).

Management-plane event reporting

Between phase [2/6] (helm uninstall) and phase [3/6] (finalizer sweep), tare uninstall reports the operation to the management plane:

  1. Read the pre-uninstall Helm revision (preRev) so the event payload can carry the helm_revision that matches the install / upgrade events in the workspace's deployment history. The PK is unrecoverable once helm uninstall has run, which is why the read happens before phase 2.
  2. After helm uninstall returns, sync-POST the event to POST /v1/dataplane-install-events on the management plane, signed with the identity file's SA token.
  3. On 2xx: bump the tars-doctor-install-event-state ConfigMap so the doctor's reconciler doesn't re-emit a synthetic event on its next tick, then continue with phases 3–6.
  4. On 5xx or network failure: write a ConfigMap to tars-system labelled tars.io/component=install-event, same shape as the install / upgrade outbox CMs. The tare-doctor cron in that cluster would normally pick it up on the next tick, but the namespace is about to be deleted in phase 4, so the CM may not survive long enough to be forwarded. This is a documented gap (see ADR 046 §10): the dashboard timeline may not show an uninstall row in this failure case.
  5. On 4xx: log a warning and skip the fallback (the next retry would re-reject with the same error). The CLI continues teardown.

The event POST never blocks teardown, never changes the CLI's exit code, and never re-prompts. The dataplane is removed regardless of whether the management plane could be reached.

Configured via the identity file's apiUri. No env var override is honored on this code path (the doctor's TARE_DOCTOR_API_URI only affects in-cluster forwarding, not CLI-side uninstall reporting).

Confirmation prompt

By default tare uninstall prints the plan and asks the operator to type the system namespace name to confirm. Use --yes to skip in automation.

About to uninstall TARS dataplane:

Identity: identity.json (client_email: [email protected])
Release: tars
System namespace: tars-system
Dataplane: tars-dataplane
CRDs: will be deleted (aigateway.envoyproxy.io, tars.tetrate.ai)

Touches MP: appends one row to dataplane_install_events (operation=uninstall) after helm uninstall.
NOT touched: dataplane URL registration, SA identity revocation, image-pull secrets outside the namespaces above.

Type the system namespace name (tars-system) to confirm: _

Stuck finalizers

The TARS CRs (AIGatewayRoute, MCPRoute, BackendSecurityPolicy, etc.) and GatewayClass/tars-egress carry finalizers that the dataplane controllers normally clear during a graceful delete. After phase 2's helm uninstall removes those controllers, the finalizers can never clear on their own: the only reconciler that could is gone.

For this reason, tare uninstall automatically patches metadata.finalizers: [] on any CR or GatewayClass that remains after a brief poll. This is the only path to completion at that point and does not require --force.

The patch bypasses controller cleanup hooks (egress backends may remain registered with external services, telemetry exports may not be flushed). That is the unavoidable cost of teardown; the same cost applies whether you patch via tare uninstall or via kubectl patch by hand.

Multi-DP guard

Before deleting CRDs in phase 6, tare uninstall runs helm list -A and checks for other releases of the same chart. Behaviour:

SituationEffect
No other TARS releasesCRDs are deleted.
Other releases found, --force not setCRDs skipped. Other releases remain functional. Command exits 0 with a warning.
Other releases found, --force setCRDs deleted anyway. Other releases will break.
--keep-crds setPhase 6 skipped unconditionally. No detection run.

Dry run

--dry-run prints the plan, runs helm uninstall --dry-run, lists the CRs that would be drained, lists the CRDs that would be deleted (or notes the multi-DP skip), and names the namespaces that would be removed. No mutating calls (kubectl delete, kubectl patch, helm uninstall without --dry-run) are made.

Exit codes

  • 0: Success, or "nothing to do" (release already absent).
  • 1: Phase failed; see error message.