Complete the service option export configuration

This commit is contained in:
Dane Everitt 2017-10-03 20:18:27 -05:00
parent 0d739257a9
commit d608c313c3
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
6 changed files with 141 additions and 40 deletions

View file

@ -9,23 +9,29 @@
namespace Pterodactyl\Contracts\Repository; namespace Pterodactyl\Contracts\Repository;
use Pterodactyl\Models\ServiceOption;
interface ServiceOptionRepositoryInterface extends RepositoryInterface interface ServiceOptionRepositoryInterface extends RepositoryInterface
{ {
/** /**
* Return a service option with the variables relation attached. * Return a service option with the variables relation attached.
* *
* @param int $id * @param int $id
* @return mixed * @return \Pterodactyl\Models\ServiceOption
*
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/ */
public function getWithVariables($id); public function getWithVariables(int $id): ServiceOption;
/** /**
* Return a service option with the copyFrom relation loaded onto the model. * Return a service option with the scriptFrom and configFrom relations loaded onto the model.
* *
* @param int $id * @param int $id
* @return mixed * @return \Pterodactyl\Models\ServiceOption
*
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/ */
public function getWithCopyFrom($id); public function getWithCopyAttributes(int $id): ServiceOption;
/** /**
* Confirm a copy script belongs to the same service as the item trying to use it. * Confirm a copy script belongs to the same service as the item trying to use it.
@ -34,5 +40,5 @@ interface ServiceOptionRepositoryInterface extends RepositoryInterface
* @param int $service * @param int $service
* @return bool * @return bool
*/ */
public function isCopiableScript($copyFromId, $service); public function isCopiableScript(int $copyFromId, int $service): bool;
} }

View file

