installer: restore cell identity prompts and domain setup
Unit Tests / test (push) Successful in 15m39s
Unit Tests / test (push) Successful in 15m39s
Reverts 8d1ef39. The installer must collect cell name, domain mode, and
provider tokens before 'make install' so that DDNS registration,
availability checks, and Caddy TLS can be configured at first boot.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -510,6 +510,11 @@ class ConfigManager:
|
||||
cfg.setdefault('peer_exit_map', {})
|
||||
return dict(cfg)
|
||||
|
||||
def set_ddns_config(self, ddns_cfg: Dict[str, Any]) -> None:
|
||||
"""Replace the top-level ddns section and persist."""
|
||||
self.configs['ddns'] = ddns_cfg
|
||||
self._save_all_configs()
|
||||
|
||||
def set_connectivity_field(self, field: str, value: Any) -> bool:
|
||||
"""Set a single field within the connectivity config and persist."""
|
||||
cfg = self.configs.setdefault('connectivity', {'exits': {}, 'peer_exit_map': {}})
|
||||
|
||||
@@ -55,11 +55,4 @@ def complete_setup():
|
||||
payload = request.get_json(silent=True) or {}
|
||||
result = sm.complete_setup(payload)
|
||||
status_code = 200 if result.get('success') else 400
|
||||
|
||||
# TODO (Phase 3): if result.get('success') and domain_mode == 'pic_ngo':
|
||||
# from app import ddns_manager
|
||||
# name = payload.get('cell_name', '')
|
||||
# ip = payload.get('public_ip', '')
|
||||
# ddns_manager.register(name, ip)
|
||||
|
||||
return jsonify(result), status_code
|
||||
|
||||
+49
-3
@@ -60,6 +60,37 @@ VALID_DOMAIN_MODES = {'pic_ngo', 'cloudflare', 'duckdns', 'http01', 'lan'}
|
||||
CELL_NAME_RE = re.compile(r'^[a-z][a-z0-9-]{1,30}$')
|
||||
|
||||
|
||||
DDNS_API_BASE = os.environ.get('DDNS_URL', 'https://ddns.pic.ngo/api/v1').replace('/api/v1', '')
|
||||
DDNS_TOTP_SECRET = os.environ.get('DDNS_TOTP_SECRET', '')
|
||||
|
||||
|
||||
def _build_ddns_config(domain_mode: str, cloudflare_api_token: str = '',
|
||||
duckdns_token: str = '', duckdns_subdomain: str = '') -> dict:
|
||||
"""Return the top-level ddns config dict for a given domain mode."""
|
||||
if domain_mode == 'pic_ngo':
|
||||
return {
|
||||
'provider': 'pic_ngo',
|
||||
'api_base_url': DDNS_API_BASE,
|
||||
'totp_secret': DDNS_TOTP_SECRET,
|
||||
'enabled': True,
|
||||
}
|
||||
if domain_mode == 'cloudflare':
|
||||
cfg = {'provider': 'cloudflare', 'enabled': True}
|
||||
if cloudflare_api_token:
|
||||
cfg['api_token'] = cloudflare_api_token
|
||||
return cfg
|
||||
if domain_mode == 'duckdns':
|
||||
cfg = {'provider': 'duckdns', 'enabled': True}
|
||||
if duckdns_token:
|
||||
cfg['token'] = duckdns_token
|
||||
if duckdns_subdomain:
|
||||
cfg['subdomain'] = duckdns_subdomain
|
||||
return cfg
|
||||
if domain_mode == 'http01':
|
||||
return {'provider': 'http01', 'enabled': True}
|
||||
return {'provider': 'none', 'enabled': False}
|
||||
|
||||
|
||||
class SetupManager:
|
||||
"""Manages the first-run setup wizard state and completion."""
|
||||
|
||||
@@ -209,10 +240,25 @@ class SetupManager:
|
||||
if duckdns_token:
|
||||
self.config_manager.set_identity_field('duckdns_token', duckdns_token)
|
||||
|
||||
logger.info(
|
||||
'DDNS registration deferred to Phase 3. '
|
||||
f'ddns_provider={ddns_provider!r} domain_name={domain_name!r}'
|
||||
# ── write top-level ddns section so DDNSManager can find provider ──
|
||||
duckdns_sub = domain_name.replace('.duckdns.org', '') if domain_mode == 'duckdns' else ''
|
||||
ddns_cfg = _build_ddns_config(
|
||||
domain_mode,
|
||||
cloudflare_api_token=cloudflare_api_token,
|
||||
duckdns_token=duckdns_token,
|
||||
duckdns_subdomain=duckdns_sub,
|
||||
)
|
||||
self.config_manager.set_ddns_config(ddns_cfg)
|
||||
|
||||
# ── trigger DDNS registration for pic_ngo ─────────────────────────
|
||||
if domain_mode == 'pic_ngo':
|
||||
try:
|
||||
from ddns_manager import DDNSManager
|
||||
ddns_mgr = DDNSManager(self.config_manager)
|
||||
ddns_mgr.register(cell_name, '')
|
||||
logger.info(f'DDNS registered: {cell_name}.pic.ngo')
|
||||
except Exception as exc:
|
||||
logger.warning(f'DDNS registration failed (will retry at next heartbeat): {exc}')
|
||||
|
||||
# ── mark setup complete (must be last) ─────────────────────────
|
||||
self.config_manager.set_identity_field('setup_complete', True)
|
||||
|
||||
Reference in New Issue
Block a user