Compare commits
12 Commits
9b2c7f3495
...
0a67c16862
Author | SHA1 | Date |
---|---|---|
tracer | 0a67c16862 | |
tracer | b90d91fda2 | |
tracer | ddae287748 | |
tracer | 22e2d57b61 | |
tracer | d6922be2a4 | |
tracer | 2f79e39a8c | |
tracer | 7036633a8b | |
tracer | 69cca0c2a7 | |
tracer | 47585fccd4 | |
tracer | 8635c9625f | |
tracer | 747b157ac3 | |
tracer | f803570ba7 |
|
@ -5,3 +5,4 @@
|
||||||
/swagger-ui/
|
/swagger-ui/
|
||||||
/config.json.local
|
/config.json.local
|
||||||
/bindAPI.log
|
/bindAPI.log
|
||||||
|
|
||||||
|
|
10
README.md
10
README.md
|
@ -92,7 +92,7 @@ Here I will install it under /usr/local/bin, in the example with the standalone
|
||||||
|
|
||||||
`wget https://getcomposer.org/installer`
|
`wget https://getcomposer.org/installer`
|
||||||
|
|
||||||
`php composer-setup.php --install-dir=/usr/local/bin --filename=composer`
|
`php installer --install-dir=/usr/local/bin --filename=composer`
|
||||||
|
|
||||||
Now we can change into our new user, remind to give him shell access in the panel.
|
Now we can change into our new user, remind to give him shell access in the panel.
|
||||||
|
|
||||||
|
@ -296,10 +296,10 @@ GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, INDEX, DROP, ALTER, CREATE TEMPORA
|
||||||
There is no need to run FLUSH PRIVILEGES when using GRANT!
|
There is no need to run FLUSH PRIVILEGES when using GRANT!
|
||||||
```
|
```
|
||||||
|
|
||||||
So, now it offers us the SQL statements to create a new user and database and set permissions.
|
So, now it offers us the SQL statements to create a new user and database and set permissions. If were on plain debian,
|
||||||
If were on plain debian, we just can copy and paste (the password is random) this as root into mysql.
|
we just can copy and paste (the password is random) this as root into mysql.
|
||||||
|
|
||||||
If we're using hte panel, lets create a database and write down the credentials and update config.json.
|
If we're using the panel, lets create a database and write down the credentials and update config.json.
|
||||||
|
|
||||||
And another call to the console:
|
And another call to the console:
|
||||||
|
|
||||||
|
@ -420,7 +420,7 @@ We create a new key:
|
||||||
```
|
```
|
||||||
$ ./bin/console apikeys:create
|
$ ./bin/console apikeys:create
|
||||||
API key 1 has been generated. Store it in a save place, it cannot be recovered.
|
API key 1 has been generated. Store it in a save place, it cannot be recovered.
|
||||||
6213acb116613.[truncated]]
|
6213acb116613.[truncated]
|
||||||
```
|
```
|
||||||
|
|
||||||
And add it to our list of nameservers:
|
And add it to our list of nameservers:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#!/usr/bin/keyhelp-php81
|
#!/usr/local/bin/php
|
||||||
<?php declare(strict_types=1);
|
<?php declare(strict_types=1);
|
||||||
namespace App\Controller;
|
namespace App\Controller;
|
||||||
|
// #!/usr/bin/keyhelp-php81
|
||||||
|
|
||||||
// & ~E_DEPRECATED is needed because of a bug in PhpStorm
|
// & ~E_DEPRECATED is needed because of a bug in PhpStorm
|
||||||
use DI\DependencyException;
|
use DI\DependencyException;
|
||||||
|
@ -46,9 +47,9 @@ $shortOpts .= "V::"; // verbose
|
||||||
$shortOpts .= "h::"; // help
|
$shortOpts .= "h::"; // help
|
||||||
|
|
||||||
$longOpts = [
|
$longOpts = [
|
||||||
'version::',
|
'version::',
|
||||||
'verbose::',
|
'verbose::',
|
||||||
'help::'
|
'help::'
|
||||||
];
|
];
|
||||||
|
|
||||||
$options = getopt(short_options: $shortOpts, long_options: $longOpts, rest_index: $restIndex);
|
$options = getopt(short_options: $shortOpts, long_options: $longOpts, rest_index: $restIndex);
|
||||||
|
|
|
@ -70,7 +70,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/dyndns/{hostname}": {
|
"/dyndns/{hostname}": {
|
||||||
"get": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"DNS"
|
"DNS"
|
||||||
],
|
],
|
||||||
|
|
|
@ -384,6 +384,7 @@ class BindAPI
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param String $domainName
|
* @param String $domainName
|
||||||
* @param \App\Entity\Panel $panel
|
* @param \App\Entity\Panel $panel
|
||||||
|
@ -470,6 +471,7 @@ class BindAPI
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if ($create['header'] != 201) {
|
if ($create['header'] != 201) {
|
||||||
|
print_r(value: $create);
|
||||||
die("make error handling");
|
die("make error handling");
|
||||||
} else {
|
} else {
|
||||||
echo COLOR_GREEN . 'OK' . COLOR_DEFAULT;
|
echo COLOR_GREEN . 'OK' . COLOR_DEFAULT;
|
||||||
|
@ -1011,7 +1013,7 @@ class BindAPI
|
||||||
}
|
}
|
||||||
if (!empty($domains)) {
|
if (!empty($domains)) {
|
||||||
$table = new ConsoleTable();
|
$table = new ConsoleTable();
|
||||||
$table->setHeaders(content: ['ID', 'Name', 'Panel']);
|
$table->setHeaders(content: ['ID', 'Name', 'Panel', 'Type']);
|
||||||
/** @var Domain $domain */
|
/** @var Domain $domain */
|
||||||
foreach ($domains as $domain) {
|
foreach ($domains as $domain) {
|
||||||
$row = [];
|
$row = [];
|
||||||
|
@ -1019,6 +1021,7 @@ class BindAPI
|
||||||
$row[] = $domain->getId();
|
$row[] = $domain->getId();
|
||||||
$row[] = $domain->getName();
|
$row[] = $domain->getName();
|
||||||
$row[] = $domain->getPanel();
|
$row[] = $domain->getPanel();
|
||||||
|
$row[] = $this->domainController->isMasterZone(domain: $domain) ? 'MASTER' : 'SLAVE';
|
||||||
} catch (DependencyException|NotFoundException $e) {
|
} catch (DependencyException|NotFoundException $e) {
|
||||||
echo $e->getMessage();
|
echo $e->getMessage();
|
||||||
}
|
}
|
||||||
|
@ -1105,14 +1108,14 @@ class BindAPI
|
||||||
|
|
||||||
if (empty($name) && empty($panel)) {
|
if (empty($name) && empty($panel)) {
|
||||||
echo 'No name or panel given, just recreate the config file' . PHP_EOL;
|
echo 'No name or panel given, just recreate the config file' . PHP_EOL;
|
||||||
$this->domainController->createSlaveZoneFile(domain: $domain);
|
$this->domainController->updateSlaveZones();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
$newDomain = new Domain(name: $name, panel: $panelName, id: $domain->getId());
|
$newDomain = new Domain(name: $name, panel: $panelName, id: $domain->getId());
|
||||||
|
|
||||||
if ($this->domainRepository->update(domain: $newDomain) !== false) {
|
if ($this->domainRepository->update(domain: $newDomain) !== false) {
|
||||||
echo 'Domain server has been updated' . PHP_EOL;
|
echo 'Domain server has been updated' . PHP_EOL;
|
||||||
$this->domainController->createSlaveZoneFile(domain: $domain);
|
$this->domainController->updateSlaveZones();
|
||||||
} else {
|
} else {
|
||||||
echo 'Error while updating domain server.' . PHP_EOL;
|
echo 'Error while updating domain server.' . PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ class DatabaseConnection
|
||||||
const TABLE_NAMESERVERS = self::TABLE_PREFIX . "nameservers";
|
const TABLE_NAMESERVERS = self::TABLE_PREFIX . "nameservers";
|
||||||
const TABLE_PANELS = self::TABLE_PREFIX . "panels";
|
const TABLE_PANELS = self::TABLE_PREFIX . "panels";
|
||||||
const TABLE_APIKEYS = self::TABLE_PREFIX . "apikeys";
|
const TABLE_APIKEYS = self::TABLE_PREFIX . "apikeys";
|
||||||
|
const TABLE_DYNDNS = self::TABLE_PREFIX . "dyndns";
|
||||||
|
|
||||||
public function __construct(private array $config)
|
public function __construct(private array $config)
|
||||||
{
|
{
|
||||||
|
@ -83,6 +84,19 @@ class DatabaseConnection
|
||||||
$statement = $this->dbConnection->prepare(query: $sql);
|
$statement = $this->dbConnection->prepare(query: $sql);
|
||||||
$statement->execute();
|
$statement->execute();
|
||||||
|
|
||||||
|
$sql = "
|
||||||
|
CREATE TABLE `dyndns` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` VARCHAR(255) NOT NULL,
|
||||||
|
`a` VARBINARY(255) NOT NULL,
|
||||||
|
`aaaa` VARBINARY(255) NOT NULL,
|
||||||
|
`last_update` TIMESTAMP NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
|
||||||
|
|
||||||
|
$statement = $this->dbConnection->prepare(query: $sql);
|
||||||
|
$statement->execute();
|
||||||
|
|
||||||
echo 'Tables have been created.' . PHP_EOL;
|
echo 'Tables have been created.' . PHP_EOL;
|
||||||
}
|
}
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
|
@ -67,6 +67,30 @@ class DomainController
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function updateSlaveZones()
|
||||||
|
{
|
||||||
|
if ($this->config['verbose']) {
|
||||||
|
echo 'Delete all slave zones';
|
||||||
|
}
|
||||||
|
|
||||||
|
$zones = glob(pattern: $this->localZonesDir . '*');
|
||||||
|
foreach ($zones as $zone) {
|
||||||
|
unlink(filename: $zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
$domains = $this->domainRepository->findAll();
|
||||||
|
|
||||||
|
foreach ($domains as $domain) {
|
||||||
|
if ($this->config['verbose']) {
|
||||||
|
echo 'Create zone: ' . $domain->getName() . PHP_EOL;
|
||||||
|
}
|
||||||
|
$this->createSlaveZoneFile(domain: $domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->createIncludeFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function deleteOnNameservers(Domain $domain)
|
function deleteOnNameservers(Domain $domain)
|
||||||
{
|
{
|
||||||
if ($this->config['debug']) {
|
if ($this->config['debug']) {
|
||||||
|
@ -202,25 +226,28 @@ class DomainController
|
||||||
*/
|
*/
|
||||||
public function createSlaveZoneFile(Domain $domain): void
|
public function createSlaveZoneFile(Domain $domain): void
|
||||||
{
|
{
|
||||||
|
$domainName = $domain->getName();
|
||||||
if ($this->config['debug']) {
|
if ($this->config['debug']) {
|
||||||
$domainName = $domain->getName();
|
|
||||||
$this->log->debug(message: "createZoneFile($domainName)");
|
$this->log->debug(message: "createZoneFile($domainName)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we're a master zone
|
// check if we're a master zone
|
||||||
if ($this->isMasterZone(domain: $domain)) {
|
if ($this->isMasterZone(domain: $domain)) {
|
||||||
echo 'We are zone master for ' . $domain->getName() . PHP_EOL;
|
echo 'We are zone master for ' . $domainName . PHP_EOL;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($zonefile = fopen(filename: $this->localZonesDir . $domain->getName(), mode: 'w')) {
|
if ($zonefile = fopen(filename: $this->localZonesDir . $domainName, mode: 'w')) {
|
||||||
$panelName = $domain->getPanel();
|
$panelName = $domain->getPanel();
|
||||||
$panel = $this->panelRepository->findByName(name: $panelName);
|
if (!$panel = $this->panelRepository->findByName(name: $panelName)) {
|
||||||
|
echo "Error: Panel $panelName doesn't exist." . PHP_EOL;
|
||||||
|
die();
|
||||||
|
}
|
||||||
$a = $panel->getA();
|
$a = $panel->getA();
|
||||||
$aaaa = $panel->getAaaa();
|
$aaaa = $panel->getAaaa();
|
||||||
fputs(stream: $zonefile, data: 'zone "' . $domain->getName() . '"' . ' IN {' . PHP_EOL);
|
fputs(stream: $zonefile, data: 'zone "' . $domainName . '"' . ' IN {' . PHP_EOL);
|
||||||
fputs(stream: $zonefile, data: "\ttype slave;" . PHP_EOL);
|
fputs(stream: $zonefile, data: "\ttype slave;" . PHP_EOL);
|
||||||
fputs(stream: $zonefile, data: "\tfile \"" . $this->zoneCachePath . $domain->getName() . '.db";' . PHP_EOL);
|
fputs(stream: $zonefile, data: "\tfile \"" . $this->zoneCachePath . $domainName . '.db";' . PHP_EOL);
|
||||||
fputs(stream: $zonefile, data: "\tmasters {" . PHP_EOL);
|
fputs(stream: $zonefile, data: "\tmasters {" . PHP_EOL);
|
||||||
if (!empty($a)) {
|
if (!empty($a)) {
|
||||||
fputs(stream: $zonefile, data: "\t\t" . $a . ';' . PHP_EOL);
|
fputs(stream: $zonefile, data: "\t\t" . $a . ';' . PHP_EOL);
|
||||||
|
@ -231,10 +258,10 @@ class DomainController
|
||||||
fputs(stream: $zonefile, data: "\t};" . PHP_EOL);
|
fputs(stream: $zonefile, data: "\t};" . PHP_EOL);
|
||||||
fputs(stream: $zonefile, data: "};" . PHP_EOL);
|
fputs(stream: $zonefile, data: "};" . PHP_EOL);
|
||||||
}
|
}
|
||||||
$this->createIncludeFile();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function isMasterZone(Domain $domain): bool
|
|
||||||
|
public function isMasterZone(Domain $domain): bool
|
||||||
{
|
{
|
||||||
if (file_exists(filename: '/etc/bind/keyhelp_domains/' . $domain->getName())) {
|
if (file_exists(filename: '/etc/bind/keyhelp_domains/' . $domain->getName())) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -5,8 +5,10 @@ namespace App\Controller;
|
||||||
error_reporting(error_level: E_ALL);
|
error_reporting(error_level: E_ALL);
|
||||||
|
|
||||||
use App\Entity\Domain;
|
use App\Entity\Domain;
|
||||||
|
use App\Entity\DynDNS;
|
||||||
use App\Repository\ApikeyRepository;
|
use App\Repository\ApikeyRepository;
|
||||||
use App\Repository\DomainRepository;
|
use App\Repository\DomainRepository;
|
||||||
|
use App\Repository\DynDNSRepository;
|
||||||
use App\Repository\PanelRepository;
|
use App\Repository\PanelRepository;
|
||||||
use DI\Container;
|
use DI\Container;
|
||||||
use DI\ContainerBuilder;
|
use DI\ContainerBuilder;
|
||||||
|
@ -55,6 +57,7 @@ class RequestController
|
||||||
private DomainController $domainController;
|
private DomainController $domainController;
|
||||||
private DomainRepository $domainRepository;
|
private DomainRepository $domainRepository;
|
||||||
private PanelRepository $panelRepository;
|
private PanelRepository $panelRepository;
|
||||||
|
private DynDNSRepository $DynDNSRepository;
|
||||||
private Container $container;
|
private Container $container;
|
||||||
private string $header;
|
private string $header;
|
||||||
private array $result;
|
private array $result;
|
||||||
|
@ -73,7 +76,6 @@ class RequestController
|
||||||
{
|
{
|
||||||
$this->requestMethod = strtoupper(string: $requestMethod);
|
$this->requestMethod = strtoupper(string: $requestMethod);
|
||||||
|
|
||||||
|
|
||||||
$dateFormat = "Y:m:d H:i:s";
|
$dateFormat = "Y:m:d H:i:s";
|
||||||
$output = "%datetime% %channel%.%level_name% %message%\n"; // %context% %extra%
|
$output = "%datetime% %channel%.%level_name% %message%\n"; // %context% %extra%
|
||||||
$formatter = new LineFormatter(format: $output, dateFormat: $dateFormat);
|
$formatter = new LineFormatter(format: $output, dateFormat: $dateFormat);
|
||||||
|
@ -84,6 +86,10 @@ class RequestController
|
||||||
$this->log = new Logger(name: 'bindAPI');
|
$this->log = new Logger(name: 'bindAPI');
|
||||||
$this->log->pushHandler(handler: $stream);
|
$this->log->pushHandler(handler: $stream);
|
||||||
|
|
||||||
|
if ($this->config['debug']) {
|
||||||
|
$this->log->debug(message: 'RequestController::__construct');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$containerBuilder = new ContainerBuilder();
|
$containerBuilder = new ContainerBuilder();
|
||||||
$containerBuilder->addDefinitions([
|
$containerBuilder->addDefinitions([
|
||||||
|
@ -94,6 +100,9 @@ class RequestController
|
||||||
DomainRepository::class => autowire()
|
DomainRepository::class => autowire()
|
||||||
->constructorParameter(parameter: 'config', value: $this->config)
|
->constructorParameter(parameter: 'config', value: $this->config)
|
||||||
->constructorParameter(parameter: 'log', value: $this->log),
|
->constructorParameter(parameter: 'log', value: $this->log),
|
||||||
|
DynDNSRepository::class => autowire()
|
||||||
|
->constructorParameter(parameter: 'config', value: $this->config)
|
||||||
|
->constructorParameter(parameter: 'log', value: $this->log),
|
||||||
|
|
||||||
]);
|
]);
|
||||||
$this->container = $containerBuilder->build();
|
$this->container = $containerBuilder->build();
|
||||||
|
@ -103,6 +112,7 @@ class RequestController
|
||||||
$this->domainController = $this->container->get(name: DomainController::class);
|
$this->domainController = $this->container->get(name: DomainController::class);
|
||||||
$this->domainRepository = $this->container->get(name: DomainRepository::class);
|
$this->domainRepository = $this->container->get(name: DomainRepository::class);
|
||||||
$this->panelRepository = $this->container->get(name: PanelRepository::class);
|
$this->panelRepository = $this->container->get(name: PanelRepository::class);
|
||||||
|
$this->dynDNSRepository = $this->container->get(name: DynDNSRepository::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -288,7 +298,6 @@ class RequestController
|
||||||
echo $this->status;
|
echo $this->status;
|
||||||
} else {
|
} else {
|
||||||
echo json_encode(value: [
|
echo json_encode(value: [
|
||||||
'status' => $this->status ?? "Error: No status",
|
|
||||||
'message' => $this->message ?? "Error: No message."
|
'message' => $this->message ?? "Error: No message."
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -516,6 +525,10 @@ class RequestController
|
||||||
|
|
||||||
private function handleDynDNS()
|
private function handleDynDNS()
|
||||||
{
|
{
|
||||||
|
if ($this->config['debug']) {
|
||||||
|
$this->log->debug(message: 'handleDynDNS()');
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->checkPassword()) {
|
if ($this->checkPassword()) {
|
||||||
$host = $this->uri[3] ?? '';
|
$host = $this->uri[3] ?? '';
|
||||||
|
|
||||||
|
@ -536,109 +549,159 @@ class RequestController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->config['debug']) {
|
||||||
|
$this->log->debug(message: 'a: ' . $a);
|
||||||
|
$this->log->debug(message: 'aaaa: ' . $aaaa);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$domainName = $this->getDomain(host: $host);
|
$domainName = $this->getDomain(host: $host);
|
||||||
$hostName = str_replace(search: '.' . $domainName, replace: '', subject: $host);
|
$hostName = str_replace(search: '.' . $domainName, replace: '', subject: $host);
|
||||||
$domain = $this->domainRepository->findByName(name: $domainName);
|
if (!$domain = $this->domainRepository->findByName(name: $domainName)) {
|
||||||
$panel = $this->panelRepository->findByName(name: $domain->getPanel());
|
$this->header = '404 Not Found';
|
||||||
|
$this->message = 'Domain ' . $domainName . ' not found';
|
||||||
if (!empty($panel->getAaaa())) {
|
|
||||||
$domainData = $this->apiController->sendCommand(
|
|
||||||
requestType: 'GET',
|
|
||||||
serverName : $panel->getName(),
|
|
||||||
versionIP : 6,
|
|
||||||
apiKey : $panel->getApikey(),
|
|
||||||
command : 'domains/name/' . $domainName,
|
|
||||||
serverType : 'panel');
|
|
||||||
} else {
|
} else {
|
||||||
$domainData = $this->apiController->sendCommand(
|
|
||||||
requestType: 'GET',
|
// check if address has changed
|
||||||
serverName : $panel->getName(),
|
if ($dynDNS = $this->dynDNSRepository->findByName(name: $host)) {
|
||||||
versionIP : 4,
|
echo 'found host';
|
||||||
apiKey : $panel->getApikey(),
|
print_r($dynDNS);
|
||||||
command : 'domains/name/' . $domainName,
|
|
||||||
serverType : 'panel');
|
print("a: $a");
|
||||||
}
|
print("aaaa: $aaaa");
|
||||||
|
|
||||||
$domainDecodedData = json_decode(json: $domainData['data']);
|
$ipChanged = false;
|
||||||
$domainID = $domainDecodedData->id;
|
|
||||||
|
if (!empty($a)) {
|
||||||
if (!empty($panel->getAaaa())) {
|
if ($a != $dynDNS->getA()) {
|
||||||
$dnsData = $this->apiController->sendCommand(
|
echo $a . '!=' . $dynDNS->getA();
|
||||||
requestType: 'GET',
|
$dynDNS->setA(a: $a);
|
||||||
serverName : $panel->getName(),
|
$ipChanged = true;
|
||||||
versionIP : 6,
|
|
||||||
apiKey : $panel->getApikey(),
|
|
||||||
command : 'dns/' . $domainID,
|
|
||||||
serverType : 'panel');
|
|
||||||
} else {
|
|
||||||
$dnsData = $this->apiController->sendCommand(
|
|
||||||
requestType: 'GET',
|
|
||||||
serverName : $panel->getName(),
|
|
||||||
versionIP : 4,
|
|
||||||
apiKey : $panel->getApikey(),
|
|
||||||
command : 'dns/' . $domainID,
|
|
||||||
serverType : 'panel');
|
|
||||||
}
|
|
||||||
|
|
||||||
$dnsDataDecoded = json_decode(json: $dnsData['data']);
|
|
||||||
$soa = $dnsDataDecoded->records->soa;
|
|
||||||
$others = $dnsDataDecoded->records->other;
|
|
||||||
|
|
||||||
$hostFound = false;
|
|
||||||
|
|
||||||
$updateHost = function (object $host) use ($hostName, $a, $aaaa, &$hostFound) {
|
|
||||||
if ($host->host == $hostName) {
|
|
||||||
$hostFound = true;
|
|
||||||
if ($host->type == 'A') {
|
|
||||||
if (!empty($a)) {
|
|
||||||
$host->value = $a;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!empty($aaaa)) {
|
|
||||||
$host->value = $aaaa;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!empty($aaaa)) {
|
||||||
|
if ($aaaa != $dynDNS->getAaaa()) {
|
||||||
|
$dynDNS->setAaaa(aaaa: $aaaa);
|
||||||
|
|
||||||
|
$ipChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$ipChanged) {
|
||||||
|
$this->header = '304 Not Modified';
|
||||||
|
$this->message = 'Not modified';
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$this->dynDNSRepository->update(dynDNS: $dynDNS);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$dynDNS = new DynDNS(name: $host, a: $a, aaaa: $aaaa);
|
||||||
|
$this->dynDNSRepository->insert(dynDNS: $dynDNS);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
array_map(callback: $updateHost, array: $others);
|
$panel = $this->panelRepository->findByName(name: $domain->getPanel());
|
||||||
|
|
||||||
if ($hostFound) {
|
|
||||||
$newDnsData = json_encode(value: [
|
|
||||||
'records' => [
|
|
||||||
'soa' => $soa,
|
|
||||||
'other' => $others
|
|
||||||
]
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (!empty($panel->getAaaa())) {
|
if (!empty($panel->getAaaa())) {
|
||||||
$result = $this->apiController->sendCommand(
|
$domainData = $this->apiController->sendCommand(
|
||||||
requestType: 'PUT',
|
requestType: 'GET',
|
||||||
|
serverName : $panel->getName(),
|
||||||
|
versionIP : 6,
|
||||||
|
apiKey : $panel->getApikey(),
|
||||||
|
command : 'domains/name/' . $domainName,
|
||||||
|
serverType : 'panel');
|
||||||
|
} else {
|
||||||
|
$domainData = $this->apiController->sendCommand(
|
||||||
|
requestType: 'GET',
|
||||||
|
serverName : $panel->getName(),
|
||||||
|
versionIP : 4,
|
||||||
|
apiKey : $panel->getApikey(),
|
||||||
|
command : 'domains/name/' . $domainName,
|
||||||
|
serverType : 'panel');
|
||||||
|
}
|
||||||
|
|
||||||
|
$domainDecodedData = json_decode(json: $domainData['data']);
|
||||||
|
$domainID = $domainDecodedData->id;
|
||||||
|
|
||||||
|
if (!empty($panel->getAaaa())) {
|
||||||
|
$dnsData = $this->apiController->sendCommand(
|
||||||
|
requestType: 'GET',
|
||||||
serverName : $panel->getName(),
|
serverName : $panel->getName(),
|
||||||
versionIP : 6,
|
versionIP : 6,
|
||||||
apiKey : $panel->getApikey(),
|
apiKey : $panel->getApikey(),
|
||||||
command : 'dns/' . $domainID,
|
command : 'dns/' . $domainID,
|
||||||
serverType : 'panel',
|
serverType : 'panel');
|
||||||
body : json_decode(json: $newDnsData, associative: true)
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
$result = $this->apiController->sendCommand(
|
$dnsData = $this->apiController->sendCommand(
|
||||||
requestType: 'PUT',
|
requestType: 'GET',
|
||||||
serverName : $panel->getName(),
|
serverName : $panel->getName(),
|
||||||
versionIP : 4,
|
versionIP : 4,
|
||||||
apiKey : $panel->getApikey(),
|
apiKey : $panel->getApikey(),
|
||||||
command : 'dns/' . $domainID,
|
command : 'dns/' . $domainID,
|
||||||
serverType : 'panel',
|
serverType : 'panel');
|
||||||
body : json_decode(json: $newDnsData, associative: true)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if ($result['header'] == 200) {
|
|
||||||
$this->header = '200 OK';
|
$dnsDataDecoded = json_decode(json: $dnsData['data']);
|
||||||
$this->status = json_encode(value: ['message' => 'DynDNS host successfully updated']);
|
$soa = $dnsDataDecoded->records->soa;
|
||||||
|
$others = $dnsDataDecoded->records->other;
|
||||||
|
|
||||||
|
$hostFound = false;
|
||||||
|
|
||||||
|
$updateHost = function (object $host) use ($hostName, $a, $aaaa, &$hostFound) {
|
||||||
|
if ($host->host == $hostName) {
|
||||||
|
$hostFound = true;
|
||||||
|
if ($host->type == 'A') {
|
||||||
|
if (!empty($a)) {
|
||||||
|
$host->value = $a;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!empty($aaaa)) {
|
||||||
|
$host->value = $aaaa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
array_map(callback: $updateHost, array: $others);
|
||||||
|
|
||||||
|
if ($hostFound) {
|
||||||
|
$newDnsData = json_encode(value: [
|
||||||
|
'records' => [
|
||||||
|
'soa' => $soa,
|
||||||
|
'other' => $others
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!empty($panel->getAaaa())) {
|
||||||
|
$result = $this->apiController->sendCommand(
|
||||||
|
requestType: 'PUT',
|
||||||
|
serverName : $panel->getName(),
|
||||||
|
versionIP : 6,
|
||||||
|
apiKey : $panel->getApikey(),
|
||||||
|
command : 'dns/' . $domainID,
|
||||||
|
serverType : 'panel',
|
||||||
|
body : json_decode(json: $newDnsData, associative: true)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$result = $this->apiController->sendCommand(
|
||||||
|
requestType: 'PUT',
|
||||||
|
serverName : $panel->getName(),
|
||||||
|
versionIP : 4,
|
||||||
|
apiKey : $panel->getApikey(),
|
||||||
|
command : 'dns/' . $domainID,
|
||||||
|
serverType : 'panel',
|
||||||
|
body : json_decode(json: $newDnsData, associative: true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if ($result['header'] == 200) {
|
||||||
|
$this->header = '200 OK';
|
||||||
|
$this->message = 'DynDNS host successfully updated';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->header = '404 Not Found';
|
||||||
|
$this->message = 'Host ' . $hostName . ' not found';
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
$this->header = '404 Not Found';
|
|
||||||
$this->status = 'Host ' . COLOR_YELLOW . $hostName . ' not found';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class DynDNS
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public function __construct(private string $name, private string $a, private string $aaaa, private int $id = 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public function getA(): string
|
||||||
|
{
|
||||||
|
return $this->a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public function getAaaa(): string
|
||||||
|
{
|
||||||
|
return $this->aaaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getId(): int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public function getName(): string
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param String $a
|
||||||
|
*/
|
||||||
|
public function setA(string $a): void
|
||||||
|
{
|
||||||
|
$this->a = $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param String $aaaa
|
||||||
|
*/
|
||||||
|
public function setAaaa(string $aaaa): void
|
||||||
|
{
|
||||||
|
$this->aaaa = $aaaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $id
|
||||||
|
*/
|
||||||
|
public function setId(int $id): void
|
||||||
|
{
|
||||||
|
$this->id = $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param String $name
|
||||||
|
*/
|
||||||
|
public function setName(string $name): void
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
enum PanelType
|
||||||
|
{
|
||||||
|
case Panel;
|
||||||
|
case Custom;
|
||||||
|
case Undefined;
|
||||||
|
}
|
|
@ -0,0 +1,245 @@
|
||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Repository;
|
||||||
|
|
||||||
|
use App\Controller\DatabaseConnection;
|
||||||
|
use App\Entity\DynDNS;
|
||||||
|
use Monolog\Logger;
|
||||||
|
use PDO;
|
||||||
|
use PDOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class DynDNSRepository
|
||||||
|
{
|
||||||
|
public function __construct(private DatabaseConnection $databaseConnection, private array $config, private Logger $log)
|
||||||
|
{
|
||||||
|
if ($this->config['debug']) {
|
||||||
|
$this->log->debug(message: "DynDNSRepository::__construct()");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \App\Entity\DynDNS $dynDNS
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function delete(DynDNS $dynDNS): int
|
||||||
|
{
|
||||||
|
$dynDNSName = $dynDNS->getName();
|
||||||
|
if ($this->config['debug']) {
|
||||||
|
$this->log->debug(message: "delete($dynDNSName)");
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "
|
||||||
|
DELETE FROM " . DatabaseConnection::TABLE_DYNDNS . "
|
||||||
|
WHERE id = :id";
|
||||||
|
|
||||||
|
try {
|
||||||
|
$statement = $this->databaseConnection->getConnection()->prepare(query: $sql);
|
||||||
|
$id = $dynDNS->getId();
|
||||||
|
$statement->bindParam(param: 'id', var: $id);
|
||||||
|
$statement->execute();
|
||||||
|
|
||||||
|
return $statement->rowCount();
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
exit($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function findAll(): array
|
||||||
|
{
|
||||||
|
if ($this->config['debug']) {
|
||||||
|
$this->log->debug(message: "findAll()");
|
||||||
|
}
|
||||||
|
|
||||||
|
$dyndns = [];
|
||||||
|
$sql = "
|
||||||
|
SELECT id, name, a, aaaa
|
||||||
|
FROM " . DatabaseConnection::TABLE_DYNDNS . "
|
||||||
|
ORDER BY name";
|
||||||
|
|
||||||
|
try {
|
||||||
|
$statement = $this->databaseConnection->getConnection()->prepare(query: $sql);
|
||||||
|
$statement->execute();
|
||||||
|
while ($result = $statement->fetch(mode: PDO::FETCH_ASSOC)) {
|
||||||
|
$dyndns = new DynDNS(name: $result['name'], a: $result['a'], aaaa: $result['aaaa'], id: $result['id']);
|
||||||
|
$dyndns[] = $dyndns;
|
||||||
|
}
|
||||||
|
return $dyndns;
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
exit($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param String $name
|
||||||
|
*
|
||||||
|
* @return \App\Entity\Domain|bool
|
||||||
|
*/
|
||||||
|
public function findByName(string $name): DynDNS|bool
|
||||||
|
{
|
||||||
|
if ($this->config['debug']) {
|
||||||
|
$this->log->debug(message: "findByName($name)");
|
||||||
|
}
|
||||||
|
$sql = "
|
||||||
|
SELECT id, name, a, aaaa
|
||||||
|
FROM " . DatabaseConnection::TABLE_DYNDNS . "
|
||||||
|
WHERE name = :name";
|
||||||
|
|
||||||
|
try {
|
||||||
|
$statement = $this->databaseConnection->getConnection()->prepare(query: $sql);
|
||||||
|
$statement->bindParam(param: ':name', var: $name);
|
||||||
|
$statement->execute();
|
||||||
|
if ($result = $statement->fetch(mode: PDO::FETCH_ASSOC)) {
|
||||||
|
return new DynDNS(name: $result['name'], a: $result['a'], aaaa: $result['aaaa'], id: $result['id']);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
exit($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param String $field
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getLongestEntry(string $field): int
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT MAX(LENGTH(" . $field . ")) as length FROM " . DatabaseConnection::TABLE_DYNDNS;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$statement = $this->databaseConnection->getConnection()->prepare(query: $sql);
|
||||||
|
$statement->execute();
|
||||||
|
$result = $statement->fetch();
|
||||||
|
return $result['length'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
exit($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \App\Entity\DynDNS $dynDNS
|
||||||
|
*
|
||||||
|
* @return string|false
|
||||||
|
*/
|
||||||
|
public function insert(DynDNS $dynDNS): bool|string
|
||||||
|
{
|
||||||
|
$dynDNSName = $dynDNS->getName();
|
||||||
|
if ($this->config['debug']) {
|
||||||
|
$this->log->debug(message: "insert($dynDNSName)");
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "
|
||||||
|
INSERT INTO " . DatabaseConnection::TABLE_DYNDNS . " (name, a, aaaa)
|
||||||
|
VALUES (:name, :a, :aaaa)";
|
||||||
|
|
||||||
|
try {
|
||||||
|
$a = $dynDNS->getA();
|
||||||
|
$aaaa = $dynDNS->getAaaa();
|
||||||
|
|
||||||
|
$statement = $this->databaseConnection->getConnection()->prepare(query: $sql);
|
||||||
|
$statement->bindParam(param: ':name', var: $dynDNSName);
|
||||||
|
$statement->bindParam(param: ':a', var: $a);
|
||||||
|
$statement->bindParam(param: ':aaaa', var: $aaaa);
|
||||||
|
$statement->execute();
|
||||||
|
|
||||||
|
return $this->databaseConnection->getConnection()->lastInsertId();
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
exit($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \App\Entity\DynDNS $dynDNS
|
||||||
|
*
|
||||||
|
* @return false|int
|
||||||
|
*/
|
||||||
|
public function update(DynDNS $dynDNS): bool|int
|
||||||
|
{
|
||||||
|
$dynDNSnName = $dynDNS->getName();
|
||||||
|
|
||||||
|
if ($this->config['debug']) {
|
||||||
|
$this->log->debug(message: "update($dynDNSnName)");
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = $dynDNS->getId();
|
||||||
|
$current = $this->findByID(id: $id);
|
||||||
|
|
||||||
|
if (empty($dynDNSnName)) {
|
||||||
|
$name = $current->getName();
|
||||||
|
} else {
|
||||||
|
$name = $dynDNSnName;
|
||||||
|
}
|
||||||
|
if (empty($dynDNS->getA())) {
|
||||||
|
$a = $current->getA();
|
||||||
|
} else {
|
||||||
|
$a = $dynDNS->getA();
|
||||||
|
}
|
||||||
|
if (empty($dynDNS->getAaaa())) {
|
||||||
|
$aaaa = $current->getAaaa();
|
||||||
|
} else {
|
||||||
|
$aaaa = $dynDNS->getAaaa();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$sql = "
|
||||||
|
UPDATE " . DatabaseConnection::TABLE_DYNDNS . " SET
|
||||||
|
name = :name,
|
||||||
|
a = :a,
|
||||||
|
aaaa = :aaaa
|
||||||
|
WHERE id = :id";
|
||||||
|
|
||||||
|
try {
|
||||||
|
$statement = $this->databaseConnection->getConnection()->prepare(query: $sql);
|
||||||
|
$statement->bindParam(param: 'id', var: $id);
|
||||||
|
$statement->bindParam(param: 'name', var: $name);
|
||||||
|
$statement->bindParam(param: 'a', var: $a);
|
||||||
|
$statement->bindParam(param: 'aaaa', var: $aaaa);
|
||||||
|
$statement->execute();
|
||||||
|
|
||||||
|
return $statement->rowCount();
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo $e->getMessage();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $id
|
||||||
|
*
|
||||||
|
* @return bool|\App\Entity\Domain
|
||||||
|
*/
|
||||||
|
public function findByID(int $id): bool|DynDNS
|
||||||
|
{
|
||||||
|
if ($this->config['debug']) {
|
||||||
|
$this->log->debug(message: "findById($id)");
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "
|
||||||
|
SELECT id, name, a, aaaa
|
||||||
|
FROM . " . DatabaseConnection::TABLE_DYNDNS . "
|
||||||
|
WHERE id = :id";
|
||||||
|
|
||||||
|
try {
|
||||||
|
$statement = $this->databaseConnection->getConnection()->prepare(query: $sql);
|
||||||
|
$statement->bindParam(param: ':id', var: $id);
|
||||||
|
$statement->execute();
|
||||||
|
if ($result = $statement->fetch(mode: PDO::FETCH_ASSOC)) {
|
||||||
|
return new DynDNS(name: $result['name'], a: $result['a'], aaaa: $result['aaaa'], id: $result['id']);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
exit($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,6 +42,28 @@ class NameserverRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \App\Entity\Nameserver
|
||||||
|
*/
|
||||||
|
public function findFirst(): Nameserver
|
||||||
|
{
|
||||||
|
$nameservers = [];
|
||||||
|
$sql = "
|
||||||
|
SELECT id, name, a, aaaa, apikey
|
||||||
|
FROM " . DatabaseConnection::TABLE_NAMESERVERS . "
|
||||||
|
ORDER BY name";
|
||||||
|
|
||||||
|
try {
|
||||||
|
$statement = $this->databaseConnection->getConnection()->prepare(query: $sql);
|
||||||
|
$statement->execute();
|
||||||
|
$result = $statement->fetch(mode: PDO::FETCH_ASSOC);
|
||||||
|
return new Nameserver(name: $result['name'], id: $result['id'], a: $result['a'], aaaa: $result['aaaa'], apikey: $result['apikey']);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
exit($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $id
|
* @param int $id
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue