-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #23 from shopware/feat-add-fastly-support
feat: add fastly support, fixes #19
- Loading branch information
Showing
15 changed files
with
1,022 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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 |
---|---|---|
@@ -0,0 +1,54 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Shopware\Deployment\Command; | ||
|
||
use Shopware\Deployment\Helper\EnvironmentHelper; | ||
use Shopware\Deployment\Integration\Fastly\FastlyAPIClient; | ||
use Symfony\Component\Console\Attribute\AsCommand; | ||
use Symfony\Component\Console\Command\Command; | ||
use Symfony\Component\Console\Helper\Table; | ||
use Symfony\Component\Console\Input\InputInterface; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
|
||
#[AsCommand( | ||
name: 'fastly:snippet:list', | ||
description: 'List all Fastly snippets' | ||
)] | ||
class FastlySnippetListCommand extends Command | ||
{ | ||
public function __construct(private readonly FastlyAPIClient $fastlyAPIClient) | ||
{ | ||
parent::__construct(); | ||
} | ||
|
||
protected function execute(InputInterface $input, OutputInterface $output): int | ||
{ | ||
$apiToken = EnvironmentHelper::getVariable('FASTLY_API_TOKEN', ''); | ||
$serviceId = EnvironmentHelper::getVariable('FASTLY_SERVICE_ID', ''); | ||
|
||
if ($apiToken === '' || $serviceId === '') { | ||
$output->writeln('FASTLY_API_TOKEN or FASTLY_SERVICE_ID is not set.'); | ||
|
||
return self::FAILURE; | ||
} | ||
|
||
$this->fastlyAPIClient->setApiKey($apiToken); | ||
|
||
$currentlyActiveVersion = $this->fastlyAPIClient->getCurrentlyActiveVersion($serviceId); | ||
|
||
$snippets = $this->fastlyAPIClient->listSnippets($serviceId, $currentlyActiveVersion); | ||
|
||
$table = new Table($output); | ||
$table->setHeaders(['Name', 'Type', 'Priority', 'Last change']); | ||
|
||
foreach ($snippets as $snippet) { | ||
$table->addRow([$snippet['name'], $snippet['type'], $snippet['priority'], $snippet['updated_at']]); | ||
} | ||
|
||
$table->render(); | ||
|
||
return self::SUCCESS; | ||
} | ||
} |
This file contains 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 |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Shopware\Deployment\Command; | ||
|
||
use Shopware\Deployment\Helper\EnvironmentHelper; | ||
use Shopware\Deployment\Integration\Fastly\FastlyAPIClient; | ||
use Symfony\Component\Console\Attribute\AsCommand; | ||
use Symfony\Component\Console\Command\Command; | ||
use Symfony\Component\Console\Input\InputArgument; | ||
use Symfony\Component\Console\Input\InputInterface; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
|
||
#[AsCommand( | ||
name: 'fastly:snippet:remove', | ||
description: 'Remove a Fastly snippet' | ||
)] | ||
class FastlySnippetRemoveCommand extends Command | ||
{ | ||
public function __construct(private readonly FastlyAPIClient $fastlyAPIClient) | ||
{ | ||
parent::__construct(); | ||
} | ||
|
||
protected function configure(): void | ||
{ | ||
$this->addArgument('snippetName', InputArgument::REQUIRED, 'The name of the snippet to remove'); | ||
} | ||
|
||
protected function execute(InputInterface $input, OutputInterface $output): int | ||
{ | ||
$apiToken = EnvironmentHelper::getVariable('FASTLY_API_TOKEN', ''); | ||
$serviceId = EnvironmentHelper::getVariable('FASTLY_SERVICE_ID', ''); | ||
|
||
if ($apiToken === '' || $serviceId === '') { | ||
$output->writeln('FASTLY_API_TOKEN or FASTLY_SERVICE_ID is not set.'); | ||
|
||
return self::FAILURE; | ||
} | ||
|
||
$this->fastlyAPIClient->setApiKey($apiToken); | ||
|
||
$currentlyActiveVersion = $this->fastlyAPIClient->getCurrentlyActiveVersion($serviceId); | ||
|
||
$snippetName = $input->getArgument('snippetName'); | ||
|
||
$newVersionId = $this->fastlyAPIClient->cloneServiceVersion($serviceId, $currentlyActiveVersion); | ||
|
||
$this->fastlyAPIClient->deleteSnippet($serviceId, $newVersionId, $snippetName); | ||
|
||
$this->fastlyAPIClient->activateServiceVersion($serviceId, $newVersionId); | ||
|
||
$output->writeln('Snippet removed.'); | ||
|
||
return self::SUCCESS; | ||
} | ||
} |
This file contains 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
This file contains 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 |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Shopware\Deployment\Event; | ||
|
||
use Shopware\Deployment\Struct\RunConfiguration; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
use Symfony\Component\DependencyInjection\Attribute\Exclude; | ||
|
||
#[Exclude] | ||
readonly class PostDeploy | ||
{ | ||
public function __construct(public readonly RunConfiguration $configuration, public readonly OutputInterface $output) | ||
{ | ||
} | ||
} |
This file contains 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 |
---|---|---|
@@ -0,0 +1,94 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Shopware\Deployment\Integration\Fastly; | ||
|
||
use Symfony\Component\HttpClient\HttpClient; | ||
use Symfony\Contracts\HttpClient\HttpClientInterface; | ||
|
||
/** | ||
* @phpstan-type Snippet array{name: string, type: string, content: string, priority: int, updated_at: string} | ||
*/ | ||
class FastlyAPIClient | ||
{ | ||
private HttpClientInterface $client; | ||
private HttpClientInterface $baseClient; | ||
|
||
public function __construct(?HttpClientInterface $baseClient = null) | ||
{ | ||
$this->baseClient = $baseClient ?? HttpClient::createForBaseUri('https://api.fastly.com'); | ||
} | ||
|
||
public function setApiKey(string $apiKey): void | ||
{ | ||
$this->client = $this->baseClient->withOptions([ | ||
'headers' => [ | ||
'Fastly-Key' => $apiKey, | ||
'Accept' => 'application/json', | ||
], | ||
]); | ||
} | ||
|
||
/** | ||
* @return Snippet[] | ||
*/ | ||
public function listSnippets(string $serviceId, int $version): array | ||
{ | ||
$snippets = $this->client->request('GET', \sprintf('/service/%s/version/%d/snippet', $serviceId, $version))->toArray(); | ||
|
||
return $snippets; | ||
} | ||
|
||
public function createSnippet(string $serviceId, int $version, string $name, string $type, string $content, int $priority): void | ||
{ | ||
$this->client->request('POST', \sprintf('/service/%s/version/%d/snippet', $serviceId, $version), [ | ||
'json' => [ | ||
'name' => $name, | ||
'type' => $type, | ||
'content' => $content, | ||
'dynamic' => 0, | ||
'priority' => $priority, | ||
], | ||
]); | ||
} | ||
|
||
public function updateSnippet(string $serviceId, int $version, string $name, string $type, string $content, int $priority): void | ||
{ | ||
$this->client->request('PUT', \sprintf('/service/%s/version/%d/snippet/%s', $serviceId, $version, $name), [ | ||
'json' => [ | ||
'type' => $type, | ||
'content' => $content, | ||
'priority' => $priority, | ||
], | ||
]); | ||
} | ||
|
||
public function deleteSnippet(string $serviceId, int $version, string $name): void | ||
{ | ||
$this->client->request('DELETE', \sprintf('/service/%s/version/%d/snippet/%s', $serviceId, $version, $name))->toArray(); | ||
} | ||
|
||
public function cloneServiceVersion(string $serviceId, int $version): int | ||
{ | ||
$response = $this->client->request('PUT', \sprintf('/service/%s/version/%d/clone', $serviceId, $version)); | ||
|
||
$data = $response->toArray(); | ||
|
||
return $data['number']; | ||
} | ||
|
||
public function activateServiceVersion(string $serviceId, int $version): void | ||
{ | ||
$this->client->request('PUT', \sprintf('/service/%s/version/%d/activate', $serviceId, $version))->toArray(); | ||
} | ||
|
||
public function getCurrentlyActiveVersion(string $serviceId): int | ||
{ | ||
$response = $this->client->request('GET', \sprintf('/service/%s/version/active', $serviceId)); | ||
|
||
$data = $response->toArray(); | ||
|
||
return $data['number']; | ||
} | ||
} |
This file contains 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 |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Shopware\Deployment\Integration\Fastly; | ||
|
||
use Symfony\Component\DependencyInjection\Attribute\Exclude; | ||
|
||
/** | ||
* @phpstan-import-type Snippet from FastlyAPIClient | ||
*/ | ||
#[Exclude] | ||
class FastlyContext | ||
{ | ||
/** | ||
* @param Snippet[] $snippets | ||
*/ | ||
public function __construct( | ||
public array $snippets, | ||
public string $serviceId, | ||
public int $currentlyActiveVersion, | ||
public ?int $createdVersion = null) | ||
{ | ||
} | ||
|
||
public function hasSnippet(string $snippetName): bool | ||
{ | ||
foreach ($this->snippets as $snippet) { | ||
if ($snippet['name'] === $snippetName) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
public function hasSnippetChanged(string $snippetName, string $content): bool | ||
{ | ||
foreach ($this->snippets as $snippet) { | ||
if ($snippet['name'] === $snippetName && $snippet['content'] !== $content) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
} |
Oops, something went wrong.