mirror of
https://github.com/appwrite/appwrite
synced 2026-05-24 09:28:40 +00:00
Add logs to rules
This commit is contained in:
parent
08e4bb5e18
commit
e7351f4eec
5 changed files with 42 additions and 16 deletions
|
|
@ -3064,10 +3064,10 @@ $collections = [
|
|||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('log'),
|
||||
'$id' => ID::custom('logs'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16384,
|
||||
'size' => 1000000,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
|
|
|
|||
|
|
@ -106,6 +106,8 @@ App::post('/v1/proxy/rules')
|
|||
|
||||
$events->setParam('ruleId', $rule->getId());
|
||||
|
||||
$rule->setAttribute('logs', '');
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($rule, Response::MODEL_PROXY_RULE);
|
||||
|
|
@ -154,8 +156,14 @@ App::get('/v1/proxy/rules')
|
|||
|
||||
$filterQueries = Query::groupByType($queries)['filters'];
|
||||
|
||||
$rules = $dbForConsole->find('rules', $queries);
|
||||
foreach ($rules as $rule) {
|
||||
$certificate = $dbForConsole->getDocument('certificates', $rule->getAttribute('certificateId', ''));
|
||||
$rule->setAttribute('logs', $certificate->getAttribute('logs', ''));
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'rules' => $dbForConsole->find('rules', $queries),
|
||||
'rules' => $rules,
|
||||
'total' => $dbForConsole->count('rules', $filterQueries, APP_LIMIT_COUNT),
|
||||
]), Response::MODEL_PROXY_RULE_LIST);
|
||||
});
|
||||
|
|
@ -182,6 +190,9 @@ App::get('/v1/proxy/rules/:ruleId')
|
|||
throw new Exception(Exception::RULE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$certificate = $dbForConsole->getDocument('certificates', $rule->getAttribute('certificateId', ''));
|
||||
$rule->setAttribute('logs', $certificate->getAttribute('logs', ''));
|
||||
|
||||
$response->dynamic($rule, Response::MODEL_PROXY_RULE);
|
||||
});
|
||||
|
||||
|
|
@ -278,5 +289,8 @@ App::patch('/v1/proxy/rules/:ruleId/verification')
|
|||
|
||||
$events->setParam('ruleId', $rule->getId());
|
||||
|
||||
$certificate = $dbForConsole->getDocument('certificates', $rule->getAttribute('certificateId', ''));
|
||||
$rule->setAttribute('logs', $certificate->getAttribute('logs', ''));
|
||||
|
||||
$response->dynamic($rule, Response::MODEL_PROXY_RULE);
|
||||
});
|
||||
|
|
@ -43,7 +43,9 @@ Config::setParam('domainVerification', false);
|
|||
Config::setParam('cookieDomain', 'localhost');
|
||||
Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE);
|
||||
|
||||
function router(Database $dbForConsole, string $host, SwooleRequest $swooleRequest, Response $response) {
|
||||
function router(Database $dbForConsole, SwooleRequest $swooleRequest, Response $response) {
|
||||
$host = $swooleRequest->header['host'] ?? '';
|
||||
|
||||
$route = Authorization::skip(
|
||||
fn() => $dbForConsole->find('rules', [
|
||||
Query::equal('domain', [$host]),
|
||||
|
|
@ -66,6 +68,12 @@ function router(Database $dbForConsole, string $host, SwooleRequest $swooleReque
|
|||
}
|
||||
}
|
||||
|
||||
// Skip Appwrite Router for ACME challenge. Nessessary for certificate generation
|
||||
$path = ($swooleRequest->server['request_uri'] ?? '');
|
||||
if(\str_starts_with($path, '/.well-known/acme-challenge')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$type = $route->getAttribute('resourceType');
|
||||
|
||||
if($type === 'function') {
|
||||
|
|
@ -164,7 +172,7 @@ App::init()
|
|||
$mainDomain = App::getEnv('_APP_DOMAIN', '');
|
||||
// Only run Router when external domain
|
||||
if($host !== $mainDomain && $host !== 'localhost') {
|
||||
if(router($dbForConsole, $host, $swooleRequest, $response)) {
|
||||
if(router($dbForConsole, $swooleRequest, $response)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -454,7 +462,7 @@ App::options()
|
|||
$mainDomain = App::getEnv('_APP_DOMAIN', '');
|
||||
// Only run Router when external domain
|
||||
if($host !== $mainDomain && $host !== 'localhost') {
|
||||
if(router($dbForConsole, $host, $swooleRequest, $response)) {
|
||||
if(router($dbForConsole, $swooleRequest, $response)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -660,7 +668,6 @@ App::get('/humans.txt')
|
|||
$response->text($template->render(false));
|
||||
});
|
||||
|
||||
// TODO: @Meldiron this must run before Appwrite Router. Router makes it NOT get here. But it needs to. This must be endpoint reserved by Appwrite for certificate generation and re-generation
|
||||
App::get('/.well-known/acme-challenge')
|
||||
->desc('SSL Verification')
|
||||
->label('scope', 'public')
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class CertificatesV1 extends Worker
|
|||
* 4. Validate security email. Cannot be empty, required by LetsEncrypt
|
||||
* 5. Validate renew date with certificate file, unless requested to skip by parameter
|
||||
* 6. Issue a certificate using certbot CLI
|
||||
* 7. Update 'log' attribute on certificate document with Certbot message
|
||||
* 7. Update 'logs' attribute on certificate document with Certbot message
|
||||
* 8. Create storage folder for certificate, if not ready already
|
||||
* 9. Move certificates from Certbot location to our Storage
|
||||
* 10. Create/Update our Storage with new Traefik config with new certificate paths
|
||||
|
|
@ -57,7 +57,7 @@ class CertificatesV1 extends Worker
|
|||
* If at any point unexpected error occurs, program stops without applying changes to document, and error is thrown into worker
|
||||
*
|
||||
* If code stops with expected error:
|
||||
* 1. 'log' attribute on document is updated with error message
|
||||
* 1. 'logs' attribute on document is updated with error message
|
||||
* 2. 'attempts' amount is increased
|
||||
* 3. Console log is shown
|
||||
* 4. Email is sent to security email
|
||||
|
|
@ -113,11 +113,8 @@ class CertificatesV1 extends Worker
|
|||
$letsEncryptData = $this->issueCertificate($folder, $domain->get(), $email);
|
||||
|
||||
// Command succeeded, store all data into document
|
||||
// We store stderr too, because it may include warnings
|
||||
$certificate->setAttribute('log', \json_encode([
|
||||
'stdout' => $letsEncryptData['stdout'],
|
||||
'stderr' => $letsEncryptData['stderr'],
|
||||
]));
|
||||
$logs = 'Certificate successfully generated.';
|
||||
$certificate->setAttribute('logs', \mb_strcut($logs, 0, 1000000));// Limit to 1MB
|
||||
|
||||
// Give certificates to Traefik
|
||||
$this->applyCertificateFiles($folder, $domain->get(), $letsEncryptData);
|
||||
|
|
@ -129,8 +126,10 @@ class CertificatesV1 extends Worker
|
|||
|
||||
$success = true;
|
||||
} catch (Throwable $e) {
|
||||
$logs = $e->getMessage();
|
||||
|
||||
// Set exception as log in certificate document
|
||||
$certificate->setAttribute('log', $e->getMessage());
|
||||
$certificate->setAttribute('logs', \mb_strcut($logs, 0, 1000000));// Limit to 1MB
|
||||
|
||||
// Increase attempts count
|
||||
$attempts = $certificate->getAttribute('attempts', 0) + 1;
|
||||
|
|
@ -280,7 +279,7 @@ class CertificatesV1 extends Worker
|
|||
$stderr = '';
|
||||
|
||||
$staging = (App::isProduction()) ? '' : ' --dry-run';
|
||||
$exit = Console::execute("certbot certonly --webroot --noninteractive --agree-tos{$staging}"
|
||||
$exit = Console::execute("certbot certonly -v --webroot --noninteractive --agree-tos{$staging}"
|
||||
. " --email " . $email
|
||||
. " --cert-name " . $folder
|
||||
. " -w " . APP_STORAGE_CERTIFICATES
|
||||
|
|
|
|||
|
|
@ -54,6 +54,12 @@ class Rule extends Model
|
|||
'default' => false,
|
||||
'example' => 'verified',
|
||||
])
|
||||
->addRule('logs', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Certificate generation logs. This will return an empty string if generation did not run, or succeeded.',
|
||||
'default' => '',
|
||||
'example' => 'HTTP challegne failed.',
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue