Skip to content

chore: allow tenant cleanup script to skip control plane if tenant not found#7290

Merged
wenxi-onyx merged 6 commits intomainfrom
whuang/allow-tenant-cleanup-force-to-skip-control-plane
Jan 10, 2026
Merged

chore: allow tenant cleanup script to skip control plane if tenant not found#7290
wenxi-onyx merged 6 commits intomainfrom
whuang/allow-tenant-cleanup-force-to-skip-control-plane

Conversation

@wenxi-onyx
Copy link
Copy Markdown
Member

@wenxi-onyx wenxi-onyx commented Jan 8, 2026

Description

How Has This Been Tested?

Additional Options

  • [Optional] Override Linear Check

Summary by cubic

Allow tenant cleanup and connector-marking scripts to skip control plane steps when the tenant is not found in the control plane. In force mode, we continue with data plane only; otherwise we prompt.

  • New Features

    • Detect tenant not found in control plane (missing table or record) and raise TenantNotFoundInControlPlaneError.
    • In --force, skip control-plane steps and proceed with data plane cleanup.
    • In non-force, prompt before proceeding.
    • Applied to bastion and no-bastion scripts, including mark-connectors.
  • Migration

    • No-bastion scripts now require --data-plane-context and --control-plane-context.

Written for commit 3e7ce56. Summary will update on new commits.

@wenxi-onyx wenxi-onyx requested a review from a team as a code owner January 8, 2026 19:18
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

2 issues found across 4 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="backend/scripts/tenant_cleanup/no_bastion_cleanup_tenants.py">

<violation number="1" location="backend/scripts/tenant_cleanup/no_bastion_cleanup_tenants.py:494">
P1: Missing `tenant_not_found_in_control_plane = True` in interactive mode. When user confirms to continue after "tenant not found in control plane", the flag remains False, causing Step 3 to unnecessarily attempt control plane cleanup which will fail or have unexpected behavior.</violation>
</file>

<file name="backend/scripts/tenant_cleanup/cleanup_tenants.py">

<violation number="1" location="backend/scripts/tenant_cleanup/cleanup_tenants.py:476">
P2: Missing `tenant_not_found_in_control_plane = True` after user confirms to continue. In non-force mode, if the user acknowledges the tenant wasn't found and confirms to continue, the flag should also be set so Step 3 skips control plane cleanup (matching force mode behavior).</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

greptile-apps[bot]

This comment was marked as outdated.

Copy link
Copy Markdown
Contributor

@jmelahman jmelahman left a comment

Choose a reason for hiding this comment

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

many small nits and I think they're all optional. Please do at least read them though

except TenantNotFoundInControlPlaneError as e:
# Tenant/table not found in control plane
error_str = str(e)
print(f"⚠️ WARNING: Tenant not found in control plane: {error_str}")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this is fine, but it's probably preferred to use a logger for these so they're sent to stderr by default. slightly less likely to be missed that way

from pathlib import Path


class TenantNotFoundInControlPlaneError(Exception):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this is fine, but very nitpicky: it's nice to keep exceptions in a dedicated module. that's much more important with public interfaces though which this isn't really

error_msg = e.stderr if e.stderr else str(e)
print(
f"✗ Failed to get tenant status for {tenant_id}: {e}",
f"✗ Failed to get tenant status for {tenant_id}: {error_msg}",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: while you're here wanna convert to an emoji for visibility (ideally just a colored logger imo but im boring)

print(
"Usage: PYTHONPATH=. python scripts/tenant_cleanup/"
"no_bastion_mark_connectors.py <tenant_id> [--force] [--concurrency N]"
"no_bastion_mark_connectors.py <tenant_id> \\"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

i know you're not introducing these prints, but the python argparser is pretty extensible and supports custom long messages. this is like a decades old pattern left over from shell scripting

cmd = ["kubectl", "get", "po"]
if context:
cmd.extend(["--context", context])
cmd = ["kubectl", "get", "po", "--context", context]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

optional nitpick, but this would be so much better with a KubectlHelper class that stored the "kubectl" (preferably as /usr/bin/kubectl) command and context as private variables.

"Error: --data-plane-context is required",
file=sys.stderr,
)
sys.exit(1)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: i personally prefer raise SystemExit(1)

if confirm_step(
# Step 3: Clean up control plane (skip if tenant not found in control plane with --force)
if tenant_not_found_in_control_plane:
print(f"\n{'=' * 80}")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: I feel like this would be safer without an f-string

sys.exit(1)

# Parse contexts
# Parse contexts (required)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nitttt: these really should be required by the argparser and the corresponding types should not be optional



def setup_scripts_on_pod(pod_name: str, context: str | None = None) -> None:
def setup_scripts_on_pod(pod_name: str, context: str) -> None:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

its hard to tell if this was required for this change, but would have been really nice as a separate change so the behavioral changes related to skipping the control plane were more prominent

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This was required. The intention of this script is to do actions in both planes, but the script would attempt to access control plane via data plane pods (which is impossible).

@wenxi-onyx wenxi-onyx added this pull request to the merge queue Jan 10, 2026
Merged via the queue into main with commit c7fc1cd Jan 10, 2026
74 of 75 checks passed
@wenxi-onyx wenxi-onyx deleted the whuang/allow-tenant-cleanup-force-to-skip-control-plane branch January 10, 2026 00:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants