Skip to content

Commit 212b6e0

Browse files
committed
feat: #28 allow to add redirect rules
1 parent bad4e73 commit 212b6e0

13 files changed

+430
-215
lines changed

app/Models/Deployment.php

+78-38
Original file line numberDiff line numberDiff line change
@@ -104,50 +104,82 @@ public function asNodeTasks(): array
104104

105105
$this->latestDeployments()->each(function ($deployment) use (&$caddyHandlers) {
106106
foreach ($deployment->data->processes as $process) {
107-
$caddyHandlers[] = collect($process->caddy)->map(fn(Caddy $caddy) => [
108-
'apps' =>[
109-
'http' => [
110-
'servers' => [
111-
"listen_{$caddy->publishedPort}" => [
112-
'listen' => [
113-
"0.0.0.0:{$caddy->publishedPort}",
107+
$caddyHandlers[] = collect($process->caddy)->map(function(Caddy $caddy) use ($deployment, $process) {
108+
$routes = [];
109+
110+
$routes[] = [
111+
'match' => [
112+
[
113+
'host' => [$caddy->domain],
114+
'path' => [$caddy->path],
115+
],
116+
],
117+
'handle' => [
118+
[
119+
'handler' => 'reverse_proxy',
120+
'headers' => [
121+
'request' => [
122+
'set' => $this->getForwardedHeaders($caddy),
114123
],
115-
'routes' => [
116-
[
117-
'match' => [
118-
[
119-
'host' => [$caddy->domain],
120-
'path' => [$caddy->path],
121-
],
122-
],
123-
'handle' => [
124-
[
125-
'handler' => 'reverse_proxy',
126-
'headers' => [
127-
'request' => [
128-
'set' => $this->getForwardedHeaders($caddy),
129-
],
130-
'response' => [
131-
'set' => [
132-
'X-Powered-By' => ['https://ptah.sh'],
133-
],
134-
],
135-
],
136-
'transport' => $this->getTransportOptions($caddy, $process),
137-
'upstreams' => [
138-
[
139-
'dial' => "{$process->name}.{$deployment->data->internalDomain}:{$caddy->targetPort}",
140-
]
141-
]
142-
]
143-
]
124+
'response' => [
125+
'set' => [
126+
'X-Powered-By' => ['https://ptah.sh'],
144127
],
128+
],
129+
],
130+
'transport' => $this->getTransportOptions($caddy, $process),
131+
'upstreams' => [
132+
[
133+
'dial' => "{$process->name}.{$deployment->data->internalDomain}:{$caddy->targetPort}",
145134
]
146135
]
147136
]
148137
]
149-
]
150-
])->toArray();
138+
];
139+
140+
foreach ($process->redirectRules as $redirectRule) {
141+
$regexpName = dockerize_name($redirectRule->id);
142+
143+
$pathTo = preg_replace("/\\$(\d+)/", "{http.regexp.$regexpName.$1}", $redirectRule->pathTo);
144+
145+
$routes[] = [
146+
'match' => [
147+
[
148+
'host' => [$redirectRule->domainFrom],
149+
'path_regexp' => [
150+
'name' => $regexpName,
151+
'pattern' => $redirectRule->pathFrom
152+
],
153+
]
154+
],
155+
'handle' => [
156+
[
157+
'handler' => 'static_response',
158+
'status_code' => (string) $redirectRule->statusCode,
159+
'headers' => [
160+
'X-Powered-By' => ['https://ptah.sh'],
161+
'Location' => ["{http.request.scheme}://{$redirectRule->domainTo}{$pathTo}"],
162+
],
163+
]
164+
]
165+
];
166+
}
167+
168+
return [
169+
'apps' => [
170+
'http' => [
171+
'servers' => [
172+
"listen_{$caddy->publishedPort}" => [
173+
'listen' => [
174+
"0.0.0.0:{$caddy->publishedPort}",
175+
],
176+
'routes' => $routes,
177+
]
178+
]
179+
]
180+
]
181+
];
182+
})->toArray();
151183
}
152184
});
153185

@@ -250,6 +282,14 @@ protected function sortRoutes($routes): array
250282

251283
protected function getRouteWeights($route): array
252284
{
285+
// Let's prioritize regexp routes to be first to execute
286+
if (isset($route['match'][0]['path_regexp'])) {
287+
return [
288+
'segments' => 0,
289+
'wildcards' => -100,
290+
];
291+
}
292+
253293
$path = $route['match'][0]['path'][0];
254294

255295
$pathSegments = count(explode('/', $path)) * -1;

app/Models/DeploymentData.php

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
class DeploymentData extends Data
1616
{
1717
public function __construct(
18-
// #[Exists(DockerRegistry::class)]
19-
// #[Exists(Network::class, 'networkName')]
2018
public string $networkName,
2119
public string $internalDomain,
2220
#[Exists(Node::class, 'id')]
@@ -51,6 +49,7 @@ public static function make(array $attributes): static
5149
'replicas' => 1,
5250
'caddy' => [],
5351
'fastCgi' => null,
52+
'redirectRules' => [],
5453
];
5554

5655
$defaults = [

app/Models/DeploymentData/Process.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace App\Models\DeploymentData;
44

55
use App\Models\Deployment;
6-
use App\Models\NodeTask;
76
use App\Models\NodeTasks\CreateConfig\CreateConfigMeta;
87
use App\Models\NodeTasks\CreateSecret\CreateSecretMeta;
98
use App\Models\NodeTasks\CreateService\CreateServiceMeta;
@@ -12,7 +11,6 @@
1211
use App\Models\NodeTasks\UpdateService\UpdateServiceMeta;
1312
use App\Models\NodeTaskType;
1413
use App\Rules\RequiredIfArrayHas;
15-
use Illuminate\Support\Str;
1614
use Spatie\LaravelData\Attributes\DataCollectionOf;
1715
use Spatie\LaravelData\Attributes\Validation\Enum;
1816
use Spatie\LaravelData\Attributes\Validation\Rule;
@@ -54,6 +52,9 @@ public function __construct(
5452
public array $caddy,
5553
#[Rule(new RequiredIfArrayHas('caddy.*.targetProtocol', 'fastcgi'))]
5654
public ?FastCgi $fastCgi,
55+
#[DataCollectionOf(RedirectRule::class)]
56+
/* @var RedirectRule[] */
57+
public array $redirectRules
5758
)
5859
{
5960

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace App\Models\DeploymentData;
4+
5+
use Spatie\LaravelData\Data;
6+
7+
class RedirectRule extends Data
8+
{
9+
public function __construct(
10+
public string $id,
11+
public string $domainFrom,
12+
public string $domainTo,
13+
public string $pathFrom,
14+
public string $pathTo,
15+
public int $statusCode
16+
)
17+
{
18+
19+
}
20+
}

app/Models/Service.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ class Service extends Model
2929
protected static function booted()
3030
{
3131
self::saved(function (Service $service) {
32-
$service->docker_name = $service->makeResourceName($service->name);
33-
$service->saveQuietly();
32+
if (!$service->docker_name) {
33+
$service->docker_name = $service->makeResourceName($service->name);
34+
$service->saveQuietly();
35+
}
3436
});
3537

3638
self::deleting(function (Service $service) {

0 commit comments

Comments
 (0)