Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions src/Migration/Destinations/Appwrite.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
use Utopia\Migration\Resources\Messaging\Provider;
use Utopia\Migration\Resources\Messaging\Subscriber;
use Utopia\Migration\Resources\Messaging\Topic;
use Utopia\Migration\Resources\Settings\ProjectVariable;
use Utopia\Migration\Resources\Sites\Deployment as SiteDeployment;
use Utopia\Migration\Resources\Sites\EnvVar as SiteEnvVar;
use Utopia\Migration\Resources\Sites\Site;
Expand Down Expand Up @@ -278,6 +279,9 @@ public static function getSupportedResources(): array
Resource::TYPE_PLATFORM,
Resource::TYPE_API_KEY,

// Settings
Resource::TYPE_PROJECT_VARIABLE,

// Backups
Resource::TYPE_BACKUP_POLICY,
];
Expand Down Expand Up @@ -438,6 +442,7 @@ protected function import(array $resources, callable $callback): void
Transfer::GROUP_SITES => $this->importSiteResource($resource),
Transfer::GROUP_INTEGRATIONS => $this->importIntegrationsResource($resource),
Transfer::GROUP_BACKUPS => $this->importBackupResource($resource),
Transfer::GROUP_SETTINGS => $this->importSettingsResource($resource),
default => throw new \Exception('Invalid resource group', Exception::CODE_VALIDATION),
};
} catch (\Throwable $e) {
Expand Down Expand Up @@ -3089,6 +3094,61 @@ public function importIntegrationsResource(Resource $resource): Resource
return $resource;
}

public function importSettingsResource(Resource $resource): Resource
{
switch ($resource->getName()) {
case Resource::TYPE_PROJECT_VARIABLE:
/** @var ProjectVariable $resource */
$this->createProjectVariable($resource);
break;
}

if ($resource->getStatus() !== Resource::STATUS_SKIPPED) {
$resource->setStatus(Resource::STATUS_SUCCESS);
}

return $resource;
}

protected function createProjectVariable(ProjectVariable $resource): bool
{
$existing = $this->dbForProject->findOne('variables', [
Query::equal('resourceType', ['project']),
Query::equal('key', [$resource->getKey()]),
]);

if ($existing !== false && !$existing->isEmpty()) {
$resource->setStatus(Resource::STATUS_SKIPPED, 'Project variable already exists');
return false;
}

$createdAt = $this->normalizeDateTime($resource->getCreatedAt());
$updatedAt = $this->normalizeDateTime($resource->getUpdatedAt(), $createdAt);
$variableId = ID::unique();
$key = $resource->getKey();

try {
$this->dbForProject->createDocument('variables', new UtopiaDocument([
'$id' => $variableId,
'$permissions' => $resource->getPermissions(),
'resourceInternalId' => '',
'resourceId' => '',
'resourceType' => 'project',
'key' => $key,
'value' => $resource->getValue(),
'secret' => $resource->isSecret(),
'search' => \implode(' ', [$variableId, $key, 'project']),
'$createdAt' => $createdAt,
'$updatedAt' => $updatedAt,
]));
} catch (DuplicateException) {
$resource->setStatus(Resource::STATUS_SKIPPED, 'Project variable already exists');
return false;
}

return true;
}

/**
* @throws \Throwable
*/
Expand Down
7 changes: 6 additions & 1 deletion src/Migration/Resource.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,12 @@ abstract class Resource implements \JsonSerializable
// Integrations
public const TYPE_PLATFORM = 'platform';
public const TYPE_API_KEY = 'api-key';
public const TYPE_SUBSCRIBER = 'subscriber';

// Settings
public const TYPE_PROJECT_VARIABLE = 'project-variable';

// Messaging
public const TYPE_SUBSCRIBER = 'subscriber';
public const TYPE_MESSAGE = 'message';

// Backups
Expand Down Expand Up @@ -114,6 +118,7 @@ abstract class Resource implements \JsonSerializable
self::TYPE_MEMBERSHIP,
self::TYPE_PLATFORM,
self::TYPE_API_KEY,
self::TYPE_PROJECT_VARIABLE,
self::TYPE_PROVIDER,
self::TYPE_TOPIC,
self::TYPE_SUBSCRIBER,
Expand Down
78 changes: 78 additions & 0 deletions src/Migration/Resources/Settings/ProjectVariable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

