Support functionality for per-egg features

This commit is contained in:
Dane Everitt 2020-11-02 20:20:36 -08:00
parent 7ec614ed2c
commit 7618f306bd
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
7 changed files with 70 additions and 20 deletions

View file

@ -9,6 +9,7 @@ namespace Pterodactyl\Models;
* @property string $author
* @property string $name
* @property string|null $description
* @property array|null $features
* @property string $docker_image
* @property string|null $config_files
* @property string|null $config_startup
@ -31,6 +32,7 @@ namespace Pterodactyl\Models;
* @property string|null $inherit_config_startup
* @property string|null $inherit_config_logs
* @property string|null $inherit_config_stop
* @property array|null $inherit_features
*
* @property \Pterodactyl\Models\Nest $nest
* @property \Illuminate\Database\Eloquent\Collection|\Pterodactyl\Models\Server[] $servers
@ -46,6 +48,18 @@ class Egg extends Model
*/
const RESOURCE_NAME = 'egg';
/**
* Different features that can be enabled on any given egg. These are used internally
* to determine which types of frontend functionality should be shown to the user. Eggs
* will automatically inherit features from a parent egg if they are already configured
* to copy configuration values from said egg.
*
* To skip copying the features, an empty array value should be passed in ("[]") rather
* than leaving it null.
*/
const FEATURE_EULA_POPUP = 'eula';
const FEATURE_FASTDL = 'fastdl';
/**
* The table associated with the model.
*
@ -61,6 +75,7 @@ class Egg extends Model
protected $fillable = [
'name',
'description',
'features',
'docker_image',
'config_files',
'config_startup',
@ -85,6 +100,7 @@ class Egg extends Model
'config_from' => 'integer',
'script_is_privileged' => 'boolean',
'copy_script_from' => 'integer',
'features' => 'array',
];
/**
@ -95,6 +111,7 @@ class Egg extends Model
'uuid' => 'required|string|size:36',
'name' => 'required|string|max:191',
'description' => 'string|nullable',
'features' => 'json|nullable',
'author' => 'required|string|email',
'docker_image' => 'required|string|max:191',
'startup' => 'required|nullable|string',
@ -109,6 +126,7 @@ class Egg extends Model
* @var array
*/
protected $attributes = [
'features' => null,
'config_stop' => null,
'config_startup' => null,
'config_logs' => null,
@ -216,6 +234,21 @@ class Egg extends Model
return $this->configFrom->config_stop;
}
/**
* Returns the features available to this egg from the parent configuration if there are
* no features defined for this egg specifically and there is a parent egg configured.
*
* @return array|null
*/
public function getInheritFeaturesAttribute()
{
if (! is_null($this->features) || is_null($this->config_from)) {
return $this->features;
}
return $this->configFrom->features;
}
/**
* Gets nest associated with an egg.
*

View file

@ -33,19 +33,15 @@ class EggUpdateService
/**
* Update a service option.
*
* @param int|\Pterodactyl\Models\Egg $egg
* @param \Pterodactyl\Models\Egg $egg
* @param array $data
*
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
* @throws \Pterodactyl\Exceptions\Service\Egg\NoParentConfigurationFoundException
*/
public function handle($egg, array $data)
public function handle(Egg $egg, array $data)
{
if (! $egg instanceof Egg) {
$egg = $this->repository->find($egg);
}
if (! is_null(array_get($data, 'config_from'))) {
$results = $this->repository->findCountWhere([
['nest_id', '=', $egg->nest_id],

View file

@ -43,6 +43,7 @@ class EggExporterService
'name' => $egg->name,
'author' => $egg->author,
'description' => $egg->description,
'features' => $egg->features,
'image' => $egg->docker_image,
'startup' => $egg->startup,
'config' => [

View file

@ -101,6 +101,7 @@ class EggImporterService
'author' => object_get($parsed, 'author'),
'name' => object_get($parsed, 'name'),
'description' => object_get($parsed, 'description'),
'features' => object_get($parsed, 'features'),
'docker_image' => object_get($parsed, 'image'),
'config_files' => object_get($parsed, 'config.files'),
'config_startup' => object_get($parsed, 'config.startup'),

View file

@ -86,6 +86,7 @@ class EggUpdateImporterService
'author' => object_get($parsed, 'author'),
'name' => object_get($parsed, 'name'),
'description' => object_get($parsed, 'description'),
'features' => object_get($parsed, 'features'),
'docker_image' => object_get($parsed, 'image'),
'config_files' => object_get($parsed, 'config.files'),
'config_startup' => object_get($parsed, 'config.startup'),

View file

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddFeaturesColumnToEggs extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('eggs', function (Blueprint $table) {
$table->json('features')->after('description')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('eggs', function (Blueprint $table) {
$table->dropColumn('features');
});
}
}

View file

@ -88,18 +88,4 @@ class EggUpdateServiceTest extends TestCase
$this->assertEquals(trans('exceptions.nest.egg.must_be_child'), $exception->getMessage());
}
}
/**
* Test that an integer linking to a model can be passed in place of the Egg model.
*/
public function testIntegerCanBePassedInPlaceOfModel()
{
$this->repository->shouldReceive('find')->with($this->model->id)->once()->andReturn($this->model);
$this->repository->shouldReceive('withoutFreshModel->update')
->with($this->model->id, ['test_field' => 'field_value'])->once()->andReturnNull();
$this->service->handle($this->model->id, ['test_field' => 'field_value']);
$this->assertTrue(true);
}
}