Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/1.0-develop/app/Services/Deployment/AllocationSelectionService.php
10263 views
1
<?php
2
3
namespace Pterodactyl\Services\Deployment;
4
5
use Pterodactyl\Models\Allocation;
6
use Pterodactyl\Exceptions\DisplayException;
7
use Pterodactyl\Services\Allocations\AssignmentService;
8
use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;
9
use Pterodactyl\Exceptions\Service\Deployment\NoViableAllocationException;
10
11
class AllocationSelectionService
12
{
13
protected bool $dedicated = false;
14
15
protected array $nodes = [];
16
17
protected array $ports = [];
18
19
/**
20
* AllocationSelectionService constructor.
21
*/
22
public function __construct(private AllocationRepositoryInterface $repository)
23
{
24
}
25
26
/**
27
* Toggle if the selected allocation should be the only allocation belonging
28
* to the given IP address. If true an allocation will not be selected if an IP
29
* already has another server set to use on if its allocations.
30
*/
31
public function setDedicated(bool $dedicated): self
32
{
33
$this->dedicated = $dedicated;
34
35
return $this;
36
}
37
38
/**
39
* A list of node IDs that should be used when selecting an allocation. If empty, all
40
* nodes will be used to filter with.
41
*/
42
public function setNodes(array $nodes): self
43
{
44
$this->nodes = $nodes;
45
46
return $this;
47
}
48
49
/**
50
* An array of individual ports or port ranges to use when selecting an allocation. If
51
* empty, all ports will be considered when finding an allocation. If set, only ports appearing
52
* in the array or range will be used.
53
*
54
* @throws DisplayException
55
*/
56
public function setPorts(array $ports): self
57
{
58
$stored = [];
59
foreach ($ports as $port) {
60
if (is_digit($port)) {
61
$stored[] = $port;
62
}
63
64
// Ranges are stored in the ports array as an array which can be
65
// better processed in the repository.
66
if (preg_match(AssignmentService::PORT_RANGE_REGEX, $port, $matches)) {
67
if (abs($matches[2] - $matches[1]) > AssignmentService::PORT_RANGE_LIMIT) {
68
throw new DisplayException(trans('exceptions.allocations.too_many_ports'));
69
}
70
71
$stored[] = [$matches[1], $matches[2]];
72
}
73
}
74
75
$this->ports = $stored;
76
77
return $this;
78
}
79
80
/**
81
* Return a single allocation that should be used as the default allocation for a server.
82
*
83
* @throws NoViableAllocationException
84
*/
85
public function handle(): Allocation
86
{
87
$allocation = $this->repository->getRandomAllocation($this->nodes, $this->ports, $this->dedicated);
88
89
if (is_null($allocation)) {
90
throw new NoViableAllocationException(trans('exceptions.deployment.no_viable_allocations'));
91
}
92
93
return $allocation;
94
}
95
}
96
97