@ -163,7 +163,7 @@ class OptionController extends Controller
*/ */
public function viewScripts($option) public function viewScripts($option)
{ {
$option = $this->serviceOptionRepository->getWithCopyFrom($option); $option = $this->serviceOptionRepository->getWithCopyAttributes($option);
$copyOptions = $this->serviceOptionRepository->findWhere([ $copyOptions = $this->serviceOptionRepository->findWhere([
['copy_script_from', '=', null], ['copy_script_from', '=', null],
['service_id', '=', $option->service_id], ['service_id', '=', $option->service_id],

View file

@ -11,6 +11,7 @@ namespace Pterodactyl\Http\Controllers\Admin\Services\Options;
use Pterodactyl\Models\ServiceOption; use Pterodactyl\Models\ServiceOption;
use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Http\Controllers\Controller;
use Symfony\Component\HttpFoundation\Response;
use Pterodactyl\Services\Services\Exporter\XMLExporterService; use Pterodactyl\Services\Services\Exporter\XMLExporterService;
class OptionShareController extends Controller class OptionShareController extends Controller
@ -32,13 +33,16 @@ class OptionShareController extends Controller
/** /**
* @param \Pterodactyl\Models\ServiceOption $option * @param \Pterodactyl\Models\ServiceOption $option
* @return $this * @return \Symfony\Component\HttpFoundation\Response
* *
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/ */
public function export(ServiceOption $option) public function export(ServiceOption $option): Response
{ {
return response($this->exporterService->handle($option), 200, [ return response($this->exporterService->handle($option->id), 200, [
'Content-Transfer-Encoding' => 'binary',
'Content-Description' => 'File Transfer',
'Content-Disposition' => 'attachment; filename=' . kebab_case($option->name) . '.xml',
'Content-Type' => 'application/xml', 'Content-Type' => 'application/xml',
]); ]);
} }

View file

@ -114,7 +114,7 @@ class ServiceOption extends Model implements CleansAttributes, ValidableContract
* *
* @return string * @return string
*/ */
public function getDisplayStartupAttribute($value) public function getDisplayStartupAttribute()
{ {
return (is_null($this->startup)) ? $this->service->startup : $this->startup; return (is_null($this->startup)) ? $this->service->startup : $this->startup;
} }
@ -125,9 +125,9 @@ class ServiceOption extends Model implements CleansAttributes, ValidableContract
* *
* @return string * @return string
*/ */
public function getCopyScriptInstallAttribute($value) public function getCopyScriptInstallAttribute()
{ {
return (is_null($this->copy_script_from)) ? $this->script_install : $this->copyFrom->script_install; return (is_null($this->copy_script_from)) ? $this->script_install : $this->scriptFrom->script_install;
} }
/** /**
@ -136,9 +136,9 @@ class ServiceOption extends Model implements CleansAttributes, ValidableContract
* *
* @return string * @return string
*/ */
public function getCopyScriptEntryAttribute($value) public function getCopyScriptEntryAttribute()
{ {
return (is_null($this->copy_script_from)) ? $this->script_entry : $this->copyFrom->script_entry; return (is_null($this->copy_script_from)) ? $this->script_entry : $this->scriptFrom->script_entry;
} }
/** /**
@ -147,9 +147,49 @@ class ServiceOption extends Model implements CleansAttributes, ValidableContract
* *
* @return string * @return string
*/ */
public function getCopyScriptContainerAttribute($value) public function getCopyScriptContainerAttribute()
{ {
return (is_null($this->copy_script_from)) ? $this->script_container : $this->copyFrom->script_container; return (is_null($this->copy_script_from)) ? $this->script_container : $this->scriptFrom->script_container;
}
/**
* Return the file configuration for a service option.
*
* @return string
*/
public function getInheritConfigFilesAttribute()
{
return is_null($this->config_from) ? $this->config_files : $this->configFrom->config_files;
}
/**
* Return the startup configuration for a service option.
*
* @return string
*/
public function getInheritConfigStartupAttribute()
{
return is_null($this->config_from) ? $this->config_startup : $this->configFrom->config_startup;
}
/**
* Return the log reading configuration for a service option.
*
* @return string
*/
public function getInheritConfigLogsAttribute()
{
return is_null($this->config_from) ? $this->config_logs : $this->configFrom->config_logs;
}
/**
* Return the stop command configuration for a service option.
*
* @return string
*/
public function getInheritConfigStopAttribute()
{
return is_null($this->config_from) ? $this->config_stop : $this->configFrom->config_stop;
} }
/** /**
@ -197,8 +237,18 @@ class ServiceOption extends Model implements CleansAttributes, ValidableContract
* *
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/ */
public function copyFrom() public function scriptFrom()
{ {
return $this->belongsTo(self::class, 'copy_script_from'); return $this->belongsTo(self::class, 'copy_script_from');
} }
/**
* Get the parent service option from which to copy configuration settings.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function configFrom()
{
return $this->belongsTo(self::class, 'config_from');
}
} }

View file

@ -10,6 +10,7 @@
namespace Pterodactyl\Repositories\Eloquent; namespace Pterodactyl\Repositories\Eloquent;
use Pterodactyl\Models\ServiceOption; use Pterodactyl\Models\ServiceOption;
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
use Pterodactyl\Contracts\Repository\ServiceOptionRepositoryInterface; use Pterodactyl\Contracts\Repository\ServiceOptionRepositoryInterface;
class ServiceOptionRepository extends EloquentRepository implements ServiceOptionRepositoryInterface class ServiceOptionRepository extends EloquentRepository implements ServiceOptionRepositoryInterface
@ -23,25 +24,51 @@ class ServiceOptionRepository extends EloquentRepository implements ServiceOptio
} }
/** /**
* {@inheritdoc} * Return a service option with the variables relation attached.
*
* @param int $id
* @return \Pterodactyl\Models\ServiceOption
*
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/ */
public function getWithVariables($id) public function getWithVariables(int $id): ServiceOption
{ {
return $this->getBuilder()->with('variables')->find($id, $this->getColumns()); /** @var \Pterodactyl\Models\ServiceOption $instance */
$instance = $this->getBuilder()->with('variables')->find($id, $this->getColumns());
if (! $instance) {
throw new RecordNotFoundException;
}
return $instance;
} }
/** /**
* {@inheritdoc} * Return a service option with the scriptFrom and configFrom relations loaded onto the model.
*
* @param int $id
* @return \Pterodactyl\Models\ServiceOption
*
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/ */
public function getWithCopyFrom($id) public function getWithCopyAttributes(int $id): ServiceOption
{ {
return $this->getBuilder()->with('copyFrom')->find($id, $this->getColumns()); /** @var \Pterodactyl\Models\ServiceOption $instance */
$instance = $this->getBuilder()->with('scriptFrom', 'configFrom')->find($id, $this->getColumns());
if (! $instance) {
throw new RecordNotFoundException;
}
return $instance;
} }
/** /**
* {@inheritdoc} * Confirm a copy script belongs to the same service as the item trying to use it.
*
* @param int $copyFromId
* @param int $service
* @return bool
*/ */
public function isCopiableScript($copyFromId, $service) public function isCopiableScript(int $copyFromId, int $service): bool
{ {
return $this->getBuilder()->whereNull('copy_script_from') return $this->getBuilder()->whereNull('copy_script_from')
->where('id', '=', $copyFromId) ->where('id', '=', $copyFromId)

View file

@ -9,10 +9,10 @@
namespace Pterodactyl\Services\Services\Exporter; namespace Pterodactyl\Services\Services\Exporter;
use Closure;
use Carbon\Carbon; use Carbon\Carbon;
use Sabre\Xml\Writer; use Sabre\Xml\Writer;
use Sabre\Xml\Service; use Sabre\Xml\Service;
use Pterodactyl\Models\ServiceOption;
use Pterodactyl\Contracts\Repository\ServiceOptionRepositoryInterface; use Pterodactyl\Contracts\Repository\ServiceOptionRepositoryInterface;
class XMLExporterService class XMLExporterService
@ -58,35 +58,36 @@ class XMLExporterService
/** /**
* Return an XML structure to represent this service option. * Return an XML structure to represent this service option.
* *
* @param int|\Pterodactyl\Models\ServiceOption $option * @param int $option
* @return string * @return string
* *
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/ */
public function handle($option): string public function handle(int $option): string
{ {
if (! $option instanceof ServiceOption) { $option = $this->repository->getWithCopyAttributes($option);
$option = $this->repository->find($option);
}
$struct = [ $struct = [
'meta' => [
'version' => 'PTDL_v1',
],
'exported_at' => $this->carbon->now()->toIso8601String(), 'exported_at' => $this->carbon->now()->toIso8601String(),
'name' => $option->name, 'name' => $option->name,
'author' => array_get(explode(':', $option->tag), 0), 'author' => array_get(explode(':', $option->tag), 0),
'tag' => $option->tag, 'tag' => $option->tag,
'description' => $option->description, 'description' => $this->writeCData($option->description),
'image' => $option->docker_image, 'image' => $option->docker_image,
'config' => [ 'config' => [
'files' => $option->config_files, 'files' => $this->writeCData($option->inherit_config_files),
'startup' => $option->config_startup, 'startup' => $this->writeCData($option->inherit_config_startup),
'logs' => $option->config_logs, 'logs' => $this->writeCData($option->inherit_config_logs),
'stop' => $option->config_stop, 'stop' => $option->inherit_config_stop,
], ],
'scripts' => [ 'scripts' => [
'installation' => [ 'installation' => [
'script' => function (Writer $writer) use ($option) { 'script' => $this->writeCData($option->copy_script_install),
return $writer->writeCData($option->copy_script_install); 'container' => $option->copy_script_container,
}, 'entrypoint' => $option->copy_script_entry,
], ],
], ],
]; ];
@ -115,4 +116,17 @@ class XMLExporterService
return $parsed; return $parsed;
} }
/**
* Return a closure to be used by the XML writer to generate a string wrapped in CDATA tags.
*
* @param string $value
* @return \Closure
*/
protected function writeCData(string $value): Closure
{
return function (Writer $writer) use ($value) {
return $writer->writeCData($value);
};
}
} }