-
Notifications
You must be signed in to change notification settings - Fork 56
CLI-1631: validating backup link before importing database #1958
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
+566
−57
Closed
Changes from 23 commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
faaad8a
validating backup link before importing database
kalindi-adhiya 37e199c
test failing fix
kalindi-adhiya 0a58a1d
code cov improvement
kalindi-adhiya 0f22eba
code cov improvment
kalindi-adhiya 343becc
code cov improvement
kalindi-adhiya 3bd4c75
code cov fix
kalindi-adhiya 4275303
corrected import
kalindi-adhiya 39a8333
updated testcases for windows
kalindi-adhiya c767a92
widows test fix
kalindi-adhiya ccb527a
windows test failing: fix
kalindi-adhiya 4433969
windows test fix
kalindi-adhiya c293862
windows test fix
kalindi-adhiya db07310
Merge branch 'main' into CLI-1631
jigar-shah-acquia c6ab7ff
addressed co pilot reviews
kalindi-adhiya 394f17e
addressed reviews: removed gzip and empty file validations
kalindi-adhiya 95d55fe
mutation fix
kalindi-adhiya e9198b3
mutation fix
kalindi-adhiya 79f56b7
mutation fix
kalindi-adhiya eee2337
mutation fix
kalindi-adhiya 32e4306
mutation fix
kalindi-adhiya 549cebf
windows test fix
kalindi-adhiya 262088b
mutation fix
kalindi-adhiya 3b22ba8
mutation fix
kalindi-adhiya 4dffde7
Update src/Command/Pull/PullCommandBase.php
kalindi-adhiya 5c42e98
addressed co pilot comments
kalindi-adhiya 051c5c6
mutation fix
kalindi-adhiya 494e4cc
mutation fix
kalindi-adhiya 77a4588
Merge branch 'main' into CLI-1631
kalindi-adhiya File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -68,6 +68,28 @@ public function __construct( | |
| parent::__construct($this->localMachineHelper, $this->datastoreCloud, $this->datastoreAcli, $this->cloudCredentials, $this->telemetryHelper, $this->projectDir, $this->cloudApiClientService, $this->sshHelper, $this->sshDir, $logger, $this->selfUpdateManager); | ||
| } | ||
|
|
||
| /** | ||
| * Get the backup download URL. | ||
| * This is primarily used for testing purposes. | ||
| */ | ||
| public function getBackupDownloadUrl(): ?UriInterface | ||
| { | ||
| return $this->backupDownloadUrl ?? null; | ||
| } | ||
|
|
||
| /** | ||
| * Set the backup download URL. | ||
| * This is primarily used for testing purposes. | ||
| */ | ||
| public function setBackupDownloadUrl(string|UriInterface $url): void | ||
| { | ||
| if (is_string($url)) { | ||
| $this->backupDownloadUrl = new \GuzzleHttp\Psr7\Uri($url); | ||
| } else { | ||
| $this->backupDownloadUrl = $url; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * @see https://github.com/drush-ops/drush/blob/c21a5a24a295cc0513bfdecead6f87f1a2cf91a2/src/Sql/SqlMysql.php#L168 | ||
| * @return string[] | ||
|
|
@@ -96,20 +118,25 @@ private function listTablesQuoted(string $out): array | |
|
|
||
| public static function getBackupPath(object $environment, DatabaseResponse $database, object $backupResponse): string | ||
| { | ||
| // Databases have a machine name not exposed via the API; we can only | ||
| // approximately reconstruct it and match the filename you'd get downloading | ||
| // a backup from Cloud UI. | ||
| if ($database->flags->default) { | ||
| $dbMachineName = $database->name . $environment->name; | ||
| } else { | ||
| $dbMachineName = 'db' . $database->id; | ||
| } | ||
| $filename = implode('-', [ | ||
| $environment->name, | ||
| $database->name, | ||
| $dbMachineName, | ||
| $backupResponse->completedAt, | ||
| ]) . '.sql.gz'; | ||
| if (PHP_OS_FAMILY === 'Windows') { | ||
danepowell marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // Use short filename to comply with 8.3 format and avoid long path issues. | ||
| // The hash-based filename still preserves the '.sql.gz' extension. | ||
| $hash = substr(md5($environment->name . $database->name . $dbMachineName . $backupResponse->completedAt), 0, 8); | ||
| $filename = $hash . '.sql.gz'; | ||
| } else { | ||
| $completedAtFormatted = $backupResponse->completedAt; | ||
| $filename = implode('-', [ | ||
| $environment->name, | ||
| $database->name, | ||
| $dbMachineName, | ||
| $completedAtFormatted, | ||
| ]) . '.sql.gz'; | ||
| } | ||
| return Path::join(sys_get_temp_dir(), $filename); | ||
| } | ||
|
|
||
|
|
@@ -261,19 +288,21 @@ static function (mixed $totalBytes, mixed $downloadedBytes) use (&$progress, $ou | |
| if ($codebaseUuid) { | ||
| // Download the backup file directly from the provided URL. | ||
| $downloadUrl = $backupResponse->links->download->href; | ||
| $this->httpClient->request('GET', $downloadUrl, [ | ||
| $response = $this->httpClient->request('GET', $downloadUrl, [ | ||
| 'progress' => static function (mixed $totalBytes, mixed $downloadedBytes) use (&$progress, $output): void { | ||
| self::displayDownloadProgress($totalBytes, $downloadedBytes, $progress, $output); | ||
| }, | ||
| 'sink' => $localFilepath, | ||
| ]); | ||
| $this->validateDownloadResponse($response, $localFilepath); | ||
| return $localFilepath; | ||
| } | ||
| $acquiaCloudClient->stream( | ||
| "get", | ||
| "/environments/$environment->uuid/databases/$database->name/backups/$backupResponse->id/actions/download", | ||
| $acquiaCloudClient->getOptions() | ||
| ); | ||
| $this->validateDownloadedFile($localFilepath); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are calling this function at two different places, try to reduce code redundancy. |
||
| return $localFilepath; | ||
| } catch (RequestException $exception) { | ||
| // Deal with broken SSL certificates. | ||
|
|
@@ -308,14 +337,49 @@ static function (mixed $totalBytes, mixed $downloadedBytes) use (&$progress, $ou | |
| throw new AcquiaCliException('Could not download backup'); | ||
| } | ||
|
|
||
| public function setBackupDownloadUrl(UriInterface $url): void | ||
| /** | ||
| * Validates the HTTP response from a database backup download request. | ||
| * | ||
| * @param \Psr\Http\Message\ResponseInterface $response The HTTP response object | ||
| * @param string $localFilepath The local file path where the backup was downloaded | ||
| * @throws \Acquia\Cli\Exception\AcquiaCliException If the response is invalid | ||
| */ | ||
| private function validateDownloadResponse(object $response, string $localFilepath): void | ||
| { | ||
| $this->backupDownloadUrl = $url; | ||
| $statusCode = $response->getStatusCode(); | ||
kalindi-adhiya marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| // Check for successful HTTP response. | ||
| if ($statusCode !== 200) { | ||
kalindi-adhiya marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // Clean up the potentially corrupted file. | ||
| if (file_exists($localFilepath)) { | ||
| $this->localMachineHelper->getFilesystem()->remove($localFilepath); | ||
| } | ||
| throw new AcquiaCliException( | ||
| 'Database backup download failed with HTTP status {status}. Please try again or contact support.', | ||
kalindi-adhiya marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
kalindi-adhiya marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ['status' => $statusCode] | ||
| ); | ||
| } | ||
|
|
||
| // Validate the downloaded file. | ||
| $this->validateDownloadedFile($localFilepath); | ||
| } | ||
|
|
||
| private function getBackupDownloadUrl(): ?UriInterface | ||
| /** | ||
| * Validates that the downloaded backup file exists. | ||
| * | ||
| * @param string $localFilepath The local file path to validate | ||
| * @throws \Acquia\Cli\Exception\AcquiaCliException If the file is invalid | ||
| */ | ||
| private function validateDownloadedFile(string $localFilepath): void | ||
| { | ||
| return $this->backupDownloadUrl ?? null; | ||
| // Check if file exists. | ||
| if (!file_exists($localFilepath)) { | ||
| throw new AcquiaCliException( | ||
| 'Database backup download failed: file was not created.' | ||
kalindi-adhiya marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ); | ||
| } | ||
|
|
||
| // File exists - assume it's valid since it comes from trusted Acquia API. | ||
| } | ||
|
|
||
| public static function displayDownloadProgress(mixed $totalBytes, mixed $downloadedBytes, mixed &$progress, OutputInterface $output): void | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.