You've already forked Traefik-Redis-Api
Nothing to see here, move along
This commit is contained in:
@@ -2,6 +2,15 @@ volumes:
|
||||
redisdata: {}
|
||||
|
||||
services:
|
||||
composer-runtime:
|
||||
ports:
|
||||
- "9501:9501"
|
||||
volumes:
|
||||
- .:/app
|
||||
image: siteworxpro/composer
|
||||
entrypoint: "/bin/sh -c 'while true; do sleep 30; done;'"
|
||||
environment:
|
||||
PHP_IDE_CONFIG: serverName=localhost
|
||||
dev-runtime:
|
||||
ports:
|
||||
- "9501:9501"
|
||||
|
||||
@@ -71,21 +71,4 @@ class RoutesController extends Controller
|
||||
|
||||
return JsonResponseFactory::createJsonResponse(['message' => 'Router deleted successfully']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \JsonException
|
||||
*/
|
||||
public function patch(ServerRequest $request): ResponseInterface
|
||||
{
|
||||
$name = $request->getAttribute('id');
|
||||
$data = $request->getParsedBody();
|
||||
|
||||
try {
|
||||
RedisClient::patchEntity($name, $data, EntityEnum::ROUTER, $this->protocolEnumFromRequest($request));
|
||||
} catch (\InvalidArgumentException) {
|
||||
return JsonResponseFactory::createJsonResponse(['error' => 'Router not found'], 404);
|
||||
}
|
||||
|
||||
return JsonResponseFactory::createJsonResponse(['message' => 'Router updated successfully']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,6 @@ class Server
|
||||
$router->get('/', RoutesController::class . '::get');
|
||||
$router->get('/{id}', RoutesController::class . '::get');
|
||||
$router->post('/{id}', RoutesController::class . '::post');
|
||||
$router->patch('/{id}', RoutesController::class . '::patch');
|
||||
$router->delete('/{id}', RoutesController::class . '::delete');
|
||||
});
|
||||
|
||||
|
||||
@@ -41,66 +41,6 @@ class RedisClient
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param array $data
|
||||
* @param EntityEnum $entity
|
||||
* @param ProtocolEnum $type
|
||||
* @return void
|
||||
*/
|
||||
public static function patchEntity(
|
||||
string $name,
|
||||
array $data,
|
||||
EntityEnum $entity,
|
||||
ProtocolEnum $type = ProtocolEnum::HTTP
|
||||
): void {
|
||||
$collection = self::flattenToDotArray($data);
|
||||
|
||||
$checkKey = 'traefik/' . $type->getValue() . '/' . $entity->getValue() . "/$name";
|
||||
|
||||
$keys = Redis::keys($checkKey . '/*');
|
||||
if (empty($keys)) {
|
||||
throw new \InvalidArgumentException("The key $checkKey does not exist.");
|
||||
}
|
||||
|
||||
$cleanedUpKeys = [];
|
||||
|
||||
foreach ($collection as $key => $value) {
|
||||
// regex if key matches [key].[digit]
|
||||
if (preg_match('/\.[0-9]+$/', $key)) {
|
||||
$arrayKey = preg_replace('/\.[0-9]+$/', '', $key);
|
||||
|
||||
if (in_array($arrayKey, $cleanedUpKeys)) {
|
||||
$redisKey = 'traefik/' .
|
||||
$type->getValue() .
|
||||
'/' .
|
||||
$entity->getValue() .
|
||||
"/$name/" .
|
||||
str_replace('.', '/', $key);
|
||||
|
||||
Redis::set($redisKey, $value);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// key is an array, delete keys under array
|
||||
$arrayKeys = Redis::keys($checkKey . '/' . str_replace('.', '/', $arrayKey) . '/*');
|
||||
foreach ($arrayKeys as $k) {
|
||||
Redis::del($k);
|
||||
}
|
||||
|
||||
$cleanedUpKeys[] = $arrayKey;
|
||||
}
|
||||
|
||||
$redisKey = 'traefik/' .
|
||||
$type->getValue() . '/' . $entity->getValue() .
|
||||
"/$name/" .
|
||||
str_replace('.', '/', $key);
|
||||
|
||||
Redis::set($redisKey, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param EntityEnum $entity
|
||||
|
||||
@@ -40,4 +40,16 @@ class JsonResponseFactoryTest extends TestCase
|
||||
$data = ["invalid" => "\xB1\x31"];
|
||||
JsonResponseFactory::createJsonResponse($data);
|
||||
}
|
||||
|
||||
public function testCreateResponseReturnsValidResponse(): void
|
||||
{
|
||||
$code = 200;
|
||||
$reasonPhrase = 'OK';
|
||||
|
||||
$factory = new JsonResponseFactory();
|
||||
$response = $factory->createResponse($code, $reasonPhrase);
|
||||
|
||||
$this->assertSame($code, $response->getStatusCode());
|
||||
$this->assertSame('application/json', $response->getHeaderLine('Content-Type'));
|
||||
}
|
||||
}
|
||||
|
||||
102
tests/Traefik/MiddlewareServiceTest.php
Normal file
102
tests/Traefik/MiddlewareServiceTest.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Siteworxpro\Tests\Traefik;
|
||||
|
||||
use Mockery;
|
||||
use Predis\Command\FactoryInterface;
|
||||
use Siteworxpro\App\Facades\Redis;
|
||||
use Siteworxpro\App\Traefik\ProtocolEnum;
|
||||
use Siteworxpro\App\Traefik\RedisClient;
|
||||
use Siteworxpro\Tests\Unit;
|
||||
|
||||
class MiddlewareServiceTest extends Unit
|
||||
{
|
||||
|
||||
public function testGerMiddlewareHttpAll(): void
|
||||
{
|
||||
$this->getAllMiddleware(ProtocolEnum::HTTP);
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testGetMiddlewareTcpAll(): void
|
||||
{
|
||||
$this->getAllMiddleware(ProtocolEnum::TCP);
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
private function getAllMiddleware(ProtocolEnum $protocolEnum): void
|
||||
{
|
||||
$commandFactory = Mockery::mock(FactoryInterface::class)
|
||||
->expects('supports')
|
||||
->andReturn(true)
|
||||
->getMock();
|
||||
|
||||
Redis::expects('getCommandFactory')
|
||||
->andReturn($commandFactory);
|
||||
|
||||
Redis::expects('scan')
|
||||
->with(0, ['MATCH' => 'traefik/' . $protocolEnum->getValue() . '/middlewares/*'])
|
||||
->andReturn([0, [
|
||||
'traefik/' . $protocolEnum->getValue() . '/middlewares/foo/headers/customrequestheaders/Host',
|
||||
'traefik/' . $protocolEnum->getValue() . '/middlewares/foo/headers/customrequestheaders/X-Forwarded-Host',
|
||||
'traefik/' . $protocolEnum->getValue() . '/middlewares/foo/headers/customrequestheaders/X-Forwarded-Port',
|
||||
'traefik/' . $protocolEnum->getValue() . '/middlewares/foo/headers/customrequestheaders/X-Forwarded-Proto',
|
||||
]]);
|
||||
|
||||
$services = RedisClient::getAllMiddlewares($protocolEnum);
|
||||
$this->assertCount(1, $services);
|
||||
$this->assertSame('foo', $services[0]);
|
||||
}
|
||||
|
||||
|
||||
public function testGetMiddlewareHttp()
|
||||
{
|
||||
$this->getIndMiddleware(ProtocolEnum::HTTP);
|
||||
}
|
||||
|
||||
private function getIndMiddleware(ProtocolEnum $protocolEnum): void
|
||||
{
|
||||
$commandFactory = Mockery::mock(FactoryInterface::class)
|
||||
->expects('supports')
|
||||
->andReturn(true)
|
||||
->getMock();
|
||||
|
||||
Redis::expects('getCommandFactory')
|
||||
->andReturn($commandFactory);
|
||||
|
||||
Redis::expects('scan')
|
||||
->with(0, ['MATCH' => 'traefik/' . $protocolEnum->getValue() . '/middlewares/foo/*'])
|
||||
->andReturn([0, [
|
||||
'traefik/' . $protocolEnum->getValue() . '/middlewares/foo/headers/customrequestheaders/Host',
|
||||
'traefik/' . $protocolEnum->getValue() . '/middlewares/foo/headers/customrequestheaders/X-Forwarded-Host',
|
||||
'traefik/' . $protocolEnum->getValue() . '/middlewares/foo/headers/customrequestheaders/X-Forwarded-Port',
|
||||
'traefik/' . $protocolEnum->getValue() . '/middlewares/foo/headers/customrequestheaders/X-Forwarded-Proto',
|
||||
]]);
|
||||
|
||||
Redis::expects('get')
|
||||
->with('traefik/' . $protocolEnum->getValue() . '/middlewares/foo/headers/customrequestheaders/Host')
|
||||
->andReturn('foo.localhost');
|
||||
|
||||
Redis::expects('get')
|
||||
->with('traefik/' . $protocolEnum->getValue() . '/middlewares/foo/headers/customrequestheaders/X-Forwarded-Host')
|
||||
->andReturn('foo.localhost');
|
||||
|
||||
Redis::expects('get')
|
||||
->with('traefik/' . $protocolEnum->getValue() . '/middlewares/foo/headers/customrequestheaders/X-Forwarded-Port')
|
||||
->andReturn('80');
|
||||
|
||||
Redis::expects('get')
|
||||
->with('traefik/' . $protocolEnum->getValue() . '/middlewares/foo/headers/customrequestheaders/X-Forwarded-Proto')
|
||||
->andReturn('http');
|
||||
|
||||
$middleware = RedisClient::getMiddleware('foo', $protocolEnum);
|
||||
|
||||
$this->assertCount(4, $middleware['headers']['customrequestheaders']);
|
||||
$this->assertSame('foo.localhost', $middleware['headers']['customrequestheaders']['Host']);
|
||||
$this->assertSame('foo.localhost', $middleware['headers']['customrequestheaders']['X-Forwarded-Host']);
|
||||
$this->assertSame('80', $middleware['headers']['customrequestheaders']['X-Forwarded-Port']);
|
||||
$this->assertSame('http', $middleware['headers']['customrequestheaders']['X-Forwarded-Proto']);
|
||||
}
|
||||
}
|
||||
19
tests/Traefik/ProtocolEnumTest.php
Normal file
19
tests/Traefik/ProtocolEnumTest.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Siteworxpro\Tests\Traefik;
|
||||
|
||||
use Siteworxpro\App\Traefik\ProtocolEnum;
|
||||
use Siteworxpro\Tests\Unit;
|
||||
|
||||
class ProtocolEnumTest extends Unit
|
||||
{
|
||||
|
||||
public function testFromString(): void
|
||||
{
|
||||
$this->assertEquals(ProtocolEnum::HTTP, ProtocolEnum::fromString('http'));
|
||||
$this->assertEquals(ProtocolEnum::TCP, ProtocolEnum::fromString('tcp'));
|
||||
$this->assertEquals(ProtocolEnum::UDP, ProtocolEnum::fromString('udp'));
|
||||
}
|
||||
}
|
||||
@@ -68,6 +68,58 @@ class RedisClientRoutersTest extends Unit
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testGetOneHttp(): void
|
||||
{
|
||||
$this->getOneTest(ProtocolEnum::HTTP);
|
||||
}
|
||||
|
||||
public function testGetOneTcp(): void
|
||||
{
|
||||
$this->getOneTest(ProtocolEnum::TCP);
|
||||
}
|
||||
|
||||
public function testGetOneUdp(): void
|
||||
{
|
||||
$this->getOneTest(ProtocolEnum::UDP);
|
||||
}
|
||||
|
||||
private function getOneTest(ProtocolEnum $protocolEnum): void
|
||||
{
|
||||
$commandFactory = Mockery::mock(FactoryInterface::class)
|
||||
->expects('supports')
|
||||
->andReturn(true)
|
||||
->getMock();
|
||||
|
||||
Redis::expects('getCommandFactory')
|
||||
->andReturn($commandFactory);
|
||||
|
||||
Redis::expects('scan')
|
||||
->with(0, ['MATCH' => 'traefik/' . $protocolEnum->getValue() . '/routers/foo/*'])
|
||||
->andReturn([0, [
|
||||
'traefik/' . $protocolEnum->getValue() . '/routers/foo/rule',
|
||||
'traefik/' . $protocolEnum->getValue() . '/routers/foo/service',
|
||||
]]);
|
||||
|
||||
Redis::expects('get')
|
||||
->with('traefik/' . $protocolEnum->getValue() . '/routers/foo/rule')
|
||||
->andReturn('Host(`foo.localhost`)');
|
||||
|
||||
Redis::expects('get')
|
||||
->with('traefik/' . $protocolEnum->getValue() . '/routers/foo/service')
|
||||
->andReturn('foo');
|
||||
|
||||
$routers = RedisClient::getRouter('foo', $protocolEnum);
|
||||
|
||||
$this->assertIsArray($routers);
|
||||
|
||||
$this->assertCount(2, $routers);
|
||||
|
||||
$this->assertEquals([
|
||||
'rule' => 'Host(`foo.localhost`)',
|
||||
'service' => 'foo',
|
||||
], $routers);
|
||||
}
|
||||
|
||||
private function allTest(ProtocolEnum $protocol): void
|
||||
{
|
||||
$commandFactory = Mockery::mock(FactoryInterface::class)
|
||||
|
||||
143
tests/Traefik/RedisClientServiceTest.php
Normal file
143
tests/Traefik/RedisClientServiceTest.php
Normal file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Siteworxpro\Tests\Traefik;
|
||||
|
||||
use Mockery;
|
||||
use Predis\Command\FactoryInterface;
|
||||
use Siteworxpro\App\Facades\Redis;
|
||||
use Siteworxpro\App\Traefik\EntityEnum;
|
||||
use Siteworxpro\App\Traefik\ProtocolEnum;
|
||||
use Siteworxpro\App\Traefik\RedisClient;
|
||||
use Siteworxpro\Tests\Unit;
|
||||
|
||||
class RedisClientServiceTest extends Unit
|
||||
{
|
||||
|
||||
public function testCreateServiceHttp(): void
|
||||
{
|
||||
$this->createTest(ProtocolEnum::HTTP);
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testCreateServiceTcp(): void
|
||||
{
|
||||
$this->createTest(ProtocolEnum::TCP);
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testCreateServiceUdp(): void
|
||||
{
|
||||
$this->createTest(ProtocolEnum::UDP);
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
|
||||
public function createTest(ProtocolEnum $protocol): void
|
||||
{
|
||||
|
||||
$commandFactory = Mockery::mock(FactoryInterface::class)
|
||||
->expects('supports')
|
||||
->andReturn(true)
|
||||
->getMock();
|
||||
|
||||
Redis::expects('getCommandFactory')
|
||||
->andReturn($commandFactory);
|
||||
|
||||
Redis::expects('scan')
|
||||
->with(0, ['MATCH' => 'traefik/' . $protocol->getValue() . '/services/foo/*'])
|
||||
->andReturn([0, []]);
|
||||
|
||||
Redis::expects('set')
|
||||
->with('traefik/' . $protocol->getValue() . '/services/foo/loadbalancer/servers/server1/url', 'http://foo.localhost:80')
|
||||
->once()
|
||||
->andReturn(true);
|
||||
|
||||
RedisClient::createOrReplace('foo', [
|
||||
'loadbalancer' => [
|
||||
'servers' => [
|
||||
'server1' => [
|
||||
'url' => 'http://foo.localhost:80',
|
||||
],
|
||||
],
|
||||
],
|
||||
], EntityEnum::SERVICE, $protocol);
|
||||
}
|
||||
|
||||
public function testGetOneHttp(): void
|
||||
{
|
||||
$this->runGet(ProtocolEnum::HTTP);
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testGetOneTcp(): void
|
||||
{
|
||||
$this->runGet(ProtocolEnum::TCP);
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testGetOneUdp(): void
|
||||
{
|
||||
$this->runGet(ProtocolEnum::UDP);
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
private function runGet(ProtocolEnum $protocol): void
|
||||
{
|
||||
$commandFactory = Mockery::mock(FactoryInterface::class)
|
||||
->expects('supports')
|
||||
->andReturn(true)
|
||||
->getMock();
|
||||
|
||||
Redis::expects('getCommandFactory')
|
||||
->andReturn($commandFactory);
|
||||
|
||||
Redis::expects('scan')
|
||||
->with(0, ['MATCH' => 'traefik/' . $protocol->getValue() . '/services/foo/*'])
|
||||
->andReturn([0, [
|
||||
'traefik/' . $protocol->getValue() . '/services/foo/loadbalancer/servers/server1/url',
|
||||
]]);
|
||||
|
||||
Redis::expects('get')
|
||||
->with('traefik/' . $protocol->getValue() . '/services/foo/loadbalancer/servers/server1/url')
|
||||
->andReturn('http://foo.localhost:80');
|
||||
|
||||
$services = RedisClient::getService('foo', $protocol);
|
||||
|
||||
$this->assertIsArray($services);
|
||||
$this->assertArrayHasKey('loadbalancer', $services);
|
||||
$this->assertArrayHasKey('servers', $services['loadbalancer']);
|
||||
$this->assertArrayHasKey('server1', $services['loadbalancer']['servers']);
|
||||
$this->assertEquals('http://foo.localhost:80', $services['loadbalancer']['servers']['server1']['url']);
|
||||
}
|
||||
|
||||
public function testGetAllHttp()
|
||||
{
|
||||
$this->runGetAll(ProtocolEnum::HTTP);
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
private function runGetAll(ProtocolEnum $protocol): void
|
||||
{
|
||||
$commandFactory = Mockery::mock(FactoryInterface::class)
|
||||
->expects('supports')
|
||||
->andReturn(true)
|
||||
->getMock();
|
||||
|
||||
Redis::expects('getCommandFactory')
|
||||
->andReturn($commandFactory);
|
||||
|
||||
Redis::expects('scan')
|
||||
->with(0, ['MATCH' => 'traefik/' . $protocol->getValue() . '/services/*'])
|
||||
->andReturn([0, [
|
||||
'traefik/' . $protocol->getValue() . '/services/foo/loadbalancer/servers/server1/url',
|
||||
'traefik/' . $protocol->getValue() . '/services/bar/loadbalancer/servers/server2/url',
|
||||
]]);
|
||||
|
||||
$services = RedisClient::getAllServices($protocol);
|
||||
|
||||
$this->assertIsArray($services);
|
||||
$this->assertCount(2, $services);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user