mirror of
				https://github.com/pelican-dev/panel.git
				synced 2025-11-01 00:26:51 +01:00 
			
		
		
		
	Add endpoints
This commit is contained in:
		
							parent
							
								
									30051ab0d7
								
							
						
					
					
						commit
						4cba1540ac
					
				
							
								
								
									
										41
									
								
								app/Casts/EndpointCollection.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								app/Casts/EndpointCollection.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | |||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | namespace App\Casts; | ||||||
|  | 
 | ||||||
|  | use App\Models\Objects\Endpoint; | ||||||
|  | use Illuminate\Contracts\Database\Eloquent\Castable; | ||||||
|  | use Illuminate\Contracts\Database\Eloquent\CastsAttributes; | ||||||
|  | use Illuminate\Support\Collection; | ||||||
|  | use Stringable; | ||||||
|  | use TypeError; | ||||||
|  | 
 | ||||||
|  | class EndpointCollection implements Castable | ||||||
|  | { | ||||||
|  |     public static function castUsing(array $arguments) | ||||||
|  |     { | ||||||
|  |         return new class() implements CastsAttributes | ||||||
|  |         { | ||||||
|  |             public function get($model, $key, $value, $attributes) | ||||||
|  |             { | ||||||
|  |                 if (! isset($attributes[$key])) { | ||||||
|  |                     return new Collection(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 $data = json_decode($attributes[$key], true); | ||||||
|  | 
 | ||||||
|  |                 return (new Collection($data))->map(function ($value) { | ||||||
|  |                     return new Endpoint($value); | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             public function set($model, $key, $value, $attributes) | ||||||
|  |             { | ||||||
|  |                 if (!$value instanceof Collection) { | ||||||
|  |                     return new Collection(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 return $value->map(fn ($endpoint) => (string) $endpoint); | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										26
									
								
								app/Livewire/EndpointSynth.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								app/Livewire/EndpointSynth.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | namespace App\Livewire; | ||||||
|  | 
 | ||||||
|  | use App\Models\Objects\Endpoint; | ||||||
|  | use Livewire\Mechanisms\HandleComponents\Synthesizers\Synth; | ||||||
|  | 
 | ||||||
|  | class EndpointSynth extends Synth | ||||||
|  | { | ||||||
|  |     public static $key = 'endpoint'; | ||||||
|  | 
 | ||||||
|  |     public static function match($target) | ||||||
|  |     { | ||||||
|  |         return $target instanceof Endpoint; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function dehydrate($target) | ||||||
|  |     { | ||||||
|  |         return (string) $target; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function hydrate($value) | ||||||
|  |     { | ||||||
|  |         return new Endpoint($value); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -12,28 +12,30 @@ class Endpoint | |||||||
|     public const PORT_CEIL = 65535; |     public const PORT_CEIL = 65535; | ||||||
|     public const PORT_RANGE_LIMIT = 1000; |     public const PORT_RANGE_LIMIT = 1000; | ||||||
|     public const PORT_RANGE_REGEX = '/^(\d{4,5})-(\d{4,5})$/'; |     public const PORT_RANGE_REGEX = '/^(\d{4,5})-(\d{4,5})$/'; | ||||||
|  |     public const INADDR_ANY = '0.0.0.0'; | ||||||
| 
 | 
 | ||||||
|     public int $port; |     public int $port; | ||||||
|     public string $ip; |     public string $ip; | ||||||
| 
 | 
 | ||||||
|     public function __construct(string $address = null, int $port = null) { |     public function __construct(string|int $port, string $ip = null) { | ||||||
|         if ($address === null) { |         $this->ip = $ip ?? self::INADDR_ANY; | ||||||
|             $address = '0.0.0.0'; |         $this->port = (int) $port; | ||||||
|  | 
 | ||||||
|  |         if (str_contains($port, ':')) { | ||||||
|  |             [$this->ip, $this->port] = explode(':', $port); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         $ip = $address; |         throw_unless(filter_var($this->ip, FILTER_VALIDATE_IP) !== false, new InvalidArgumentException("$this->ip is an invalid IP address")); | ||||||
|         if (str_contains($address, ':')) { |         throw_unless($this->port > self::PORT_FLOOR, "Port $this->port must be greater than " . self::PORT_FLOOR); | ||||||
|             [$ip, $port] = explode(':', $address); |         throw_unless($this->port < self::PORT_CEIL, "Port $this->port must be less than " . self::PORT_CEIL); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|             throw_unless(is_numeric($port), new InvalidArgumentException("Port ($port) must be a number")); |     public function __toString() | ||||||
| 
 |     { | ||||||
|             $port = (int) $port; |         if ($this->ip === self::INADDR_ANY) { | ||||||
|  |             return (string) $this->port; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         throw_unless(is_int($port), new InvalidArgumentException("Port ($port) must be an integer")); |         return "$this->ip:$this->port"; | ||||||
|         throw_unless(filter_var($ip, FILTER_VALIDATE_IP) !== false, new InvalidArgumentException("$ip is an invalid IP address")); |  | ||||||
| 
 |  | ||||||
|         $this->ip = $ip; |  | ||||||
|         $this->port = $port; |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -2,8 +2,10 @@ | |||||||
| 
 | 
 | ||||||
| namespace App\Models; | namespace App\Models; | ||||||
| 
 | 
 | ||||||
|  | use App\Casts\EndpointCollection; | ||||||
| use App\Enums\ServerState; | use App\Enums\ServerState; | ||||||
| use App\Exceptions\Http\Connection\DaemonConnectionException; | use App\Exceptions\Http\Connection\DaemonConnectionException; | ||||||
|  | use App\Models\Objects\Endpoint; | ||||||
| use GuzzleHttp\Exception\GuzzleException; | use GuzzleHttp\Exception\GuzzleException; | ||||||
| use Illuminate\Database\Eloquent\Relations\BelongsToMany; | use Illuminate\Database\Eloquent\Relations\BelongsToMany; | ||||||
| use Illuminate\Notifications\Notifiable; | use Illuminate\Notifications\Notifiable; | ||||||
| @ -67,7 +69,6 @@ class Server extends Model | |||||||
|         'database_limit' => 'present|nullable|integer|min:0', |         'database_limit' => 'present|nullable|integer|min:0', | ||||||
|         'allocation_limit' => 'sometimes|nullable|integer|min:0', |         'allocation_limit' => 'sometimes|nullable|integer|min:0', | ||||||
|         'backup_limit' => 'present|nullable|integer|min:0', |         'backup_limit' => 'present|nullable|integer|min:0', | ||||||
|         'ports' => 'array', |  | ||||||
|     ]; |     ]; | ||||||
| 
 | 
 | ||||||
|     protected function casts(): array |     protected function casts(): array | ||||||
| @ -90,7 +91,7 @@ class Server extends Model | |||||||
|             'deleted_at' => 'datetime', |             'deleted_at' => 'datetime', | ||||||
|             'installed_at' => 'datetime', |             'installed_at' => 'datetime', | ||||||
|             'docker_labels' => 'array', |             'docker_labels' => 'array', | ||||||
|             'ports' => 'array', |             'ports' => EndpointCollection::class, | ||||||
|         ]; |         ]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -309,9 +310,16 @@ class Server extends Model | |||||||
|         return cache()->get("servers.$this->uuid.container.status") ?? 'missing'; |         return cache()->get("servers.$this->uuid.container.status") ?? 'missing'; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function getPrimaryEndpoint() |     public function getPrimaryEndpoint(): ?Endpoint | ||||||
|     { |     { | ||||||
|         dd($this->ports); |         $endpoint = $this->ports->first(); | ||||||
|         dd($this->variables); | 
 | ||||||
|  |         $portEggVariable = $this->variables->firstWhere('env_variable', 'SERVER_PORT'); | ||||||
|  |         if ($portEggVariable) { | ||||||
|  |             $portServerVariable = $this->serverVariables->firstWhere('variable_id', $portEggVariable->id); | ||||||
|  |             $endpoint = new Endpoint($portServerVariable->variable_value); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return $endpoint; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ | |||||||
| namespace App\Providers; | namespace App\Providers; | ||||||
| 
 | 
 | ||||||
| use App\Extensions\Themes\Theme; | use App\Extensions\Themes\Theme; | ||||||
|  | use App\Livewire\EndpointSynth; | ||||||
| use App\Models; | use App\Models; | ||||||
| use App\Models\ApiKey; | use App\Models\ApiKey; | ||||||
| use App\Models\Node; | use App\Models\Node; | ||||||
| @ -21,6 +22,7 @@ use Illuminate\Support\Facades\View; | |||||||
| use Illuminate\Support\ServiceProvider; | use Illuminate\Support\ServiceProvider; | ||||||
| use Illuminate\Support\Str; | use Illuminate\Support\Str; | ||||||
| use Laravel\Sanctum\Sanctum; | use Laravel\Sanctum\Sanctum; | ||||||
|  | use Livewire\Livewire; | ||||||
| 
 | 
 | ||||||
| class AppServiceProvider extends ServiceProvider | class AppServiceProvider extends ServiceProvider | ||||||
| { | { | ||||||
| @ -72,6 +74,8 @@ class AppServiceProvider extends ServiceProvider | |||||||
|         $this->bootAuth(); |         $this->bootAuth(); | ||||||
|         $this->bootBroadcast(); |         $this->bootBroadcast(); | ||||||
| 
 | 
 | ||||||
|  |         Livewire::propertySynthesizer(EndpointSynth::class); | ||||||
|  | 
 | ||||||
|         $bearerTokens = fn (OpenApi $openApi) => $openApi->secure(SecurityScheme::http('bearer')); |         $bearerTokens = fn (OpenApi $openApi) => $openApi->secure(SecurityScheme::http('bearer')); | ||||||
|         Gate::define('viewApiDocs', fn () => true); |         Gate::define('viewApiDocs', fn () => true); | ||||||
|         Scramble::registerApi('application', ['api_path' => 'api/application', 'info' => ['version' => '1.0']]); |         Scramble::registerApi('application', ['api_path' => 'api/application', 'info' => ['version' => '1.0']]); | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ | |||||||
| 
 | 
 | ||||||
| namespace App\Services\Servers; | namespace App\Services\Servers; | ||||||
| 
 | 
 | ||||||
|  | use App\Models\Objects\Endpoint; | ||||||
| use App\Models\Server; | use App\Models\Server; | ||||||
| 
 | 
 | ||||||
| class StartupCommandService | class StartupCommandService | ||||||
| @ -13,9 +14,8 @@ class StartupCommandService | |||||||
|     { |     { | ||||||
|         $endpoint = $server->getPrimaryEndpoint(); |         $endpoint = $server->getPrimaryEndpoint(); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|         $find = ['{{SERVER_MEMORY}}', '{{SERVER_IP}}', '{{SERVER_PORT}}']; |         $find = ['{{SERVER_MEMORY}}', '{{SERVER_IP}}', '{{SERVER_PORT}}']; | ||||||
|         $replace = [$server->memory, $server->allocation->ip, $server->allocation->port]; |         $replace = [$server->memory, $endpoint->ip ?? Endpoint::INADDR_ANY, $endpoint->port ?? '']; | ||||||
| 
 | 
 | ||||||
|         foreach ($server->variables as $variable) { |         foreach ($server->variables as $variable) { | ||||||
|             $find[] = '{{' . $variable->env_variable . '}}'; |             $find[] = '{{' . $variable->env_variable . '}}'; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Lance Pioch
						Lance Pioch