Coverage for frappe_manager / commands / ssl / dns_config / cloudflare.py: 42%

36 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-07-02 18:13 +0530

1"""Cloudflare DNS configuration command.""" 

2 

3from typing import Annotated 

4 

5import typer 

6from typer_examples import example 

7 

8from frappe_manager.output_manager import get_global_output_handler 

9from frappe_manager.ssl_manager import DNS_PROVIDER 

10from frappe_manager.utils.callbacks import sites_autocompletion_callback 

11 

12from ..dns_helpers import _configure_dns_credentials, _remove_dns_credentials, _show_dns_credentials 

13 

14 

15@example( 

16 "Configure global Cloudflare credentials using API Token (recommended)", 

17 "--api-token YOUR_CLOUDFLARE_API_TOKEN", 

18 detail="Stores a global Cloudflare API token for DNS-01 challenges. Recommended for scoped permissions.", 

19) 

20@example( 

21 "Configure global Cloudflare credentials using API Key (legacy)", 

22 "--api-key YOUR_API_KEY --email admin@example.com", 

23 detail="Stores legacy Global API Key credentials; less secure and requires account email.", 

24) 

25@example( 

26 "Configure bench-specific Cloudflare credentials (overrides global)", 

27 "--api-token BENCH_SPECIFIC_TOKEN", 

28 detail="Sets Cloudflare credentials for a specific bench, overriding global configuration.", 

29) 

30@example( 

31 "Show global Cloudflare DNS credentials configuration", 

32 "--show", 

33 detail="Displays stored global Cloudflare credentials (if any).", 

34) 

35@example( 

36 "Show bench-specific Cloudflare DNS credentials", 

37 "--show", 

38 detail="Displays stored Cloudflare credentials for the specified bench.", 

39) 

40@example( 

41 "Remove global Cloudflare DNS credentials", 

42 "--remove", 

43 detail="Removes global Cloudflare credential configuration.", 

44) 

45@example( 

46 "Remove bench-specific Cloudflare DNS credentials", 

47 "--remove", 

48 detail="Removes Cloudflare credential configuration for the specified bench.", 

49) 

50def dns_config_cloudflare( 

51 ctx: typer.Context, 

52 benchname: Annotated[ 

53 str | None, 

54 typer.Argument( 

55 help="Bench name for bench-specific credentials. Omit for global configuration.", 

56 autocompletion=sites_autocompletion_callback, 

57 ), 

58 ] = None, 

59 api_token: Annotated[ 

60 str | None, 

61 typer.Option("--api-token", help="Cloudflare API Token (recommended - scoped permissions)"), 

62 ] = None, 

63 api_key: Annotated[ 

64 str | None, 

65 typer.Option("--api-key", help="Cloudflare Global API Key (legacy - full account access)"), 

66 ] = None, 

67 email: Annotated[ 

68 str | None, 

69 typer.Option("--email", help="Cloudflare account email (required with Global API Key)"), 

70 ] = None, 

71 show: Annotated[ 

72 bool, 

73 typer.Option("--show", "-s", help="Show current Cloudflare DNS credentials"), 

74 ] = False, 

75 remove: Annotated[ 

76 bool, 

77 typer.Option("--remove", "-r", help="Remove Cloudflare DNS credentials"), 

78 ] = False, 

79): 

80 """ 

81 Configure Cloudflare DNS credentials for DNS-01 challenge. 

82 

83 Credentials can be configured at two levels: 

84 - [bold]Global[/bold]: Used by all benches (omit benchname) 

85 - [bold]Bench-specific[/bold]: Override for a specific bench (provide benchname) 

86 

87 [bold cyan]Authentication Methods:[/bold cyan] 

88 

89 1. [green]API Token[/green] (Recommended): 

90 - More secure with scoped permissions 

91 - Create at: https://dash.cloudflare.com/profile/api-tokens 

92 - Template: "Edit zone DNS" 

93 - Required permission: Zone > DNS > Edit 

94 

95 2. [yellow]Global API Key[/yellow] (Legacy): 

96 - Full account access (less secure) 

97 - Requires --email with your Cloudflare account email 

98 - Find at: https://dash.cloudflare.com/profile/api-tokens 

99 """ 

100 provider_name = DNS_PROVIDER.cloudflare.value 

101 

102 # Show configuration 

103 if show: 

104 _show_dns_credentials(ctx, provider_name, benchname) 

105 return 

106 

107 # Remove configuration 

108 if remove: 

109 _remove_dns_credentials(ctx, provider_name, benchname) 

110 return 

111 

112 # Validate Cloudflare-specific credentials 

113 if not api_token and not api_key: 

114 output = get_global_output_handler() 

115 output.display_error("Either [bold]--api-token[/bold] or [bold]--api-key[/bold] must be provided") 

116 output.print("\n[green]Recommended:[/green] Use --api-token for better security and scoped permissions") 

117 output.print("[yellow]Legacy:[/yellow] Use --api-key with --email for Global API Key authentication") 

118 output.print("\n[dim]Create API Token at: https://dash.cloudflare.com/profile/api-tokens[/dim]") 

119 raise typer.Exit(1) 

120 

121 if api_key and not email: 

122 output = get_global_output_handler() 

123 output.display_error("[bold]--email[/bold] is required when using [bold]--api-key[/bold] (Global API Key)") 

124 output.print("\n[yellow]Note:[/yellow] API Key authentication requires your Cloudflare account email") 

125 output.print("[green]Better option:[/green] Use --api-token instead (doesn't require email)") 

126 raise typer.Exit(1) 

127 

128 # Configure credentials 

129 _configure_dns_credentials(ctx, provider_name, benchname, api_token, api_key, email)