2024-04-25 20:58:01 +02:00
< ? php declare ( strict_types = 1 );
2024-04-16 18:24:38 +02:00
namespace App\Controller ;
error_reporting ( error_level : E_ALL );
define ( constant_name : 'COLOR_RED' , value : " \033 [31m " );
define ( constant_name : 'COLOR_GREEN' , value : " \033 [32m " );
define ( constant_name : 'COLOR_YELLOW' , value : " \033 [33m " );
define ( constant_name : 'COLOR_BLUE' , value : " \033 [34m " );
define ( constant_name : 'COLOR_WHITE' , value : " \033 [37m " );
define ( constant_name : 'COLOR_DEFAULT' , value : " \033 [39m " );
use App\Controller\Commands\Command ;
use App\Controller\Commands\CommandGroup ;
use App\Controller\Commands\CommandGroupContainer ;
use App\Entity\Apikey ;
use App\Entity\Domain ;
use App\Entity\DynDNS ;
use App\Entity\KeyHelp\KeyHelpDomain ;
use App\Entity\Nameserver ;
use App\Entity\Panel ;
use App\Repository\ApikeyRepository ;
use App\Repository\DomainRepository ;
use App\Repository\DynDNSRepository ;
use App\Repository\NameserverRepository ;
use App\Repository\PanelRepository ;
2024-04-19 15:11:21 +02:00
use App\Repository\SettingsRepository ;
2024-04-25 20:58:01 +02:00
use App\Service\ApiClient ;
2024-04-16 18:24:38 +02:00
use Arubacao\TldChecker\Validator ;
use Exception ;
use JsonMapper ;
use JsonMapper_Exception ;
use LucidFrame\Console\ConsoleTable ;
use Odan\Migration\Command\GenerateCommand ;
use Phinx\Console\PhinxApplication ;
use SodiumException ;
use Symfony\Component\Console\Input\ArrayInput ;
use Symfony\Component\Console\Output\ConsoleOutput ;
if ( php_sapi_name () !== 'cli' ) {
exit ;
}
class CLIController
{
private array $arguments ;
private CommandGroupContainer $commandGroupContainer ;
2024-04-30 11:13:24 +02:00
private string $baseDir ;
2024-04-16 18:24:38 +02:00
/**
* @ throws Exception
*/
public function __construct (
2024-04-30 11:13:24 +02:00
private readonly ApiClient $apiClient ,
2024-04-16 18:24:38 +02:00
private readonly ApikeyRepository $apikeyRepository ,
private readonly DomainController $domainController ,
private readonly DomainRepository $domainRepository ,
private readonly DynDNSRepository $dynDNSRepository ,
private readonly NameserverRepository $nameserverRepository ,
private readonly PanelRepository $panelRepository ,
private readonly ConfigController $configController ,
private readonly EncryptionController $encryptionController ,
2024-04-19 15:11:21 +02:00
private readonly SettingsRepository $settingsRepository ,
2024-04-16 18:24:38 +02:00
private $logger ,
2024-04-25 20:58:01 +02:00
private readonly bool $quiet
2024-04-16 18:24:38 +02:00
)
2022-09-27 19:13:28 +02:00
{
2024-04-30 11:13:24 +02:00
$this -> baseDir = dirname ( path : __DIR__ , levels : 2 ) . '/' ;
2024-04-16 18:24:38 +02:00
$this -> commandGroupContainer = ( new CommandGroupContainer ())
2024-04-19 15:11:21 +02:00
-> addCommandGroup ( commandGroup : ( new CommandGroup ( name : 'apikeys' , description : 'API keys to access this bindAPI' ))
-> addCommand ( command : new Command (
name : 'list' ,
callback : function () {
$this -> apikeysList ();
2024-04-25 20:58:01 +02:00
}
)
)
2024-04-19 15:11:21 +02:00
-> addCommand ( command : new Command (
name : 'create' ,
callback : function () {
$this -> apikeysCreate ();
},
2024-04-25 20:58:01 +02:00
mandatoryParameters : [ 'name' ])
)
2024-04-19 15:11:21 +02:00
-> addCommand ( command : new Command (
name : 'update' ,
callback : function () {
$this -> apikeysUpdate ();
},
mandatoryParameters : [ 'ID' ,],
optionalParameters : [ 'name=<name>' ]))
-> addCommand ( command : new Command (
name : 'delete' ,
callback : function () {
$this -> apikeysDelete ();
},
mandatoryParameters : [ 'ID' ])))
2024-04-30 17:22:43 +02:00
-> addCommandGroup ( commandGroup : ( new CommandGroup ( name : 'cron' , description : 'Run zone file maintenance' ))
2024-04-21 13:49:02 +02:00
-> addCommand ( command : new Command (
name : 'run' ,
callback : function () {
$this -> cronRun ();
})))
2024-04-16 18:24:38 +02:00
-> addCommandGroup ( commandGroup : ( new CommandGroup ( name : 'check' , description : 'health checks the system can perform' ))
2024-05-01 18:39:55 +02:00
-> addCommand ( command : new Command (
name : 'cache' ,
callback : function () {
$this -> checkCache ();
},
description : 'Clear the opcache. Note: It doesn\'t call composer clear-cache.' ))
2024-04-16 18:24:38 +02:00
-> addCommand ( command : new Command (
name : 'permissions' ,
callback : function () {
$this -> checkPermissions ();
},
description : 'check file permissions' ))
2024-04-17 20:28:51 +02:00
-> addCommand ( command : new Command (
name : 'panel' ,
callback : function () {
$this -> checkPanel ();
},
description : 'Validate setting for this panel' ))
2024-04-16 18:24:38 +02:00
-> addCommand ( command : new Command (
name : 'panels' ,
callback : function () {
$this -> checkPanels ();
},
optionalParameters : [ 'ID' , 'fix=xes' ]))
2024-04-30 11:13:24 +02:00
-> addCommand ( command : new Command (
name : 'nameserver' ,
callback : function () {
$this -> checkNameserver ();
},
description : 'Validate setting for this panel' ))
2024-04-30 17:22:43 +02:00
-> addCommand ( command : new Command (
name : 'nameservers' ,
callback : function () {
$this -> checkNameservers ();
},
description : 'Check version on nameservers' ))
2024-04-16 18:24:38 +02:00
-> addCommand ( command : new Command (
name : 'domains' ,
callback : function () {
$this -> checkDomains ();
}))
-> addCommand ( command : new Command (
name : 'mail' ,
callback : function () {
$this -> checkMail ();
}))
-> addCommand ( command : new Command (
name : 'showincludes' ,
callback : function () {
$this -> checkShowIncludes ();
},
description : 'Shows needed setting on panels' ))
-> addCommand ( command : new Command (
name : 'generatekey' ,
callback : function () {
$this -> checkGenerateKey ();
},
description : 'Generates a a new key for encryption' ))
-> addCommand ( command : new Command (
name : 'setup' ,
callback : function () {
$this -> checkSetup ();
},
mandatoryParameters : [ 'username' ],
description : 'Adapt filesystem permissions (requires elaborated permissions)' ))
-> addCommand ( command : new Command (
name : 'version' ,
callback : function () {
2024-04-19 15:11:21 +02:00
$this -> checkVersion ();
2024-04-16 18:24:38 +02:00
},
2024-04-19 15:11:21 +02:00
optionalParameters : [ 'update' ],
2024-04-16 18:24:38 +02:00
description : 'Read or set the bindApi version in the database' )))
-> addCommandGroup ( commandGroup : ( new CommandGroup ( name : 'panels' , description : 'all KeyHelp systems configured' ))
-> addCommand ( command : new Command (
name : 'list' ,
callback : function () {
$this -> panelsList ();
}))
-> addCommand ( command : new Command (
name : 'create' ,
callback : function () {
$this -> panelsCreate ();
},
mandatoryParameters : [ 'name' ],
2024-04-30 11:13:24 +02:00
optionalParameters : [ 'A=<IPv4>' , 'AAAA=<IPv6>' , 'apikey=<API-Key>' , 'self=<yes|no>' ]))
2024-04-16 18:24:38 +02:00
-> addCommand ( command : new Command (
name : 'update' ,
callback : function () {
$this -> panelsUpdate ();
},
mandatoryParameters : [ 'ID' ],
2024-04-18 14:20:46 +02:00
optionalParameters : [ 'name=<name>' , 'A=<IPv4>' , 'AAAA=<IPv6>' , 'apikey=<API-Key>' , 'self=<yes|no>' ]))
2024-04-16 18:24:38 +02:00
-> addCommand ( command : new Command (
name : 'delete' ,
callback : function () {
$this -> panelsDelete ();
},
mandatoryParameters : [ 'ID' ]))
-> addCommand ( command : new Command (
name : 'apiping' ,
callback : function () {
$this -> apiPing ( type : 'panel' );
},
optionalParameters : [ 'ID' ])))
-> addCommandGroup ( commandGroup : ( new CommandGroup ( name : 'nameservers' , description : 'available nameservers' ))
-> addCommand ( command : new Command (
name : 'list' ,
callback : function () {
$this -> nameserversList ();
}))
-> addCommand ( command : new Command (
name : 'create' ,
callback : function () {
$this -> nameserversCreate ();
},
mandatoryParameters : [ 'name' ],
optionalParameters : [ 'A=<IPv4>' , 'AAAA=<IPv6>' , 'apikey=<API-Key>' ]))
-> addCommand ( command : new Command (
name : 'update' ,
callback : function () {
$this -> nameserversUpdate ();
},
mandatoryParameters : [ 'ID' ],
optionalParameters : [ 'name=<name>' , 'A=<IPv4>' , 'AAAA=<IPv6>' , 'apikey=<API-Key>' ]))
-> addCommand ( command : new Command (
name : 'delete' ,
callback : function () {
$this -> nameserversDelete ();
},
mandatoryParameters : [ 'ID' ]))
-> addCommand ( command : new Command (
name : 'apiping' ,
callback : function () {
$this -> apiPing ( type : 'nameserver' );
},
optionalParameters : [ 'ID' ])))
-> addCommandGroup ( commandGroup : ( new CommandGroup ( name : 'domains' , description : 'configured domains' ))
-> addCommand ( command : new Command (
name : 'list' ,
callback : function () {
$this -> domainsList ();
}))
-> addCommand ( command : new Command (
2024-04-18 18:04:25 +02:00
name : 'update' ,
2024-04-16 18:24:38 +02:00
callback : function () {
2024-04-18 18:04:25 +02:00
$this -> domainsUpdate ();
2024-04-16 18:24:38 +02:00
},
2024-04-09 18:45:28 +02:00
// mandatoryParameters: ['name'],
// optionalParameters: ['A=<IPv4>', 'AAAA=<IPv6>', 'apikey=<API-Key>'])))
2024-04-18 18:04:25 +02:00
description : 'Update zone files' )))
2024-04-16 18:24:38 +02:00
-> addCommandGroup ( commandGroup : ( new CommandGroup ( name : 'dyndns' , description : 'handle DynDNS entries' ))
-> addCommand ( command : new Command (
name : 'list' ,
callback : function () {
$this -> dynDnsList ();
}))
-> addCommand ( command : new Command (
name : 'create' ,
callback : function () {
$this -> dynDnsCreate ();
},
mandatoryParameters : [ 'hostname.example.com' , 'password' ],
optionalParameters : [ 'A=<IPv4>' , 'AAAA=<IPv6>' ],
description : 'FQDN within a domain where this server is master' ))
-> addCommand ( command : new Command (
name : 'update' ,
callback : function () {
$this -> dynDnyUpdate ();
},
mandatoryParameters : [ 'hostname.example.com' ,],
optionalParameters : [ 'password=<password>' , 'A=<IPv4>' , 'AAAA=<IPv6>' ]))
-> addCommand ( command : new Command (
name : 'delete' ,
callback : function () {
$this -> dynDnsDelete ();
},
mandatoryParameters : [ 'ID' ])))
-> addCommandGroup ( commandGroup : ( new CommandGroup ( name : 'migrations' , description : 'maintain database migrations' ))
-> addCommand ( command : new Command (
name : 'status' ,
callback : function () {
$this -> migrationsStatus ();
},
description : 'List information about migrations'
))
-> addCommand ( command : new Command (
2024-04-17 20:28:51 +02:00
name : 'migrate' ,
2024-04-16 18:24:38 +02:00
callback : function () {
2024-04-17 20:28:51 +02:00
$this -> migrationsMigrate ();
2024-04-16 18:24:38 +02:00
},
2024-04-17 20:28:51 +02:00
description : 'Apply a new migration file'
2024-04-16 18:24:38 +02:00
))
-> addCommand ( command : new Command (
2024-04-17 20:28:51 +02:00
name : 'make' ,
2024-04-16 18:24:38 +02:00
callback : function () {
2024-04-17 20:28:51 +02:00
$this -> migrationsMake ();
2024-04-16 18:24:38 +02:00
},
2024-04-17 20:28:51 +02:00
description : '!Use only on dev environments, not in production! Build a new migration file'
2024-04-16 18:24:38 +02:00
))
);
2024-04-13 20:35:20 +02:00
2024-04-08 19:01:13 +02:00
// ->addCommandGroup(commandGroup: (new CommandGroup(name: 'webmail', description: 'manage webmail setup'))
// ->addCommand(command: new Command(
// name: 'check',
// callback: function () {
// $this->webmailCheck();
// },
// mandatoryParameters: ['example.com']
// ))
// ->addCommand(command: new Command(
// name: 'create',
// callback: function () {
// $this->webmailCreate();
// },
// mandatoryParameters: ['example.com']))
// ->addCommand(command: new Command(
// name: 'delete',
// callback: function () {
// $this->webmailDelete();
// },
// mandatoryParameters: ['ID'])));
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2023-09-19 18:21:42 +02:00
2024-04-16 18:24:38 +02:00
function runCheckSetup () : void
{
if ( ! $this -> domainController -> checkPermissions ()) {
echo COLOR_RED . 'You need to setup the bindAPI permission first.' . COLOR_DEFAULT . PHP_EOL ;
echo 'Run ' . COLOR_YELLOW . './bin/console check:setup' . COLOR_DEFAULT . ' as root or with sudo.' . PHP_EOL ;
}
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
function runCommand ( array $arguments ) : void
{
if ( count ( $arguments ) < 1 ) {
$this -> showUsage ();
exit ( 0 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$this -> logger -> debug ( message : " runCommand() " );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( str_contains ( haystack : $arguments [ 0 ], needle : ':' )) {
[ $command , $subcommand ] = explode ( separator : ':' , string : $arguments [ 0 ]);
} else {
$command = $arguments [ 0 ];
$subcommand = '' ;
2024-04-13 20:35:20 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$this -> arguments = $this -> parseArguments ( arguments : $arguments );
$this -> commandGroupContainer -> run ( command : $command , subcommand : $subcommand );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
function showUsage () : void
{
$this -> logger -> debug ( message : " showUsage() " );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$debug = $this -> configController -> getConfig ( configKey : 'debug' );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
echo COLOR_YELLOW . 'Usage:' . PHP_EOL ;
echo COLOR_DEFAULT . " \t ./bin/console { options} { arguments} " . PHP_EOL . PHP_EOL ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
echo COLOR_YELLOW . 'Options:' . PHP_EOL ;
echo COLOR_GREEN . " \t -v, --version \t \t " . COLOR_DEFAULT . " Display the version of the API " . PHP_EOL ;
echo COLOR_GREEN . " \t -q, --quiet \t \t " . COLOR_DEFAULT . " No output to stdout, for cronjobs " . PHP_EOL . PHP_EOL ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
echo COLOR_YELLOW . 'Arguments: ' . COLOR_WHITE . '<mandatory> {optional}' . PHP_EOL ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$this -> commandGroupContainer -> printCommands ();
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
echo PHP_EOL . " \033 [39me.g. ./bin/console apikeys:list " . PHP_EOL ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
public function checkPermissions () : void
{
$this -> logger -> debug ( message : " checkPermissions() " );
if ( ! $this -> domainController -> checkPermissions ()) {
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo PHP_EOL . COLOR_DEFAULT ;
echo 'Missing permissions, please run ' . COLOR_YELLOW . './bin/console check:setup' . COLOR_DEFAULT . ' as root or with sudo.' . PHP_EOL ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
} else {
exit ( 0 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
function checkSetup () : void
{
if ( empty ( $this -> arguments [ 1 ])) {
echo 'You need to supply a username.' . PHP_EOL ;
exit ( 1 );
}
$uid = posix_getuid ();
if ( $uid != 0 ) {
echo 'You need to run this as root or with sudo.' . PHP_EOL ;
exit ( 1 );
}
$username = $this -> arguments [ 1 ];
if ( ! $impersonatedUser = posix_getpwnam ( username : $username )) {
echo 'Cannot find user: ' . $username . PHP_EOL ;
exit ( 1 );
}
$impersonatedUserId = $impersonatedUser [ 'uid' ];
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
// add user to group bind
exec ( command : " adduser $username bind " , output : $output , result_code : $return );
if ( $return != 0 ) {
echo 'Could not add user to bind group.' . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
// for /etc/bind/local.zones file
if ( ! file_exists ( filename : $this -> domainController -> localZoneFile )) {
echo 'Could not find ' . COLOR_YELLOW . $this -> domainController -> localZoneFile . COLOR_DEFAULT . '.' . PHP_EOL ;
echo 'Creating …' ;
touch ( filename : $this -> domainController -> localZoneFile );
2022-09-27 19:13:28 +02:00
if ( ! file_exists ( filename : $this -> domainController -> localZoneFile )) {
2024-04-16 18:24:38 +02:00
echo 'Could not create ' . $this -> domainController -> localZoneFile . '.' . PHP_EOL ;
exit ( 1 );
2022-09-27 19:13:28 +02:00
} else {
echo ' done.' . PHP_EOL ;
echo 'Setting owner …' ;
2024-04-16 18:24:38 +02:00
if ( chown ( filename : $this -> domainController -> localZoneFile , user : 'bind' )) {
2022-09-27 19:13:28 +02:00
echo " done. " . PHP_EOL ;
}
echo 'Setting permissions …' ;
2024-04-16 18:24:38 +02:00
if ( chmod ( filename : $this -> domainController -> localZoneFile , permissions : 0664 )) {
2022-09-27 19:13:28 +02:00
echo " done. " . PHP_EOL ;
}
}
2024-04-16 18:24:38 +02:00
} else {
// check /etc/bind/local.zones permissions
echo 'Found ' . COLOR_YELLOW . $this -> domainController -> localZoneFile . COLOR_DEFAULT . '.' . PHP_EOL ;
2024-04-05 17:17:33 +02:00
2024-04-16 18:24:38 +02:00
echo 'Check permissions for ' . COLOR_YELLOW . $this -> domainController -> localZoneFile . COLOR_DEFAULT . ' …' ;
// dont repeat yourself, use check from DomainController FIXME
$this -> domainController -> checkPermissions ( impersonatedUserId : $impersonatedUserId );
}
// /etc/bind/local.zones file must be included in /etc/bind/named.conf.local
$namedConfLocal = file_get_contents ( filename : $this -> domainController -> namedConfLocalFile );
if ( str_contains ( haystack : $namedConfLocal , needle : $this -> domainController -> localZoneFile )) {
echo 'Found ' . COLOR_YELLOW . $this -> domainController -> localZoneFile . COLOR_DEFAULT . ' included ' . COLOR_YELLOW . $this -> domainController -> namedConfLocalFile . COLOR_DEFAULT . '.' . PHP_EOL ;
} else {
echo 'Could not find ' . COLOR_YELLOW . $this -> domainController -> localZoneFile . COLOR_DEFAULT . ' in ' . COLOR_YELLOW . $this -> domainController -> namedConfLocalFile . COLOR_DEFAULT . '.' . PHP_EOL ;
echo 'Adding …' ;
$namedConfLocal .= PHP_EOL . 'include "' . $this -> domainController -> localZoneFile . '";' . PHP_EOL ;
file_put_contents ( filename : $this -> domainController -> namedConfLocalFile , data : $namedConfLocal );
if ( str_contains ( haystack : $namedConfLocal , needle : $this -> domainController -> localZoneFile )) {
echo ' done.' . PHP_EOL ;
} else {
echo 'Could not add ' . COLOR_YELLOW . $this -> domainController -> localZoneFile . COLOR_DEFAULT . ' to ' . COLOR_YELLOW . $this -> domainController -> namedConfLocalFile . COLOR_DEFAULT . '.' . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
// check /etc/bind/zones exists
echo 'Check for ' . COLOR_YELLOW . $this -> domainController -> localZonesDir . COLOR_DEFAULT . ' …' ;
if ( is_dir ( filename : $this -> domainController -> localZonesDir )) {
echo " exists. " . PHP_EOL ;
} else {
echo ' Could not find ' . COLOR_YELLOW . $this -> domainController -> localZonesDir . COLOR_DEFAULT . '.' . PHP_EOL ;
echo 'Creating …' ;
mkdir ( directory : $this -> domainController -> localZonesDir , permissions : 0775 , recursive : true );
echo ' done.' . PHP_EOL ;
echo 'Setting owner …' ;
if ( chown ( filename : $this -> domainController -> localZonesDir , user : 'bind' )) {
echo " done. " . PHP_EOL ;
}
echo 'Setting permissions …' ;
if ( chmod ( filename : $this -> domainController -> localZonesDir , permissions : 0774 )) {
echo " done. " . PHP_EOL ;
}
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function checkPanels () : void
{
$this -> logger -> debug ( message : " checkPanels() " );
$id = intval ( value : $this -> arguments [ 1 ] ? ? 0 );
if ( $id != 0 ) {
if ( $panel = $this -> panelRepository -> findByID ( id : $id )) {
$this -> checkSinglePanel ( panel : $panel );
2024-04-13 20:35:20 +02:00
} else {
2024-04-16 18:24:38 +02:00
echo " Unknown panel ID $id " . PHP_EOL ;
}
} else {
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo " check all … " . PHP_EOL ;
2024-04-16 18:24:38 +02:00
}
$panels = $this -> panelRepository -> findAll ();
foreach ( $panels as $panel ) {
$this -> checkSinglePanel ( panel : $panel );
2022-09-27 19:13:28 +02:00
}
}
2024-04-16 18:24:38 +02:00
}
2024-04-05 17:17:33 +02:00
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ param Panel $panel
*
* @ return void
*/
public
function checkSinglePanel ( Panel $panel ) : void
{
$this -> logger -> debug ( message : " checkSinglePanel() " );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo COLOR_DEFAULT . 'KeyHelp-Panel: ' . COLOR_YELLOW . $panel -> getName () . COLOR_DEFAULT ;
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$encryptionKey = $this -> configController -> getConfig ( configKey : 'encryptionKey' );
$decryptedKey = $this -> encryptionController -> safeDecrypt ( encrypted : $panel -> getApikey (), key : $encryptionKey );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$f = $panel -> getA ();
if ( ! $this -> quiet ) {
2024-04-14 20:14:41 +02:00
echo COLOR_DEFAULT . ' IPv4: ' . COLOR_YELLOW . $f . COLOR_DEFAULT ;
2024-04-16 18:24:38 +02:00
}
2024-04-14 20:14:41 +02:00
2024-04-16 18:24:38 +02:00
if ( ! empty ( $panel -> getA ())) {
2024-04-25 20:58:01 +02:00
$panelRequest = $this -> apiClient -> sendCommand (
2024-04-16 18:24:38 +02:00
requestType : 'GET' ,
serverName : $panel -> getName (),
versionIP : 4 ,
apiKey : $decryptedKey ,
command : '/server' ,
serverType : 'panel' );
} else {
2024-04-25 20:58:01 +02:00
$panelRequest = $this -> apiClient -> sendCommand (
2024-04-16 18:24:38 +02:00
requestType : 'GET' ,
serverName : $panel -> getName (),
versionIP : 6 ,
apiKey : $decryptedKey ,
command : '/server' ,
serverType : 'panel' );
}
$panelData = json_decode ( json : $panelRequest [ 'data' ]);
if ( ! empty ( $panelData )) {
$panelVersion = $panelData -> meta -> panel_version ;
$responseTime = sprintf ( " %0.3f " , $panelRequest [ 'responseTime' ]);
} else {
$panelVersion = 'n/a' ;
$responseTime = 'n/a' ;
}
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo COLOR_DEFAULT . ' KeyHelp version: ' . $panelVersion . " ( $responseTime seconds) " . PHP_EOL ;
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( empty ( $panel -> getA ())) {
2024-04-25 20:58:01 +02:00
$result = $this -> apiClient -> sendCommand (
2024-04-16 18:24:38 +02:00
requestType : 'GET' ,
serverName : $panel -> getName (),
versionIP : 6 ,
apiKey : $decryptedKey ,
command : 'domains?sort=domain&subdomains=false' ,
serverType : 'panel'
);
} else {
2024-04-25 20:58:01 +02:00
$result = $this -> apiClient -> sendCommand (
2024-04-16 18:24:38 +02:00
requestType : 'GET' ,
serverName : $panel -> getName (),
versionIP : 4 ,
apiKey : $decryptedKey ,
command : 'domains?sort=domain&subdomains=false' ,
serverType : 'panel' );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( ! empty ( $result [ 'error' ])) {
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo $result [ 'data' ] . PHP_EOL ;
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
}
if ( ! empty ( $result [ 'data' ])) {
$domains = json_decode ( json : $result [ 'data' ]);
} else {
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo 'No domains found' . PHP_EOL ;
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$maxDomainNameLength = 0 ;
$tmpDomainList = [];
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$mapper = new JsonMapper ();
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( count ( $domains ) > 0 ) {
foreach ( $domains as $domain ) {
$mapper -> bExceptionOnUndefinedProperty = true ;
$mapper -> bStrictNullTypes = false ;
try {
$domainObject = $mapper -> map ( json : $domain , object : new KeyHelpDomain ());
} catch ( JsonMapper_Exception $e ) {
exit ( $e -> getMessage () . PHP_EOL );
}
$tmpDomainList [] = $domainObject ;
if ( strlen ( string : $domain -> domain ) > $maxDomainNameLength ) {
$maxDomainNameLength = strlen ( string : $domain -> domain );
2022-09-27 19:13:28 +02:00
}
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$domainCount = 0 ;
foreach ( $tmpDomainList as $domain ) {
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo COLOR_DEFAULT . " Domain: " . COLOR_YELLOW . str_pad ( string : $domain -> getDomain (), length : $maxDomainNameLength );
2024-04-16 18:24:38 +02:00
}
2024-04-08 19:01:13 +02:00
2024-04-16 18:24:38 +02:00
if ( ! $domain -> isSubdomain ()) {
$this -> checkNS ( domainName : $domain -> getDomain (), panel : $panel );
$domainCount ++ ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $domainCount == 0 ) {
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo 'No second level domains found.' . COLOR_DEFAULT . PHP_EOL ;
}
2024-04-16 18:24:38 +02:00
}
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo PHP_EOL ;
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
try {
sodium_memzero ( string : $decryptedKey );
} catch ( SodiumException $e ) {
exit ( $e -> getMessage () . PHP_EOL );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
function isSubDomain ( Domain $domain ) : bool
{
$this -> logger -> debug ( message : " isSubDomain() " );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
// valid second level domain
if ( ! Validator :: endsWithTld ( value : $domain )) {
return false ;
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$domainParts = explode ( separator : '.' , string : $domain -> getName ());
$reversedParts = array_reverse ( array : $domainParts );
$testDomain = '' ;
$foundDomain = '' ;
foreach ( $reversedParts as $part ) {
if ( $testDomain ) {
$testDomain = $part . '.' . $testDomain ;
} else {
$testDomain = $part ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
if ( $this -> domainRepository -> findByName ( name : $testDomain )) {
$foundDomain = $testDomain ;
echo $part . PHP_EOL ;
2024-04-13 20:35:20 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
echo " found domain *** " . $foundDomain . PHP_EOL ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/*
// system domain
if ( str_contains ( haystack : $domainName , needle : $panel )) {
return false ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
// no second level domain
if ( substr_count ( haystack : $domainName , needle : '.' ) > 1 ) {
return false ;
}
*/
return true ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
function isValidSecondLevelDomain ( string $domainName , string $panel , int $parent ) : bool
{
$this -> logger -> debug ( message : " isValidSecondLevelDomain() " );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
// subdomain
if ( $parent != 0 ) {
return false ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
// system domain
if ( str_contains ( haystack : $domainName , needle : $panel )) {
return false ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
// valid second level domain
if ( ! Validator :: endsWithTld ( value : $domainName )) {
return false ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
// no second level domain
if ( substr_count ( haystack : $domainName , needle : '.' ) > 1 ) {
return false ;
2024-04-13 20:35:20 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
return true ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ param String $domainName
* @ param Panel $panel
*
* @ return void
*/
function checkNS ( string $domainName , Panel $panel ) : void
{
$this -> logger -> debug ( message : " checkNS() " );
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
$nameservers = $this -> nameserverRepository -> findAll ();
foreach ( $nameservers as $nameserver ) {
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$encryptionKey = $this -> configController -> getConfig ( configKey : 'encryptionKey' );
$decryptedKey = $this -> encryptionController -> safeDecrypt ( encrypted : $nameserver -> getApikey (), key : $encryptionKey );
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo COLOR_YELLOW . ' ' . $nameserver -> getName ();
2024-04-16 18:24:38 +02:00
}
2024-04-22 20:19:34 +02:00
if ( ! empty ( $nameserver -> getA ())) {
2024-04-25 20:58:01 +02:00
$result = $this -> apiClient -> sendCommand (
2024-04-16 18:24:38 +02:00
requestType : 'GET' ,
serverName : $nameserver -> getName (),
2024-04-22 20:19:34 +02:00
versionIP : 4 ,
2024-04-16 18:24:38 +02:00
apiKey : $decryptedKey ,
command : 'domains/name/' . $domainName ,
serverType : 'nameserver' );
} else {
2024-04-25 20:58:01 +02:00
$result = $this -> apiClient -> sendCommand (
2024-04-16 18:24:38 +02:00
requestType : 'GET' ,
serverName : $nameserver -> getName (),
2024-04-22 20:19:34 +02:00
versionIP : 6 ,
2024-04-16 18:24:38 +02:00
apiKey : $decryptedKey (),
command : 'domains/name/' ,
serverType : 'nameserver' . $domainName );
}
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
switch ( $result [ 'header' ]) {
case 200 :
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo COLOR_GREEN . ' OK' ;
2024-04-16 18:24:38 +02:00
}
break ;
2024-04-22 20:19:34 +02:00
case 401 :
if ( ! $this -> quiet ) {
echo COLOR_RED . ' Error: ' . COLOR_YELLOW . $result [ 'data' ] . COLOR_DEFAULT . PHP_EOL ;
}
exit ( 1 );
2024-04-16 18:24:38 +02:00
case 404 :
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo COLOR_RED . ' ' . $result [ 'header' ] . COLOR_DEFAULT ;
2024-04-16 18:24:38 +02:00
}
if ( ! empty ( $this -> arguments [ 'fix' ]) && $this -> arguments [ 'fix' ] == 'yes' ) {
if ( ! $this -> quiet ) {
echo ' trying to fix …' ;
}
$body = [
'name' => $domainName ,
'panel' => $panel -> getName (),
];
$encryptionKey = $this -> configController -> getConfig ( configKey : 'encryptionKey' );
$decryptedKey = $this -> encryptionController -> safeDecrypt ( encrypted : $nameserver -> getApikey (), key : $encryptionKey );
if ( ! empty ( $nameserver -> getAaaa ())) {
2024-04-25 20:58:01 +02:00
$create = $this -> apiClient -> sendCommand (
2024-04-16 18:24:38 +02:00
requestType : 'POST' ,
serverName : $nameserver -> getName (),
versionIP : 6 ,
apiKey : $decryptedKey ,
command : 'domains' ,
serverType : 'nameserver' ,
body : $body );
} else {
2024-04-25 20:58:01 +02:00
$create = $this -> apiClient -> sendCommand (
2024-04-16 18:24:38 +02:00
requestType : 'POST' ,
serverName : $nameserver -> getName (),
versionIP : 4 ,
apiKey : $decryptedKey (),
command : 'domains' ,
serverType : 'nameserver' ,
body : $body );
}
if ( $create [ 'header' ] != 201 ) {
print_r ( value : $create );
die ( " make error handling " );
} else {
2024-04-14 20:14:41 +02:00
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo COLOR_GREEN . 'OK' . COLOR_DEFAULT ;
}
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
break ;
default :
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo 'Server error' . PHP_EOL ;
2024-04-16 18:24:38 +02:00
}
exit ( 1 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo PHP_EOL ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ param array $arguments
* @ return array
*/
public
function parseArguments ( array $arguments ) : array
{
$this -> logger -> debug ( message : " parseArguments() " );
$parsedArguments = [];
$parseCount = 0 ;
foreach ( $arguments as $argument ) {
if ( str_contains ( haystack : $argument , needle : '=' )) {
[ $key , $value ] = explode ( separator : '=' , string : $argument );
$parsedArguments [ strtolower ( string : $key )] = $value ;
$parsedArguments [ $parseCount ++ ] = $value ;
} else {
$parsedArguments [ strtolower ( string : $argument )] = $argument ;
$parsedArguments [ $parseCount ++ ] = $argument ;
2022-09-27 19:13:28 +02:00
}
}
2024-04-16 18:24:38 +02:00
return $parsedArguments ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
function panelsCreate () : void
{
$this -> logger -> debug ( message : " panelsCreate() " );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$name = $this -> arguments [ 1 ] ? ? '' ;
if ( empty ( $name )) {
echo 'You need to supply the panel name.' . PHP_EOL ;
exit ( 1 );
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$filteredName = filter_var ( value : $name , filter : FILTER_VALIDATE_DOMAIN , options : FILTER_FLAG_HOSTNAME );
if ( ! empty ( $filteredName ) && str_contains ( haystack : $filteredName , needle : '.' )) {
$name = $filteredName ;
} else {
echo " $name is no valid DNS domain name. " . PHP_EOL ;
exit ( 1 );
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$a = $this -> arguments [ 'a' ] ? ? '' ;
$aaaa = $this -> arguments [ 'aaaa' ] ? ? '' ;
if ( empty ( $a ) && empty ( $aaaa )) {
echo 'At least one IP address is required.' . PHP_EOL ;
exit ( 0 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
$apikey = $this -> arguments [ 'apikey' ] ? ? '' ;
$self = $this -> arguments [ 'self' ] ? ? 'no' ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $this -> panelRepository -> findByName ( name : $name )) {
echo " Panel: $name already exists. " . PHP_EOL ;
exit ( 1 );
} else {
$panel = new Panel ( name : $name , a : $a , aaaa : $aaaa , passphrase : $apikey , self : $self );
$result = $this -> panelRepository -> insert ( panel : $panel );
echo " Panel $name has been created with id $result " . PHP_EOL ;
2022-09-27 19:13:28 +02:00
exit ( 0 );
}
2024-04-16 18:24:38 +02:00
}
/**
* @ return void
*/
function panelsList () : void
{
$this -> logger -> debug ( message : " panelsList() " );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$panels = $this -> panelRepository -> findAll ();
if ( ! empty ( $panels )) {
echo 'All available panels:' . PHP_EOL ;
$table = new ConsoleTable ();
$table -> setHeaders ( content : [ 'ID' , 'Name' , 'A' , 'AAAA' , 'API Key (Prefix)' , 'This Panel' ]);
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
foreach ( $panels as $panel ) {
$row = [];
$row [] = $panel -> getID ();
$row [] = $panel -> getName ();
$row [] = $panel -> getA ();
$row [] = $panel -> getAaaa ();
$row [] = $panel -> getApikeyPrefix ();
$row [] = ucfirst ( string : $panel -> getSelf ());
$table -> addRow ( data : $row );
}
$table -> setPadding ( value : 2 );
$table -> display ();
} else {
echo 'No panels found.' . PHP_EOL ;
exit ( 1 );
}
exit ( 0 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function panelsUpdate () : void
{
$this -> logger -> debug ( message : " panelsUpdate() " );
$id = intval ( value : $this -> arguments [ 1 ] ? ? 0 );
$name = $this -> arguments [ 'name' ] ? ? '' ;
$a = $this -> arguments [ 'a' ] ? ? '' ;
$aaaa = $this -> arguments [ 'aaaa' ] ? ? '' ;
$apikey = $this -> arguments [ 'apikey' ] ? ? '' ;
$self = $this -> arguments [ 'self' ] ? ? '' ;
if ( $id == 0 ) {
2024-04-18 17:33:07 +02:00
if ( ! $this -> quiet ) {
echo 'An ID is required' . PHP_EOL ;
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
}
2024-04-21 13:04:38 +02:00
2024-04-16 18:24:38 +02:00
if ( ! $this -> panelRepository -> findByID ( id : $id )) {
2024-04-18 17:33:07 +02:00
if ( ! $this -> quiet ) {
echo " Panel with ID : $id doesn't exist. " . PHP_EOL ;
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
}
2024-04-21 13:04:38 +02:00
2024-04-16 18:24:38 +02:00
if ( $apikey ) {
2024-04-21 13:04:38 +02:00
// sanity check for panel apikey
if ( ! str_contains ( haystack : $apikey , needle : '.' )) {
$this -> exitInvalidPanelApiKey ();
} else {
[ $prefix , $key ] = explode ( separator : '.' , string : $apikey );
$prefixLen = strlen ( string : $prefix );
if ( $prefixLen != 8 ) {
$errorMessage = 'The prefix must be 8 characters long' ;
$this -> exitInvalidPanelApiKey ( details : $errorMessage );
}
2024-04-30 11:13:24 +02:00
// FIXME check validation state of panel and nameserver keys
2024-04-21 13:04:38 +02:00
var_dump ( $prefix , $key );
echo 'Length of prefix: ' . strlen ( $prefix ) . PHP_EOL ;
echo 'Length of key: ' . strlen ( $key ) . PHP_EOL ;
die ();
}
2024-04-16 18:24:38 +02:00
$panel = new Panel ( name : $name , id : $id , a : $a , aaaa : $aaaa , passphrase : $apikey , self : $self );
} else {
$panel = new Panel ( name : $name , id : $id , a : $a , aaaa : $aaaa , self : $self );
}
if ( $this -> panelRepository -> update ( panel : $panel ) !== false ) {
2024-04-18 17:33:07 +02:00
if ( ! $this -> quiet ) {
echo 'Panel ' . COLOR_YELLOW . $id . COLOR_DEFAULT . ' has been updated' . PHP_EOL ;
}
2024-04-16 18:24:38 +02:00
} else {
2024-04-18 17:33:07 +02:00
if ( ! $this -> quiet ) {
echo 'Error while updating domain server.' . PHP_EOL ;
}
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function panelsDelete () : void
{
$this -> logger -> debug ( message : " panelsDelete() " );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( empty ( $this -> arguments [ 1 ])) {
echo " You need to supply an ID. " . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$id = intval ( value : $this -> arguments [ 1 ]) ? ? 0 ;
if ( $id == 0 ) {
echo " Panel with ID $id not found. " . PHP_EOL ;
exit ( 1 );
}
if ( ! $this -> panelRepository -> findByID ( id : $id )) {
echo " There is no panel with ID $id . " . PHP_EOL ;
exit ( 1 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
$this -> panelRepository -> delete ( id : $id );
echo " The panel with ID $id has been deleted. " . PHP_EOL ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function apiPing ( string $type ) : void
{
$this -> logger -> debug ( message : " apiPing() " );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$error = false ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$id = $this -> getId ();
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $id != 0 ) {
if ( $type == 'panel' ) {
$server = $this -> panelRepository -> findByID ( id : $id );
} else {
$server = $this -> nameserverRepository -> findByID ( id : $id );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $server ) {
if ( ! $this -> checkPing ( server : $server , type : $type )) {
2022-09-27 19:13:28 +02:00
$error = true ;
}
} else {
2024-04-16 18:24:38 +02:00
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo " Unknown $type ID $id " . PHP_EOL ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
$error = true ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
} else {
if ( $type == 'panel' ) {
$servers = $this -> panelRepository -> findAll ();
2022-09-27 19:13:28 +02:00
} else {
2024-04-16 18:24:38 +02:00
$servers = $this -> nameserverRepository -> findAll ();
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
if ( $servers ) {
foreach ( $servers as $server ) {
if ( ! $this -> checkPing ( server : $server , type : $type )) {
$error = true ;
}
2024-04-13 20:35:20 +02:00
}
} else {
2024-04-16 18:24:38 +02:00
echo 'No Servers of type ' . $type . ' defined' ;
2022-09-27 19:13:28 +02:00
}
}
2024-04-16 18:24:38 +02:00
if ( $error ) {
exit ( 1 );
} else {
exit ( 0 );
}
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return int | void
*/
public function getId ()
{
if ( ! empty ( $this -> arguments [ 1 ])) {
$id = intval ( value : $this -> arguments [ 1 ] ? ? 0 );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $id != $this -> arguments [ 1 ]) {
echo 'ID has to be a number.' . PHP_EOL ;
exit ( 1 );
2024-04-13 20:35:20 +02:00
}
2024-04-16 18:24:38 +02:00
} else {
$id = 0 ;
}
return $id ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
public function checkPing ( Panel | Nameserver $server , string $type ) : bool
{
$this -> logger -> debug ( message : " checkPing() - server, type: " . $server -> getName () . ', ' . $type );
$error = false ;
if ( $type == 'nameserver' ) {
$maxName = $this -> nameserverRepository -> getLongestEntry ( field : 'name' );
$maxA = $this -> nameserverRepository -> getLongestEntry ( field : 'a' );
$maxAAAA = $this -> nameserverRepository -> getLongestEntry ( field : 'aaaa' );
} else {
$maxName = $this -> panelRepository -> getLongestEntry ( field : 'name' );
$maxA = $this -> panelRepository -> getLongestEntry ( field : 'a' );
$maxAAAA = $this -> panelRepository -> getLongestEntry ( field : 'aaaa' );
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo COLOR_YELLOW . str_pad ( string : $server -> getName (), length : $maxName );
}
$encryptionKey = $this -> configController -> getConfig ( configKey : 'encryptionKey' );
$decryptedKey = $this -> encryptionController -> safeDecrypt ( encrypted : $server -> getApikey (), key : $encryptionKey );
echo 'server: ' . $server -> getName () . PHP_EOL ;
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$a = $server -> getA () ? ? '' ;
if ( ! empty ( $a )) {
$this -> logger -> debug ( " check a " );
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo COLOR_DEFAULT . ' ' . str_pad ( string : $a , length : $maxA , pad_type : STR_PAD_LEFT ) . ' ' ;
}
2024-04-25 20:58:01 +02:00
if ( $result = $this -> apiClient -> sendCommand (
2024-04-16 18:24:38 +02:00
requestType : 'GET' ,
serverName : $server -> getName (),
versionIP : 4 ,
apiKey : $decryptedKey ,
command : 'ping' ,
serverType : $type )) {
2022-09-27 19:13:28 +02:00
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
2024-04-16 18:24:38 +02:00
if ( $result [ 'data' ] == 'pong' ) {
echo ' ' . COLOR_GREEN . $result [ 'data' ];
} else {
echo COLOR_BLUE . ' skip' . COLOR_DEFAULT ;
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo ' ' . $result [ 'data' ];
2022-09-27 19:13:28 +02:00
}
}
}
2024-04-16 18:24:38 +02:00
} else {
$error = true ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
$aaaa = $server -> getAaaa () ? ? '' ;
if ( ! empty ( $aaaa )) {
$this -> logger -> debug ( " check aaaa " );
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo COLOR_DEFAULT . ' ' . str_pad ( string : $aaaa , length : $maxAAAA , pad_type : STR_PAD_LEFT ) . ' ' ;
}
2024-04-25 20:58:01 +02:00
if ( $result = $this -> apiClient -> sendCommand (
2024-04-16 18:24:38 +02:00
requestType : 'GET' ,
serverName : $server -> getName (),
versionIP : 6 ,
apiKey : $decryptedKey ,
command : 'ping' ,
serverType : $type )) {
2022-09-27 19:13:28 +02:00
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
2024-04-16 18:24:38 +02:00
if ( $result [ 'data' ] == 'pong' ) {
echo ' ' . COLOR_GREEN . $result [ 'data' ];
} else {
2024-04-21 13:04:38 +02:00
echo COLOR_BLUE . ' xxskip' . COLOR_DEFAULT ;
2024-04-16 18:24:38 +02:00
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo ' ' . $result [ 'data' ];
2022-09-27 19:13:28 +02:00
}
}
}
2024-04-16 18:24:38 +02:00
} else {
$error = true ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
try {
sodium_memzero ( string : $decryptedKey );
} catch ( SodiumException $e ) {
exit ( $e -> getMessage () . PHP_EOL );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo COLOR_DEFAULT . PHP_EOL ;
}
return ! $error ;
}
2022-09-16 14:59:23 +02:00
2024-04-30 17:22:43 +02:00
public function checkNameserverVersion ( Nameserver $server ) : bool
{
$this -> logger -> debug ( message : " checkNameServerVersion() - server: " . $server -> getName ());
$error = false ;
$skipAAAA = false ;
$encryptionKey = $this -> configController -> getConfig ( configKey : 'encryptionKey' );
$decryptedKey = $this -> encryptionController -> safeDecrypt ( encrypted : $server -> getApikey (), key : $encryptionKey );
$a = $server -> getA () ? ? '' ;
if ( ! empty ( $a )) {
$this -> logger -> debug ( " check a version " );
if ( $result = $this -> apiClient -> sendCommand (
requestType : 'GET' ,
serverName : $server -> getName (),
versionIP : 4 ,
apiKey : $decryptedKey ,
command : 'version' ,
serverType : 'nameserver' )) {
if ( ! $this -> quiet ) {
if ( $result [ 'error' ] === false ) {
$data = $result [ 'data' ];
$decodedData = json_decode ( json : $data );
echo COLOR_DEFAULT . ' Version: ' . COLOR_YELLOW . $decodedData -> version ;
echo COLOR_DEFAULT . ' (Build: ' . COLOR_YELLOW . $decodedData -> buildnumber . COLOR_DEFAULT . ')' . PHP_EOL ;
} else {
echo COLOR_RED . ' Error: ' . COLOR_YELLOW . $result [ 'data' ] . COLOR_DEFAULT . PHP_EOL ;
}
// var_dump($result);
$skipAAAA = true ;
// if ($result['data'] == 'pong') {
// echo ' ' . COLOR_GREEN . $result['data'];
// } else {
// echo COLOR_BLUE . ' skip' . COLOR_DEFAULT;
// if (!$this->configController->getConfig(configKey: 'quiet')) {
// echo ' ' . $result['data'];
// }
// }
}
return true ;
} else {
$error = true ;
}
}
$aaaa = $server -> getAaaa () ? ? '' ;
if ( ! empty ( $aaaa ) && ! $skipAAAA ) {
$this -> logger -> debug ( " check aaaa version " );
if ( $result = $this -> apiClient -> sendCommand (
requestType : 'GET' ,
serverName : $server -> getName (),
versionIP : 6 ,
apiKey : $decryptedKey ,
command : 'version' ,
serverType : 'nameserver' )) {
if ( ! $this -> quiet ) {
echo $result ;
// if ($result['data'] == 'pong') {
// echo ' ' . COLOR_GREEN . $result['data'];
// } else {
// echo COLOR_BLUE . ' xxskip' . COLOR_DEFAULT;
// if (!$this->configController->getConfig(configKey: 'quiet')) {
// echo ' ' . $result['data'];
// }
// }
}
} else {
$error = true ;
}
}
try {
sodium_memzero ( string : $decryptedKey );
} catch ( SodiumException $e ) {
exit ( $e -> getMessage () . PHP_EOL );
}
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo COLOR_DEFAULT . PHP_EOL ;
}
return ! $error ;
}
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
function apikeysCreate () : void
{
2024-04-17 20:28:51 +02:00
$name = $this -> arguments [ 1 ] ? ? '' ;
if ( empty ( $name )) {
echo 'You need to supply a descriptive name for the apikey.' . PHP_EOL ;
exit ( 1 );
}
2022-09-16 14:59:23 +02:00
2024-04-16 18:24:38 +02:00
$apiKeyPrefix = uniqid ();
try {
$apikeyRand = bin2hex ( string : random_bytes ( length : 24 ));
} catch ( Exception $e ) {
exit ( $e -> getMessage () . PHP_EOL );
}
2022-09-17 18:56:20 +02:00
2024-04-16 18:24:38 +02:00
$passphrase = password_hash ( password : $apiKeyPrefix . '.' . $apikeyRand , algo : PASSWORD_ARGON2ID );
2022-09-16 14:59:23 +02:00
2024-04-16 18:24:38 +02:00
$apikey = new Apikey ( name : $name , apikeyPrefix : $apiKeyPrefix , passphrase : $passphrase );
2022-09-16 14:59:23 +02:00
2024-04-16 18:24:38 +02:00
$result = $this -> apikeyRepository -> insert ( apikey : $apikey );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $name ) {
echo 'API key ' . COLOR_YELLOW . $name . COLOR_DEFAULT ;
} else {
echo 'Unnamed API key ' ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
echo ' with ID ' . COLOR_YELLOW . $result . COLOR_DEFAULT . ' has been generated. Store it in a safe place, it cannot be recovered.' . PHP_EOL ;
echo COLOR_YELLOW . $apiKeyPrefix . '.' . $apikeyRand . COLOR_DEFAULT . PHP_EOL ;
exit ( 0 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
function apikeysList () : void
{
$keys = $this -> apikeyRepository -> findAll ();
if ( ! empty ( $keys )) {
$table = new ConsoleTable ();
2024-04-19 15:11:21 +02:00
$table -> setHeaders ( content : [ 'ID' , 'Name' , 'API key prefix' , 'Created at' ]);
2024-04-16 18:24:38 +02:00
foreach ( $keys as $key ) {
$row = [];
$row [] = $key -> getID ();
$row [] = $key -> getName ();
$row [] = $key -> getApikeyPrefix ();
2024-04-19 15:11:21 +02:00
$row [] = $key -> getCreatedAt ();
2024-04-16 18:24:38 +02:00
$table -> addRow ( data : $row );
}
$table -> setPadding ( value : 2 );
$table -> display ();
} else {
echo 'No keys found.' . PHP_EOL ;
}
exit ( 0 );
}
2022-09-17 17:39:47 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function apikeysUpdate () : void
{
$id = intval ( value : $this -> arguments [ 1 ]) ? ? 0 ;
$name = $this -> arguments [ 'name' ] ? ? '' ;
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
if ( $id == 0 ) {
echo 'An ID is required' . PHP_EOL ;
exit ( 1 );
}
if ( ! $this -> apikeyRepository -> findByID ( id : intval ( value : $id ))) {
echo " Apikeys with ID : $id doesn't exist. " . PHP_EOL ;
exit ( 1 );
}
if ( ! $name ) {
echo 'You need tu supply a name.' . PHP_EOL ;
exit ( 1 );
2022-09-27 19:13:28 +02:00
}
2022-09-16 14:59:23 +02:00
2024-04-16 18:24:38 +02:00
$apikey = new Apikey ( id : $id , name : $name );
if ( $this -> apikeyRepository -> update ( apikey : $apikey ) !== false ) {
echo 'Apikey has been updated' . PHP_EOL ;
} else {
echo 'Error while updating apikey.' . PHP_EOL ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
function apikeysDelete () : void
{
$id = intval ( value : $this -> arguments [ 1 ] ? ? 0 );
if ( $id == 0 ) {
echo 'You need to add the ID of the API key.' . PHP_EOL ;
exit ( 1 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
if ( $this -> apikeyRepository -> findByID ( id : $id )) {
$this -> apikeyRepository -> delete ( id : $id );
echo 'API key ' . COLOR_YELLOW . $id . COLOR_DEFAULT . ' has been deleted.' . PHP_EOL ;
2024-04-13 20:35:20 +02:00
exit ( 0 );
2024-04-16 18:24:38 +02:00
} else {
echo 'Unknown ID ' . COLOR_YELLOW . $id . '.' . PHP_EOL ;
exit ( 1 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-16 14:59:23 +02:00
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
function domainsList () : void
{
$domains = $this -> domainRepository -> findAll ();
if ( ! empty ( $domains )) {
echo 'All available domains:' . PHP_EOL ;
$table = new ConsoleTable ();
$table -> setHeaders ( content : [ 'ID' , 'Name' , 'Panel' , 'Type' ]);
/** @var Domain $domain */
foreach ( $domains as $domain ) {
$row = [];
$row [] = $domain -> getId ();
$row [] = $domain -> getName ();
$row [] = $domain -> getPanel ();
$row [] = $this -> domainController -> isMasterZone ( domain : $domain ) ? 'MASTER' : 'SLAVE' ;
$table -> addRow ( data : $row );
}
$table -> setPadding ( value : 2 );
$table -> display ();
} else {
echo 'No domains found.' . PHP_EOL ;
}
exit ( 0 );
}
2022-09-16 14:59:23 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
function dynDnsList () : void
{
$dyndns = $this -> dynDNSRepository -> findAll ();
if ( ! empty ( $dyndns )) {
echo 'All available DynDNS hosts:' . PHP_EOL ;
$table = new ConsoleTable ();
$table -> setHeaders ( content : [ 'ID' , 'Name' , 'Panel' , 'Type' ]);
/** @var \App\Entity\DynDNS $dyndnsHost */
foreach ( $dyndns as $dyndnsHost ) {
$row = [];
$row [] = $dyndnsHost -> getId ();
$row [] = $dyndnsHost -> getName ();
$table -> addRow ( data : $row );
}
$table -> setPadding ( value : 2 );
$table -> display ();
} else {
echo 'No DynDNS hosts found.' . PHP_EOL ;
}
exit ( 0 );
}
2022-09-16 14:59:23 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
function dynDnsCreate () : void
{
$name = $this -> arguments [ 1 ] ? ? '' ;
if ( empty ( $name )) {
echo 'You need to supply the FQDN (hostname).' . PHP_EOL ;
exit ( 1 );
}
2022-09-16 14:59:23 +02:00
2024-04-16 18:24:38 +02:00
$filteredName = filter_var ( value : $name , filter : FILTER_VALIDATE_DOMAIN , options : FILTER_FLAG_HOSTNAME );
if ( ! empty ( $filteredName ) && str_contains ( haystack : $filteredName , needle : '.' )) {
$name = $filteredName ;
} else {
echo " $name is no valid DNS domain name. " . PHP_EOL ;
exit ( 1 );
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$password = $this -> arguments [ 2 ] ? ? '' ;
2022-09-17 18:56:20 +02:00
2024-04-16 18:24:38 +02:00
var_dump ( $this -> arguments );
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
die ();
$domainParts = explode ( separator : '.' , string : $name );
$reversedParts = array_reverse ( array : $domainParts );
$testDomain = '' ;
$foundDomain = '' ;
foreach ( $reversedParts as $part ) {
if ( $testDomain ) {
$testDomain = $part . '.' . $testDomain ;
2024-04-13 20:35:20 +02:00
} else {
2024-04-16 18:24:38 +02:00
$testDomain = $part ;
}
if ( $this -> domainRepository -> findByName ( name : $testDomain )) {
$foundDomain = $testDomain ;
echo $part . PHP_EOL ;
2024-04-13 20:35:20 +02:00
}
2024-04-16 18:24:38 +02:00
}
if ( ! $foundDomain ) {
echo 'No matching domain found for this panel.' . PHP_EOL ;
exit ( 1 );
2022-09-16 14:59:23 +02:00
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo " Found domain: " . COLOR_YELLOW . $foundDomain . COLOR_DEFAULT . PHP_EOL ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
// get host
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
if ( $this -> dynDNSRepository -> findByName ( name : $name )) {
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo " DynDNS host " . COLOR_YELLOW . $name . COLOR_DEFAULT . " already exists. " . PHP_EOL ;
2024-04-13 20:35:20 +02:00
exit ( 0 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
} else {
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo " DynDNS host " . COLOR_YELLOW . $name . COLOR_DEFAULT . " will be created. " . PHP_EOL ;
// insert in db
$dyndnsHost = new DynDNS ( name : $name );
// why is the property set in the cunstructor and afterwards again? FIXME
$dyndnsHost -> setName ( name : $name );
}
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
// check on NS
// => add if missing
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $this -> domainRepository -> findByName ( name : $name )) {
echo " Domain: $name already exists. " . PHP_EOL ;
exit ( 1 );
} else {
if ( ! $this -> panelRepository -> findByName ( name : $panel )) {
echo 'Unknown panel: ' . COLOR_YELLOW . $panel . COLOR_DEFAULT . '.' . PHP_EOL ;
2024-04-13 20:35:20 +02:00
exit ( 1 );
}
2024-04-16 18:24:38 +02:00
$domain = new Domain ( name : $name , panel : $panel );
$result = $this -> domainRepository -> insert ( domain : $domain );
echo 'Domain' . COLOR_YELLOW . $name . COLOR_DEFAULT . ' has been created with id ' . COLOR_YELLOW . $result . COLOR_DEFAULT . '.' . PHP_EOL ;
$this -> domainController -> createSlaveZoneFile ( domain : $domain );
exit ( 0 );
}
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
function domainsCreate () : void
{
// check if we're correctly setup
if ( ! $this -> domainController -> checkPermissions ()) {
echo 'You need to setup the bindAPI first.' . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$name = $this -> arguments [ 1 ] ? ? " " ;
if ( empty ( $name )) {
echo 'You need to supply the domain name.' . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$filteredName = filter_var ( value : $name , filter : FILTER_VALIDATE_DOMAIN , options : FILTER_FLAG_HOSTNAME );
if ( ! empty ( $filteredName ) && str_contains ( haystack : $filteredName , needle : '.' )) {
$name = $filteredName ;
} else {
echo " $name is no valid DNS domain name. " . PHP_EOL ;
exit ( 1 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
$panel = $this -> arguments [ 'panel' ] ? ? '' ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( empty ( $panel )) {
echo 'You need to supply the panel name.' . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $this -> domainRepository -> findByName ( name : $name )) {
echo " Domain: $name already exists. " . PHP_EOL ;
exit ( 1 );
} else {
if ( ! $this -> panelRepository -> findByName ( name : $panel )) {
echo 'Unknown panel: ' . COLOR_YELLOW . $panel . COLOR_DEFAULT . '.' . PHP_EOL ;
2024-04-13 20:35:20 +02:00
exit ( 1 );
}
2024-04-16 18:24:38 +02:00
$domain = new Domain ( name : $name , panel : $panel );
$result = $this -> domainRepository -> insert ( domain : $domain );
echo 'Domain' . COLOR_YELLOW . $name . COLOR_DEFAULT . ' has been created with id ' . COLOR_YELLOW . $result . COLOR_DEFAULT . '.' . PHP_EOL ;
$this -> domainController -> createSlaveZoneFile ( domain : $domain );
exit ( 0 );
}
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
2024-04-18 18:04:25 +02:00
// function domainsUpdate(): void
// {
// // check if we're correctly setup
// if (!$this->domainController->checkPermissions()) {
// echo 'You need to setup the bindAPI first.' . PHP_EOL;
// exit(1);
// }
//
// $id = intval(value: $this->arguments[1] ?? 0);
// $name = $this->arguments['name'] ?? '';
// $panelName = $this->arguments['panel'] ?? '';
//
// if ($id == 0) {
// echo 'An ID is required' . PHP_EOL;
// exit(1);
// }
// if (!$domain = $this->domainRepository->findByID(id: $id)) {
// echo "Domain with ID : $id doesn't exist." . PHP_EOL;
// exit(1);
// }
//
// if (!empty($panelName)) {
// $panel = $this->panelRepository->findByName(name: $panelName);
// }
//
// if (empty($name) && empty($panel)) {
// echo COLOR_DEFAULT . 'No name or panel given, just recreate the config file' . PHP_EOL;
// $this->domainController->updateSlaveZones();
// exit(1);
// }
// $newDomain = new Domain(name: $name, panel: $panelName, id: $domain->getId());
//
// if ($this->domainRepository->update(domain: $newDomain) !== false) {
// echo 'Domain server has been updated' . PHP_EOL;
// $this->domainController->updateSlaveZones();
// } else {
// echo 'Error while updating domain server.' . PHP_EOL;
// }
// }
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function domainsDelete () : void
{
if ( empty ( $this -> arguments [ 1 ])) {
echo " You need to supply an ID. " . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$id = intval ( value : $this -> arguments [ 1 ]) ? ? 0 ;
if ( $id == 0 ) {
echo " Domain with ID $id not found. " . PHP_EOL ;
exit ( 1 );
}
if ( ! $domain = $this -> domainRepository -> findByID ( id : $id )) {
echo " There is no domain with ID $id . " . PHP_EOL ;
exit ( 1 );
}
$this -> domainRepository -> delete ( domain : $domain );
$this -> domainController -> deleteZone ( domain : $domain );
echo " The domain with ID $id has been deleted. " . PHP_EOL ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
function nameserversCreate () : void
{
$name = $this -> arguments [ 1 ] ? ? '' ;
if ( empty ( $name )) {
echo 'You need to supply the nameserver name.' . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$filteredName = filter_var ( value : $name , filter : FILTER_VALIDATE_DOMAIN );
if ( ! empty ( $filteredName ) && str_contains ( haystack : $filteredName , needle : '.' )) {
$name = $filteredName ;
} else {
echo " $name is no valid nameserver name. " . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$a = $this -> arguments [ 'a' ] ? ? '' ;
$aaaa = $this -> arguments [ 'aaaa' ] ? ? '' ;
if ( empty ( $a ) && empty ( $aaaa )) {
echo 'At least one IP address is required.' . PHP_EOL ;
exit ( 0 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
$apikey = $this -> arguments [ 'apikey' ] ? ? '' ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( empty ( $apikey )) {
echo 'An API key is required.' . PHP_EOL ;
exit ( 0 );
}
2022-09-27 19:13:28 +02:00
2024-04-30 11:13:24 +02:00
$self = $this -> arguments [ 'self' ] ? ? '' ;
2024-04-16 18:24:38 +02:00
if ( $this -> nameserverRepository -> findByName ( name : $name )) {
echo " Nameserver: $name already exists. " . PHP_EOL ;
exit ( 1 );
} else {
2024-04-30 11:13:24 +02:00
$nameserver = new Nameserver ( name : $name , a : $a , aaaa : $aaaa , passphrase : $apikey , self : $self );
2024-04-16 18:24:38 +02:00
$result = $this -> nameserverRepository -> insert ( nameserver : $nameserver );
echo 'Nameserver ' . COLOR_YELLOW . $name . COLOR_DEFAULT . ' has been created with id ' . COLOR_YELLOW . $result . COLOR_DEFAULT . PHP_EOL ;
2024-04-30 11:13:24 +02:00
$this -> createOpenAPIBootstrap ();
2024-04-13 20:35:20 +02:00
exit ( 0 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-30 11:13:24 +02:00
// FIXME add method create bootstrap php, add it to create, delete and update nameservers
2024-04-30 17:22:43 +02:00
public function createOpenAPIBootstrap () : void
2024-04-30 11:13:24 +02:00
{
$basePath = $this -> baseDir . '/public/openapi/' ;
$bootStrapFile = $basePath . 'bootstrap.php' ;
$allNameservers = $this -> nameserverRepository -> findAll ();
$nameservers = [];
$defaultNS = '' ;
foreach ( $allNameservers as $ns ) {
$nameservers [] = $ns -> getName ();
if ( $ns -> getSelf () === 'yes' ) {
$defaultNS = $ns -> getName ();
}
}
// Improvement in generating file content
$nameserverList = implode ( separator : " ', ' " , array : $nameservers );
$currentDBVersion = $this -> settingsRepository -> findByName ( name : 'version' );
2024-04-30 19:33:07 +02:00
if ( $dbVersion = json_decode ( json : $currentDBVersion )) {
$versionSting = $dbVersion -> version -> major . '.' . $dbVersion -> version -> minor . '.' . $dbVersion -> version -> patch ;
} else {
if ( ! $this -> quiet ) {
echo COLOR_RED . 'Error: ' . COLOR_DEFAULT . 'Check version settings.' . PHP_EOL ;
}
exit ( 1 );
}
2024-04-30 11:13:24 +02:00
$fileContent = " <?php
const DEFAULT_NS = '{$defaultNS}' ;
const NAMESERVERS = [ '{$nameserverList}' ];
const VERSION = '{$versionSting}' ;
" . PHP_EOL;
try {
file_put_contents ( filename : $bootStrapFile , data : $fileContent );
} catch ( Exception $e ) {
if ( ! $this -> quiet ) {
echo 'Error: ' . $e -> getMessage () . PHP_EOL ;
}
}
shell_exec ( command : $this -> baseDir . 'vendor/bin/openapi src/Controller/RequestController.php -b public/openapi/bootstrap.php -o public/openapi/bindapi.json' );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
function nameserversList () : void
{
$nameservers = $this -> nameserverRepository -> findAll ();
if ( ! empty ( $nameservers )) {
echo 'All available nameservers:' . PHP_EOL ;
$table = new ConsoleTable ();
2024-04-30 11:13:24 +02:00
$table -> setHeaders ( content : [ 'ID' , 'Name' , 'A' , 'AAAA' , 'API Key' , 'self' ]);
2024-04-16 18:24:38 +02:00
foreach ( $nameservers as $nameserver ) {
$row = [];
$row [] = $nameserver -> getId ();
$row [] = $nameserver -> getName ();
$row [] = $nameserver -> getA ();
$row [] = $nameserver -> getAaaa ();
$row [] = $nameserver -> getApikeyPrefix ();
2024-04-30 11:13:24 +02:00
$row [] = $nameserver -> getSelf ();
2024-04-16 18:24:38 +02:00
$table -> addRow ( data : $row );
}
$table -> setPadding ( value : 2 );
$table -> display ();
} else {
echo 'No nameservers found.' . PHP_EOL ;
exit ( 1 );
}
exit ( 0 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function nameserversUpdate () : void
{
$id = $this -> arguments [ 1 ] ? ? 0 ;
$name = $this -> arguments [ 'name' ] ? ? '' ;
$a = $this -> arguments [ 'a' ] ? ? '' ;
$aaaa = $this -> arguments [ 'aaaa' ] ? ? '' ;
$apikey = $this -> arguments [ 'apikey' ] ? ? '' ;
2024-04-30 11:13:24 +02:00
$self = $this -> arguments [ 'self' ] ? ? '' ;
2024-04-16 18:24:38 +02:00
if ( $id == 0 ) {
echo 'An ID is required.' . PHP_EOL ;
exit ( 1 );
}
if ( ! $this -> nameserverRepository -> findByID ( id : intval ( value : $id ))) {
echo 'Nameserver with ID ' . COLOR_YELLOW . $id . COLOR_DEFAULT . " doesn't exist. " . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $apikey ) {
2024-04-30 11:13:24 +02:00
$nameserver = new Nameserver ( name : $name , id : intval ( value : $id ), a : $a , aaaa : $aaaa , passphrase : $apikey , self : $self );
2024-04-16 18:24:38 +02:00
} else {
2024-04-30 11:13:24 +02:00
$nameserver = new Nameserver ( name : $name , id : intval ( value : $id ), a : $a , aaaa : $aaaa , self : $self );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
if ( $this -> nameserverRepository -> update ( nameserver : $nameserver ) !== false ) {
2024-04-30 11:13:24 +02:00
$this -> createOpenAPIBootstrap ();
if ( ! $this -> quiet ) {
echo 'Nameserver ' . COLOR_YELLOW . $id . COLOR_DEFAULT . ' has been updated.' . PHP_EOL ;
}
2024-04-16 18:24:38 +02:00
} else {
2024-04-30 11:13:24 +02:00
if ( ! $this -> quiet ) {
echo 'Error while updating nameserver ' . COLOR_YELLOW . $id . '.' . PHP_EOL ;
}
2024-04-16 18:24:38 +02:00
}
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function nameserversDelete () : void
{
if ( empty ( $this -> arguments [ 1 ])) {
2024-04-30 11:13:24 +02:00
if ( ! $this -> quiet ) {
echo " You need to supply an ID. " . PHP_EOL ;
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
}
$id = intval ( value : $this -> arguments [ 1 ] ? ? 0 );
if ( $id == 0 ) {
2024-04-30 11:13:24 +02:00
if ( ! $this -> quiet ) {
echo 'Nameserver with ID ' . COLOR_YELLOW . $id . COLOR_DEFAULT . ' not found.' . PHP_EOL ;
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
}
if ( ! $this -> nameserverRepository -> findByID ( id : $id )) {
2024-04-30 11:13:24 +02:00
if ( ! $this -> quiet ) {
echo 'There is no nameserver with ID ' . COLOR_YELLOW . $id . COLOR_DEFAULT . '.' . PHP_EOL ;
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
}
$this -> nameserverRepository -> delete ( id : $id );
2024-04-30 11:13:24 +02:00
$this -> createOpenAPIBootstrap ();
if ( ! $this -> quiet ) {
echo 'The nameserver with ID ' . COLOR_YELLOW . $id . COLOR_DEFAULT . ' has been deleted.' . PHP_EOL ;
}
2024-04-16 18:24:38 +02:00
}
/**
*/
function checkShowIncludes () : void
{
$nameservers = $this -> nameserverRepository -> findAll ();
if ( count ( $nameservers ) === 0 ) {
echo 'No nameservers found.' . PHP_EOL ;
echo 'You first need to setup the system.' . PHP_EOL ;
exit ( 1 );
}
echo COLOR_DEFAULT . 'You need to add these lines to ' . COLOR_YELLOW . '/etc/bind/local.bindapi.options' . COLOR_DEFAULT . ' on every panel and make sure' . PHP_EOL ;
echo 'that ' . COLOR_YELLOW . 'include "/etc/bind/local.bindapi.options";' . COLOR_DEFAULT . ' exists in ' . COLOR_YELLOW . '/etc/bind/named.conf.options' . COLOR_DEFAULT . '.' . PHP_EOL ;
$ip = [];
foreach ( $nameservers as $nameserver ) {
if ( ! empty ( $nameserver -> getA ())) {
$ip [] = $nameserver -> getA ();
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
if ( ! empty ( $nameserver -> getAaaa ())) {
$ip [] = $nameserver -> getAaaa ();
2022-09-27 19:13:28 +02:00
}
}
2024-04-16 18:24:38 +02:00
echo PHP_EOL . 'allow-transfer {' . PHP_EOL ;
foreach ( $ip as $currentIp )
echo " \t $currentIp ; " . PHP_EOL ;
echo '};' ;
echo PHP_EOL . 'also-notify {' . PHP_EOL ;
foreach ( $ip as $currentIp )
echo " \t $currentIp ; " . PHP_EOL ;
echo '};' . PHP_EOL ;
echo PHP_EOL . 'After the modification feel free to run ' . COLOR_YELLOW . 'named-checkconf' . COLOR_DEFAULT . ' to ensure there were no errors.' . PHP_EOL ;
echo PHP_EOL . 'Run ' . COLOR_YELLOW . 'rndc reload' . COLOR_DEFAULT . ' to activate the changes.' . PHP_EOL ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function checkDomains () : void
{
$this -> domainController -> checkDomains ();
}
2022-09-27 19:13:28 +02:00
2024-04-21 13:04:38 +02:00
public function exitInvalidPanelApiKey ( string $details = null ) : void
{
if ( ! $this -> quiet ) {
if ( $details ) {
echo COLOR_YELLOW . $details . COLOR_DEFAULT . PHP_EOL ;
}
echo 'This is no valid panel apikey. A valid key looks like this one:' . PHP_EOL ;
echo COLOR_YELLOW . 'A7hjZx52.u8Rzj2S5KUvqozPlQwh4k3eDCrLikL8ZYlcdPr488QkbOW2JaS6Hg5syNllgnNOpQv6TntNMzt62LiH5CTlrMovRQhMcwZzM5dOfLKzqEePFRv1y6qZ7CT9' . PHP_EOL ;
}
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-21 13:04:38 +02:00
public function exitInvalidNameserverApiKey ( string $details = null ) : void
{
echo 'fixme' ;
}
2024-04-25 20:58:01 +02:00
/**
2024-04-16 18:24:38 +02:00
*/
private function dynDnsPush () : void
{
$hostName = $this -> arguments [ 1 ] ? ? '' ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( empty ( $hostName )) {
echo 'You need to supply at least the hostname' . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo " Updating DynDNS host: $hostName " . PHP_EOL ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
echo 'here' ;
$domain = $this -> domainRepository -> findByHost ( host : $hostName );
print_r ( value : $domain );
echo 'there' ;
// we need the panel who is master for zone
$panel = $this -> panelRepository -> findByName ( name : $domain -> getPanel ());
// which NS belongs to that panel
$encryptionKey = $this -> configController -> getConfig ( configKey : 'encryptionKey' );
$decryptedKey = $this -> encryptionController -> safeDecrypt ( encrypted : $panel -> getApikey (), key : $encryptionKey );
if ( ! empty ( $panel -> getAaaa ())) {
2024-04-25 20:58:01 +02:00
$result = $this -> apiClient -> sendCommand (
2024-04-16 18:24:38 +02:00
requestType : 'POST' ,
serverName : $panel -> getName (),
versionIP : 6 ,
apiKey : $decryptedKey ,
command : 'dyndns/' . $hostName ,
serverType : 'nameserver' );
} else {
2024-04-25 20:58:01 +02:00
$result = $this -> apiClient -> sendCommand (
2024-04-16 18:24:38 +02:00
requestType : 'POST' ,
serverName : $panel -> getName (),
versionIP : 4 ,
apiKey : $decryptedKey (),
command : 'dyndns/' . $hostName ,
serverType : 'nameserver' );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
if ( $result [ 'header' ] == 200 ) {
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
$data = $result [ 'data' ];
$decodedData = json_decode ( json : $data , associative : true );
echo $decodedData [ 'message' ] . PHP_EOL ;
}
} else {
echo 'Something went wrong:' . PHP_EOL ;
print_r ( value : $result );
exit ( 1 );
}
exit ( 0 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
private
function checkGenerateKey () : void
{
echo 'This generates a fresh encryption key.' . PHP_EOL ;
echo 'Copy it to config.json.' . PHP_EOL ;
echo 'Note: You must update all API-Keys for panels and nameservers after changing the key!' . PHP_EOL ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
try {
$key = sodium_bin2hex ( string : sodium_crypto_secretbox_keygen ());
echo 'Suggested new key : "' . COLOR_YELLOW . $key . COLOR_DEFAULT . '".' . PHP_EOL ;
echo PHP_EOL ;
exit ( 0 );
} catch ( SodiumException $e ) {
exit ( $e -> getMessage () . PHP_EOL );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-18 18:04:25 +02:00
private function domainsUpdate () : void
2024-04-16 18:24:38 +02:00
{
2024-04-18 18:04:25 +02:00
$this -> logger -> debug ( message : " domainsUpdate() " );
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
$panels = $this -> panelRepository -> findAll ();
foreach ( $panels as $panel ) {
if ( ! $this -> quiet ) {
echo COLOR_DEFAULT . 'Checking panel ' . COLOR_YELLOW . $panel -> getName () . COLOR_DEFAULT . PHP_EOL ;
$longestEntry = $this -> domainRepository -> getLongestEntry ( field : 'name' );
}
2022-09-29 19:21:42 +02:00
$encryptionKey = $this -> configController -> getConfig ( configKey : 'encryptionKey' );
2024-04-16 18:24:38 +02:00
$decryptedKey = $this -> encryptionController -> safeDecrypt ( encrypted : $panel -> getApikey (), key : $encryptionKey );
$currentDomains = $this -> domainRepository -> findByPanel ( name : $panel -> getName ());
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
if ( empty ( $panel -> getA ())) {
2024-04-25 20:58:01 +02:00
$result = $this -> apiClient -> sendCommand (
2024-04-16 18:24:38 +02:00
requestType : 'GET' ,
serverName : $panel -> getName (),
versionIP : 6 ,
apiKey : $decryptedKey ,
command : 'domains?sort=domain&subdomains=false' ,
serverType : 'panel'
);
2022-09-27 19:13:28 +02:00
} else {
2024-04-25 20:58:01 +02:00
$result = $this -> apiClient -> sendCommand (
2024-04-16 18:24:38 +02:00
requestType : 'GET' ,
serverName : $panel -> getName (),
versionIP : 4 ,
apiKey : $decryptedKey ,
command : 'domains?sort=domain&subdomains=false' ,
serverType : 'panel' );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
if ( ! empty ( $result [ 'error' ])) {
2024-04-21 13:04:38 +02:00
echo 'Error: ' . $result [ 'data' ] . PHP_EOL ;
2022-09-27 19:13:28 +02:00
exit ( 1 );
}
2024-04-16 18:24:38 +02:00
if ( ! empty ( $result [ 'data' ])) {
$domains = json_decode ( json : $result [ 'data' ]);
} else {
echo 'No domains found' . PHP_EOL ;
exit ( 1 );
2022-09-27 19:13:28 +02:00
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$domainCount = 0 ;
if ( count ( $domains ) > 0 ) {
foreach ( $domains as $domain ) {
$domainCount ++ ;
if ( ! $this -> quiet ) {
2024-04-25 20:58:01 +02:00
echo COLOR_YELLOW . ' ' . str_pad ( string : $domain -> domain , length : $longestEntry + 1 , pad_type : STR_PAD_RIGHT );
2024-04-16 18:24:38 +02:00
}
2024-04-17 13:34:01 +02:00
if ( $currentDomain = $this -> domainRepository -> findByName ( name : $domain -> domain )) {
$currentPanel = $currentDomain -> getPanel ();
2024-04-16 18:24:38 +02:00
$panelName = $panel -> getName ();
if ( strcmp ( string1 : $currentPanel , string2 : $panelName )) {
2024-04-17 13:34:01 +02:00
$currentDomain -> setPanel ( panel : $panelName );
$this -> domainRepository -> update ( domain : $currentDomain );
2024-04-16 18:24:38 +02:00
if ( ! $this -> quiet ) {
echo COLOR_DEFAULT . ' updated to: ' . COLOR_YELLOW . $panelName ;
}
}
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo COLOR_GREEN . ' OK' . COLOR_DEFAULT . PHP_EOL ;
2024-04-16 18:24:38 +02:00
}
} else {
2024-04-17 13:34:01 +02:00
$newDomain = new Domain ( name : $domain -> domain , panel : $panel -> getName ());
2024-04-16 18:24:38 +02:00
$result = $this -> domainRepository -> insert ( domain : $newDomain );
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo COLOR_DEFAULT . ' has been created with id ' . COLOR_YELLOW . $result . COLOR_DEFAULT . '.' . PHP_EOL ;
}
}
2024-04-17 13:34:01 +02:00
unset ( $currentDomains [ $domain -> domain ]);
2024-04-13 20:35:20 +02:00
}
2024-04-16 18:24:38 +02:00
}
if ( $domainCount == 0 ) {
echo 'No second level domains found.' . COLOR_DEFAULT . PHP_EOL ;
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
//clean up stale domains
if ( count ( $currentDomains ) > 0 ) {
echo 'Dropping stale domains:' . PHP_EOL ;
foreach ( $currentDomains as $domain ) {
echo $domain -> getName () . PHP_EOL ;
$this -> domainRepository -> delete ( domain : $domain );
2024-04-13 20:35:20 +02:00
}
2022-09-29 19:21:42 +02:00
}
2024-04-16 18:24:38 +02:00
2022-09-29 19:21:42 +02:00
}
2024-04-16 18:24:38 +02:00
if ( ! $this -> quiet ) {
echo 'Creating slave zone files' . PHP_EOL ;
}
$this -> domainController -> updateSlaveZones ();
}
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
public function webmailCheck () : void
{
$quiet = $this -> configController -> getConfig ( configKey : 'quiet' );
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
if ( empty ( $this -> arguments [ 1 ])) {
if ( ! $quiet ) {
echo COLOR_DEFAULT . 'You need to supply a domain name.' . PHP_EOL ;
2024-04-13 20:35:20 +02:00
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
} else {
$domainName = $this -> arguments [ 1 ];
}
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
if ( ! $quiet ) {
echo COLOR_DEFAULT . 'Checking domain ' . COLOR_YELLOW . $domainName . COLOR_DEFAULT . '.' . PHP_EOL ;
}
if ( ! $domain = $this -> domainRepository -> findByName ( name : $domainName )) {
2024-04-08 19:01:13 +02:00
if ( ! $quiet ) {
2024-04-16 18:24:38 +02:00
echo COLOR_DEFAULT . 'Domain ' . $domainName . ' not found on this server.' . PHP_EOL ;
2024-04-13 20:35:20 +02:00
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
}
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
if ( ! $this -> domainController -> isMasterZone ( domain : $domain )) {
if ( ! $quiet ) {
echo 'This server is not responsible for ' . COLOR_YELLOW . $domainName . COLOR_DEFAULT . '.' . PHP_EOL ;
2022-09-29 19:21:42 +02:00
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$panel = $this -> panelRepository -> getSelf ();
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
$encryptionKey = $this -> configController -> getConfig ( configKey : 'encryptionKey' );
$decryptedKey = $this -> encryptionController -> safeDecrypt ( encrypted : $panel -> getApikey (), key : $encryptionKey );
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$webmailDomain = 'webmail.' . $domainName ;
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
if ( ! empty ( $panel -> getAAAA ())) {
if ( ! $quiet ) {
echo 'Check using IPv6: ' . COLOR_YELLOW . $panel -> getAaaa () . '.' . COLOR_DEFAULT . PHP_EOL ;
}
2024-04-25 20:58:01 +02:00
$result = $this -> apiClient -> sendCommand (
2024-04-16 18:24:38 +02:00
requestType : 'GET' ,
serverName : $panel -> getName (),
versionIP : 6 ,
apiKey : $decryptedKey ,
command : 'domains/name/' . $webmailDomain ,
serverType : 'panel' );
} else {
if ( ! $quiet ) {
echo 'Check using IPv4: ' . COLOR_YELLOW . $panel -> getA () . COLOR_DEFAULT . PHP_EOL ;
}
2024-04-25 20:58:01 +02:00
$result = $this -> apiClient -> sendCommand (
2024-04-16 18:24:38 +02:00
requestType : 'GET' ,
serverName : $panel -> getName (),
versionIP : 4 ,
apiKey : $decryptedKey ,
command : 'domains/name/' . $webmailDomain ,
serverType : 'panel' );
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
if ( $result [ 'header' ] === 404 ) {
if ( ! $quiet ) {
echo 'The domain ' . COLOR_YELLOW . $webmailDomain . COLOR_DEFAULT . " doesn't exist. " . PHP_EOL ;
}
exit ( 1 );
} else {
if ( ! $quiet ) {
echo 'Found ' . COLOR_YELLOW . $webmailDomain . COLOR_DEFAULT . '.' . PHP_EOL ;
}
}
if ( $v4 = dns_get_record ( hostname : $webmailDomain , type : DNS_A )[ 0 ]) {
if ( ! $quiet ) {
echo " Found IPv4 entry: " . COLOR_YELLOW . $v4 [ 'ip' ] . COLOR_DEFAULT . '.' . PHP_EOL ;
2022-10-08 10:54:55 +02:00
}
2024-04-25 20:58:01 +02:00
$v4Test = $this -> apiClient -> fileGetContents ( url : $webmailDomain , versionIP : 4 );
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
if ( $v4Test [ 'error' ]) {
2022-10-08 10:54:55 +02:00
if ( ! $quiet ) {
2024-04-16 18:24:38 +02:00
echo 'There was an error: ' . COLOR_YELLOW . $v4Test [ 'errorMessage' ] . COLOR_DEFAULT . '.' ;
2022-10-08 10:54:55 +02:00
}
exit ( 1 );
} else {
if ( ! $quiet ) {
2024-04-16 18:24:38 +02:00
echo 'Successfully connected to webserver via ' . COLOR_YELLOW . 'IPv4' . COLOR_DEFAULT . '.' . PHP_EOL ;
2022-10-08 10:54:55 +02:00
}
}
2024-04-16 18:24:38 +02:00
} else {
if ( ! $quiet ) {
echo " Found no IPv4 entry for " . COLOR_YELLOW . $webmailDomain . COLOR_DEFAULT . PHP_EOL ;
}
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
if ( $v6 = dns_get_record ( hostname : $webmailDomain , type : DNS_AAAA )[ 0 ]) {
if ( ! $quiet ) {
echo " Found IPv6 entry: " . COLOR_YELLOW . $v6 [ 'ipv6' ] . COLOR_DEFAULT . '.' . PHP_EOL ;
2022-10-08 10:54:55 +02:00
}
2024-04-25 20:58:01 +02:00
$v6Test = $this -> apiClient -> fileGetContents ( url : $webmailDomain , versionIP : 6 );
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
if ( $v6Test [ 'error' ]) {
2024-04-13 20:35:20 +02:00
if ( ! $quiet ) {
2024-04-16 18:24:38 +02:00
echo 'There was an error: ' . COLOR_YELLOW . $v6Test [ 'errorMessage' ] . COLOR_DEFAULT . '.' ;
2024-04-13 20:35:20 +02:00
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
2024-04-13 20:35:20 +02:00
} else {
if ( ! $quiet ) {
2024-04-16 18:24:38 +02:00
echo 'Successfully connected to webserver via ' . COLOR_YELLOW . 'IPv6' . COLOR_DEFAULT . '.' . PHP_EOL ;
2024-04-13 20:35:20 +02:00
}
2022-10-08 10:54:55 +02:00
}
2024-04-16 18:24:38 +02:00
} else {
if ( ! $quiet ) {
echo " Found no IPv6 entry for " . COLOR_YELLOW . $webmailDomain . COLOR_DEFAULT . '.' . PHP_EOL ;
}
}
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
// TODO check that at least IPv4 or IP6 exists?
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$domainData = json_decode ( json : $result [ 'data' ]);
$apacheData = $domainData -> apache ;
$httpsDirectives = $apacheData -> https_directives . PHP_EOL ;
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
if ( ! str_contains ( haystack : $httpsDirectives , needle : '# bindAPI - webmailer' )) {
if ( ! $quiet ) {
echo 'Generated config is missing.' . PHP_EOL ;
}
exit ( 1 );
} else {
if ( ! $quiet ) {
echo 'Generated config is valid.' . PHP_EOL ;
2022-10-08 10:54:55 +02:00
}
2024-04-16 18:24:38 +02:00
exit ( 0 );
2022-10-08 10:54:55 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
public function webmailCreate () : bool
{
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
// TODO
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
/*
$webmailConfig = '# bindAPI - webmailer' . PHP_EOL ;
$webmailConfig .= 'SSLProxyEngine On' . PHP_EOL ;
$webmailConfig .= 'ProxyPass /.well-known/ !' . PHP_EOL ;
$webmailConfig .= 'ProxyPass "/" "https://webmail' . $panel -> getName () . '"' . PHP_EOL ;
$webmailConfig .= '## bindAPI - webmailer' . PHP_EOL ;
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
echo $webmailConfig ;
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
//$httpsDirectives += $w
*/
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
}
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
private function checkMail () : void
{
echo 'Not yet implemented.' . PHP_EOL ;
}
2022-09-29 19:21:42 +02:00
2024-04-19 15:11:21 +02:00
private function checkVersion () : void
2024-04-16 18:24:38 +02:00
{
2024-04-19 15:11:21 +02:00
$update = false ;
if ( isset ( $this -> arguments [ 1 ])) {
$action = $this -> arguments [ 1 ];
if ( $action !== 'update' ) {
if ( ! $this -> quiet ) {
echo 'The only allowed argument is "' . COLOR_YELLOW . 'update' . COLOR_DEFAULT . '.' . PHP_EOL ;
}
exit ( 1 );
}
$update = true ;
}
2024-04-30 11:13:24 +02:00
$composerFile = $this -> baseDir . DIRECTORY_SEPARATOR . 'composer.json' ;
2024-04-19 15:11:21 +02:00
$composerJson = json_decode ( json : file_get_contents ( filename : $composerFile ), associative : false );
$fileVersion = $composerJson -> version ;
$fileBuildNumber = $composerJson -> build_number ;
[ $major , $minor , $patch ] = explode ( separator : '.' , string : $fileVersion );
$version = [
'major' => $major ,
'minor' => $minor ,
'patch' => $patch
];
$json = json_encode ( value : [ 'version' => $version ]);
echo " File version: \t \t $fileVersion " . PHP_EOL ;
echo " File build number: \t $fileBuildNumber " . PHP_EOL ;
if ( $update ) {
$this -> settingsRepository -> set ( name : 'version' , value : $json );
$this -> settingsRepository -> set ( name : 'buildnumber' , value : $fileBuildNumber );
}
$currentDBVersion = $this -> settingsRepository -> findByName ( name : 'version' );
2024-04-30 11:13:24 +02:00
$dbVersion = json_decode ( json : $currentDBVersion );
2024-04-19 15:11:21 +02:00
2024-04-25 20:58:01 +02:00
$currentDBBuildnumber = $this -> settingsRepository -> findByName ( name : 'buildnumber' );
2024-04-19 15:11:21 +02:00
echo " DB version: \t \t " ;
echo $dbVersion -> version -> major . '.' ;
echo $dbVersion -> version -> minor . '.' ;
echo $dbVersion -> version -> patch . PHP_EOL ;
echo " DB build number: \t $currentDBBuildnumber " . PHP_EOL ;
2024-04-16 18:24:38 +02:00
}
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
private function dynDnyUpdate () : void
{
echo 'Not yet implemented.' . PHP_EOL ;
}
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
private function dynDnsDelete () : void
{
echo 'Not yet implemented.' . PHP_EOL ;
}
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
private function webmailDelete () : void
{
}
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
private function migrationsStatus () : void
{
$phinx = new PhinxApplication ( 'Phinx' , '0.9.2' );
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
// use DI later when moving to symfony
2024-04-18 14:20:46 +02:00
// $input = new \Symfony\Component\Console\Input\ArgvInput();
// $output = new \Symfony\Component\Console\Output\ConsoleOutput();
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
echo 'show migration status' . PHP_EOL ;
$command = $phinx -> find ( name : 'status' ); // change 'migrate' to 'status'
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
$arguments = [
'command' => 'status' ,
];
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
$phinxOutput = new ConsoleOutput ();
$returnCode = $command -> run ( input : new ArrayInput ( parameters : $arguments ), output : $phinxOutput );
echo 'return code: ' . $returnCode . PHP_EOL ;
}
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
private function migrationsMake ()
{
$phinx = new PhinxApplication ();
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
$phinx -> add ( new GenerateCommand ());
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$arguments = [
'command' => 'generate' ,
2024-04-18 14:20:46 +02:00
'--overwrite' => true ,
2024-04-16 18:24:38 +02:00
];
$output = new ConsoleOutput ();
$returnCode = $phinx -> run ( input : new ArrayInput ( parameters : $arguments ), output : $output );
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
private function migrationsMigrate () : void
{
$phinx = new PhinxApplication ( 'Phinx' , '0.9.2' );
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
echo 'show migration status' . PHP_EOL ;
$command = $phinx -> find ( name : 'migrate' );
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$arguments = [
'command' => 'migrate' ,
];
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$phinxOutput = new ConsoleOutput ();
$returnCode = $command -> run ( input : new ArrayInput ( parameters : $arguments ), output : $phinxOutput );
2022-10-08 10:54:55 +02:00
}
2024-04-17 20:28:51 +02:00
private function checkPanel ()
{
$self = $this -> panelRepository -> findSelf ();
$panelCount = count ( $self );
if ( $panelCount != 1 ) {
if ( $panelCount == 0 ) {
echo 'No panel marked as this server.' . PHP_EOL ;
2024-04-18 14:20:46 +02:00
echo 'Use ' . COLOR_YELLOW . 'panels:update <ID> self=yes ' . COLOR_DEFAULT . 'to mark this panel.' . PHP_EOL ;
2024-04-17 20:28:51 +02:00
} else {
echo 'Only one panel can be marked as self.' . PHP_EOL ;
2024-04-18 14:20:46 +02:00
echo 'Use ' . COLOR_YELLOW . 'panels:update <ID> self=no ' . COLOR_DEFAULT . 'to remove the stale panel' . PHP_EOL ;
2024-04-17 20:28:51 +02:00
}
} else {
if ( ! $this -> quiet ) {
echo 'Only one panel is designated as our host' . COLOR_GREEN . ' OK' . COLOR_DEFAULT . PHP_EOL ;
2024-04-19 18:11:21 +02:00
$self = $this -> panelRepository -> getSelf ();
$selfName = $self -> getName ();
echo 'The panel is configured to be ' . COLOR_YELLOW . $selfName ;
$hostname = gethostname ();
if ( strcmp ( string1 : $hostname , string2 : $selfName ) === 0 ) {
echo COLOR_DEFAULT . ' and that seems to be valid.' . PHP_EOL ;
} else {
echo PHP_EOL ;
echo $selfName . COLOR_DEFAULT . ' and ' . COLOR_YELLOW . $hostname . COLOR_DEFAULT . ' differ.' . PHP_EOL ;
echo 'Name mismatch, maybe panel:self not set?' . PHP_EOL ;
}
2024-04-17 20:28:51 +02:00
}
}
}
2024-04-21 13:49:02 +02:00
2024-04-30 11:13:24 +02:00
private function checkNameserver ()
{
$self = $this -> panelRepository -> findSelf ();
$nameserverCount = count ( $self );
if ( $nameserverCount != 1 ) {
if ( $nameserverCount == 0 ) {
if ( ! $this -> quiet ) {
echo 'No nameserver marked as this server.' . PHP_EOL ;
echo 'The setting is used to generate the default nameserver in SwaggerUI.' . PHP_EOL ;
echo 'Use ' . COLOR_YELLOW . 'nameservers:update <ID> self=yes ' . COLOR_DEFAULT . 'to mark this nameserver.' . PHP_EOL ;
exit ( 1 );
}
} else {
if ( ! $this -> quiet ) {
echo 'Only one nameserver should be marked as self.' . PHP_EOL ;
echo 'The setting is used to generate the default nameserver in SwaggerUI.' . PHP_EOL ;
echo 'Use ' . COLOR_YELLOW . 'nameservers:update <ID> self=no ' . COLOR_DEFAULT . 'to remove the stale nameserver' . PHP_EOL ;
}
}
} else {
if ( ! $this -> quiet ) {
echo 'Only one nameserver is designated as our host' . COLOR_GREEN . ' OK' . COLOR_DEFAULT . PHP_EOL ;
}
}
}
2024-04-21 13:49:02 +02:00
private function cronRun ()
{
2024-04-23 19:53:57 +02:00
$this -> logger -> info ( message : 'cronRun()' );
2024-05-01 18:39:55 +02:00
$this -> checkPanel ();
$this -> checkNameserver ();
2024-04-21 13:49:02 +02:00
$this -> domainsUpdate ();
}
2024-04-30 17:22:43 +02:00
private function checkNameservers ()
{
if ( ! $this -> quiet ) {
echo 'Check nameserver versions:' . PHP_EOL ;
}
$nameservers = $this -> nameserverRepository -> findAll ();
foreach ( $nameservers as $nameserver ) {
if ( ! $this -> quiet ) {
echo COLOR_YELLOW . $nameserver -> getName ();
$this -> checkNameserverVersion ( server : $nameserver );
}
}
}
2024-04-16 18:24:38 +02:00
}