Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions cortexapps_cli/commands/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,22 +123,29 @@ def delete(
client.delete("api/v1/catalog/" + tag)

@app.command()
def delete_by_type(
def delete_by_id(
ctx: typer.Context,
types: CatalogCommandOptions.types = None,
ids: Optional[List[str]] = typer.Option(None, "--id", "-i", help="CID of an entity to delete (e.g. en2da8159dbeefb974). Can be specified multiple times.", show_default=False),
file_input: Annotated[Optional[typer.FileText], typer.Option("--file", "-f", help="File containing one CID per line; can be passed as stdin with -, example: -f-")] = None,
batch_size: int = typer.Option(100, "--batch-size", hidden=True, help="Number of IDs per API call when processing file input"),
):
"""
Dangerous operation that will delete all entities that are of the given type
Delete entities by CID. Accepts one or more --id flags, or a file with one CID per line.
"""
client = ctx.obj["client"]
if ids and file_input:
raise typer.BadParameter("Specify either --id or --file, not both")

#TODO: check if types is a regex of form: ([-A-Za-z]+,)+
if not ids and not file_input:
raise typer.BadParameter("One of --id or --file is required")

params = {
"types": types
}
client = ctx.obj["client"]

client.delete("api/v1/catalog", params=params)
if file_input:
all_ids = [line.strip() for line in file_input if line.strip()]
for i in range(0, len(all_ids), batch_size):
client.delete("api/v1/catalog", params={"ids": all_ids[i:i + batch_size]})
else:
client.delete("api/v1/catalog", params={"ids": ids})

@app.command()
def descriptor(
Expand Down
5 changes: 0 additions & 5 deletions data/run-time/catalog-delete-by-type-entity.yaml

This file was deleted.

6 changes: 0 additions & 6 deletions data/run-time/entity-type-delete-by-type.json

This file was deleted.

59 changes: 59 additions & 0 deletions tests/test_catalog_delete_by_id.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from tests.helpers.utils import *
import tempfile
import os

def _create_entity(tag):
content = f"""openapi: 3.0.1
info:
title: Delete By ID Test Entity
x-cortex-tag: {tag}
x-cortex-type: service
"""
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
f.write(content)
return f.name

def test_delete_by_id_flag():
tag = "cli-test-delete-by-id-flag"
path = _create_entity(tag)
try:
cli(["catalog", "create", "-f", path])

response = cli(["catalog", "details", "-t", tag])
cid = response['id']
assert cid.startswith("en"), f"Expected a CID starting with 'en', got: {cid}"

cli(["catalog", "delete-by-id", "--id", cid])

response = cli(["catalog", "details", "-t", tag], ReturnType.RAW)
assert "HTTP Error 404:" in response.stdout, "Entity should be deleted (404 expected)"
finally:
os.unlink(path)

def test_delete_by_id_file():
tag1 = "cli-test-delete-by-id-file-1"
tag2 = "cli-test-delete-by-id-file-2"
path1 = _create_entity(tag1)
path2 = _create_entity(tag2)
try:
cli(["catalog", "create", "-f", path1])
cli(["catalog", "create", "-f", path2])

cid1 = cli(["catalog", "details", "-t", tag1])['id']
cid2 = cli(["catalog", "details", "-t", tag2])['id']

with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as f:
f.write(f"{cid1}\n{cid2}\n")
ids_file = f.name

try:
cli(["catalog", "delete-by-id", "--file", ids_file])

for tag in [tag1, tag2]:
response = cli(["catalog", "details", "-t", tag], ReturnType.RAW)
assert "HTTP Error 404:" in response.stdout, f"Entity {tag} should be deleted (404 expected)"
finally:
os.unlink(ids_file)
finally:
os.unlink(path1)
os.unlink(path2)
20 changes: 0 additions & 20 deletions tests/test_catalog_delete_by_type.py

This file was deleted.

Loading