Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/1.0-develop/app/Repositories/Eloquent/NodeRepository.php
7460 views
1
<?php
2
3
namespace Pterodactyl\Repositories\Eloquent;
4
5
use Pterodactyl\Models\Node;
6
use Illuminate\Support\Collection;
7
use Pterodactyl\Contracts\Repository\NodeRepositoryInterface;
8
9
class NodeRepository extends EloquentRepository implements NodeRepositoryInterface
10
{
11
/**
12
* Return the model backing this repository.
13
*/
14
public function model(): string
15
{
16
return Node::class;
17
}
18
19
/**
20
* Return the usage stats for a single node.
21
*/
22
public function getUsageStats(Node $node): array
23
{
24
$stats = $this->getBuilder()
25
->selectRaw('IFNULL(SUM(servers.memory), 0) as sum_memory, IFNULL(SUM(servers.disk), 0) as sum_disk')
26
->join('servers', 'servers.node_id', '=', 'nodes.id')
27
->where('node_id', '=', $node->id)
28
->first();
29
30
return Collection::make(['disk' => $stats->sum_disk, 'memory' => $stats->sum_memory])
31
->mapWithKeys(function ($value, $key) use ($node) {
32
$maxUsage = $node->{$key};
33
if ($node->{$key . '_overallocate'} > 0) {
34
$maxUsage = $node->{$key} * (1 + ($node->{$key . '_overallocate'} / 100));
35
}
36
37
$percent = ($value / $maxUsage) * 100;
38
39
return [
40
$key => [
41
'value' => number_format($value),
42
'max' => number_format($maxUsage),
43
'percent' => $percent,
44
'css' => ($percent <= self::THRESHOLD_PERCENTAGE_LOW) ? 'green' : (($percent > self::THRESHOLD_PERCENTAGE_MEDIUM) ? 'red' : 'yellow'),
45
],
46
];
47
})
48
->toArray();
49
}
50
51
/**
52
* Return the usage stats for a single node.
53
*/
54
public function getUsageStatsRaw(Node $node): array
55
{
56
$stats = $this->getBuilder()->select(
57
$this->getBuilder()->raw('IFNULL(SUM(servers.memory), 0) as sum_memory, IFNULL(SUM(servers.disk), 0) as sum_disk')
58
)->join('servers', 'servers.node_id', '=', 'nodes.id')->where('node_id', $node->id)->first();
59
60
return collect(['disk' => $stats->sum_disk, 'memory' => $stats->sum_memory])->mapWithKeys(function ($value, $key) use ($node) {
61
$maxUsage = $node->{$key};
62
if ($node->{$key . '_overallocate'} > 0) {
63
$maxUsage = $node->{$key} * (1 + ($node->{$key . '_overallocate'} / 100));
64
}
65
66
return [
67
$key => [
68
'value' => $value,
69
'max' => $maxUsage,
70
],
71
];
72
})->toArray();
73
}
74
75
/**
76
* Return a single node with location and server information.
77
*/
78
public function loadLocationAndServerCount(Node $node, bool $refresh = false): Node
79
{
80
if (!$node->relationLoaded('location') || $refresh) {
81
$node->load('location');
82
}
83
84
// This is quite ugly and can probably be improved down the road.
85
// And by probably, I mean it should.
86
if (is_null($node->servers_count) || $refresh) {
87
$node->load('servers');
88
$node->setRelation('servers_count', count($node->getRelation('servers')));
89
unset($node->servers);
90
}
91
92
return $node;
93
}
94
95
/**
96
* Attach a paginated set of allocations to a node mode including
97
* any servers that are also attached to those allocations.
98
*/
99
public function loadNodeAllocations(Node $node, bool $refresh = false): Node
100
{
101
$node->setRelation(
102
'allocations',
103
$node->allocations()
104
->orderByRaw('server_id IS NOT NULL DESC, server_id IS NULL')
105
->orderByRaw('INET_ATON(ip) ASC')
106
->orderBy('port')
107
->with('server:id,name')
108
->paginate(50)
109
);
110
111
return $node;
112
}
113
114
/**
115
* Return a collection of nodes for all locations to use in server creation UI.
116
*/
117
public function getNodesForServerCreation(): Collection
118
{
119
return $this->getBuilder()->with('allocations')->get()->map(function (Node $item) {
120
$filtered = $item->getRelation('allocations')->where('server_id', null)->map(function ($map) {
121
return collect($map)->only(['id', 'ip', 'port']);
122
});
123
124
$item->ports = $filtered->map(function ($map) {
125
return [
126
'id' => $map['id'],
127
'text' => sprintf('%s:%s', $map['ip'], $map['port']),
128
];
129
})->values();
130
131
return [
132
'id' => $item->id,
133
'text' => $item->name,
134
'allocations' => $item->ports,
135
];
136
})->values();
137
}
138
139
/**
140
* Returns a node with the given id with the Node's resource usage.
141
*/
142
public function getNodeWithResourceUsage(int $node_id): Node
143
{
144
$instance = $this->getBuilder()
145
->select(['nodes.id', 'nodes.fqdn', 'nodes.scheme', 'nodes.daemon_token', 'nodes.daemonListen', 'nodes.memory', 'nodes.disk', 'nodes.memory_overallocate', 'nodes.disk_overallocate'])
146
->selectRaw('IFNULL(SUM(servers.memory), 0) as sum_memory, IFNULL(SUM(servers.disk), 0) as sum_disk')
147
->leftJoin('servers', 'servers.node_id', '=', 'nodes.id')
148
->where('nodes.id', $node_id);
149
150
return $instance->first();
151
}
152
}
153
154