Skip to content

Commit 09d23de

Browse files
committed
New models for node and location admin pages.
1 parent 96d3aa7 commit 09d23de

File tree

10 files changed

+152
-78
lines changed

10 files changed

+152
-78
lines changed

app/Http/Controllers/Admin/LocationsController.php

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ public function getIndex(Request $request)
4545
return view('admin.locations.index', [
4646
'locations' => Models\Location::select(
4747
'locations.*',
48-
DB::raw('(SELECT COUNT(*) FROM nodes WHERE nodes.location = locations.id) as a_nodeCount'),
49-
DB::raw('(SELECT COUNT(*) FROM servers WHERE servers.node_id IN (SELECT nodes.id FROM nodes WHERE nodes.location = locations.id)) as a_serverCount')
48+
DB::raw('(SELECT COUNT(*) FROM nodes WHERE nodes.location_id = locations.id) as a_nodeCount'),
49+
DB::raw('(SELECT COUNT(*) FROM servers WHERE servers.node_id IN (SELECT nodes.id FROM nodes WHERE nodes.location_id = locations.id)) as a_serverCount')
5050
)->paginate(20),
5151
]);
5252
}
@@ -55,8 +55,8 @@ public function deleteLocation(Request $request, $id)
5555
{
5656
$model = Models\Location::select(
5757
'locations.id',
58-
DB::raw('(SELECT COUNT(*) FROM nodes WHERE nodes.location = locations.id) as a_nodeCount'),
59-
DB::raw('(SELECT COUNT(*) FROM servers WHERE servers.node_id IN (SELECT nodes.id FROM nodes WHERE nodes.location = locations.id)) as a_serverCount')
58+
DB::raw('(SELECT COUNT(*) FROM nodes WHERE nodes.location_id = locations.id) as a_nodeCount'),
59+
DB::raw('(SELECT COUNT(*) FROM servers WHERE servers.node_id IN (SELECT nodes.id FROM nodes WHERE nodes.location_id = locations.id)) as a_serverCount')
6060
)->where('id', $id)->first();
6161

6262
if (! $model) {
@@ -80,12 +80,12 @@ public function patchLocation(Request $request, $id)
8080
{
8181
try {
8282
$location = new LocationRepository;
83-
$location->edit($id, $request->all());
83+
$location->edit($id, $request->only(['long', 'short']));
8484

8585
return response('', 204);
8686
} catch (DisplayValidationException $ex) {
8787
return response()->json([
88-
'error' => 'There was a validation error while processing this request. Location descriptions must be between 1 and 255 characters, and the location code must be between 1 and 10 characters with no spaces or special characters.',
88+
'error' => 'There was a validation error while processing this request. Location descriptions must be between 1 and 255 characters, and the location code must be between 1 and 20 characters with no spaces or special characters.',
8989
], 422);
9090
} catch (\Exception $ex) {
9191
// This gets caught and processed into JSON anyways.
@@ -97,9 +97,7 @@ public function postLocation(Request $request)
9797
{
9898
try {
9999
$location = new LocationRepository;
100-
$id = $location->create($request->except([
101-
'_token',
102-
]));
100+
$id = $location->create($request->only(['long', 'short']));
103101
Alert::success('New location successfully added.')->flash();
104102

105103
return redirect()->route('admin.locations');

app/Http/Controllers/Admin/NodesController.php

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,15 @@ public function __construct()
4848

4949
public function getScript(Request $request, $id)
5050
{
51-
return response()->view('admin.nodes.remote.deploy', ['node' => Models\Node::findOrFail($id)])->header('Content-Type', 'text/plain');
51+
return response()->view('admin.nodes.remote.deploy', [
52+
'node' => Models\Node::findOrFail($id),
53+
])->header('Content-Type', 'text/plain');
5254
}
5355

5456
public function getIndex(Request $request)
5557
{
5658
return view('admin.nodes.index', [
57-
'nodes' => Models\Node::select(
58-
'nodes.*',
59-
'locations.long as a_locationName',
60-
DB::raw('(SELECT COUNT(*) FROM servers WHERE servers.node_id = nodes.id) as a_serverCount')
61-
)->join('locations', 'nodes.location', '=', 'locations.id')->paginate(20),
59+
'nodes' => Models\Node::with('location')->withCount('servers')->paginate(20),
6260
]);
6361
}
6462

@@ -78,15 +76,25 @@ public function getNew(Request $request)
7876
public function postNew(Request $request)
7977
{
8078
try {
81-
$node = new NodeRepository;
82-
$new = $node->create($request->except([
83-
'_token',
79+
$repo = new NodeRepository;
80+
$node = $repo->create($request->only([
81+
'name',
82+
'location',
83+
'public',
84+
'fqdn',
85+
'scheme',
86+
'memory',
87+
'memory_overallocate',
88+
'disk',
89+
'disk_overallocate',
90+
'daemonBase',
91+
'daemonSFTP',
92+
'daemonListen',
8493
]));
85-
Alert::success('Successfully created new node. <strong>Before you can add any servers you need to first assign some IP addresses and ports.</strong>')->flash();
86-
Alert::info('<strong>To simplify the node setup you can generate a token on the configuration tab.</strong>')->flash();
94+
Alert::success('Successfully created new node that can be configured automatically on your remote machine by visiting the configuration tab. <strong>Before you can add any servers you need to first assign some IP addresses and ports.</strong>')->flash();
8795

8896
return redirect()->route('admin.nodes.view', [
89-
'id' => $new,
97+
'id' => $node->id,
9098
'tab' => 'tab_allocation',
9199
]);
92100
} catch (DisplayValidationException $e) {
@@ -103,35 +111,40 @@ public function postNew(Request $request)
103111

104112
public function getView(Request $request, $id)
105113
{
106-
$node = Models\Node::findOrFail($id);
114+
$node = Models\Node::with(
115+
'servers.user',
116+
'servers.service',
117+
'servers.allocations',
118+
'location'
119+
)->findOrFail($id);
120+
$node->setRelation('allocations', $node->allocations()->paginate(40));
107121

108122
return view('admin.nodes.view', [
109123
'node' => $node,
110-
'servers' => Models\Server::select('servers.*', 'users.email as a_ownerEmail', 'services.name as a_serviceName')
111-
->join('users', 'users.id', '=', 'servers.owner_id')
112-
->join('services', 'services.id', '=', 'servers.service_id')
113-
->where('node_id', $id)->paginate(10, ['*'], 'servers'),
114124
'stats' => Models\Server::select(DB::raw('SUM(memory) as memory, SUM(disk) as disk'))->where('node_id', $node->id)->first(),
115125
'locations' => Models\Location::all(),
116-
'allocations' => Models\Allocation::select('allocations.*', 'servers.name as assigned_to_name')
117-
->where('allocations.node', $node->id)
118-
->leftJoin('servers', 'servers.id', '=', 'allocations.assigned_to')
119-
->orderBy('allocations.ip', 'asc')
120-
->orderBy('allocations.port', 'asc')
121-
->paginate(20, ['*'], 'allocations'),
122-
'allocation_ips' => Models\Allocation::select('id', 'ip')
123-
->where('node', $node->id)
124-
->groupBy('ip')
125-
->get(),
126126
]);
127127
}
128128

129129
public function postView(Request $request, $id)
130130
{
131131
try {
132132
$node = new NodeRepository;
133-
$node->update($id, $request->except([
134-
'_token',
133+
$node->update($id, $request->only([
134+
'name',
135+
'location',
136+
'public',
137+
'fqdn',
138+
'scheme',
139+
'memory',
140+
'memory_overallocate',
141+
'disk',
142+
'disk_overallocate',
143+
'upload_size',
144+
'daemonBase',
145+
'daemonSFTP',
146+
'daemonListen',
147+
'reset_secret',
135148
]));
136149
Alert::success('Successfully update this node\'s information. If you changed any daemon settings you will need to restart it now.')->flash();
137150

app/Models/Allocation.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ class Allocation extends Model
4848
* @var array
4949
*/
5050
protected $casts = [
51-
'node' => 'integer',
51+
'node_id' => 'integer',
5252
'port' => 'integer',
53-
'assigned_to' => 'integer',
53+
'server_id' => 'integer',
5454
];
5555
}

app/Models/Node.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,4 +226,24 @@ public function location()
226226
{
227227
return $this->hasOne(Location::class, 'id', 'location_id');
228228
}
229+
230+
/**
231+
* Gets the servers associated with a node.
232+
*
233+
* @return \Illuminate\Database\Eloquent\Relations\HasMany
234+
*/
235+
public function servers()
236+
{
237+
return $this->hasMany(Server::class);
238+
}
239+
240+
/**
241+
* Gets the allocations associated with a node.
242+
*
243+
* @return \Illuminate\Database\Eloquent\Relations\HasMany
244+
*/
245+
public function allocations()
246+
{
247+
return $this->hasMany(Allocation::class);
248+
}
229249
}

app/Models/Server.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public static function getUserServers($paginate = null)
121121
'services.name as a_serviceName',
122122
'service_options.name as a_serviceOptionName'
123123
)->join('nodes', 'servers.node_id', '=', 'nodes.id')
124-
->join('locations', 'nodes.location', '=', 'locations.id')
124+
->join('locations', 'nodes.location_id', '=', 'locations.id')
125125
->join('services', 'servers.service_id', '=', 'services.id')
126126
->join('service_options', 'servers.option_id', '=', 'service_options.id')
127127
->join('allocations', 'servers.allocation_id', '=', 'allocations.id');
@@ -218,14 +218,24 @@ public function js($additional = null, $overwrite = null)
218218
return Javascript::put($response);
219219
}
220220

221+
/**
222+
* Gets the user who owns the server.
223+
*
224+
* @return \Illuminate\Database\Eloquent\Relations\HasOne
225+
*/
226+
public function user()
227+
{
228+
return $this->hasOne(User::class, 'id', 'owner_id');
229+
}
230+
221231
/**
222232
* Gets all allocations associated with this server.
223233
*
224234
* @return \Illuminate\Database\Eloquent\Relations\HasMany
225235
*/
226236
public function allocations()
227237
{
228-
return $this->hasMany(Allocation::class, 'assigned_to');
238+
return $this->hasMany(Allocation::class, 'server_id');
229239
}
230240

231241
/**

app/Repositories/LocationRepository.php

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function __construct()
4444
public function create(array $data)
4545
{
4646
$validator = Validator::make($data, [
47-
'short' => 'required|regex:/^[a-z0-9_.-]{1,10}$/i|unique:locations,short',
47+
'short' => 'required|regex:/^[\w.-]{1,20}$/i|unique:locations,short',
4848
'long' => 'required|string|min:1|max:255',
4949
]);
5050

@@ -73,9 +73,11 @@ public function create(array $data)
7373
*/
7474
public function edit($id, array $data)
7575
{
76+
$location = Models\Location::findOrFail($id);
77+
7678
$validator = Validator::make($data, [
77-
'short' => 'regex:/^[a-z0-9_.-]{1,10}$/i',
78-
'long' => 'string|min:1|max:255',
79+
'short' => 'required|regex:/^[\w.-]{1,20}$/i|unique:locations,short,' . $location->id,
80+
'long' => 'required|string|min:1|max:255',
7981
]);
8082

8183
// Run validator, throw catchable and displayable exception if it fails.
@@ -84,15 +86,7 @@ public function edit($id, array $data)
8486
throw new DisplayValidationException($validator->errors());
8587
}
8688

87-
$location = Models\Location::findOrFail($id);
88-
89-
if (isset($data['short'])) {
90-
$location->short = $data['short'];
91-
}
92-
93-
if (isset($data['long'])) {
94-
$location->long = $data['long'];
95-
}
89+
$location->fill($data);
9690

9791
return $location->save();
9892
}

app/Repositories/NodeRepository.php

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public function create(array $data)
6565

6666
// Verify the FQDN if using SSL
6767
if (filter_var($data['fqdn'], FILTER_VALIDATE_IP) && $data['scheme'] === 'https') {
68-
throw new DisplayException('A fully qualified domain name is required to use secure comunication on this node.');
68+
throw new DisplayException('A fully qualified domain name is required to use a secure comunication method on this node.');
6969
}
7070

7171
// Verify FQDN is resolvable, or if not using SSL that the IP is valid.
@@ -86,7 +86,7 @@ public function create(array $data)
8686
$node->fill($data);
8787
$node->save();
8888

89-
return $node->id;
89+
return $node;
9090
}
9191

9292
public function update($id, array $data)
@@ -152,18 +152,12 @@ public function update($id, array $data)
152152
$oldDaemonKey = $node->daemonSecret;
153153
$node->update($data);
154154
try {
155-
$client = Models\Node::guzzleRequest($node->id);
156-
$client->request('PATCH', '/config', [
157-
'headers' => [
158-
'X-Access-Token' => $oldDaemonKey,
159-
],
155+
$node->guzzleClient(['X-Access-Token' => $oldDaemonKey])->request('PATCH', '/config', [
160156
'json' => [
161157
'web' => [
162158
'listen' => $node->daemonListen,
163159
'ssl' => [
164160
'enabled' => ($node->scheme === 'https'),
165-
'certificate' => '/etc/letsencrypt/live/' . $node->fqdn . '/fullchain.pem',
166-
'key' => '/etc/letsencrypt/live/' . $node->fqdn . '/privkey.pem',
167161
],
168162
],
169163
'sftp' => [
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
use Illuminate\Support\Facades\Schema;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Database\Migrations\Migration;
6+
7+
class RenameColumns extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::table('allocations', function (Blueprint $table) {
17+
$table->dropForeign('allocations_node_foreign');
18+
$table->dropForeign('allocations_assigned_to_foreign');
19+
$table->dropIndex('allocations_node_foreign');
20+
$table->dropIndex('allocations_assigned_to_foreign');
21+
22+
$table->renameColumn('node', 'node_id');
23+
$table->renameColumn('assigned_to', 'server_id');
24+
$table->foreign('node_id')->references('id')->on('nodes');
25+
$table->foreign('server_id')->references('id')->on('servers');
26+
});
27+
}
28+
29+
/**
30+
* Reverse the migrations.
31+
*
32+
* @return void
33+
*/
34+
public function down()
35+
{
36+
Schema::table('allocations', function (Blueprint $table) {
37+
$table->dropForeign('allocations_node_id_foreign');
38+
$table->dropForeign('allocations_server_id_foreign');
39+
$table->dropIndex('allocations_node_id_foreign');
40+
$table->dropIndex('allocations_server_id_foreign');
41+
42+
$table->renameColumn('node_id', 'node');
43+
$table->renameColumn('server_id', 'assigned_to');
44+
$table->foreign('node')->references('id')->on('nodes');
45+
$table->foreign('assigned_to')->references('id')->on('servers');
46+
});
47+
}
48+
}

resources/views/admin/nodes/index.blade.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@
5353
<tr>
5454
<td class="text-center text-muted left-icon" data-action="ping" data-secret="{{ $node->daemonSecret }}" data-location="{{ $node->scheme }}://{{ $node->fqdn }}:{{ $node->daemonListen }}"><i class="fa fa-fw fa-refresh fa-spin"></i></td>
5555
<td><a href="/admin/nodes/view/{{ $node->id }}">{{ $node->name }}</td>
56-
<td>{{ $node->a_locationName }}</td>
56+
<td>{{ $node->location->short }}</td>
5757
<td class="hidden-xs">{{ $node->memory }} MB</td>
5858
<td class="hidden-xs">{{ $node->disk }} MB</td>
59-
<td class="text-center hidden-xs">{{ $node->a_serverCount }}</td>
59+
<td class="text-center hidden-xs">{{ $node->servers_count }}</td>
6060
<td class="text-center" style="color:{{ ($node->scheme === 'https') ? '#50af51' : '#d9534f' }}"><i class="fa fa-{{ ($node->scheme === 'https') ? 'lock' : 'unlock' }}"></i></td>
6161
<td class="text-center hidden-xs"><i class="fa fa-{{ ($node->public === 1) ? 'eye' : 'eye-slash' }}"></i></td>
6262
</tr>

0 commit comments

Comments
 (0)