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

1"""Remove SSL certificate command.""" 

2 

3from typing import Annotated 

4 

5import typer 

6from typer_examples import example 

7 

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 

11 

12from .bench_helpers import _remove_bench_certificate 

13from .external_helpers import _remove_external_certificate 

14from .helpers import get_output_handler 

15 

16 

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. 

55 

56 Works in bench mode (removes from a bench) or standalone mode for external Docker projects. 

57 """ 

58 

59 if standalone: 

60 # Standalone mode: domain can be first arg (as benchname) or second arg 

61 actual_domain = domain if domain else benchname 

62 

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) 

70 

71 _remove_external_certificate(ctx, actual_domain, yes) 

72 else: 

73 benchname = prompt_for_bench_selection(benchname) 

74 

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) 

82 

83 _remove_bench_certificate(ctx, benchname, domain, yes)