Coverage for frappe_manager / commands / ssl / dns_helpers.py: 14%
76 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"""Helper functions for DNS provider credential management."""
3import typer
5from frappe_manager.logger.context import LoggerContext
6from frappe_manager.metadata_manager import FMCloudflareConfig, FMConfigManager
7from frappe_manager.output_manager import get_global_output_handler
8from frappe_manager.site_manager.bench_config import DNSProviderConfig
9from frappe_manager.site_manager.site import Bench
10from frappe_manager.ssl_manager import DNS_PROVIDER
12from .helpers import get_output_handler
15def _show_dns_credentials(ctx: typer.Context, provider_name: str, benchname: str | None = None):
16 """Show DNS credentials for a provider."""
17 if benchname:
18 # Show bench-level config
19 services_manager = ctx.obj["services"]
20 context = LoggerContext(bench=benchname, operation="dns-config-show")
21 output = get_output_handler(ctx, context=context)
22 logger = ctx.obj.get("logger")
23 bench = Bench.get_object(benchname, services_manager, logger=logger, output_handler=output)
25 if bench.bench_config.dns_providers and provider_name in bench.bench_config.dns_providers:
26 config = bench.bench_config.dns_providers[provider_name]
27 output.print(f"\n[bold cyan]DNS Credentials for bench '{benchname}':[/bold cyan]", emoji_code="")
28 output.print(f"Provider: [green]{provider_name}[/green]", emoji_code="")
29 output.print(f"Email: {config.email if config.email else '[dim]Not set[/dim]'}", emoji_code="")
30 output.print(
31 f"API Token: {'[green]*** (set)[/green]' if config.api_token else '[dim]Not set[/dim]'}",
32 emoji_code="",
33 )
34 output.print(
35 f"API Key: {'[yellow]*** (set)[/yellow]' if config.api_key else '[dim]Not set[/dim]'}",
36 emoji_code="",
37 )
38 else:
39 output.print(
40 f"\n[yellow]No {provider_name} credentials configured for bench '{benchname}'[/yellow]",
41 emoji_code=":warning:",
42 )
43 output.print("[dim]Falling back to global configuration (if any)[/dim]", emoji_code="")
45 # Show global config (always show, no output handler needed for global info display)
46 fm_config = FMConfigManager.import_from_toml()
47 output = get_global_output_handler()
48 output.print("\n[bold cyan]Global DNS Credentials:[/bold cyan]")
49 output.print(f"Provider: [green]{provider_name}[/green]")
51 if provider_name == DNS_PROVIDER.cloudflare.value:
52 output.print(f"Email: {fm_config.cloudflare.email if fm_config.cloudflare.email else '[dim]Not set[/dim]'}")
53 output.print(
54 f"API Token: {'[green]*** (set)[/green]' if fm_config.cloudflare.api_token else '[dim]Not set[/dim]'}",
55 )
56 output.print(
57 f"API Key: {'[yellow]*** (set)[/yellow]' if fm_config.cloudflare.api_key else '[dim]Not set[/dim]'}",
58 )
61def _remove_dns_credentials(ctx: typer.Context, provider_name: str, benchname: str | None = None):
62 """Remove DNS credentials for a provider."""
63 if benchname:
64 services_manager = ctx.obj["services"]
65 context = LoggerContext(bench=benchname, operation="dns-config-remove")
66 output = get_output_handler(ctx, context=context)
67 logger = ctx.obj.get("logger")
68 bench = Bench.get_object(benchname, services_manager, logger=logger, output_handler=output)
70 if bench.bench_config.dns_providers and provider_name in bench.bench_config.dns_providers:
71 bench.bench_config.dns_providers.pop(provider_name)
72 if not bench.bench_config.dns_providers:
73 bench.bench_config.dns_providers = None
74 bench.bench_config.export_to_toml(bench.bench_config.root_path)
75 output.print(
76 f"Removed [green]{provider_name}[/green] credentials for bench '{benchname}'",
77 emoji_code=":white_check_mark:",
78 )
79 else:
80 output.warning(f"No {provider_name} credentials configured for bench '{benchname}'")
81 else:
82 # Remove global config
83 fm_config = FMConfigManager.import_from_toml()
85 if provider_name == DNS_PROVIDER.cloudflare.value:
86 fm_config.cloudflare = FMCloudflareConfig(email=None, api_token=None, api_key=None)
88 fm_config.export_to_toml()
89 output = get_global_output_handler()
90 output.print(f"✅ Removed global [green]{provider_name}[/green] credentials")
93def _configure_dns_credentials(
94 ctx: typer.Context,
95 provider_name: str,
96 benchname: str | None,
97 api_token: str | None,
98 api_key: str | None,
99 email: str | None,
100):
101 """Configure DNS credentials for a provider."""
102 if benchname:
103 services_manager = ctx.obj["services"]
104 context = LoggerContext(bench=benchname, operation="dns-config")
105 output = get_output_handler(ctx, context=context)
106 logger = ctx.obj.get("logger")
107 bench = Bench.get_object(benchname, services_manager, logger=logger, output_handler=output)
109 output.change_head(f"Configuring {provider_name} credentials for bench '{benchname}'")
111 if not bench.bench_config.dns_providers:
112 bench.bench_config.dns_providers = {}
114 bench.bench_config.dns_providers[provider_name] = DNSProviderConfig(
115 email=email,
116 api_token=api_token,
117 api_key=api_key,
118 )
120 # Save bench config
121 bench.bench_config.export_to_toml(bench.bench_config.root_path)
123 output.print(
124 f"[green]{provider_name}[/green] credentials configured for bench '{benchname}'",
125 emoji_code=":white_check_mark:",
126 )
127 output.print("[dim]These credentials will be used for DNS-01 challenges on this bench[/dim]", emoji_code="")
128 output.print(f"[dim]Saved to: {bench.bench_config.root_path}[/dim]", emoji_code="")
129 else:
130 # Configure global credentials (use output handler for global operations)
131 output = get_global_output_handler()
132 output.change_head(f"Configuring global {provider_name} credentials")
134 fm_config = FMConfigManager.import_from_toml()
136 if provider_name == DNS_PROVIDER.cloudflare.value:
137 fm_config.cloudflare = FMCloudflareConfig(
138 email=email,
139 api_token=api_token,
140 api_key=api_key,
141 )
143 # Save global config
144 fm_config.export_to_toml()
146 output.print(f"✅ Global [green]{provider_name}[/green] credentials configured")
147 output.print("[dim]These credentials will be used by all benches unless overridden at bench level[/dim]")
148 output.print("[dim]Saved to: ~/frappe/fm_config.toml[/dim]")