Coverage for frappe_manager / commands / ssl / remove.py: 41%
32 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-07-02 18:13 +0530
« prev ^ index » next coverage.py v7.13.5, created at 2026-07-02 18:13 +0530
1"""Remove SSL certificate command."""
3from typing import Annotated
5import typer
6from typer_examples import example
8from frappe_manager.logger.context import LoggerContext
9from frappe_manager.output_manager import temporary_stop
10from frappe_manager.utils.callbacks import prompt_for_bench_selection, sites_autocompletion_callback
12from .bench_helpers import _remove_bench_certificate
13from .external_helpers import _remove_external_certificate
14from .helpers import get_output_handler
17@example(
18 "Remove SSL certificate from a bench",
19 "{benchname} example.com",
20 detail="Removes the certificate from the bench and its nginx configuration. Use --yes to skip confirmation.",
21 benchname="mybench",
22)
23@example(
24 "Remove without confirmation",
25 "{benchname} example.com --yes",
26 detail="Removes the certificate immediately without prompting for confirmation.",
27 benchname="mybench",
28)
29@example(
30 "Remove external (standalone) certificate",
31 "example.com --standalone",
32 detail="Removes a certificate managed in standalone mode for external Docker projects.",
33)
34def remove_certificate(
35 ctx: typer.Context,
36 benchname: Annotated[
37 str | None,
38 typer.Argument(
39 help="Name of the bench (omit for standalone mode).",
40 autocompletion=sites_autocompletion_callback,
41 ),
42 ] = None,
43 domain: Annotated[str | None, typer.Argument(help="Domain name of the certificate to remove")] = None,
44 yes: Annotated[
45 bool,
46 typer.Option("--yes", "-y", help="Skip confirmation prompt"),
47 ] = False,
48 standalone: Annotated[
49 bool,
50 typer.Option("--standalone", help="Remove certificate for external (non-bench) domain"),
51 ] = False,
52):
53 """
54 Remove an SSL certificate for a domain.
56 Works in bench mode (removes from a bench) or standalone mode for external Docker projects.
57 """
59 if standalone:
60 # Standalone mode: domain can be first arg (as benchname) or second arg
61 actual_domain = domain if domain else benchname
63 if not actual_domain:
64 context = LoggerContext(operation="ssl-remove-external")
65 output = get_output_handler(ctx, context=context)
66 output.display_error("Domain is required in standalone mode")
67 with temporary_stop(output):
68 typer.echo(ctx.get_help())
69 raise typer.Exit(1)
71 _remove_external_certificate(ctx, actual_domain, yes)
72 else:
73 benchname = prompt_for_bench_selection(benchname)
75 if not benchname or not domain:
76 context = LoggerContext(operation="ssl-remove")
77 output = get_output_handler(ctx, context=context)
78 output.display_error("Both benchname and domain are required in bench mode")
79 with temporary_stop(output):
80 typer.echo(ctx.get_help())
81 raise typer.Exit(1)
83 _remove_bench_certificate(ctx, benchname, domain, yes)