├── .gitignore
├── README.md
├── blacksmith
├── composer.json
├── doc
└── servers.md
├── phpunit.xml
└── src
└── Mpociot
└── Blacksmith
├── Blacksmith.php
├── Browser.php
├── Driver
└── BlacksmithDriver.php
└── Models
├── Circle.php
├── Database.php
├── DatabaseUser.php
├── ForgeModel.php
├── Recipe.php
├── SSHKey.php
├── ScheduledJob.php
├── Server.php
├── Site.php
└── User.php
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | composer.lock
3 | .php_cs.cache
4 | /vendor/
5 | .idea
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Blacksmith - The unofficial Laravel Forge PHP API
2 |
3 | Laravel Forge is **awesome**, right?
4 | Yes it is - but there's one thing it's missing - a proper API.
5 |
6 | That's why this library exists - Blacksmith is an unofficial [Laravel Forge API](http://forge.laravel.com) to automate common tasks.
7 |
8 | The API is still improving and I will keep adding features, as I need them.
9 |
10 | ## Getting Started
11 |
12 | ```php
13 | use Mpociot\Blacksmith\Blacksmith;
14 |
15 | $blacksmith = new Blacksmith($email, $password);
16 |
17 | ```
18 |
19 | ## Available methods
20 |
21 |
22 | ### Get all active servers
23 |
24 | Returns a Collection of `Server` objects.
25 |
26 | ```php
27 | $activeServers = $blacksmith->getActiveServers();
28 | ```
29 |
30 | ### Get all sites for all servers
31 |
32 | Returns a Collection of `Site` objects.
33 |
34 | ```php
35 | $sites = $blacksmith->getSites();
36 | ```
37 |
38 | ### Get a server by its ID
39 |
40 | Returns a single `Server` object.
41 |
42 | ```php
43 | $server = $blacksmith->getServer(1);
44 | ```
45 |
46 | ### Add a server to Forge
47 |
48 | Returns a single `Server` object with a provision url.
49 |
50 | The following example will create a Load Balancer with a custom provider
51 | ```php
52 | $server = $blacksmith->addServer([
53 | 'backups' => false,
54 | 'database' => 'forge',
55 | 'hhvm' => false,
56 | 'ip_address' => '94.212.124.121',
57 | 'maria' => false,
58 | 'name' => 'harmonious-lagoon',
59 | 'nodeBalancer' => true,
60 | 'old_php' => false,
61 | 'php_version' => 'php70',
62 | 'private_ip_address' => '10.0.0.2',
63 | 'provider' => 'custom',
64 | 'size' => '2',
65 | 'timezone' => 'Europe/Berlin',
66 | ]);
67 | ```
68 |
69 | ### Get a site by its ID
70 |
71 | Returns a single `Site` object.
72 |
73 | ```php
74 | $site = $blacksmith->getSite(1);
75 | ```
76 |
77 | ### Get all circles
78 |
79 | Returns a Collection of `Circle` objects of the user.
80 |
81 | ```php
82 | $circles = $blacksmith->getCircles();
83 | ```
84 |
85 | ### Get a circle by its ID
86 |
87 | Returns a single `Circle` object.
88 |
89 | ```php
90 | $circle = $blacksmith->getCircle(1);
91 | ```
92 |
93 | ### Add a new circle
94 |
95 | Returns a single `Circle` object.
96 |
97 | ```php
98 | $circle = $blacksmith->addCircle('Name of Circle');
99 | ```
100 |
101 | ### Get all recipes
102 |
103 | Returns a Collection of `Recipe` objects.
104 |
105 | ```php
106 | $recipes = $blacksmith->getRecipes();
107 | ```
108 |
109 | ### Get a recipe by its ID
110 |
111 | Returns a single `Recipe` object.
112 |
113 | ```php
114 | $recipe = $blacksmith->getRecipe(1);
115 | ```
116 |
117 | ### Add a new recipe
118 |
119 | Returns a single `Recipe` object.
120 |
121 | ```php
122 | $recipe = $blacksmith->addRecipe('RecipeName', 'root', 'Recipe contents');
123 | ```
124 |
125 | ## Server methods
126 |
127 | ### Get Sites
128 |
129 | Returns a Collection of `Site` objects for the server.
130 |
131 | ```php
132 | $sites = $server->getSites();
133 | ```
134 |
135 | ### Add a new site
136 |
137 | Returns a the newly created `Site` object or throws an exception if errors occur.
138 |
139 | ```php
140 | $newSite = $server->addSite($site_name, $project_type = 'php', $directory = '/public', $wildcards = false);
141 | ```
142 |
143 | ### Add a new SSH key
144 |
145 | Add a SSH key to a server
146 |
147 | ```php
148 | $server->addSSHKey('Name SSH key', 'Contents of SSH key');
149 | ```
150 |
151 | ### Remove a SSH key from a server
152 |
153 | ```php
154 | $server->removeSSHKey(1);
155 | ```
156 |
157 | ### Update Metadata
158 |
159 | Update the metadata of the current site, and return an updated `Server` object or throws an exception if errors occur.
160 |
161 | ```php
162 | $server = $server->updateMetadata($server_name, $ip_address, $private_ip_address, $size);
163 | ```
164 |
165 | ### Get Schedules Jobs
166 |
167 | Returns a Collection of `ScheduledJob` objects for the server.
168 |
169 | ```php
170 | $jobs = $server->getScheduledJobs();
171 | ```
172 |
173 | ### Add a new scheduled job
174 |
175 | Returns a the newly created `ScheduledJob` object or throws an exception if errors occur.
176 |
177 | ```php
178 | $newJob = $server->addScheduledJob($command, $user = 'forge', $frequency = 'minutely');
179 | ```
180 |
181 | ### toArray
182 |
183 | Returns an array containing all available server information.
184 |
185 | ```php
186 | $data = $server->toArray();
187 | ```
188 |
189 |
190 | ## Site methods
191 |
192 | ### Get Environment
193 |
194 | Returns the configured .env file
195 |
196 | ```php
197 | $env_content = $site->getEnvironment();
198 | ```
199 |
200 | ### Install an application
201 |
202 | Install and deploy an application to the site.
203 |
204 | ```php
205 | $site->installApp($repository, $provider = 'github', $branch = 'master', $composer = true, $migrate = false);
206 | ```
207 |
208 | ### Deploy an application
209 |
210 | Deploys an application on this site.
211 |
212 | ```php
213 | $site->deploy();
214 | ```
215 |
216 | ### Get last deployment log
217 |
218 | Returns the last deployment log for this site.
219 |
220 | ```php
221 | $site->deployLog();
222 | ```
223 |
224 | ### toArray
225 |
226 | Returns an array containing all available site information.
227 |
228 | ```php
229 | $data = $site->toArray();
230 | ```
231 |
232 | ## Circle methods
233 |
234 | ### Invite a member by email
235 |
236 | Returns a fresh `Circle` object or throws an exception if errors occur.
237 |
238 | ```php
239 | $circle = $circle->inviteMember('email@company.com');
240 | ```
241 |
242 | ### Set all circle members
243 |
244 | If you want to delete a member you update a circle with all member id's.
245 | It return a fresh `Circle` object.
246 |
247 | ```php
248 | $circle = $circle->setMembers([1,2]);
249 | ```
250 |
251 | ### Set all circle servers
252 |
253 | If you want to add or delete a server from the circle you update a circle with all server id's.
254 | It return a fresh `Circle` object.
255 |
256 | ```php
257 | $circle = $circle->setServers([1,2]);
258 | ```
259 |
260 | ## Recipe methods
261 |
262 | ### Update a Recipe
263 |
264 | ```php
265 | $recipe = $recipe->update($name, $user, $script);
266 | ```
267 |
268 | ## License
269 |
270 | Blacksmith is free software distributed under the terms of the MIT license.
271 |
--------------------------------------------------------------------------------
/blacksmith:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | '', 'password' => '']));
26 | }
27 | $config = json_decode(file_get_contents(BLACKSMITH_HOME_PATH.'/config.json'));
28 |
29 | $blacksmith = new Blacksmith($config->email, $config->password);
30 |
31 | $app->command('login email password', function ($email, $password, OutputInterface $output) use ($configFile) {
32 | file_put_contents($configFile, json_encode([
33 | 'email' => $email,
34 | 'password' => $password
35 | ]));
36 |
37 | $output->write('Email and Password successfully set.');
38 | });
39 |
40 |
41 | $app->command(
42 | 'servers:list [--format=]',
43 | function ($format, OutputInterface $output) use ($blacksmith) {
44 | $servers = $blacksmith->getActiveServers();
45 |
46 | if($format === 'json') {
47 | $output->writeln(json_encode($servers->toArray(), JSON_PRETTY_PRINT));
48 | exit;
49 | }
50 |
51 | $table = new Table($output);
52 | $table->setHeaders(['ID', 'Name', 'Provider', 'IP Address', 'PHP Version', 'Status', 'Connection']);
53 | $servers->each(function ($server) use ($table, $blacksmith) {
54 | $server = $blacksmith->getServer($server->id);
55 | $table->addRow([$server->id, $server->name, $server->provider, $server->ip_address, $server->php_version, $server->displayable_provision, $server->connection_status]);
56 | });
57 | $table->render();
58 | }
59 | );
60 |
61 | $app->command(
62 | 'servers:get serverId [--format=]',
63 | function ($serverId, $format, OutputInterface $output) use ($blacksmith) {
64 |
65 | $server = $blacksmith->getServer($serverId);
66 |
67 | if($format === 'json') {
68 | $output->writeln(json_encode($server->toArray(), JSON_PRETTY_PRINT));
69 | return;
70 | }
71 |
72 | $table = new Table($output);
73 | $table->setHeaders([
74 | 'ID',
75 | 'Name',
76 | 'Provider',
77 | 'IP Address',
78 | 'PHP Version',
79 | 'Status',
80 | 'Connection'
81 | ]);
82 | $table->addRow([
83 | $server->id,
84 | $server->name,
85 | $server->provider,
86 | $server->ip_address,
87 | $server->php_version,
88 | $server->displayable_provision,
89 | $server->connection_status
90 | ]);
91 | $table->render();
92 | }
93 | );
94 |
95 | $app->command(
96 | 'sites:list [--format=]',
97 | function ($format, OutputInterface $output) use ($blacksmith) {
98 |
99 | $sites = $blacksmith->getSites();
100 |
101 | if($format === 'json') {
102 | $output->writeln(json_encode($sites->toArray(), JSON_PRETTY_PRINT));
103 | return;
104 |
105 | }
106 |
107 | $table = new Table($output);
108 | $table->setHeaders([
109 | 'ID',
110 | 'Name',
111 | 'Server Name',
112 | 'Server ID'
113 | ]);
114 | $sites->each(function ($site) use ($table, $blacksmith) {
115 | $table->addRow([
116 | $site->id,
117 | $site->name,
118 | $site->server_name,
119 | $site->server_id
120 | ]);
121 | });
122 | $table->render();
123 | }
124 | );
125 |
126 | $app->command(
127 | 'sites:get siteId [--format=]',
128 | function ($siteId, $format, OutputInterface $output) use ($blacksmith) {
129 |
130 | $site = $blacksmith->getSite($siteId);
131 |
132 | if($format === 'json') {
133 | $output->writeln(json_encode($site->toArray(), JSON_PRETTY_PRINT));
134 | return;
135 | }
136 |
137 | $table = new Table($output);
138 | $table->setHeaders([
139 | 'ID',
140 | 'Name',
141 | 'Directory',
142 | 'Wildcards',
143 | 'Status',
144 | 'Repository',
145 | 'Server ID',
146 | 'Server Name'
147 | ]);
148 | $table->addRow([
149 | $site->id,
150 | $site->name,
151 | $site->directory,
152 | $site->widlcards,
153 | $site->status,
154 | $site->repository,
155 | $site->server['id'],
156 | $site->server['name'],
157 | ]);
158 | $table->render();
159 | }
160 | );
161 |
162 | $app->command(
163 | 'server:sites:list serverId [--format]',
164 | function ($serverId, $format, OutputInterface $output) use ($blacksmith) {
165 |
166 | $server = $blacksmith->getServer($serverId);
167 | $sites = $server->getSites();
168 |
169 | if($format === 'json') {
170 | $output->writeln(json_encode($sites->toArray(), JSON_PRETTY_PRINT));
171 | exit;
172 | }
173 |
174 | $table = new Table($output);
175 | $table->setHeaders([
176 | 'ID',
177 | 'Name',
178 | 'Directory',
179 | 'Wildcards',
180 | 'Status',
181 | 'Repository',
182 | 'Server ID',
183 | 'Server Name'
184 | ]);
185 |
186 | $sites->each(function ($site) use ($table, $blacksmith, $server) {
187 | $table->addRow([
188 | $site->id,
189 | $site->name,
190 | $site->directory,
191 | $site->wildcards,
192 | $site->status,
193 | $site->repository,
194 | $server->id,
195 | $server->name,
196 | ]);
197 | });
198 |
199 | $table->render();
200 | }
201 | );
202 |
203 | $app->command(
204 | 'server:sites:get serverId siteId [--format=]',
205 | function($serverId, $siteId, $format, OutputInterface $output) use ($blacksmith) {
206 | $server = $blacksmith->getServer($serverId);
207 | $site = $server->getSite($siteId);
208 |
209 | if($format === 'json') {
210 | $output->writeln(json_encode($site->toArray(), JSON_PRETTY_PRINT));
211 | return;
212 | }
213 |
214 | $table = new Table($output);
215 | $table->setHeaders([
216 | 'ID',
217 | 'Name',
218 | 'Directory',
219 | 'Wildcards',
220 | 'Status',
221 | 'Repository',
222 | 'Server ID',
223 | 'Server Name'
224 | ]);
225 |
226 | $table->addRow([
227 | $site->id,
228 | $site->name,
229 | $site->directory,
230 | $site->wildcards,
231 | $site->status,
232 | $site->repository,
233 | $server->id,
234 | $server->name,
235 | ]);
236 |
237 | $table->render();
238 | }
239 | );
240 |
241 |
242 | $app->command(
243 | 'server:sites:add serverId siteName [--projectType=] [--directory=] [--wildcards=] [--format=]',
244 | function($serverId, $siteName, $projectType = 'php', $directory = '/public', $wildcards = false, $format, OutputInterface $output) use ($blacksmith) {
245 | $server = $blacksmith->getServer($serverId);
246 | $site = $server->addSite($siteName, $projectType, $directory, $wildcards);
247 |
248 | if($format === 'json') {
249 | $output->writeln(json_encode($site->toArray(), JSON_PRETTY_PRINT));
250 | exit;
251 | }
252 |
253 | $table = new Table($output);
254 | $table->setHeaders([
255 | 'ID',
256 | 'Name',
257 | 'Directory',
258 | 'Wildcards',
259 | 'Status',
260 | 'Repository',
261 | 'Server ID',
262 | 'Server Name'
263 | ]);
264 |
265 | $table->addRow([
266 | $site->id,
267 | $site->name,
268 | $site->directory,
269 | $site->wildcards,
270 | $site->status,
271 | $site->repository,
272 | $server->id,
273 | $server->name,
274 | ]);
275 |
276 | $table->render();
277 |
278 | }
279 | );
280 |
281 | $app->command(
282 | 'server:sites:remove serverId siteId [--format=]',
283 | function($serverId, $siteId, $format, OutputInterface $output) use ($blacksmith) {
284 | $server = $blacksmith->getServer($serverId);
285 | $response = $server->removeSite($siteId);
286 | if($format === 'json') {
287 | $output->writeln(json_encode($response->toArray(), JSON_PRETTY_PRINT));
288 | return;
289 | }
290 | }
291 | );
292 |
293 | $app->command(
294 | 'server:databases:list serverId [--format=]',
295 | function ($serverId, $format, OutputInterface $output) use ($blacksmith) {
296 |
297 | $server = $blacksmith->getServer($serverId);
298 | $databases = $server->getDatabases();
299 |
300 | if($format === 'json') {
301 | $output->writeln(json_encode($databases->toArray(), JSON_PRETTY_PRINT));
302 | return;
303 | }
304 |
305 | $table = new Table($output);
306 | $table->setHeaders([
307 | 'ID',
308 | 'Name',
309 | 'Status',
310 | 'Server ID',
311 | 'Server Name'
312 | ]);
313 |
314 | $databases->each(function ($database) use ($table, $blacksmith, $server) {
315 | $table->addRow([
316 | $database->id,
317 | $database->name,
318 | $database->status,
319 | $server->id,
320 | $server->name,
321 | ]);
322 | });
323 |
324 | $table->render();
325 | }
326 | );
327 |
328 |
329 | $app->command(
330 | 'server:databases:get serverId databaseId [--format=]',
331 | function($serverId, $databaseId, $format, OutputInterface $output) use ($blacksmith) {
332 | $server = $blacksmith->getServer($serverId);
333 | $database = $server->getDatabase($databaseId);
334 | if($format === 'json') {
335 | $output->writeln(json_encode($database->toArray(), JSON_PRETTY_PRINT));
336 | return;
337 | }
338 |
339 | $table = new Table($output);
340 | $table->setHeaders([
341 | 'ID',
342 | 'Name',
343 | 'Status',
344 | 'Server ID',
345 | 'Server Name'
346 | ]);
347 |
348 | $table->addRow([
349 | $database->id,
350 | $database->name,
351 | $database->status,
352 | $server->id,
353 | $server->name,
354 | ]);
355 |
356 | $table->render();
357 | }
358 | );
359 |
360 | $app->command(
361 | 'server:databases:add serverId databaseName [--username=] [--password=] [--format=]',
362 | function($serverId, $databaseName, $username = '', $password = '', $format, OutputInterface $output) use ($blacksmith) {
363 | $server = $blacksmith->getServer($serverId);
364 | $database = $server->addDatabase($databaseName, $username, $password);
365 | if($format === 'json') {
366 | $output->writeln(json_encode($database->toArray(), JSON_PRETTY_PRINT));
367 | return;
368 | }
369 |
370 | $table = new Table($output);
371 | $table->setHeaders([
372 | 'ID',
373 | 'Name',
374 | 'Status',
375 | 'Server ID',
376 | 'Server Name'
377 | ]);
378 |
379 | $table->addRow([
380 | $database->id,
381 | $database->name,
382 | $database->status,
383 | $server->id,
384 | $server->name,
385 | ]);
386 |
387 | $table->render();
388 | }
389 | );
390 |
391 | $app->command(
392 | 'server:databases:remove serverId databaseId [--format=]',
393 | function($serverId, $databaseId, $format, OutputInterface $output) use ($blacksmith) {
394 | $server = $blacksmith->getServer($serverId);
395 | $response = $server->removeDatabase($databaseId);
396 | if($format === 'json') {
397 | $output->writeln(json_encode($response->toArray(), JSON_PRETTY_PRINT));
398 | return;
399 | }
400 | }
401 | );
402 |
403 |
404 | $app->command(
405 | 'server:database_users:list serverId [--format=]',
406 | function ($serverId, $format, OutputInterface $output) use ($blacksmith) {
407 |
408 | $server = $blacksmith->getServer($serverId);
409 | $databaseUsers = $server->getDatabaseUsers();
410 |
411 | if($format === 'json') {
412 | echo (json_encode($databaseUsers->toArray(), JSON_PRETTY_PRINT));
413 | return;
414 | }
415 |
416 | $table = new Table($output);
417 | $table->setHeaders([
418 | 'ID',
419 | 'Name',
420 | 'Status',
421 | 'Server ID',
422 | 'Server Name',
423 | 'Databases',
424 | ]);
425 |
426 | $databaseUsers->each(function ($databaseUser) use ($table, $blacksmith, $server) {
427 | $databases = $databaseUser->getDatabases();
428 | $databaseNames = $databases->transform(function($database){
429 | return $database->name;
430 | });
431 | $table->addRow([
432 | $databaseUser->id,
433 | $databaseUser->name,
434 | $databaseUser->status,
435 | $server->id,
436 | $server->name,
437 | implode("\n", $databaseNames->toArray()),
438 | ]);
439 | });
440 |
441 | $table->render();
442 | }
443 | );
444 |
445 | $app->command(
446 | 'server:database_users:get serverId databaseUserId [--format=]',
447 | function($serverId, $databaseUserId, $format, OutputInterface $output) use ($blacksmith) {
448 | $server = $blacksmith->getServer($serverId);
449 | $databaseUser = $server->getDatabaseUser($databaseUserId);
450 |
451 | if($format === 'json') {
452 | echo (json_encode($databaseUser->toArray(), JSON_PRETTY_PRINT));
453 | return;
454 | }
455 |
456 | $table = new Table($output);
457 | $table->setHeaders([
458 | 'ID',
459 | 'Name',
460 | 'Status',
461 | 'Server ID',
462 | 'Server Name',
463 | 'Databases',
464 | ]);
465 |
466 | $databases = $databaseUser->getDatabases();
467 | $databaseNames = $databases->transform(function($database){
468 | return $database->name;
469 | });
470 | $table->addRow([
471 | $databaseUser->id,
472 | $databaseUser->name,
473 | $databaseUser->status,
474 | $server->id,
475 | $server->name,
476 | implode("\n", $databaseNames->toArray()),
477 | ]);
478 |
479 | $table->render();
480 | }
481 | );
482 |
483 | $app->command(
484 | 'server:database_users:add serverId username password [--canAccess=]* [--format=]',
485 | function($serverId, $username, $password, $canAccess = array(), $format, OutputInterface $output) use ($blacksmith) {
486 | $server = $blacksmith->getServer($serverId);
487 | $databaseUser = $server->addDatabaseUser($username, $password, $canAccess);
488 |
489 | if($format === 'json') {
490 | echo (json_encode($databaseUser->toArray(), JSON_PRETTY_PRINT));
491 | return;
492 | }
493 |
494 | $table = new Table($output);
495 | $table->setHeaders([
496 | 'ID',
497 | 'Name',
498 | 'Status',
499 | 'Server ID',
500 | 'Server Name'
501 | ]);
502 |
503 | $databases = $databaseUser->getDatabases();
504 | $table->addRow([
505 | $databaseUser->id,
506 | $databaseUser->name,
507 | $databaseUser->status,
508 | $server->id,
509 | $server->name
510 | ]);
511 |
512 | $table->render();
513 | });
514 |
515 | $app->command(
516 | 'server:database_users:remove serverId databaseUserId [--format=]',
517 | function($serverId, $databaseUserId, $format, OutputInterface $output) use ($blacksmith) {
518 | $server = $blacksmith->getServer($serverId);
519 | $response = $server->removeDatabaseUser($databaseUserId);
520 | if($format === 'json') {
521 | $output->writeln(json_encode($response->toArray(), JSON_PRETTY_PRINT));
522 | return;
523 | }
524 | }
525 | );
526 |
527 | $app->command(
528 | 'server:database_users:update serverId username [--canAccess=]* [--format=]',
529 | function($serverId, $username, $canAccess = array(), $format, OutputInterface $output) use ($blacksmith) {
530 | $server = $blacksmith->getServer($serverId);
531 | $databaseUser = $server->updateDatabaseUser($username, $canAccess);
532 |
533 | if($format === 'json') {
534 | echo (json_encode($databaseUser->toArray(), JSON_PRETTY_PRINT));
535 | return;
536 | }
537 |
538 | $table = new Table($output);
539 | $table->setHeaders([
540 | 'ID',
541 | 'Name',
542 | 'Status',
543 | 'Server ID',
544 | 'Server Name'
545 | ]);
546 |
547 | $table->addRow([
548 | $databaseUser->id,
549 | $databaseUser->name,
550 | $databaseUser->status,
551 | $server->id,
552 | $server->name
553 | ]);
554 |
555 | $table->render();
556 | });
557 |
558 |
559 | $app->command(
560 | 'server:ssh_keys:list serverId [--format=]',
561 | function ($serverId, $format, OutputInterface $output) use ($blacksmith) {
562 |
563 | $server = $blacksmith->getServer($serverId);
564 | $sshKeys = $server->getSSHKeys();
565 |
566 | if($format === 'json') {
567 | $output->writeln(json_encode($sshKeys->toArray(), JSON_PRETTY_PRINT));
568 | return;
569 | }
570 |
571 | $table = new Table($output);
572 | $table->setHeaders([
573 | 'ID',
574 | 'Name',
575 | 'Status',
576 | 'Server ID',
577 | 'Server Name'
578 | ]);
579 |
580 | $sshKeys->each(function ($sshKey) use ($table, $blacksmith, $server) {
581 | $table->addRow([
582 | $sshKey->id,
583 | $sshKey->name,
584 | $sshKey->status,
585 | $server->id,
586 | $server->name
587 | ]);
588 | });
589 |
590 | $table->render();
591 | }
592 | );
593 |
594 | $app->command(
595 | 'server:ssh_keys:add serverId name key [--format=]',
596 | function($serverId, $name, $key, $format, OutputInterface $output) use ($blacksmith) {
597 | $server = $blacksmith->getServer($serverId);
598 | $sshKey = $server->addSSHKey($name, $key);
599 |
600 | if($format === 'json') {
601 | echo (json_encode($sshKey->toArray(), JSON_PRETTY_PRINT));
602 | return;
603 | }
604 |
605 | $table = new Table($output);
606 | $table->setHeaders([
607 | 'ID',
608 | 'Name',
609 | 'Status',
610 | 'Server ID',
611 | 'Server Name'
612 | ]);
613 |
614 | $table->addRow([
615 | $sshKey->id,
616 | $sshKey->name,
617 | $sshKey->status,
618 | $server->id,
619 | $server->name
620 | ]);
621 |
622 | $table->render();
623 | });
624 |
625 | $app->command(
626 | 'server:ssh_keys:remove serverId sshKeyId [--format=]',
627 | function($serverId, $sshKeyId, $format, OutputInterface $output) use ($blacksmith) {
628 | $server = $blacksmith->getServer($serverId);
629 | $response = $server->removeSSHKey($sshKeyId);
630 | if($format === 'json') {
631 | $output->writeln(json_encode($response->toArray(), JSON_PRETTY_PRINT));
632 | return;
633 | }
634 | }
635 | );
636 |
637 | $app->command(
638 | 'server:scheduled_jobs:list serverId [--format=]',
639 | function ($serverId, $format, OutputInterface $output) use ($blacksmith) {
640 |
641 | $server = $blacksmith->getServer($serverId);
642 | $scheduledJobs = $server->getScheduledJobs();
643 |
644 | if($format === 'json') {
645 | $output->writeln(json_encode($scheduledJobs->toArray(), JSON_PRETTY_PRINT));
646 | return;
647 | }
648 |
649 | $table = new Table($output);
650 | $table->setHeaders([
651 | 'ID',
652 | 'Command',
653 | 'User',
654 | 'Frequency',
655 | 'Cron',
656 | 'Status',
657 | 'Server ID',
658 | 'Server Name'
659 | ]);
660 |
661 | $scheduledJobs->each(function ($scheduledJob) use ($table, $blacksmith, $server) {
662 | $table->addRow([
663 | $scheduledJob->id,
664 | $scheduledJob->command,
665 | $scheduledJob->user,
666 | $scheduledJob->frequency,
667 | $scheduledJob->cron,
668 | $scheduledJob->status,
669 | $server->id,
670 | $server->name
671 | ]);
672 | });
673 |
674 | $table->render();
675 | }
676 | );
677 |
678 | $app->command(
679 | 'server:scheduled_jobs:add serverId script user frequency [--format=]',
680 | function($serverId, $script, $user, $frequency, $format, OutputInterface $output) use ($blacksmith) {
681 | $server = $blacksmith->getServer($serverId);
682 | $scheduledJob = $server->addScheduledJob($script, $user, $frequency);
683 |
684 | if($format === 'json') {
685 | echo (json_encode($scheduledJob->toArray(), JSON_PRETTY_PRINT));
686 | return;
687 | }
688 |
689 | $table = new Table($output);
690 | $table->setHeaders([
691 | 'ID',
692 | 'Command',
693 | 'User',
694 | 'Frequency',
695 | 'Cron',
696 | 'Status',
697 | 'Server ID',
698 | 'Server Name'
699 | ]);
700 |
701 | $table->addRow([
702 | $scheduledJob->id,
703 | $scheduledJob->command,
704 | $scheduledJob->user,
705 | $scheduledJob->frequency,
706 | $scheduledJob->cron,
707 | $scheduledJob->status,
708 | $server->id,
709 | $server->name
710 | ]);
711 |
712 | $table->render();
713 | }
714 | );
715 |
716 | $app->command(
717 | 'server:scheduled_jobs:remove serverId scheduledJobId [--format=]',
718 | function($serverId, $scheduledJobId, $format, OutputInterface $output) use ($blacksmith) {
719 | $server = $blacksmith->getServer($serverId);
720 | $response = $server->removeScheduledJob($scheduledJobId);
721 | if($format === 'json') {
722 | $output->writeln(json_encode($response, JSON_PRETTY_PRINT));
723 | return;
724 | }
725 | }
726 | );
727 |
728 | $app->command(
729 | 'server:max_file_upload_size:update serverId megabytes [--format=]',
730 | function($serverId, $megabytes, $format, OutputInterface $output) use ($blacksmith) {
731 | $server = $blacksmith->getServer($serverId);
732 | $response = $server->updateMaxFileUploadSize($megabytes);
733 | if($format === 'json') {
734 | $output->writeln(json_encode($response, JSON_PRETTY_PRINT));
735 | return;
736 | }
737 | }
738 | );
739 |
740 | $app->command(
741 | 'server:meta:update serverId serverName ipAddress size [--privateIpAddress=] [--format=]',
742 | function($serverId, $serverName, $ipAddress, $privateIpAddress = '', $size, $format, OutputInterface $output) use ($blacksmith) {
743 | $server = $blacksmith->getServer($serverId);
744 | $response = $server->updateMetadata($serverName, $ipAddress, $privateIpAddress, $size);
745 | if($format === 'json') {
746 | $output->writeln(json_encode($response, JSON_PRETTY_PRINT));
747 | return;
748 | }
749 | }
750 | );
751 |
752 | $app->command(
753 | 'site:environment:get siteId [--format=]',
754 | function ($siteId, $format, OutputInterface $output) use ($blacksmith) {
755 | $site = $blacksmith->getSite($siteId);
756 | $response = $site->getEnvironment();
757 | if($format === 'json') {
758 | $output->write(json_encode($response, JSON_PRETTY_PRINT));
759 | return;
760 | }
761 | }
762 | );
763 |
764 | $app->command(
765 | 'site:environment:update siteId data [--format=]',
766 | function ($siteId, $data, $format, OutputInterface $output) use ($blacksmith) {
767 | $site = $blacksmith->getSite($siteId);
768 | $response = $site->updateEnvironment($data);
769 | if($format === 'json') {
770 | $output->writeln(json_encode($response, JSON_PRETTY_PRINT));
771 | return;
772 | }
773 | }
774 | );
775 |
776 | $app->command(
777 | 'site:nginx_config:get siteId [--format=]',
778 | function ($siteId, $format, OutputInterface $output) use ($blacksmith) {
779 | $site = $blacksmith->getSite($siteId);
780 | $response = $site->getNginxConfig();
781 | if($format === 'json') {
782 | $output->writeln(json_encode($response, JSON_PRETTY_PRINT));
783 | return;
784 | }
785 | }
786 | );
787 |
788 | $app->command(
789 | 'site:nginx_config:update siteId data [--format=]',
790 | function ($siteId, $data, $format, OutputInterface $output) use ($blacksmith) {
791 | $site = $blacksmith->getSite($siteId);
792 | $response = $site->updateNginxConfig($data);
793 | if($format === 'json') {
794 | $output->writeln(json_encode($response, JSON_PRETTY_PRINT));
795 | return;
796 | }
797 | }
798 | );
799 |
800 | $app->command(
801 | 'site:web_directory:update siteId directory [--format=]',
802 | function ($siteId, $directory, $format, OutputInterface $output) use ($blacksmith) {
803 | $site = $blacksmith->getSite($siteId);
804 | $response = $site->updateWebDirectory($directory);
805 | if($format === 'json') {
806 | $output->writeln(json_encode($response, JSON_PRETTY_PRINT));
807 | return;
808 | }
809 | }
810 | );
811 |
812 | $app->command('site:deploy siteId', function ($siteId, OutputInterface $output) use ($blacksmith) {
813 | $site = $blacksmith->getSite($siteId);
814 | $site->deploy();
815 | $output->writeln('Deployed '.$site->name.' successfully!');
816 | });
817 |
818 | $app->command('site:deploy:log siteId', function ($siteId, OutputInterface $output) use ($blacksmith) {
819 | $site = $blacksmith->getSite($siteId);
820 |
821 | $output->writeln('Last deployment log for: '.$site->name.'');
822 | $output->write($site->deployLog());
823 | });
824 |
825 | /**
826 | * Run the application.
827 | */
828 | $app->run();
829 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mpociot/blacksmith",
3 | "license": "MIT",
4 | "description": "The unofficial Laravel Forge API",
5 | "keywords": [
6 | "API",
7 | "Forge",
8 | "Laravel"
9 | ],
10 | "homepage": "http://github.com/mpociot/blacksmith",
11 | "authors": [
12 | {
13 | "name": "Marcel Pociot",
14 | "email": "m.pociot@gmail.com"
15 | }
16 | ],
17 | "require": {
18 | "php": ">=5.5.0",
19 | "tightenco/collect": "~5.0",
20 | "behat/mink-goutte-driver": "^1.2",
21 | "behat/mink": "^1.7",
22 | "mnapoli/silly": "^1.5"
23 | },
24 | "require-dev": {
25 | "phpunit/phpunit": "~5.0",
26 | "mockery/mockery": "^0.9.5"
27 | },
28 | "autoload": {
29 | "psr-0": {
30 | "Mpociot\\Blacksmith": "src/"
31 | }
32 | },
33 | "bin": [
34 | "blacksmith"
35 | ]
36 | }
37 |
--------------------------------------------------------------------------------
/doc/servers.md:
--------------------------------------------------------------------------------
1 | # Servers
2 |
3 | ## Get all active servers
4 |
5 | Returns a Collection of `Server` objects.
6 |
7 | ```php
8 | $activeServers = $blacksmith->getActiveServers();
9 | ```
10 |
11 | ## Get all servers
12 |
13 | Returns a Collection of `Server` objects.
14 |
15 | ```php
16 | $servers = $blacksmith->getServers();
17 | ```
18 |
19 | ## Get a server by its ID
20 |
21 | Returns a single `Server` object.
22 |
23 | ```php
24 | $server = $blacksmith->getServer(1);
25 | ```
26 |
27 | ## Add a server to Forge
28 |
29 | ### Globals options to set
30 |
31 | PHP version options
32 | - 'php71' - Install PHP 7.1 on the server
33 | - 'php70' - Install PHP 7.0 on the server
34 | - 'php56' - Install PHP 5.6 on the server
35 |
36 | Database option
37 | Set the 'maria' key on the configuration with one of the following
38 | - true - Server will install and use MariaDB 10.1
39 | - false - Server will install and use MySQL 5.7
40 |
41 | ### Add a server with DigitalOcean 2.0 provider
42 |
43 | If you want weekly backups on DigitalOcean for this server set the 'backups' key to **true**.
44 |
45 | ```php
46 | $server = $blacksmith->addServer([
47 | 'backups' => false
48 | 'credential' => _CREDENTIAL_ID_
49 | 'database' => 'forge'
50 | 'hhvm' => false
51 | 'maria' => true
52 | 'name' => 'solitary-fern'
53 | 'nodeBalancer' => false
54 | 'old_php' => false
55 | 'php_version' => 'php70'
56 | 'provider' => 'ocean2'
57 | 'region' => 'ams3'
58 | 'size' => '1GB'
59 | 'timezone' => 'Europe/Berlin'
60 | ]);
61 | ```
62 |
63 | Replace _CREDENTIAL_ID_ with your DigitalOcean2.0 provider credential ID.
64 |
65 | Possible size options:
66 | - '512MB' => 512MB RAM, 1 CPU, 20GB SSD, 1TB Transfer
67 | - '1GB' => 1GB RAM, 1 CPU, 30GB SSD, 2TB Transfer
68 | - '2GB' => 2GB RAM, 2 CPU, 40GB SSD, 3TB Transfer
69 | - '4GB' => 4GB RAM, 2 CPU, 60GB SSD, 4TB Transfer
70 | - '8GB' => 8GB RAM, 4 CPU, 80GB SSD, 5TB Transfer
71 | - '16GB' => 16GB RAM, 8 CPU, 160GB SSD, 6TB Transfer
72 | - 'm-16GB' => 16GB RAM, 2 CPU, 30GB SSD, 6TB Transfer
73 | - '32GB' => 32GB RAM, 12 CPU, 320GB SSD, 7TB Transfer
74 | - 'm-32GB' => 32GB RAM, 4 CPU, 90GB SSD, 7TB Transfer
75 | - '64GB' => 64GB RAM, 20 CPU, 640GB SSD, 9TB Transfer
76 | - 'm-64GB' => 64GB RAM, 8 CPU, 200GB SSD, 8TB Transfer
77 |
78 | Possible region options:
79 | - 'ams2' => Amsterdam 2
80 | - 'ams3' => Amsterdam 3
81 | - 'blr1' => Bangalore
82 | - 'lon1' => London
83 | - 'fra1' => Frankfurt
84 | - 'nyc1' => New York 1
85 | - 'nyc2' => New York 2
86 | - 'nyc3' => New York 3
87 | - 'sfo1' => San Francisco 1
88 | - 'sfo2' => San Francisco 2
89 | - 'sgp1' => Singapore
90 | - 'tor1' => Toronto
91 |
92 | ### Add a server with Linode provider
93 |
94 | ```php
95 | $server = $blacksmith->addServer([
96 | 'backups' => false
97 | 'credential' => _CREDENTIAL_ID_
98 | 'database' => 'forge'
99 | 'hhvm' => false
100 | 'maria' => true
101 | 'name' => 'moonlight-fern'
102 | 'nodeBalancer' => false
103 | 'old_php' => false
104 | 'php_version' => 'php70'
105 | 'provider' => 'linode'
106 | 'region' => 7
107 | 'size' => '2GB'
108 | 'timezone' => 'Europe/Berlin'
109 | ]);
110 | ```
111 |
112 | Replace _CREDENTIAL_ID_ with your Linode provider credential ID.
113 |
114 | Possible size options:
115 | - '2GB' => 2GB RAM - 1 CPU Cores - 24GB SSD - $0.015 / Hour - $10 / Month
116 | - '4GB' => 4GB RAM - 2 CPU Cores - 48GB SSD - $0.03 / Hour - $20 / Month
117 | - '8GB' => 8GB RAM - 4 CPU Cores - 96GB SSD - $0.06 / Hour - $40 / Month
118 | - '12GB' => 12GB RAM - 6 CPU Cores - 192GB SSD - $0.12 / Hour - $80 / Month
119 | - '24GB' => 24GB RAM - 8 CPU Cores - 384GB SSD - $0.24 / Hour - $160 / Month
120 | - '48GB' => 48GB RAM - 12 CPU Cores - 768GB SSD - $0.48 / Hour - $320 / Month
121 | - '64GB' => 64GB RAM - 16 CPU Cores - 1152GB SSD - $0.72 / Hour - $480 / Month
122 | - '80GB' => 80GB RAM - 20 CPU Cores - 1536GB SSD - $0.96 / Hour - $640 / Month
123 | - '120GB' => 120GB RAM - 20 CPU Cores - 1920GB SSD - $1.44 / Hour - $960 / Month
124 |
125 | Possible region options:
126 | - 4 => Atlanta
127 | - 2 => Dallas
128 | - 10 => Frankfurt
129 | - 3 => Fremont
130 | - 7 => London
131 | - 6 => Newark
132 | - 9 => Singapore
133 | - 8 => Tokyo
134 |
135 | ### Add a server with Amazon provider
136 |
137 | ```php
138 | $server = $blacksmith->addServer([
139 | 'backups' => false
140 | 'credential' => _CREDENTIAL_ID_
141 | 'database' => 'forge'
142 | 'hhvm' => false
143 | 'maria' => true
144 | 'name' => 'howling-moon'
145 | 'nodeBalancer' => false
146 | 'old_php' => false
147 | 'php_version' => 'php70'
148 | 'provider' => 'aws'
149 | 'region' => 7
150 | 'size' => '2GB'
151 | 'timezone' => 'Europe/Berlin'
152 | ]);
153 | ```
154 |
155 | Replace _CREDENTIAL_ID_ with your Amazon provider credential ID.
156 |
157 | Possible size options:
158 | - '1GB' => 1 GiB RAM - 1 vCPU - $0.013 / Hour - $10 / Month
159 | - '2GB' => 2 GiB RAM - 1 vCPU - $0.026 / Hour - $20 / Month
160 | - '4GB' => 4 GiB RAM - 2 vCPUs - $0.052 / Hour - $40 / Month
161 | - '8GB' => 8 GiB RAM - 2 vCPUs - $0.104 / Hour - $80 / Month
162 | - '16GB' => 16 GiB RAM - 4 vCPUs - $0.239 / Hour - $175 / Month
163 | - '32GB' => 32 GiB RAM - 8 vCPUs - $0.479 / Hour - $350 / Month
164 | - '64GB' => 64 GiB RAM - 16 vCPUs - $0.958 / Hour - $700 / Month
165 |
166 | Possible region options:
167 | - 'us-west-1' => California
168 | - 'eu-west-1' => Ireland
169 | - 'eu-central-1' => Frankfurt
170 | - 'us-west-2' => Oregon
171 | - 'sa-east-1' => Sao Paulo
172 | - 'ap-northeast-2' => Seoul
173 | - 'ap-southeast-1' => Singapore
174 | - 'ap-southeast-2' => Sydney
175 | - 'ap-northeast-1' => Tokyo
176 | - 'us-east-1' => Virginia
177 |
178 | ### Add a custom server example
179 |
180 | The following example will create a server with a custom provider.
181 | Returns a single `Server` object with a provision url.
182 |
183 | Fields to override:
184 | - ip_address
185 | - name
186 | - size
187 | - private_ip_address
188 |
189 | ```php
190 | $server = $blacksmith->addServer([
191 | 'backups' => false,
192 | 'database' => 'forge',
193 | 'hhvm' => false,
194 | 'ip_address' => '123.212.124.121',
195 | 'maria' => false,
196 | 'name' => 'sparkling-lake',
197 | 'nodeBalancer' => false,
198 | 'old_php' => false,
199 | 'php_version' => 'php70',
200 | 'private_ip_address' => '',
201 | 'provider' => 'custom',
202 | 'size' => '2',
203 | 'timezone' => 'Europe/Berlin',
204 | ]);
205 | ```
206 |
207 | ### Add a custom LoadBalancer example
208 |
209 | The following example will create a Load Balancer with a custom provider.
210 | Returns a single `Server` object with a provision url.
211 |
212 | Fields to override:
213 | - ip_address
214 | - name
215 | - size
216 | - private_ip_address
217 |
218 | ```php
219 | $server = $blacksmith->addServer([
220 | 'backups' => false,
221 | 'database' => 'forge',
222 | 'hhvm' => false,
223 | 'ip_address' => '123.212.124.121',
224 | 'maria' => false,
225 | 'name' => 'harmonious-lagoon',
226 | 'nodeBalancer' => true,
227 | 'old_php' => false,
228 | 'php_version' => 'php70',
229 | 'private_ip_address' => '10.0.0.2',
230 | 'provider' => 'custom',
231 | 'size' => '2',
232 | 'timezone' => 'Europe/Berlin',
233 | ]);
234 | ```
235 |
236 | Notice the difference on the custom servers. The only change is nodeBalancer is set to true instead of false when a nodeBalancer is needed.
237 |
238 | ## Remove a server by its ID
239 |
240 | Remove a server from Forge. Don't try this at home, you have been warned..
241 |
242 | ```php
243 | $server = $blacksmith->deleteServer(1);
244 | ```
245 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 | tests/
16 |
17 |
18 |
19 |
20 | src/Mpociot/
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/Mpociot/Blacksmith/Blacksmith.php:
--------------------------------------------------------------------------------
1 | browser = new Browser($email, $password);
30 | }
31 |
32 | /**
33 | * @return Collection A list of servers from /api/servers/active
34 | */
35 | public function getActiveServers()
36 | {
37 | return $this->browser->getContent('https://forge.laravel.com/api/servers/active')->transform(function ($data) {
38 | return new Server($data, $this->browser);
39 | });
40 | }
41 |
42 | /**
43 | * Get all available servers
44 | *
45 | * @return Collection A collection of servers from /api/servers
46 | */
47 | public function getServers()
48 | {
49 | return $this->browser->getContent('https://forge.laravel.com/api/servers')->transform(function ($data) {
50 | return new Server($data, $this->browser);
51 | });
52 | }
53 |
54 | /**
55 | * Get a single server by its ID or name
56 | *
57 | * @param $id
58 | * @return Server A single server from /api/servers/:serverId
59 | * @throws Exception
60 | */
61 | public function getServer($id)
62 | {
63 | if(!is_numeric($id)) {
64 | $servers = $this->getServers();
65 | $server = $servers->filter(function($server) use ($id){ return $server->name == $id; })->first();
66 | if($server) {
67 | $id = $server->id;
68 | }
69 | }
70 |
71 | $serverData = $this->browser->getContent('https://forge.laravel.com/api/servers/'.$id)->toArray();
72 |
73 | if(!$serverData) {
74 | throw new Exception(sprintf('Server "%s" could not be found', $id));
75 | }
76 |
77 | return new Server($serverData, $this->browser);
78 | }
79 |
80 | /**
81 | * Add new server to Forge with given configuration
82 | *
83 | * @param array $server_configuration
84 | * @return Server
85 | * @throws Exception
86 | */
87 | public function addServer($server_configuration)
88 | {
89 | $result = $this->browser->postContent('https://forge.laravel.com/servers', $server_configuration);
90 |
91 | if ($this->browser->getSession()->getStatusCode() === 500) {
92 | throw new Exception('Error: '.print_r($result, true));
93 | }
94 |
95 | // Add the provision URL
96 | $result['provision_url'] = 'wget -O forge.sh https://forge.laravel.com/servers/'.$result['id'].'/vps?forge_token='.$this->getUser()->forge_token.'; bash forge.sh';
97 |
98 | return new Server($result, $this->browser);
99 | }
100 |
101 | /**
102 | * Delete a server by its ID or name
103 | *
104 | * @param $id
105 | */
106 | public function deleteServer($id)
107 | {
108 | if(!is_numeric($id)) {
109 | $server = $this->getServer($id);
110 | $id = $server->id;
111 | }
112 |
113 | $this->browser->deleteContent('https://forge.laravel.com/servers/'.$id);
114 | }
115 |
116 | /**
117 | * Get sites
118 | *
119 | * @return Collection of sites from /api/servers/sites/list
120 | */
121 | public function getSites(){
122 | $sites = $this->browser->getContent('https://forge.laravel.com/api/servers/sites/list')->transform(function ($data) {
123 | return new Site($data, $this->browser);
124 | });
125 | return $sites;
126 | }
127 |
128 | /**
129 | * Get a single site by its ID or name
130 | *
131 | * @param $id
132 | * @return Site A single site from /api/servers/:serverId/sites/:siteId
133 | * @throws Exception
134 | */
135 | public function getSite($id)
136 | {
137 | $sites = $this->getSites();
138 | $criteria = !is_numeric($id) ? 'name' : 'id';
139 | $site = $sites->filter(function($site) use ($criteria, $id){
140 | return $site->{$criteria} == $id;
141 | })->first();
142 |
143 | $siteData = $this->browser->getContent('https://forge.laravel.com/api/servers/'.$site->server_id.'/sites/'.$site->id)->toArray();
144 |
145 | if(!$siteData) {
146 | throw new Exception(sprintf('Site "%s" could not be found', $id));
147 | }
148 |
149 | return new Site($siteData, $this->browser);
150 | }
151 |
152 | /**
153 | * Get all circles
154 | *
155 | * @return Collection
156 | */
157 | public function getCircles()
158 | {
159 | return $this->browser->getContent('https://forge.laravel.com/api/circles')->transform(function ($data) {
160 | return new Circle($data, $this->browser);
161 | });
162 | }
163 |
164 | /**
165 | * Get a single circle by its ID
166 | *
167 | * @param $id
168 | * @return mixed
169 | * @throws Exception
170 | */
171 | public function getCircle($id)
172 | {
173 | $circles = $this->getCircles();
174 | $criteria = is_numeric($id) ? 'id': 'name';
175 | $circle = $circles->filter(function($circle) use ($criteria, $id){
176 | return $circle->$criteria = $id;
177 | })->first();
178 |
179 | if(!$circle) {
180 | throw new Exception(sprintf('Circle "%s" could not be found', $id));
181 | }
182 |
183 | return $circle;
184 | }
185 |
186 | /**
187 | * Add a new Circle
188 | *
189 | * @param string $name
190 | * @return Circle
191 | */
192 | public function addCircle($name)
193 | {
194 | $result = $this->browser->postContent('https://forge.laravel.com/circles', ['name' => $name]);
195 | return new Circle($result, $this->browser);
196 | }
197 |
198 | /**
199 | * Delete a Circle
200 | *
201 | * @param int $id
202 | * @return mixed
203 | */
204 | public function deleteCircle($id)
205 | {
206 | $circle = $this->getCircle($id);
207 | return $this->browser->deleteContent('https://forge.laravel.com/circles/'.$circle->id);
208 | }
209 |
210 | /**
211 | * Get all recipes
212 | *
213 | * @return Collection
214 | */
215 | public function getRecipes()
216 | {
217 | return $this->browser->getContent('https://forge.laravel.com/api/recipes')->transform(function ($data) {
218 | return new Recipe($data, $this->browser);
219 | });
220 | }
221 |
222 | /**
223 | * Get a single recipe by its ID or name
224 | *
225 | * @param int $id
226 | * @return Recipe
227 | */
228 | public function getRecipe($id)
229 | {
230 | $recipes = $this->getRecipes();
231 | $criteria = is_numeric($id) ? 'id': 'name';
232 |
233 | $recipe = $recipes->filter(function($recipe) use ($criteria, $id){
234 | return $recipe->$criteria = $id;
235 | })->first();
236 |
237 | return $recipe;
238 | }
239 |
240 | /**
241 | * Add a new Recipe
242 | *
243 | * @param string $name
244 | * @return Recipe
245 | */
246 | public function addRecipe($name, $user, $script)
247 | {
248 | $result = $this->browser->postContent('https://forge.laravel.com/recipes', [
249 | 'name' => $name,
250 | 'user' => $user,
251 | 'script' => $script,
252 | ]);
253 | return new Recipe($result, $this->browser);
254 | }
255 |
256 | /**
257 | * Delete a Recipe
258 | *
259 | * @param int $id
260 | * @return mixed
261 | */
262 | public function deleteRecipe($id)
263 | {
264 | $recipe = $this->getRecipe($id);
265 | return $this->browser->deleteContent('https://forge.laravel.com/recipes/'.$recipe->id);
266 | }
267 |
268 | /**
269 | * Get the logged in User
270 | *
271 | * @return User
272 | */
273 | public function getUser()
274 | {
275 | $user = $this->browser->getContent('https://forge.laravel.com/api/user')->toArray();
276 | return new User($user, $this->browser);
277 | }
278 | }
279 |
--------------------------------------------------------------------------------
/src/Mpociot/Blacksmith/Browser.php:
--------------------------------------------------------------------------------
1 | session = new Session(new BlacksmithDriver());
37 | $this->session->start();
38 |
39 | $this->email = $email;
40 | $this->password = $password;
41 | }
42 |
43 | /**
44 | * @throws Exception
45 | */
46 | protected function login()
47 | {
48 | $this->session->visit(self::LOGIN_URL);
49 | $page = $this->session->getPage();
50 | $page->find('css', '#email')->setValue($this->email);
51 | $page->find('css', 'input[type="password"]')->setValue($this->password);
52 | $page->find('css', 'form')->submit();
53 |
54 | if ($this->session->getCurrentUrl() === self::LOGIN_URL) {
55 | throw new Exception('Invalid login');
56 | }
57 | $this->logged_in = true;
58 | }
59 |
60 | /**
61 | * @param $url
62 | * @param bool $raw
63 | * @return \Illuminate\Support\Collection
64 | * @throws Exception
65 | */
66 | public function getContent($url, $raw = false)
67 | {
68 | if ($this->logged_in === false) {
69 | $this->login();
70 | }
71 |
72 | $this->session->visit($url);
73 | $content = $this->session->getPage()->getContent();
74 |
75 | if ($raw) {
76 | return $content;
77 | }
78 | return collect(json_decode($content, true));
79 | }
80 |
81 | /**
82 | * @param $url
83 | * @param $payload
84 | * @param $raw
85 | * @return mixed
86 | * @throws Exception
87 | */
88 | public function postContent($url, $payload, $raw = false)
89 | {
90 | if ($this->logged_in === false) {
91 | $this->login();
92 | }
93 |
94 | $this->session->getDriver()->post($url, json_encode($payload));
95 | $content = $this->session->getPage()->getContent();
96 |
97 | if ($raw) {
98 | return $content;
99 | }
100 | return json_decode($content, true);
101 | }
102 |
103 | /**
104 | * @param $url
105 | * @param $payload
106 | * @return mixed
107 | * @throws Exception
108 | */
109 | public function putContent($url, $payload)
110 | {
111 | if ($this->logged_in === false) {
112 | $this->login();
113 | }
114 |
115 | $this->session->getDriver()->put($url, json_encode($payload));
116 | return json_decode($this->session->getPage()->getContent(), true);
117 | }
118 |
119 | /**
120 | * @param $url
121 | * @return mixed
122 | * @throws Exception
123 | */
124 | public function deleteContent($url)
125 | {
126 | if ($this->logged_in === false) {
127 | $this->login();
128 | }
129 |
130 | return $this->session->getDriver()->delete($url);
131 | }
132 |
133 | /**
134 | * Gets the value of session.
135 | *
136 | * @return mixed
137 | */
138 | public function getSession()
139 | {
140 | return $this->session;
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/src/Mpociot/Blacksmith/Driver/BlacksmithDriver.php:
--------------------------------------------------------------------------------
1 | getClient()->request('POST', $this->prepareUrl($url), [], [], [
15 | 'HTTP_ACCEPT' => 'application/json',
16 | 'HTTP_CONTENT_TYPE' => 'application/json',
17 | 'HTTP_X_XSRF_TOKEN' => $this->getClient()->getCookieJar()->get('XSRF-TOKEN')->getValue()
18 | ], $postData);
19 | }
20 |
21 | /**
22 | * Perform a PUT request
23 | */
24 | public function put($url, $postData)
25 | {
26 | $this->getClient()->request('PUT', $this->prepareUrl($url), [], [], [
27 | 'HTTP_ACCEPT' => 'application/json',
28 | 'HTTP_CONTENT_TYPE' => 'application/json',
29 | 'HTTP_X_XSRF_TOKEN' => $this->getClient()->getCookieJar()->get('XSRF-TOKEN')->getValue()
30 | ], $postData);
31 | }
32 |
33 | /**
34 | * Perform a PUT request
35 | */
36 | public function delete($url)
37 | {
38 | $this->getClient()->request('DELETE', $this->prepareUrl($url), [], [], [
39 | 'HTTP_ACCEPT' => 'application/json',
40 | 'HTTP_CONTENT_TYPE' => 'application/json',
41 | 'HTTP_X_XSRF_TOKEN' => $this->getClient()->getCookieJar()->get('XSRF-TOKEN')->getValue()
42 | ]);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Mpociot/Blacksmith/Models/Circle.php:
--------------------------------------------------------------------------------
1 | browser->postContent('https://forge.laravel.com/circles/'.$this->id.'/invite', [
21 | 'email' => $email,
22 | ]);
23 |
24 | if ($this->browser->getSession()->getStatusCode() === 422) {
25 | throw new Exception('Error: '.print_r($result, true));
26 | }
27 |
28 | return new Circle($result, $this->browser);
29 | }
30 |
31 | /**
32 | * Set all members of the circle
33 | *
34 | * @param array $member_ids
35 | * @return Circle
36 | */
37 | public function setMembers($member_ids)
38 | {
39 | $result = $this->browser->putContent('https://forge.laravel.com/circles/'.$this->id.'/members', [
40 | 'members' => $member_ids,
41 | ]);
42 |
43 | return new Circle($result, $this->browser);
44 | }
45 |
46 | /**
47 | * Set all servers of the circle
48 | *
49 | * @param array $server_ids
50 | * @return Circle
51 | */
52 | public function setServers($server_ids)
53 | {
54 | $result = $this->browser->putContent('https://forge.laravel.com/circles/'.$this->id.'/servers', [
55 | 'servers' => $server_ids,
56 | ]);
57 |
58 | return new Circle($result, $this->browser);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/Mpociot/Blacksmith/Models/Database.php:
--------------------------------------------------------------------------------
1 | data->get('database_users'))->transform(
21 | function ($data) {
22 | return new DatabaseUser($data, $this->browser);
23 | }
24 | );
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Mpociot/Blacksmith/Models/DatabaseUser.php:
--------------------------------------------------------------------------------
1 | data->get('databases'))->transform(function ($data) {
21 | return new Database($data, $this->browser);
22 | });
23 | }
24 |
25 | /**
26 | * Get a single user database
27 | *
28 | * @param $identifier
29 | * @return mixed
30 | */
31 | public function getDatabase($identifier) {
32 | $criteria = (is_numeric($identifier)) ? 'id' : 'name';
33 | /** @var Collection $databases */
34 | $databases = $this->getDatabases();
35 | $database = $databases->filter(function($database) use ($criteria, $identifier){
36 | return $database->$criteria == $identifier;
37 | }, $databases)->first();
38 | return $database;
39 | }
40 |
41 | /**
42 | * Add a database to the user
43 | *
44 | * @param Database $database
45 | * @return array
46 | */
47 | public function addDatabase(Database $database){
48 | /** @var Collection $databases */
49 | $databases = $this->getDatabases();
50 |
51 | // Add the database and get the ids
52 | $databaseIds = $databases
53 | ->push($database)
54 | ->map(function($value){
55 | return $value->id;
56 | })
57 | ->toArray();
58 |
59 | $data = [
60 | 'databases' => $databaseIds
61 | ];
62 |
63 | $result = $this->browser->putContent('https://forge.laravel.com/servers/'.$this->server_id.'/database-user/'.$this->id, $data);
64 |
65 | if ($this->browser->getSession()->getStatusCode() === 500) {
66 | throw new Exception('Error: '.print_r($result, true));
67 | }
68 |
69 | $response = [
70 | 'responseCode' => $this->browser->getSession()->getStatusCode(),
71 | 'response' => $result
72 | ];
73 |
74 | return $response;
75 | }
76 |
77 | /**
78 | * Remove a database to the user
79 | *
80 | * @param Database $database
81 | * @return array
82 | */
83 | public function removeDatabase(Database $database){
84 | /** @var Collection $databases */
85 | $databases = $this->getDatabases();
86 | $databaseId = $database->id;
87 |
88 | // Remove the database and get the ids
89 | $databaseIds = $databases
90 | ->filter(function($value) use ($databaseId){
91 | return $databaseId != $value->id;
92 | })
93 | ->map(function($value){
94 | return $value->id;
95 | })
96 | ->toArray();
97 |
98 | $data = [
99 | 'databases' => $databaseIds
100 | ];
101 |
102 | $result = $this->browser->putContent('https://forge.laravel.com/servers/'.$this->server_id.'/database-user/'.$this->id, $data);
103 |
104 | if ($this->browser->getSession()->getStatusCode() === 500) {
105 | throw new Exception('Error: '.print_r($result, true));
106 | }
107 |
108 | $response = [
109 | 'responseCode' => $this->browser->getSession()->getStatusCode(),
110 | 'response' => $result
111 | ];
112 |
113 | return $response;
114 | }
115 |
116 | }
117 |
--------------------------------------------------------------------------------
/src/Mpociot/Blacksmith/Models/ForgeModel.php:
--------------------------------------------------------------------------------
1 | data = collect($data);
25 | $this->browser = $browser;
26 |
27 | $this->build();
28 | }
29 |
30 | public function __get($key)
31 | {
32 | return $this->data->get($key);
33 | }
34 |
35 | protected function build()
36 | {
37 | $this->data->each(function ($value, $property) {
38 | if (property_exists($this, $property)) {
39 | $this->$property = $value;
40 | }
41 | });
42 | }
43 |
44 | /**
45 | * @return array
46 | */
47 | public function toArray()
48 | {
49 | return $this->data->toArray();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/Mpociot/Blacksmith/Models/Recipe.php:
--------------------------------------------------------------------------------
1 | browser->putContent('https://forge.laravel.com/recipes/'.$this->id, [
15 | 'name' => $name,
16 | 'user' => $user,
17 | 'script' => $script,
18 | ]);
19 |
20 | if ($this->browser->getSession()->getStatusCode() === 500) {
21 | throw new Exception('Error: '.print_r($result, true));
22 | }
23 |
24 | $this->data = $this->data->merge($result);
25 |
26 | return $this;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Mpociot/Blacksmith/Models/SSHKey.php:
--------------------------------------------------------------------------------
1 | data->get('sites'))->transform(function ($data) {
31 | return new Site($data, $this->browser);
32 | });
33 | }
34 |
35 | /**
36 | * Refresh the server data.
37 | */
38 | public function refresh(){
39 | $serverData = $this->browser->getContent('https://forge.laravel.com/api/servers/'.$this->id)->toArray();
40 | $this->data = collect($serverData);
41 | }
42 |
43 | /**
44 | * Get a site on this server
45 | *
46 | * @param $id
47 | * @return Site
48 | * @throws Exception
49 | */
50 | public function getSite($id) {
51 |
52 | if(!is_numeric($id)) {
53 | $sites = $this->getSites();
54 | $site = $sites->filter(function($site) use ($id){ return $site->name === $id; })->first();
55 | if($site) {
56 | $id = $site->id;
57 | }
58 | }
59 |
60 | $siteData = $this->browser->getContent('https://forge.laravel.com/api/servers/'.$this->id.'/sites/'.$id)->toArray();
61 |
62 | if(!$siteData) {
63 | throw new Exception(sprintf('Site "%s" could not be found', $id));
64 | }
65 |
66 | return new Site($siteData, $this->browser);
67 | }
68 |
69 | /**
70 | * Create a new site on this server.
71 | *
72 | * @param string $siteName
73 | * @param string $projectType
74 | * @param string $directory
75 | * @param bool $wildcards
76 | * @return Site
77 | * @throws Exception
78 | */
79 | public function addSite($siteName, $projectType = 'php', $directory = '/public', $wildcards = false)
80 | {
81 | $result = $this->browser->postContent('https://forge.laravel.com/servers/'.$this->id.'/sites', [
82 | 'site_name' => $siteName,
83 | 'project_type' => $projectType,
84 | 'directory' => $directory,
85 | 'wildcards' => $wildcards,
86 | ]);
87 |
88 | if ($this->browser->getSession()->getStatusCode() === 500) {
89 | throw new Exception('Error: '.print_r($result, true));
90 | }
91 |
92 | return new Site($result, $this->browser);
93 | }
94 |
95 | /**
96 | * Remove site
97 | *
98 | * @param $id
99 | * @return mixed
100 | * @throws Exception
101 | */
102 | public function removeSite($id)
103 | {
104 | if(!is_numeric($id)) {
105 | $sites = $this->getSites();
106 | $site = $sites->filter(function($site) use ($id){ return $site->name === $id; })->first();
107 | if($site) {
108 | $id = $site->id;
109 | }
110 | }
111 |
112 | $this->browser->deleteContent('https://forge.laravel.com/api/servers/'.$this->id.'/sites/'.$id);
113 | $response = [
114 | 'responseCode' => $this->browser->getSession()->getStatusCode()
115 | ];
116 |
117 | return $response;
118 | }
119 |
120 | /** ------------------------------------------------------------------------
121 | * Databases
122 | */
123 |
124 | /**
125 | * Get all databases on this server.
126 | *
127 | * @return Collection
128 | */
129 | public function getDatabases(){
130 | return collect($this->data->get('databases'))->transform(function ($data) {
131 | return new Database($data, $this->browser);
132 | });
133 | }
134 |
135 | /**
136 | * Get a database on this server
137 | *
138 | * @param $id
139 | * @return Database
140 | * @throws Exception
141 | */
142 | public function getDatabase($id) {
143 |
144 | $criteria = !is_numeric($id) ? 'name' : 'id';
145 | $databases = $this->getDatabases();
146 |
147 | $database = $databases->filter(function($database) use ($criteria, $id){
148 | return $database->{$criteria} == $id;
149 | })->first();
150 |
151 | if(!$database) {
152 | throw new Exception(sprintf('Database "%s" could not be found', $id));
153 | }
154 |
155 | return $database;
156 | }
157 |
158 | /**
159 | * Create a new database on this server.
160 | *
161 | * @param $databaseName
162 | * @param bool $username
163 | * @param bool $password
164 | * @return Database
165 | * @throws Exception
166 | */
167 | public function addDatabase($databaseName, $username = false, $password = false)
168 | {
169 | $data = array_filter([
170 | 'name' => $databaseName,
171 | 'user' => $username,
172 | 'password' => $password,
173 | ]);
174 |
175 | $result = $this->browser->postContent('https://forge.laravel.com/servers/'.$this->id.'/database', $data);
176 |
177 | if ($this->browser->getSession()->getStatusCode() === 500) {
178 | throw new Exception('Error: '.print_r($result, true));
179 | }
180 |
181 | return new Database($result, $this->browser);
182 | }
183 |
184 | /**
185 | * Delete Database
186 | *
187 | * @param $id
188 | * @return mixed
189 | */
190 | public function removeDatabase($id)
191 | {
192 | if(!is_numeric($id)) {
193 | $databases = $this->getDatabases();
194 | $database = $databases->filter(function($database) use ($id){ return $database->name === $id; })->first();
195 | if($database) {
196 | $id = $database->id;
197 | }
198 | }
199 |
200 | $this->browser->deleteContent('https://forge.laravel.com/servers/'.$this->id.'/database/'.$id);
201 | $response = [
202 | 'responseCode' => $this->browser->getSession()->getStatusCode()
203 | ];
204 | return $response;
205 | }
206 |
207 |
208 | /** ------------------------------------------------------------------------
209 | * Database Users
210 | */
211 |
212 | /**
213 | * Get all database users on this server.
214 | *
215 | * @return Collection
216 | */
217 | public function getDatabaseUsers()
218 | {
219 | return collect($this->data->get('database_users'))->transform(
220 | function ($data) {
221 | return new DatabaseUser($data, $this->browser);
222 | }
223 | );
224 | }
225 |
226 | /**
227 | * Get a database on this server
228 | *
229 | * @param $id
230 | * @return Database
231 | * @throws Exception
232 | */
233 | public function getDatabaseUser($id)
234 | {
235 | $criteria = !is_numeric($id) ? 'name' : 'id';
236 | $databaseUsers = $this->getDatabaseUsers();
237 |
238 | $databaseUser = $databaseUsers->filter(function($databaseUser) use ($criteria, $id){
239 | return $databaseUser->{$criteria} == $id;
240 | })->first();
241 |
242 | if(!$databaseUser) {
243 | throw new Exception(sprintf('Database User "%s" could not be found', $id));
244 | }
245 |
246 | return $databaseUser;
247 | }
248 |
249 | /**
250 | * Create a new database user on this server.
251 | *
252 | * @param bool $username
253 | * @param bool $password
254 | * @param array $canAccess
255 | * @return DatabaseUser
256 | * @throws Exception
257 | */
258 | public function addDatabaseUser($username = false, $password = false, $canAccess = array())
259 | {
260 | $databases = $this->getDatabases();
261 | /** @var Collection $canAccess */
262 | $canAccess = collect($canAccess);
263 | $canAccess = $canAccess->transform(function($databaseId) use ($databases) {
264 | $database = $this->getDatabase($databaseId);
265 | return $database->id;
266 | });
267 |
268 | $data = [
269 | 'name' => $username,
270 | 'password' => $password,
271 | 'databases' => $canAccess
272 | ];
273 |
274 | $result = $this->browser->postContent('https://forge.laravel.com/servers/'.$this->id.'/database-user', $data);
275 |
276 | if ($this->browser->getSession()->getStatusCode() === 500) {
277 | throw new Exception('Error: '.print_r($result, true));
278 | }
279 |
280 | return new DatabaseUser($result, $this->browser);
281 | }
282 |
283 | /**
284 | * Delete Database User
285 | *
286 | * @param $id
287 | * @return mixed
288 | */
289 | public function removeDatabaseUser($id)
290 | {
291 | if(!is_numeric($id)) {
292 | $databaseUsers = $this->getDatabaseUsers();
293 | $databaseUser = $databaseUsers->filter(function($databaseUser) use ($id){ return $databaseUser->name === $id; })->first();
294 | if($databaseUser) {
295 | $id = $databaseUser->id;
296 | }
297 | }
298 |
299 | $this->browser->deleteContent('https://forge.laravel.com/servers/'.$this->id.'/database-user/'.$id);
300 | $response = [
301 | 'responseCode' => $this->browser->getSession()->getStatusCode()
302 | ];
303 | return $response;
304 | }
305 |
306 | /**
307 | * Update an existing database user on this server.
308 | *
309 | * @param bool $id
310 | * @param array $canAccess
311 | * @return DatabaseUser
312 | * @throws Exception
313 | */
314 | public function updateDatabaseUser($id, $canAccess = array())
315 | {
316 | $databaseUser = $this->getDatabaseUser($id);
317 |
318 | $databases = $this->getDatabases();
319 | /** @var Collection $canAccess */
320 | $canAccess = collect($canAccess);
321 | $canAccess = $canAccess->transform(function($databaseId) use ($databases) {
322 | $database = $this->getDatabase($databaseId);
323 | return $database->id;
324 | });
325 |
326 | $data = [
327 | 'databases' => $canAccess
328 | ];
329 |
330 | $result = $this->browser->putContent('https://forge.laravel.com/servers/'.$this->id.'/database-user/'.$databaseUser->id, $data);
331 |
332 | if ($this->browser->getSession()->getStatusCode() === 500) {
333 | throw new Exception('Error: '.print_r($result, true));
334 | }
335 |
336 | return new DatabaseUser($result, $this->browser);
337 | }
338 |
339 | /** ------------------------------------------------------------------------
340 | * SSH Keys
341 | */
342 |
343 | /**
344 | * Get all ssh keys on this server.
345 | *
346 | * @return Collection
347 | */
348 | public function getSSHKeys(){
349 | return collect($this->data->get('keys'))->transform(function ($data) {
350 | return new SSHKey($data, $this->browser);
351 | });
352 | }
353 |
354 | /**
355 | * Add an SSH key to server.
356 | *
357 | * @param $name
358 | * @param $key
359 | * @return SSHKey
360 | * @throws Exception
361 | */
362 | public function addSSHKey($name, $key)
363 | {
364 | $data = [
365 | 'name' => $name,
366 | 'key' => $key,
367 | ];
368 | $result = $this->browser->postContent('https://forge.laravel.com/servers/'.$this->id.'/key', $data);
369 |
370 | if ($this->browser->getSession()->getStatusCode() === 500) {
371 | throw new Exception('Error: '.print_r($result, true));
372 | }
373 |
374 | return new SSHKey($result, $this->browser);
375 | }
376 |
377 | /**
378 | * Delete SSH Key from this server
379 | *
380 | * @param $id
381 | * @return mixed
382 | */
383 | public function removeSSHKey($id)
384 | {
385 | if(!is_numeric($id)) {
386 | $sshKeys = $this->getSSHKeys();
387 | $sshKey = $sshKeys->filter(function($sshKey) use ($id){ return $sshKey->name === $id; })->first();
388 | if($sshKey) {
389 | $id = $sshKey->id;
390 | }
391 | }
392 |
393 | $this->browser->deleteContent('https://forge.laravel.com/servers/'.$this->id.'/key/'.$id);
394 | $response = [
395 | 'responseCode' => $this->browser->getSession()->getStatusCode()
396 | ];
397 | return $response;
398 | }
399 |
400 | /** ------------------------------------------------------------------------
401 | * Scheduled Jobs
402 | */
403 |
404 | /**
405 | * Get all scheduled jobs on this server.
406 | *
407 | * @return Collection
408 | */
409 | public function getScheduledJobs(){
410 | return collect($this->data->get('jobs'))->transform(function ($data) {
411 | return new ScheduledJob($data, $this->browser);
412 | });
413 | }
414 |
415 | /**
416 | * Add an Scheduled Job to server.
417 | *
418 | * @param $command
419 | * @param $user
420 | * @param $frequency
421 | * @return ScheduledJob
422 | * @throws Exception
423 | */
424 | public function addScheduledJob($command, $user, $frequency)
425 | {
426 | $data = [
427 | 'command' => $command,
428 | 'user' => $user,
429 | 'frequency' => $frequency,
430 | ];
431 |
432 | $result = $this->browser->postContent('https://forge.laravel.com/servers/'.$this->id.'/job', $data);
433 |
434 | if ($this->browser->getSession()->getStatusCode() === 500) {
435 | throw new Exception('Error: '.print_r($result, true));
436 | }
437 |
438 | // Result is the full server object
439 | // So we pull out the last job
440 | $scheduledJobData = collect($result['jobs'])->last();
441 |
442 | return new ScheduledJob($scheduledJobData, $this->browser);
443 | }
444 |
445 | /**
446 | * Delete Scheduled Job from this server
447 | *
448 | * @param $id
449 | * @return array
450 | * @throws Exception
451 | */
452 | public function removeScheduledJob($id)
453 | {
454 | if(!is_numeric($id)) {
455 | $scheduledJobs = $this->getScheduledJobs();
456 | $scheduledJob = $scheduledJobs->filter(function($scheduledJob) use ($id){ return $scheduledJob->command === $id; })->first();
457 | if($scheduledJob) {
458 | $id = $scheduledJob->id;
459 | }
460 | }
461 |
462 | $result = $this->browser->deleteContent('https://forge.laravel.com/servers/'.$this->id.'/job/'.$id);
463 |
464 | if ($this->browser->getSession()->getStatusCode() === 500) {
465 | throw new Exception('Error: '.print_r($result, true));
466 | }
467 |
468 | $response = [
469 | 'responseCode' => $this->browser->getSession()->getStatusCode(),
470 | 'response' => $result
471 | ];
472 |
473 | return $response;
474 | }
475 |
476 | /** ------------------------------------------------------------------------
477 | * Metadata
478 | */
479 |
480 | /**
481 | * Update the server metadata.
482 | *
483 | * @param $serverName
484 | * @param $ipAddress
485 | * @param $privateIpAddress
486 | * @param $size
487 | * @return $this
488 | * @throws Exception
489 | */
490 | public function updateMetadata($serverName, $ipAddress, $privateIpAddress, $size)
491 | {
492 | $data = [
493 | 'name' => $serverName,
494 | 'ip_address' => $ipAddress,
495 | 'private_ip_address' => $privateIpAddress,
496 | 'size' => $size,
497 | ];
498 |
499 | $result = $this->browser->putContent('https://forge.laravel.com/servers/'.$this->id.'/meta', $data);
500 |
501 | if ($this->browser->getSession()->getStatusCode() === 500) {
502 | throw new Exception('Error: '.print_r($result, true));
503 | }
504 |
505 | $response = [
506 | 'responseCode' => $this->browser->getSession()->getStatusCode(),
507 | 'response' => $result
508 | ];
509 |
510 | return $response;
511 | }
512 |
513 | /**
514 | * Update max file upload size
515 | *
516 | * @param $megaBytes
517 | * @return $this
518 | * @throws Exception
519 | */
520 | public function updateMaxFileUploadSize($megaBytes)
521 | {
522 | $data = [
523 | 'megabytes' => $megaBytes,
524 | ];
525 |
526 | $result = $this->browser->putContent('https://forge.laravel.com/servers/'.$this->id.'/settings/php/max-upload-size', $data);
527 |
528 | if ($this->browser->getSession()->getStatusCode() === 500) {
529 | throw new Exception('Error: '.print_r($result, true));
530 | }
531 |
532 | $response = [
533 | 'responseCode' => $this->browser->getSession()->getStatusCode(),
534 | 'response' => $result
535 | ];
536 |
537 | return $response;
538 | }
539 | }
540 |
--------------------------------------------------------------------------------
/src/Mpociot/Blacksmith/Models/Site.php:
--------------------------------------------------------------------------------
1 | has_app_installed) {
34 | return false;
35 | }
36 |
37 | $data = [
38 | 'repository' => $repository,
39 | 'provider' => $provider,
40 | 'branch' => $branch,
41 | 'composer' => $composer,
42 | 'migrate' => $migrate,
43 | ];
44 |
45 | $response = $this->browser->postContent('https://forge.laravel.com/servers/'.$this->server_id.'/sites/'.$this->id.'/project', $data);
46 |
47 | return $response;
48 | }
49 |
50 | /** ------------------------------------------------------------------------
51 | * Environment
52 | */
53 |
54 | /**
55 | * Return the configured .env data
56 | *
57 | * @return string
58 | */
59 | public function getEnvironment()
60 | {
61 | $result = $this->browser->getContent('https://forge.laravel.com/servers/'.$this->server_id.'/sites/'.$this->id.'/environment', true);
62 |
63 | if ($this->browser->getSession()->getStatusCode() === 500) {
64 | throw new Exception('Error: '.print_r($result, true));
65 | }
66 |
67 | $response = [
68 | 'responseCode' => $this->browser->getSession()->getStatusCode(),
69 | 'response' => $result
70 | ];
71 |
72 | return $response;
73 | }
74 |
75 | /**
76 | * Update the configured .env data
77 | *
78 | * @return string
79 | */
80 | public function updateEnvironment($env)
81 | {
82 | $data = [
83 | 'env' => $env
84 | ];
85 |
86 | $result = $this->browser->putContent('https://forge.laravel.com/servers/'.$this->server_id.'/sites/'.$this->id.'/environment', $data);
87 |
88 | if ($this->browser->getSession()->getStatusCode() === 500) {
89 | throw new Exception('Error: '.print_r($result, true));
90 | }
91 |
92 | $response = [
93 | 'responseCode' => $this->browser->getSession()->getStatusCode(),
94 | 'response' => $result
95 | ];
96 |
97 | return $response;
98 | }
99 |
100 | /** ------------------------------------------------------------------------
101 | * Nginx Config
102 | */
103 |
104 | /**
105 | * Return the sites nginx config
106 | *
107 | * @return string
108 | */
109 | public function getNginxConfig()
110 | {
111 | $result = $this->browser->getContent('https://forge.laravel.com/servers/'.$this->server_id.'/sites/'.$this->id.'/nginx/config', true);
112 |
113 | if ($this->browser->getSession()->getStatusCode() === 500) {
114 | throw new Exception('Error: '.print_r($result, true));
115 | }
116 |
117 | $response = [
118 | 'responseCode' => $this->browser->getSession()->getStatusCode(),
119 | 'response' => $result
120 | ];
121 |
122 | return $response;
123 | }
124 |
125 |
126 | /**
127 | * Update the sites nginx config
128 | *
129 | * @return string
130 | */
131 | public function updateNginxConfig($config)
132 | {
133 | $data = [
134 | 'config' => $config
135 | ];
136 |
137 | $result = $this->browser->putContent('https://forge.laravel.com/servers/'.$this->server_id.'/sites/'.$this->id.'/nginx/config', $data);
138 |
139 | if ($this->browser->getSession()->getStatusCode() === 500) {
140 | throw new Exception('Error: '.print_r($result, true));
141 | }
142 |
143 | $response = [
144 | 'responseCode' => $this->browser->getSession()->getStatusCode(),
145 | 'response' => $result
146 | ];
147 |
148 | return $response;
149 | }
150 |
151 | /** ------------------------------------------------------------------------
152 | * Meta
153 | */
154 |
155 | /**
156 | * Update the site metadata.
157 | *
158 | * @param $directory
159 | * @return array
160 | */
161 | public function updateWebDirectory($directory)
162 | {
163 | $data = [
164 | 'directory' => $directory
165 | ];
166 |
167 | $result = $this->browser->putContent('https://forge.laravel.com/servers/'.$this->server_id.'/sites/'.$this->id.'/directory', $data);
168 |
169 | if ($this->browser->getSession()->getStatusCode() === 500) {
170 | throw new Exception('Error: '.print_r($result, true));
171 | }
172 |
173 | $response = [
174 | 'responseCode' => $this->browser->getSession()->getStatusCode(),
175 | 'response' => $result
176 | ];
177 |
178 | return $response;
179 | }
180 |
181 | /** ------------------------------------------------------------------------
182 | * Deployments
183 | */
184 |
185 | /**
186 | * Deploy the current installed application on this site.
187 | *
188 | * @return mixed
189 | */
190 | public function deploy()
191 | {
192 | if ($this->has_app_installed) {
193 | return $this->browser->postContent('https://forge.laravel.com/servers/'.$this->server_id.'/sites/'.$this->id.'/deploy/now', []);
194 | }
195 | return false;
196 | }
197 |
198 | /**
199 | * Get the last deployment log on this site.
200 | *
201 | * @return mixed
202 | */
203 | public function deployLog()
204 | {
205 | if ($this->has_app_installed) {
206 | return $this->browser->postContent('https://forge.laravel.com/servers/'.$this->server_id.'/sites/'.$this->id.'/deploy/log', [], true);
207 | }
208 | return '';
209 | }
210 | }
211 |
--------------------------------------------------------------------------------
/src/Mpociot/Blacksmith/Models/User.php:
--------------------------------------------------------------------------------
1 |