namespace Utopia\Migration\Resources\Settings;

use Utopia\Migration\Resource;
use Utopia\Migration\Transfer;

class ProjectVariable extends Resource
{
public function __construct(
string $id,
private readonly string $key,
private readonly string $value = '',
private readonly bool $secret = false,
string $createdAt = '',
string $updatedAt = '',
) {
$this->id = $id;
$this->createdAt = $createdAt;
$this->updatedAt = $updatedAt;
}

/**
* @param array<string, mixed> $array
* @return self
*/
public static function fromArray(array $array): self
{
return new self(
$array['id'],
$array['key'],
$array['value'] ?? '',
(bool) ($array['secret'] ?? false),
createdAt: $array['createdAt'] ?? '',
updatedAt: $array['updatedAt'] ?? '',
);
}

/**
* @return array<string, mixed>
*/
public function jsonSerialize(): array
{
return [
'id' => $this->id,
'key' => $this->key,
'value' => $this->value,
'secret' => $this->secret,
'createdAt' => $this->createdAt,
'updatedAt' => $this->updatedAt,
];
}

public static function getName(): string
{
return Resource::TYPE_PROJECT_VARIABLE;
}

public function getGroup(): string
{
return Transfer::GROUP_SETTINGS;
}

public function getKey(): string
{
return $this->key;
}

public function getValue(): string
{
return $this->value;
}

public function isSecret(): bool
{
return $this->secret;
}
}
17 changes: 17 additions & 0 deletions src/Migration/Source.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ public function getBackupsBatchSize(): int
return static::$defaultBatchSize;
}

public function getSettingsBatchSize(): int
{
return static::$defaultBatchSize;
}

/**
* @param array<Resource> $resources
* @return void
Expand Down Expand Up @@ -121,6 +126,7 @@ public function exportResources(array $resources): void
Transfer::GROUP_SITES => Transfer::GROUP_SITES_RESOURCES,
Transfer::GROUP_INTEGRATIONS => Transfer::GROUP_INTEGRATIONS_RESOURCES,
Transfer::GROUP_BACKUPS => Transfer::GROUP_BACKUPS_RESOURCES,
Transfer::GROUP_SETTINGS => Transfer::GROUP_SETTINGS_RESOURCES,
];

foreach ($mapping as $group => $resources) {
Expand Down Expand Up @@ -161,6 +167,9 @@ public function exportResources(array $resources): void
case Transfer::GROUP_BACKUPS:
$this->exportGroupBackups($this->getBackupsBatchSize(), $resources);
break;
case Transfer::GROUP_SETTINGS:
$this->exportGroupSettings($this->getSettingsBatchSize(), $resources);
break;
}
}
}
Expand Down Expand Up @@ -228,4 +237,12 @@ abstract protected function exportGroupIntegrations(int $batchSize, array $resou
* @param array<string> $resources Resources to export
*/
abstract protected function exportGroupBackups(int $batchSize, array $resources): void;

/**
* Export Settings Group
*
* @param int $batchSize
* @param array<string> $resources Resources to export
*/
abstract protected function exportGroupSettings(int $batchSize, array $resources): void;
}
87 changes: 87 additions & 0 deletions src/Migration/Sources/Appwrite.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
use Utopia\Migration\Resources\Messaging\Provider;
use Utopia\Migration\Resources\Messaging\Subscriber;
use Utopia\Migration\Resources\Messaging\Topic;
use Utopia\Migration\Resources\Settings\ProjectVariable;
use Utopia\Migration\Resources\Sites\Deployment as SiteDeployment;
use Utopia\Migration\Resources\Sites\EnvVar as SiteEnvVar;
use Utopia\Migration\Resources\Sites\Site;
Expand Down Expand Up @@ -214,6 +215,7 @@ public static function getSupportedResources(): array
Resource::TYPE_BACKUP_POLICY,

// Settings
Resource::TYPE_PROJECT_VARIABLE,
];
}

