121 lines
4.1 KiB
PHP
121 lines
4.1 KiB
PHP
|
|
<?php
|
|||
|
|
/**
|
|||
|
|
* Cloudflare 域名自动化回归(CLI 输出 JSON,Mock HTTP)
|
|||
|
|
*/
|
|||
|
|
$root = dirname(__DIR__);
|
|||
|
|
require_once $root . '/cong.php';
|
|||
|
|
require_once $root . '/lib/Cloak/DomainRepository.php';
|
|||
|
|
require_once $root . '/lib/Cloak/CloudflareConfig.php';
|
|||
|
|
require_once $root . '/lib/Cloak/CloudflareClient.php';
|
|||
|
|
require_once $root . '/lib/Cloak/DomainProvisioningService.php';
|
|||
|
|
|
|||
|
|
class MockCloudflareClient extends CloudflareClient
|
|||
|
|
{
|
|||
|
|
public $zoneStatus = 'pending';
|
|||
|
|
public $deleteCalled = false;
|
|||
|
|
public $upsertCalls = [];
|
|||
|
|
|
|||
|
|
public function __construct()
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public function createZone($hostname)
|
|||
|
|
{
|
|||
|
|
return [
|
|||
|
|
'ok' => true,
|
|||
|
|
'result' => [
|
|||
|
|
'id' => 'zone_mock_' . md5($hostname),
|
|||
|
|
'name_servers' => ['ada.ns.cloudflare.com', 'bob.ns.cloudflare.com'],
|
|||
|
|
],
|
|||
|
|
];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public function getZone($zoneId)
|
|||
|
|
{
|
|||
|
|
return [
|
|||
|
|
'ok' => true,
|
|||
|
|
'result' => [
|
|||
|
|
'id' => $zoneId,
|
|||
|
|
'status' => $this->zoneStatus,
|
|||
|
|
'name_servers' => ['ada.ns.cloudflare.com', 'bob.ns.cloudflare.com'],
|
|||
|
|
],
|
|||
|
|
];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public function deleteZone($zoneId)
|
|||
|
|
{
|
|||
|
|
$this->deleteCalled = true;
|
|||
|
|
return ['ok' => true, 'result' => ['id' => $zoneId]];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public function upsertARecord($zoneId, $fqdn, $ip, $proxied = true)
|
|||
|
|
{
|
|||
|
|
$this->upsertCalls[] = compact('zoneId', 'fqdn', 'ip', 'proxied');
|
|||
|
|
return ['ok' => true, 'result' => ['id' => 'rec_' . md5($fqdn)]];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public function setSslFlexible($zoneId)
|
|||
|
|
{
|
|||
|
|
return ['ok' => true];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public function setAlwaysHttps($zoneId)
|
|||
|
|
{
|
|||
|
|
return ['ok' => true];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$tests = [];
|
|||
|
|
$host = 'cf-mock-' . substr(md5((string) microtime(true)), 0, 8) . '.test';
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
$pdo = DomainRepository::pdo();
|
|||
|
|
DomainRepository::ensureTable($pdo);
|
|||
|
|
|
|||
|
|
// 未启用 CF:添加后 cf_status=local
|
|||
|
|
CloudflareConfig::clearTestOverrides();
|
|||
|
|
DomainProvisioningService::clearClientOverride();
|
|||
|
|
$addLocal = DomainProvisioningService::provisionOnAdd($pdo, $host);
|
|||
|
|
$rowLocal = DomainRepository::findById($pdo, (int) ($addLocal['id'] ?? 0));
|
|||
|
|
$tests['add_local_cf_status'] = ($addLocal['ok'] ?? false) === true
|
|||
|
|
&& ($addLocal['cf_status'] ?? '') === 'local'
|
|||
|
|
&& ($rowLocal['cf_status'] ?? '') === 'local';
|
|||
|
|
DomainRepository::deleteById($pdo, (int) $addLocal['id']);
|
|||
|
|
|
|||
|
|
// Mock:pending_ns → ready
|
|||
|
|
CloudflareConfig::setTestOverrides(['enabled' => true, 'server_ip' => '203.0.113.10']);
|
|||
|
|
$mock = new MockCloudflareClient();
|
|||
|
|
DomainProvisioningService::setClientOverride($mock);
|
|||
|
|
|
|||
|
|
$addCf = DomainProvisioningService::provisionOnAdd($pdo, $host);
|
|||
|
|
$domainId = (int) ($addCf['id'] ?? 0);
|
|||
|
|
$tests['add_cf_pending_ns'] = ($addCf['ok'] ?? false) === true
|
|||
|
|
&& ($addCf['cf_status'] ?? '') === 'pending_ns'
|
|||
|
|
&& count($addCf['nameservers'] ?? []) === 2;
|
|||
|
|
|
|||
|
|
$pending = DomainProvisioningService::checkAndProvision($pdo, $domainId);
|
|||
|
|
$tests['check_pending_ns'] = ($pending['ok'] ?? false) === true
|
|||
|
|
&& ($pending['status'] ?? '') === 'pending_ns';
|
|||
|
|
|
|||
|
|
$mock->zoneStatus = 'active';
|
|||
|
|
$ready = DomainProvisioningService::checkAndProvision($pdo, $domainId);
|
|||
|
|
$rowReady = DomainRepository::findById($pdo, $domainId);
|
|||
|
|
$tests['check_ready'] = ($ready['ok'] ?? false) === true
|
|||
|
|
&& ($ready['status'] ?? '') === 'ready'
|
|||
|
|
&& ($rowReady['cf_status'] ?? '') === 'ready'
|
|||
|
|
&& count($mock->upsertCalls) === 2;
|
|||
|
|
|
|||
|
|
$del = DomainProvisioningService::deleteWithCloudflare($pdo, $domainId);
|
|||
|
|
$tests['delete_calls_zone'] = ($del['ok'] ?? false) === true && $mock->deleteCalled === true;
|
|||
|
|
$tests['delete_row_gone'] = DomainRepository::findById($pdo, $domainId) === null;
|
|||
|
|
} catch (Throwable $e) {
|
|||
|
|
$tests['exception'] = false;
|
|||
|
|
$tests['error'] = $e->getMessage();
|
|||
|
|
} finally {
|
|||
|
|
CloudflareConfig::clearTestOverrides();
|
|||
|
|
DomainProvisioningService::clearClientOverride();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$ok = !in_array(false, $tests, true) && !isset($tests['error']);
|
|||
|
|
echo json_encode(['ok' => $ok, 'tests' => $tests], JSON_UNESCAPED_UNICODE) . "\n";
|