diff --git a/src/Controller/BindAPI.php b/src/Controller/BindAPI.php index 9ff4c19..ecbccd3 100755 --- a/src/Controller/BindAPI.php +++ b/src/Controller/BindAPI.php @@ -13,6 +13,7 @@ define(constant_name: 'COLOR_DEFAULT', value: "\033[39m"); use App\Entity\Domain; +use App\Entity\Nameserver; use App\Entity\Panel; use App\Repository\ApikeyRepository; use App\Repository\DomainRepository; @@ -24,6 +25,9 @@ use DI\ContainerBuilder; use DI\DependencyException; use DI\NotFoundException; use LucidFrame\Console\ConsoleTable; +use Monolog\Formatter\LineFormatter; +use Monolog\Handler\StreamHandler; +use Monolog\Logger; use UnhandledMatchError; use function DI\autowire; @@ -36,14 +40,14 @@ if (php_sapi_name() !== 'cli') { */ class BindAPI { - //private DatabaseConnection $databaseConnection; - private DomainController $domainController; - private PanelController $panelController; - private NameserverController $nameserverController; - private CheckController $checkController; - private DomainRepository $domainRepository; - private NameserverRepository $nameserverRepository; + private Logger $log; + private ApiController $apiController; private ApikeyRepository $apikeyRepository; + private DomainController $domainController; + private DomainRepository $domainRepository; + private NameserverController $nameserverController; + private NameserverRepository $nameserverRepository; + private PanelController $panelController; private PanelRepository $panelRepository; private Container $container; @@ -55,26 +59,46 @@ class BindAPI */ public function __construct(private array $config, private int $argumentsCount, private array $arguments) { + $dateFormat = "Y:m:d H:i:s"; + $output = "%datetime% %channel%.%level_name% %message%\n"; // %context% %extra% + $formatter = new LineFormatter(format: $output, dateFormat: $dateFormat); + + $stream = new StreamHandler(stream: dirname(path: __DIR__, levels: 2) . '/bindAPI.log'); + $stream->setFormatter(formatter: $formatter); + + $this->log = new Logger(name: 'bindAPI'); + $this->log->pushHandler(handler: $stream); $containerBuilder = new ContainerBuilder(); $containerBuilder->addDefinitions([ DatabaseConnection::class => autowire()->constructorParameter(parameter: 'config', value: $this->config), + DomainController::class => autowire() + ->constructorParameter(parameter: 'config', value: $this->config) + ->constructorParameter(parameter: 'log', value: $this->log), + DomainRepository::class => autowire() + ->constructorParameter(parameter: 'config', value: $this->config) + ->constructorParameter(parameter: 'log', value: $this->log), ]); $this->container = $containerBuilder->build(); - //$this->databaseConnection = $this->container->get(name: DatabaseConnection::class); - $this->panelController = $this->container->get(name: PanelController::class); - $this->checkController = $this->container->get(name: CheckController::class); - $this->nameserverController = $this->container->get(name: NameserverController::class); + $this->apiController = $this->container->get(name: ApiController::class); $this->domainController = $this->container->get(name: DomainController::class); $this->domainRepository = $this->container->get(name: DomainRepository::class); + $this->nameserverController = $this->container->get(name: NameserverController::class); $this->nameserverRepository = $this->container->get(name: NameserverRepository::class); - $this->apikeyRepository = $this->container->get(name: ApikeyRepository::class); + $this->panelController = $this->container->get(name: PanelController::class); $this->panelRepository = $this->container->get(name: PanelRepository::class); + $this->apikeyRepository = $this->container->get(name: ApikeyRepository::class); + + //$dotenv->required(['DB_HOST', 'DB_NAME', 'DB_USER', 'DB_PASS']); + } function runCommand() { + if ($this->config['debug']) { + $this->log->debug(message: "runCommand()"); + } if ($this->argumentsCount < 1) { $this->showUsage(); exit(0); @@ -106,12 +130,16 @@ class BindAPI */ function showUsage(): void { + if ($this->config['debug']) { + $this->log->debug(message: "showUsage()"); + } + echo COLOR_YELLOW . 'Usage:' . PHP_EOL; echo COLOR_DEFAULT . "\t./bin/console {options} {arguments}" . PHP_EOL . PHP_EOL; 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-V, --verbose\t\t" . COLOR_DEFAULT . "All :list command are auto-verbose" . PHP_EOL . PHP_EOL; + echo COLOR_GREEN . "\t-V, --verbose\t\t" . COLOR_DEFAULT . "All :lists command are auto-verbose" . PHP_EOL . PHP_EOL; echo COLOR_YELLOW . "check" . COLOR_DEFAULT . "\t health checks the system can perform" . PHP_EOL; echo COLOR_GREEN . "\t check:permissions" . PHP_EOL; @@ -122,26 +150,26 @@ class BindAPI echo COLOR_GREEN . "\t panels:list" . PHP_EOL; echo COLOR_GREEN . "\t panels:create {A=} {AAAA=} {apikey=}" . PHP_EOL; echo COLOR_GREEN . "\t panels:update {name=} {A=} {AAAA=} {apikey=}" . PHP_EOL; - echo COLOR_GREEN . "\t panels:delete" . PHP_EOL; + echo COLOR_GREEN . "\t panels:delete " . PHP_EOL; echo COLOR_GREEN . "\t panels:apiping {}" . PHP_EOL; echo COLOR_YELLOW . "nameservers" . COLOR_DEFAULT . " available nameservers" . PHP_EOL; echo COLOR_GREEN . "\t nameservers:list" . PHP_EOL; echo COLOR_GREEN . "\t nameservers:create {A=} {AAAA=} {apikey=}" . PHP_EOL; - echo COLOR_GREEN . "\t nameservers:update {name=} {panel_id=} {A=} {AAAA=} {apikey=}" . PHP_EOL; + echo COLOR_GREEN . "\t nameservers:update {name=} {A=} {AAAA=} {apikey=}" . PHP_EOL; echo COLOR_GREEN . "\t nameservers:delete " . PHP_EOL; echo COLOR_GREEN . "\t nameservers:apiping {}" . PHP_EOL; echo COLOR_YELLOW . "domains" . COLOR_DEFAULT . " domains this server is responsible for" . PHP_EOL; echo COLOR_GREEN . "\t domains:list" . PHP_EOL; - echo COLOR_GREEN . "\t domains:create {A=} {AAAA=}" . PHP_EOL; - echo COLOR_GREEN . "\t domains:update {name=} {A=} {AAAA=}" . PHP_EOL; + echo COLOR_GREEN . "\t domains:create {panel_id=} | {A=} {AAAA=}" . PHP_EOL; + echo COLOR_GREEN . "\t domains:update {name=} {panel_id=} | {A=} {AAAA=}" . PHP_EOL; echo COLOR_GREEN . "\t domains:delete " . PHP_EOL; echo COLOR_YELLOW . "apikeys" . COLOR_DEFAULT . "\t API keys for other nameservers" . PHP_EOL; echo COLOR_GREEN . "\t apikeys:list" . PHP_EOL; echo COLOR_GREEN . "\t apikeys:create {name=}" . PHP_EOL; - echo COLOR_GREEN . "\t apikeys:update name=" . PHP_EOL; + echo COLOR_GREEN . "\t apikeys:update {name=}" . PHP_EOL; echo COLOR_GREEN . "\t apikeys:delete " . PHP_EOL; echo PHP_EOL . "\033[39me.g. ./bin/console apikeys:list" . PHP_EOL; @@ -149,6 +177,10 @@ class BindAPI function handleChecks(string $subcommand) { + if ($this->config['debug']) { + $this->log->debug(message: "handleChecks()"); + } + try { match ($subcommand) { 'permissions' => $this->handleCheckPermissions(), @@ -167,6 +199,10 @@ class BindAPI */ function handleCheckPermissions() { + if ($this->config['debug']) { + $this->log->debug(message: "handleCheckPermissions()"); + } + $this->domainController->checkPermissions(); } @@ -176,6 +212,10 @@ class BindAPI */ function handleCheckPanels() { + if ($this->config['debug']) { + $this->log->debug(message: "handleCheckPanels()"); + } + $id = intval(value: $this->arguments[1] ?? 0); if ($id != 0) { @@ -193,17 +233,22 @@ class BindAPI } } + /** - * @param array $panel + * @param \App\Entity\Panel $panel * * @return void */ public function checkSinglePanel(Panel $panel): void { + if ($this->config['debug']) { + $this->log->debug(message: "checkSinglePanel()"); + } + echo COLOR_DEFAULT . 'Keyhelp-Panel: ' . COLOR_YELLOW . $panel->getName() . PHP_EOL; if (!empty($panel->getAaaa())) { try { - $result = $this->checkController->sendCommand( + $result = $this->apiController->sendCommand( requestType: 'GET', serverName: $panel->getName(), versionIP: 6, @@ -216,7 +261,7 @@ class BindAPI } } else { try { - $result = $this->checkController->sendCommand( + $result = $this->apiController->sendCommand( requestType: 'GET', serverName: $panel->getName(), versionIP: 4, @@ -263,6 +308,10 @@ class BindAPI function isValidSecondLevelDomain(string $domainName, string $panel, int $parent): bool { + if ($this->config['debug']) { + $this->log->debug(message: "isValidSecondLevelDomain()"); + } + // subdomain if ($parent != 0) { return false; @@ -294,6 +343,10 @@ class BindAPI */ function checkNS(string $domainName, $panel) { + if ($this->config['debug']) { + $this->log->debug(message: "checkNS()"); + } + try { $nameServers = $this->nameserverRepository->findAll(); } catch (DependencyException|NotFoundException $e) { @@ -309,7 +362,7 @@ class BindAPI } try { if (!empty($nameServer->getName())) { - $result = $this->checkController->sendCommand( + $result = $this->apiController->sendCommand( requestType: 'GET', serverName: $nameServer->getName(), versionIP: 6, @@ -317,7 +370,7 @@ class BindAPI command: 'domains/' . $domainName, serverType: 'nameserver'); } else { - $result = $this->checkController->sendCommand( + $result = $this->apiController->sendCommand( requestType: 'GET', serverName: $nameServer->getName(), versionIP: 4, @@ -332,7 +385,7 @@ class BindAPI if ($result['header'] == 200) { echo COLOR_GREEN . ' OK'; } else { - echo COLOR_RED . ' missing' . COLOR_DEFAULT; + echo COLOR_RED . $result['header'] . COLOR_DEFAULT; $arguments = $this->parseArguments(); if (!empty($arguments['fix']) && $arguments['fix'] == 'yes') { echo 'trying to fix …'; @@ -342,7 +395,7 @@ class BindAPI ]; try { if (!empty($nameServer['aaaa'])) { - $this->checkController->sendCommand( + $this->apiController->sendCommand( requestType: 'POST', serverName: $nameServer['name'], versionIP: 6, @@ -351,7 +404,7 @@ class BindAPI serverType: 'nameserver', body: $body); } else { - $this->checkController->sendCommand( + $this->apiController->sendCommand( requestType: 'POST', serverName: $nameServer['name'], versionIP: 4, @@ -375,6 +428,10 @@ class BindAPI */ public function parseArguments(): array { + if ($this->config['debug']) { + $this->log->debug(message: "parseArguments()"); + } + $arguments = []; foreach ($this->arguments as $argument) { if (str_contains(haystack: $argument, needle: '=')) { @@ -394,6 +451,10 @@ class BindAPI */ public function handlePanels(string $subcommand): void { + if ($this->config['debug']) { + $this->log->debug(message: "handlePanels()"); + } + try { match ($subcommand) { 'create' => $this->handlePanelsCreate(), @@ -414,6 +475,10 @@ class BindAPI */ function handlePanelsCreate(): void { + if ($this->config['debug']) { + $this->log->debug(message: "handlePanelsCreate()"); + } + $name = $this->arguments[1] ?? ''; if (empty($name)) { echo 'You need to supply the panel name.' . PHP_EOL; @@ -458,6 +523,10 @@ class BindAPI */ function handlePanelsList(): void { + if ($this->config['debug']) { + $this->log->debug(message: "handlePanelsList()"); + } + echo 'All available panels:' . PHP_EOL; try { $panels = $this->panelRepository->findAll(); @@ -491,12 +560,17 @@ class BindAPI exit(0); } + /** * @throws \DI\DependencyException * @throws \DI\NotFoundException */ function handlePanelsUpdate() { + if ($this->config['debug']) { + $this->log->debug(message: "handlePanelsUpdate()"); + } + $arguments = $this->parseArguments(); $id = $this->arguments[1] ?? 0; @@ -526,6 +600,10 @@ class BindAPI */ function handlePanelsDelete() { + if ($this->config['debug']) { + $this->log->debug(message: "handlePanelsDelete()"); + } + if (empty($this->arguments[1])) { echo "You need to supply an ID." . PHP_EOL; exit(1); @@ -550,6 +628,10 @@ class BindAPI */ function handleAPIPing(string $type) { + if ($this->config['debug']) { + $this->log->debug(message: "handleApiPing()"); + } + $error = false; $id = $this->getId(); @@ -644,7 +726,7 @@ class BindAPI echo COLOR_DEFAULT . ' ' . str_pad(string: $a, length: $maxA, pad_type: STR_PAD_LEFT) . ' '; } try { - if ($result = $this->checkController->sendCommand( + if ($result = $this->apiController->sendCommand( requestType: 'GET', serverName: $server['name'], versionIP: 4, @@ -671,7 +753,7 @@ class BindAPI echo COLOR_DEFAULT . ' ' . str_pad(string: $aaaa, length: $maxAAAA, pad_type: STR_PAD_LEFT) . ' '; } try { - if ($result = $this->checkController->sendCommand( + if ($result = $this->apiController->sendCommand( requestType: 'GET', serverName: $server['name'], versionIP: 6, @@ -924,16 +1006,16 @@ class BindAPI echo "Domain: $name already exists." . PHP_EOL; exit(1); } else { - $result = $this->domainRepository->insert(name: $name, panelID: $panelID, a: $a, aaaa: $aaaa); - echo "Domain $name has been created with id $result" . PHP_EOL; if (!empty($panelID)) { if ($panel = $this->panelController->findByID(id: $panelID)) { $a = $panel['a']; $aaaa = $panel['aaaa']; } - } - $this->domainController->createZoneFile(name: $name, a: $a, aaaa: $aaaa); + $domain = new Domain(name: $name, id: $panelID, panelID: $a, a: $aaaa); + $result = $this->domainRepository->insert(domain: $domain); + echo "Domain $name has been created with id $result" . PHP_EOL; + $this->domainController->createZoneFile(domain: $domain); exit(0); } } catch (DependencyException|NotFoundException $e) { @@ -963,19 +1045,21 @@ class BindAPI echo "Domain with ID : $id doesn't exist." . PHP_EOL; exit(1); } - if ($this->domainRepository->update(id: $id, name: $name, panelID: $panelID, a: $a, aaaa: $aaaa) !== false) { + if (!empty($panelID)) { + $panel = $this->panelController->findByID(id: $panelID); + $a = $panel['a']; + $aaaa = $panel['aaaa']; + } + $newDomain = new Domain(name: $name, id: $panelID, panelID: $a, a: $aaaa); + if ($this->domainRepository->update(domain: $newDomain) !== false) { echo 'Domain server has been updated' . PHP_EOL; - if (!empty($panelID)) { - $panel = $this->panelController->findByID(id: $panelID); - $a = $panel['a']; - $aaaa = $panel['aaaa']; - } - $this->domainController->createZoneFile(name: $domain['name'], a: $a, aaaa: $aaaa); + $this->domainController->createZoneFile(domain: $domain); } else { echo 'Error while updating domain server.' . PHP_EOL; } } + /** * @throws \DI\DependencyException * @throws \DI\NotFoundException @@ -992,20 +1076,22 @@ class BindAPI echo "Domain with ID $id not found." . PHP_EOL; exit(1); } - if (!$this->domainRepository->findByID(id: $id)) { + if (!$domain = $this->domainRepository->findByID(id: $id)) { echo "There is no domain with ID $id." . PHP_EOL; exit(1); } - $this->domainController->deleteZone(id: $id); + $this->domainController->deleteZone(domain: $domain); echo "The domain with ID $id has been deleted." . PHP_EOL; } + /** * @param string $subcommand * * @return void */ - public function handleNameservers(string $subcommand): void + public + function handleNameservers(string $subcommand): void { try { match ($subcommand) { @@ -1022,6 +1108,7 @@ class BindAPI } } + /** * @return void */ @@ -1056,7 +1143,8 @@ class BindAPI echo "Nameserver: $name already exists." . PHP_EOL; exit(1); } else { - $result = $this->nameserverRepository->insert(name: $name, a: $a, aaaa: $aaaa, apikey: $apikey); + $nameserver = new Nameserver(name: $name, a: $a, aaaa: $aaaa, apikey: $apikey); + $result = $this->nameserverRepository->insert(nameserver: $nameserver); echo "Nameserver $name has been created with id $result" . PHP_EOL; exit(0); } @@ -1066,6 +1154,7 @@ class BindAPI } } + /** * @return void */ @@ -1104,6 +1193,7 @@ class BindAPI exit(0); } + /** * @throws \DI\DependencyException * @throws \DI\NotFoundException @@ -1133,6 +1223,7 @@ class BindAPI } } + /** * @throws \DI\DependencyException * @throws \DI\NotFoundException