Expand Down Expand Up @@ -254,6 +256,7 @@ public function report(array $resources = [], array $resourceIds = []): array
$this->reportSites($resources, $report, $resourceIds);
$this->reportIntegrations($resources, $report, $resourceIds);
$this->reportBackups($resources, $report, $resourceIds);
$this->reportSettings($resources, $report, $resourceIds);

$report['version'] = $this->call(
'GET',
Expand Down Expand Up @@ -1449,6 +1452,90 @@ protected function reportBackups(array $resources, array &$report, array $resour
}
}

private function reportSettings(array $resources, array &$report, array $resourceIds = []): void
{
if (\in_array(Resource::TYPE_PROJECT_VARIABLE, $resources)) {
$variableQueries = $this->buildQueries(
resourceType: Resource::TYPE_PROJECT_VARIABLE,
resourceIds: $resourceIds,
limit: 1
);
try {
$report[Resource::TYPE_PROJECT_VARIABLE] = $this->project->listVariables($variableQueries)->total;
} catch (\Throwable) {
$report[Resource::TYPE_PROJECT_VARIABLE] = 0;
}
}
}

/**
* @param int $batchSize
* @param array<string> $resources
*/
protected function exportGroupSettings(int $batchSize, array $resources): void
{
if (\in_array(Resource::TYPE_PROJECT_VARIABLE, $resources)) {
try {
$this->exportProjectVariables($batchSize);
} catch (\Throwable $e) {
$this->addError(new Exception(
Resource::TYPE_PROJECT_VARIABLE,
Transfer::GROUP_SETTINGS,
message: $e->getMessage(),
code: $e->getCode(),
previous: $e
));
}
}
}

/**
* @throws AppwriteException
*/
private function exportProjectVariables(int $batchSize): void
{
$lastId = null;

while (true) {
$queries = [Query::limit($batchSize)];

if ($this->rootResourceId !== '' && $this->rootResourceType === Resource::TYPE_PROJECT_VARIABLE) {
$queries[] = Query::equal('$id', $this->rootResourceId);
$queries[] = Query::limit(1);
}

if ($lastId !== null) {
$queries[] = Query::cursorAfter($lastId);
}

$response = $this->project->listVariables($queries);
if ($response->total === 0) {
break;
}

$variables = [];

foreach ($response->variables as $variable) {
$variables[] = new ProjectVariable(
$variable->id,
$variable->key,
$variable->value,
$variable->secret,
createdAt: $variable->createdAt,
updatedAt: $variable->updatedAt,
);

$lastId = $variable->id;
}

$this->callback($variables);

if (\count($response->variables) < $batchSize) {
break;
}
}
}

/**
* @throws AppwriteException
*/
Expand Down
5 changes: 5 additions & 0 deletions src/Migration/Sources/CSV.php
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,11 @@ protected function exportGroupBackups(int $batchSize, array $resources): void
throw new \Exception('Not Implemented');
}

protected function exportGroupSettings(int $batchSize, array $resources): void
{
throw new \Exception('Not Implemented');
}

/**
* @param callable(resource $stream, string $delimiter): void $callback
* @return void
Expand Down
5 changes: 5 additions & 0 deletions src/Migration/Sources/Firebase.php
Original file line number Diff line number Diff line change
Expand Up @@ -827,4 +827,9 @@ protected function exportGroupBackups(int $batchSize, array $resources): void
{
throw new \Exception('Not implemented');
}

protected function exportGroupSettings(int $batchSize, array $resources): void
{
throw new \Exception('Not implemented');
}
}
5 changes: 5 additions & 0 deletions src/Migration/Sources/JSON.php
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,11 @@ protected function exportGroupBackups(int $batchSize, array $resources): void
throw new \Exception('Not Implemented');
}

protected function exportGroupSettings(int $batchSize, array $resources): void
{
throw new \Exception('Not Implemented');
}

/**
* @throws \Exception
*/
Expand Down
5 changes: 5 additions & 0 deletions src/Migration/Sources/NHost.php
Original file line number Diff line number Diff line change
Expand Up @@ -962,4 +962,9 @@ protected function exportGroupBackups(int $batchSize, array $resources): void
{
throw new \Exception('Not Implemented');
}

protected function exportGroupSettings(int $batchSize, array $resources): void
{
throw new \Exception('Not Implemented');
}
}
Loading
Loading