Skip to content

Commit 7529e96

Browse files
authored
Add back API (pterodactyl#80)
Re-implements the API after it was removed in the Laravel 5.3 upgrade.
1 parent b02df8e commit 7529e96

23 files changed

+1620
-81
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ This file is a running track of new features and fixes to each version of the pa
1010
* Adds support for IP Aliases on display pages for users. This makes it possible to use GRE tunnels and still show the user what IP they should be connecting to.
1111
* Adds support for suspending servers
1212
* Adds support for viewing SFTP password within the panel (#74, thanks @ET-Bent)
13+
* Improved API with support for server suspension and build modification.
1314

1415
### Bug Fixes
1516
* Fixes password auto-generation on 'Manage Server' page. (#67, thanks @ET-Bent)
@@ -19,4 +20,4 @@ This file is a running track of new features and fixes to each version of the pa
1920
* Fixes a few display issues relating to subusers and database management.
2021

2122
### General
22-
* Update Laravel to version `5.3` and update dependencies. **[BREAKING]** This removes the remote API from the panel due to Dingo API instability. This message will be removed when it is added back.
23+
* Update Laravel to version `5.3` and update dependencies.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
/**
3+
* Pterodactyl - Panel
4+
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
namespace Pterodactyl\Http\Controllers\API;
25+
26+
use Dingo\Api\Routing\Helpers;
27+
use Illuminate\Routing\Controller;
28+
29+
class BaseController extends Controller
30+
{
31+
use Helpers;
32+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
/**
3+
* Pterodactyl - Panel
4+
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
namespace Pterodactyl\Http\Controllers\API;
25+
26+
use DB;
27+
use Illuminate\Http\Request;
28+
use Pterodactyl\Models\Location;
29+
30+
/**
31+
* @Resource("Servers")
32+
*/
33+
class LocationController extends BaseController
34+
{
35+
36+
public function __construct()
37+
{
38+
//
39+
}
40+
41+
/**
42+
* List All Locations
43+
*
44+
* Lists all locations currently on the system.
45+
*
46+
* @Get("/locations")
47+
* @Versions({"v1"})
48+
* @Response(200)
49+
*/
50+
public function list(Request $request)
51+
{
52+
$locations = Location::select('locations.*', DB::raw('GROUP_CONCAT(nodes.id) as nodes'))
53+
->join('nodes', 'locations.id', '=', 'nodes.location')
54+
->groupBy('locations.id')
55+
->get();
56+
57+
foreach($locations as &$location) {
58+
$location->nodes = explode(',', $location->nodes);
59+
}
60+
61+
return $locations;
62+
}
63+
64+
}
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
<?php
2+
/**
3+
* Pterodactyl - Panel
4+
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
namespace Pterodactyl\Http\Controllers\API;
25+
26+
use Illuminate\Http\Request;
27+
28+
use Pterodactyl\Models;
29+
use Pterodactyl\Transformers\NodeTransformer;
30+
use Pterodactyl\Transformers\AllocationTransformer;
31+
use Pterodactyl\Repositories\NodeRepository;
32+
33+
use Pterodactyl\Exceptions\DisplayValidationException;
34+
use Pterodactyl\Exceptions\DisplayException;
35+
use Dingo\Api\Exception\ResourceException;
36+
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
37+
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
38+
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
39+
40+
/**
41+
* @Resource("Servers")
42+
*/
43+
class NodeController extends BaseController
44+
{
45+
46+
public function __construct()
47+
{
48+
//
49+
}
50+
51+
/**
52+
* List All Nodes
53+
*
54+
* Lists all nodes currently on the system.
55+
*
56+
* @Get("/nodes/{?page}")
57+
* @Versions({"v1"})
58+
* @Parameters({
59+
* @Parameter("page", type="integer", description="The page of results to view.", default=1)
60+
* })
61+
* @Response(200)
62+
*/
63+
public function list(Request $request)
64+
{
65+
$nodes = Models\Node::paginate(50);
66+
return $this->response->paginator($nodes, new NodeTransformer);
67+
}
68+
69+
/**
70+
* Create a New Node
71+
*
72+
* @Post("/nodes")
73+
* @Versions({"v1"})
74+
* @Transaction({
75+
* @Request({
76+
* 'name' => 'My API Node',
77+
* 'location' => 1,
78+
* 'public' => 1,
79+
* 'fqdn' => 'daemon.wuzzle.woo',
80+
* 'scheme' => 'https',
81+
* 'memory' => 10240,
82+
* 'memory_overallocate' => 100,
83+
* 'disk' => 204800,
84+
* 'disk_overallocate' => -1,
85+
* 'daemonBase' => '/srv/daemon-data',
86+
* 'daemonSFTP' => 2022,
87+
* 'daemonListen' => 8080
88+
* }, headers={"Authorization": "Bearer <jwt-token>"}),
89+
* @Response(201),
90+
* @Response(422, body={
91+
* "message": "A validation error occured.",
92+
* "errors": {},
93+
* "status_code": 422
94+
* }),
95+
* @Response(503, body={
96+
* "message": "There was an error while attempting to add this node to the system.",
97+
* "status_code": 503
98+
* })
99+
* })
100+
*/
101+
public function create(Request $request)
102+
{
103+
try {
104+
$node = new NodeRepository;
105+
$new = $node->create($request->all());
106+
return $this->response->created(route('api.nodes.view', [
107+
'id' => $new
108+
]));
109+
} catch (DisplayValidationException $ex) {
110+
throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true));
111+
} catch (DisplayException $ex) {
112+
throw new ResourceException($ex->getMessage());
113+
} catch (\Exception $e) {
114+
throw new BadRequestHttpException('There was an error while attempting to add this node to the system.');
115+
}
116+
}
117+
118+
/**
119+
* List Specific Node
120+
*
121+
* Lists specific fields about a server or all fields pertaining to that node.
122+
*
123+
* @Get("/nodes/{id}/{?fields}")
124+
* @Versions({"v1"})
125+
* @Parameters({
126+
* @Parameter("id", type="integer", required=true, description="The ID of the node to get information on."),
127+
* @Parameter("fields", type="string", required=false, description="A comma delimidated list of fields to include.")
128+
* })
129+
* @Response(200)
130+
*/
131+
public function view(Request $request, $id, $fields = null)
132+
{
133+
$query = Models\Node::where('id', $id);
134+
135+
if (!is_null($request->input('fields'))) {
136+
foreach(explode(',', $request->input('fields')) as $field) {
137+
if (!empty($field)) {
138+
$query->addSelect($field);
139+
}
140+
}
141+
}
142+
143+
try {
144+
if (!$query->first()) {
145+
throw new NotFoundHttpException('No node by that ID was found.');
146+
}
147+
148+
return [
149+
'node' => $query->first(),
150+
'allocations' => [
151+
'assigned' => Models\Allocation::where('node', $id)->whereNotNull('assigned_to')->get(),
152+
'unassigned' => Models\Allocation::where('node', $id)->whereNull('assigned_to')->get()
153+
]
154+
];
155+
} catch (NotFoundHttpException $ex) {
156+
throw $ex;
157+
} catch (\Exception $ex) {
158+
throw new BadRequestHttpException('There was an issue with the fields passed in the request.');
159+
}
160+
}
161+
162+
/**
163+
* List all Node Allocations
164+
*
165+
* Returns a listing of all allocations for every node.
166+
*
167+
* @Get("/nodes/allocations")
168+
* @Versions({"v1"})
169+
* @Response(200)
170+
*/
171+
public function allocations(Request $request)
172+
{
173+
$allocations = Models\Allocation::paginate(100);
174+
if ($allocations->count() < 1) {
175+
throw new NotFoundHttpException('No allocations have been created.');
176+
}
177+
return $this->response->paginator($allocations, new AllocationTransformer);
178+
}
179+
180+
/**
181+
* Delete Node
182+
*
183+
* @Delete("/nodes/{id}")
184+
* @Versions({"v1"})
185+
* @Parameters({
186+
* @Parameter("id", type="integer", required=true, description="The ID of the node."),
187+
* })
188+
* @Response(204)
189+
*/
190+
public function delete(Request $request, $id)
191+
{
192+
try {
193+
$node = new NodeRepository;
194+
$node->delete($id);
195+
return $this->response->noContent();
196+
} catch (DisplayException $ex) {
197+
throw new ResourceException($ex->getMessage());
198+
} catch(\Exception $e) {
199+
throw new ServiceUnavailableHttpException('An error occured while attempting to delete this node.');
200+
}
201+
}
202+
203+
}

0 commit comments

Comments
 (0)