Merge pull request #9632 from appwrite/revert-8667-multi-region-support

Revert "Multi region support"
This commit is contained in:
Christy Jacob 2025-04-10 20:55:05 +04:00 committed by GitHub
commit 2d0885ed70
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 40 additions and 91 deletions

1
.env
View file

@ -15,7 +15,6 @@ _APP_SYSTEM_TEAM_EMAIL=team@appwrite.io
_APP_EMAIL_SECURITY=security@appwrite.io _APP_EMAIL_SECURITY=security@appwrite.io
_APP_EMAIL_CERTIFICATES=certificates@appwrite.io _APP_EMAIL_CERTIFICATES=certificates@appwrite.io
_APP_SYSTEM_RESPONSE_FORMAT= _APP_SYSTEM_RESPONSE_FORMAT=
_APP_CUSTOM_DOMAIN_DENY_LIST=
_APP_OPTIONS_ABUSE=disabled _APP_OPTIONS_ABUSE=disabled
_APP_OPTIONS_ROUTER_PROTECTION=disabled _APP_OPTIONS_ROUTER_PROTECTION=disabled
_APP_OPTIONS_FORCE_HTTPS=disabled _APP_OPTIONS_FORCE_HTTPS=disabled

View file

@ -79,15 +79,6 @@ return [
'question' => 'Enter your Appwrite hostname', 'question' => 'Enter your Appwrite hostname',
'filter' => '' 'filter' => ''
], ],
[
'name' => '_APP_CUSTOM_DOMAIN_DENY_LIST',
'description' => 'List of reserved or prohibited domains when configuring custom domains.',
'introduction' => '',
'default' => 'example.com,test.com,app.example.com',
'required' => false,
'question' => '',
'filter' => ''
],
[ [
'name' => '_APP_DOMAIN_FUNCTIONS', 'name' => '_APP_DOMAIN_FUNCTIONS',
'description' => 'A domain to use for function preview URLs. Setting to empty turns off function preview URLs.', 'description' => 'A domain to use for function preview URLs. Setting to empty turns off function preview URLs.',

View file

@ -408,7 +408,6 @@ App::get('/v1/migrations/appwrite/report')
->inject('project') ->inject('project')
->inject('user') ->inject('user')
->action(function (array $resources, string $endpoint, string $projectID, string $key, Response $response) { ->action(function (array $resources, string $endpoint, string $projectID, string $key, Response $response) {
$appwrite = new Appwrite($projectID, $endpoint, $key); $appwrite = new Appwrite($projectID, $endpoint, $key);
try { try {

View file

@ -138,14 +138,6 @@ App::post('/v1/projects')
$databases = Config::getParam('pools-database', []); $databases = Config::getParam('pools-database', []);
if ($region !== 'default') {
$databaseKeys = System::getEnv('_APP_DATABASE_KEYS', '');
$keys = explode(',', $databaseKeys);
$databases = array_filter($keys, function ($value) use ($region) {
return str_contains($value, $region);
});
}
$databaseOverride = System::getEnv('_APP_DATABASE_OVERRIDE'); $databaseOverride = System::getEnv('_APP_DATABASE_OVERRIDE');
$index = \array_search($databaseOverride, $databases); $index = \array_search($databaseOverride, $databases);
if ($index !== false) { if ($index !== false) {
@ -213,17 +205,17 @@ App::post('/v1/projects')
$dsn = new DSN('mysql://' . $dsn); $dsn = new DSN('mysql://' . $dsn);
} }
$adapter = $pools->get($dsn->getHost())->pop()->getResource();
$dbForProject = new Database($adapter, $cache);
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', '')); $sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''));
$sharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES_V1', '')); $sharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES_V1', ''));
$projectTables = !\in_array($dsn->getHost(), $sharedTables); $projectTables = !\in_array($dsn->getHost(), $sharedTables);
$sharedTablesV1 = \in_array($dsn->getHost(), $sharedTablesV1); $sharedTablesV1 = \in_array($dsn->getHost(), $sharedTablesV1);
$sharedTablesV2 = !$projectTables && !$sharedTablesV1; $sharedTablesV2 = !$projectTables && !$sharedTablesV1;
$sharedTables = $sharedTablesV1 || $sharedTablesV2; $sharedTables = $sharedTablesV1 || $sharedTablesV2;
if (!$sharedTablesV2) { if (!$sharedTablesV2) {
$adapter = $pools->get($dsn->getHost())->pop()->getResource();
$dbForProject = new Database($adapter, $cache);
if ($sharedTables) { if ($sharedTables) {
$dbForProject $dbForProject
->setSharedTables(true) ->setSharedTables(true)

View file

@ -55,25 +55,14 @@ App::post('/v1/proxy/rules')
->inject('dbForPlatform') ->inject('dbForPlatform')
->inject('dbForProject') ->inject('dbForProject')
->action(function (string $domain, string $resourceType, string $resourceId, Response $response, Document $project, Certificate $queueForCertificates, Event $queueForEvents, Database $dbForPlatform, Database $dbForProject) { ->action(function (string $domain, string $resourceType, string $resourceId, Response $response, Document $project, Certificate $queueForCertificates, Event $queueForEvents, Database $dbForPlatform, Database $dbForProject) {
$mainDomain = System::getEnv('_APP_DOMAIN', ''); $mainDomain = System::getEnv('_APP_DOMAIN', '');
if ($domain === $mainDomain) { if ($domain === $mainDomain) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'You cannot assign your main domain to specific resource. Please use subdomain or a different domain.'); throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'You cannot assign your main domain to specific resource. Please use subdomain or a different domain.');
} }
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS'); $functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
$denyListDomains = System::getEnv('_APP_CUSTOM_DOMAIN_DENY_LIST'); if ($functionsDomain != '' && str_ends_with($domain, $functionsDomain)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'You cannot assign your functions domain or it\'s subdomain to specific resource. Please use different domain.');
if (!empty($denyListDomains)) {
$functionsDomain .= ',' . $denyListDomains;
}
$deniedDomains = array_map('trim', explode(',', $functionsDomain));
foreach ($deniedDomains as $deniedDomain) {
if (str_ends_with($domain, $deniedDomain)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'You cannot assign your functions domain or its subdomain to a specific resource. Please use a different domain.');
}
} }
if ($domain === 'localhost' || $domain === APP_HOSTNAME_INTERNAL) { if ($domain === 'localhost' || $domain === APP_HOSTNAME_INTERNAL) {

View file

@ -72,19 +72,11 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
} }
if ($route->isEmpty()) { if ($route->isEmpty()) {
if ($host === System::getEnv('_APP_DOMAIN_FUNCTIONS', '')) {
$appDomainFunctionsFallback = System::getEnv('_APP_DOMAIN_FUNCTIONS_FALLBACK', '');
$appDomainFunctions = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
if (!empty($appDomainFunctionsFallback) && \str_ends_with($host, $appDomainFunctionsFallback)) {
$appDomainFunctions = $appDomainFunctionsFallback;
}
if ($host === $appDomainFunctions) {
throw new AppwriteException(AppwriteException::GENERAL_ACCESS_FORBIDDEN, 'This domain cannot be used for security reasons. Please use any subdomain instead.'); throw new AppwriteException(AppwriteException::GENERAL_ACCESS_FORBIDDEN, 'This domain cannot be used for security reasons. Please use any subdomain instead.');
} }
if (\str_ends_with($host, $appDomainFunctions)) { if (\str_ends_with($host, System::getEnv('_APP_DOMAIN_FUNCTIONS', ''))) {
throw new AppwriteException(AppwriteException::GENERAL_ACCESS_FORBIDDEN, 'This domain is not connected to any Appwrite resource yet. Please configure custom domain or function domain to allow this request.'); throw new AppwriteException(AppwriteException::GENERAL_ACCESS_FORBIDDEN, 'This domain is not connected to any Appwrite resource yet. Please configure custom domain or function domain to allow this request.');
} }

View file

@ -534,7 +534,7 @@ App::init()
$data = $cache->load($key, $timestamp); $data = $cache->load($key, $timestamp);
if (!empty($data) && !$cacheLog->isEmpty()) { if (!empty($data) && !$cacheLog->isEmpty()) {
$parts = explode('/', $cacheLog->getAttribute('resourceType', '')); $parts = explode('/', $cacheLog->getAttribute('resourceType'));
$type = $parts[0] ?? null; $type = $parts[0] ?? null;
if ($type === 'bucket' && (!$isImageTransformation || !$isDisabled)) { if ($type === 'bucket' && (!$isImageTransformation || !$isDisabled)) {

16
composer.lock generated
View file

@ -3497,16 +3497,16 @@
}, },
{ {
"name": "utopia-php/database", "name": "utopia-php/database",
"version": "0.64.2", "version": "0.64.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/utopia-php/database.git", "url": "https://github.com/utopia-php/database.git",
"reference": "dc9c4a68c93e8bea2dfaa76d1ba308be539998bd" "reference": "6530a8a6d3c1fe92d0f9a92f0f05eda698d92e0b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/utopia-php/database/zipball/dc9c4a68c93e8bea2dfaa76d1ba308be539998bd", "url": "https://api.github.com/repos/utopia-php/database/zipball/6530a8a6d3c1fe92d0f9a92f0f05eda698d92e0b",
"reference": "dc9c4a68c93e8bea2dfaa76d1ba308be539998bd", "reference": "6530a8a6d3c1fe92d0f9a92f0f05eda698d92e0b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3547,9 +3547,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/utopia-php/database/issues", "issues": "https://github.com/utopia-php/database/issues",
"source": "https://github.com/utopia-php/database/tree/0.64.2" "source": "https://github.com/utopia-php/database/tree/0.64.1"
}, },
"time": "2025-04-09T07:53:05+00:00" "time": "2025-04-02T00:35:29+00:00"
}, },
{ {
"name": "utopia-php/domains", "name": "utopia-php/domains",
@ -8126,7 +8126,7 @@
], ],
"aliases": [], "aliases": [],
"minimum-stability": "stable", "minimum-stability": "stable",
"stability-flags": [], "stability-flags": {},
"prefer-stable": false, "prefer-stable": false,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
@ -8150,5 +8150,5 @@
"platform-overrides": { "platform-overrides": {
"php": "8.3" "php": "8.3"
}, },
"plugin-api-version": "2.2.0" "plugin-api-version": "2.6.0"
} }

View file

@ -198,7 +198,6 @@ services:
- _APP_DATABASE_SHARED_TABLES_V1 - _APP_DATABASE_SHARED_TABLES_V1
- _APP_DATABASE_SHARED_NAMESPACE - _APP_DATABASE_SHARED_NAMESPACE
- _APP_FUNCTIONS_CREATION_ABUSE_LIMIT - _APP_FUNCTIONS_CREATION_ABUSE_LIMIT
- _APP_CUSTOM_DOMAIN_DENY_LIST
extra_hosts: extra_hosts:
- "host.docker.internal:host-gateway" - "host.docker.internal:host-gateway"

View file

@ -351,7 +351,6 @@ class Event
*/ */
public function trigger(): string|bool public function trigger(): string|bool
{ {
if ($this->paused) { if ($this->paused) {
return false; return false;
} }
@ -361,7 +360,6 @@ class Event
// Merge the base payload with any trimmed values // Merge the base payload with any trimmed values
$payload = array_merge($this->preparePayload(), $this->trimPayload()); $payload = array_merge($this->preparePayload(), $this->trimPayload());
return $this->publisher->enqueue($queue, $payload); return $this->publisher->enqueue($queue, $payload);
} }

View file

@ -47,22 +47,15 @@ class Maintenance extends Action
Console::info("[{$time}] Notifying workers with maintenance tasks every {$interval} seconds"); Console::info("[{$time}] Notifying workers with maintenance tasks every {$interval} seconds");
$dbForPlatform->foreach( $dbForPlatform->foreach('projects', function (Document $project) use ($queueForDeletes, $usageStatsRetentionHourly) {
'projects', $queueForDeletes
[ ->setType(DELETE_TYPE_MAINTENANCE)
Query::equal('region', System::getEnv('_APP_REGION', 'default')) ->setProject($project)
], ->setUsageRetentionHourlyDateTime(DateTime::addSeconds(new \DateTime(), -1 * $usageStatsRetentionHourly))
function (Document $project) use ($queueForDeletes, $usageStatsRetentionHourly) { ->trigger();
$queueForDeletes }, [
->setType(DELETE_TYPE_MAINTENANCE) Query::limit(100),
->setProject($project) ]);
->setUsageRetentionHourlyDateTime(DateTime::addSeconds(new \DateTime(), -1 * $usageStatsRetentionHourly))
->trigger();
},
[
Query::limit(100),
]
);
$queueForDeletes $queueForDeletes
->setType(DELETE_TYPE_MAINTENANCE) ->setType(DELETE_TYPE_MAINTENANCE)

View file

@ -67,8 +67,7 @@ class StatsResources extends Action
* For each project that were accessed in last 24 hours * For each project that were accessed in last 24 hours
*/ */
$this->foreachDocument($this->dbForPlatform, 'projects', [ $this->foreachDocument($this->dbForPlatform, 'projects', [
Query::greaterThanEqual('accessedAt', DateTime::format($last24Hours)), Query::greaterThanEqual('accessedAt', DateTime::format($last24Hours))
Query::equal('region', System::getEnv('_APP_REGION', 'default'))
], function ($project) use ($queue) { ], function ($project) use ($queue) {
$queue $queue
->setProject($project) ->setProject($project)

View file

@ -494,22 +494,21 @@ class Deletes extends Action
} }
/** /**
* @param Database $dbForPlatform * @param Database $dbForPlatform
* @param Document $document * @param Document $document
* @return void * @return void
* @throws Authorization * @throws Authorization
* @throws DatabaseException * @throws DatabaseException
* @throws Conflict * @throws Conflict
* @throws Restricted * @throws Restricted
* @throws Structure * @throws Structure
* @throws Exception * @throws Exception
*/ */
protected function deleteProjectsByTeam(Database $dbForPlatform, callable $getProjectDB, CertificatesAdapter $certificates, Document $document): void private function deleteProjectsByTeam(Database $dbForPlatform, callable $getProjectDB, CertificatesAdapter $certificates, Document $document): void
{ {
$projects = $dbForPlatform->find('projects', [ $projects = $dbForPlatform->find('projects', [
Query::equal('teamInternalId', [$document->getInternalId()]), Query::equal('teamInternalId', [$document->getInternalId()])
Query::equal('region', [System::getEnv('_APP_REGION', 'default')])
]); ]);
foreach ($projects as $project) { foreach ($projects as $project) {

View file

@ -70,6 +70,7 @@ class StatsResources extends Action
} }
if (empty($project->getAttribute('database'))) { if (empty($project->getAttribute('database'))) {
var_dump($payload);
return; return;
} }

View file

@ -54,8 +54,6 @@ class Webhooks extends Action
$this->errors = []; $this->errors = [];
$payload = $message->getPayload() ?? []; $payload = $message->getPayload() ?? [];
if (empty($payload)) { if (empty($payload)) {
throw new Exception('Missing payload'); throw new Exception('Missing payload');
} }