diff --git a/composer.json b/composer.json index d1fe962..e73e17f 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "24unix/bindapi", "description": "manage Bind9 DNS server via REST API", "version": "2023.0.1", - "build_number": "341", + "build_number": "342", "authors": [ { "name": "Micha Espey", diff --git a/config.json.sample b/config.json.sample index 601495d..5dbb544 100644 --- a/config.json.sample +++ b/config.json.sample @@ -4,6 +4,6 @@ "dbDatabase": "sampledb", "dbUser": "sampleuser", "dbPassword": "secret", - "encryptionKey": "12345678901234567890123456789012", + "encryptionKey": "changeme", "debug": false } diff --git a/db/migrations/20240418112243_config_table.php b/db/migrations/20240418112243_config_table.php new file mode 100644 index 0000000..a4e3e3a --- /dev/null +++ b/db/migrations/20240418112243_config_table.php @@ -0,0 +1,33 @@ +table('config', [ + 'id' => false, + 'engine' => 'InnoDB', + 'encoding' => 'utf8mb4', + 'collation' => 'utf8mb4_general_ci', + 'comment' => '', + 'row_format' => 'DYNAMIC', + ]) + ->addColumn('name', 'string', [ + 'null' => false, + 'limit' => 256, + 'collation' => 'utf8mb4_general_ci', + 'encoding' => 'utf8mb4', + ]) + ->addColumn('value', 'string', [ + 'null' => false, + 'limit' => 256, + 'collation' => 'utf8mb4_general_ci', + 'encoding' => 'utf8mb4', + 'after' => 'name', + ]) + ->removeColumn('version') + ->save(); + } +} diff --git a/db/migrations/schema.php b/db/migrations/schema.php index ac9c076..814ceb3 100644 --- a/db/migrations/schema.php +++ b/db/migrations/schema.php @@ -112,23 +112,71 @@ return array ( ), 'columns' => array ( - 'version' => + 'name' => array ( 'TABLE_CATALOG' => 'def', 'TABLE_NAME' => 'config', - 'COLUMN_NAME' => 'version', + 'COLUMN_NAME' => 'name', 'ORDINAL_POSITION' => 1, 'COLUMN_DEFAULT' => NULL, 'IS_NULLABLE' => 'NO', 'DATA_TYPE' => 'varchar', - 'CHARACTER_MAXIMUM_LENGTH' => 11, - 'CHARACTER_OCTET_LENGTH' => 44, + 'CHARACTER_MAXIMUM_LENGTH' => 256, + 'CHARACTER_OCTET_LENGTH' => 1024, 'NUMERIC_PRECISION' => NULL, 'NUMERIC_SCALE' => NULL, 'DATETIME_PRECISION' => NULL, 'CHARACTER_SET_NAME' => 'utf8mb4', 'COLLATION_NAME' => 'utf8mb4_general_ci', - 'COLUMN_TYPE' => 'varchar(11)', + 'COLUMN_TYPE' => 'varchar(256)', + 'COLUMN_KEY' => '', + 'EXTRA' => '', + 'PRIVILEGES' => 'select,insert,update,references', + 'COLUMN_COMMENT' => '', + 'IS_GENERATED' => 'NEVER', + 'GENERATION_EXPRESSION' => NULL, + ), + 'value' => + array ( + 'TABLE_CATALOG' => 'def', + 'TABLE_NAME' => 'config', + 'COLUMN_NAME' => 'value', + 'ORDINAL_POSITION' => 2, + 'COLUMN_DEFAULT' => NULL, + 'IS_NULLABLE' => 'NO', + 'DATA_TYPE' => 'varchar', + 'CHARACTER_MAXIMUM_LENGTH' => 256, + 'CHARACTER_OCTET_LENGTH' => 1024, + 'NUMERIC_PRECISION' => NULL, + 'NUMERIC_SCALE' => NULL, + 'DATETIME_PRECISION' => NULL, + 'CHARACTER_SET_NAME' => 'utf8mb4', + 'COLLATION_NAME' => 'utf8mb4_general_ci', + 'COLUMN_TYPE' => 'varchar(256)', + 'COLUMN_KEY' => '', + 'EXTRA' => '', + 'PRIVILEGES' => 'select,insert,update,references', + 'COLUMN_COMMENT' => '', + 'IS_GENERATED' => 'NEVER', + 'GENERATION_EXPRESSION' => NULL, + ), + 'fff' => + array ( + 'TABLE_CATALOG' => 'def', + 'TABLE_NAME' => 'config', + 'COLUMN_NAME' => 'fff', + 'ORDINAL_POSITION' => 3, + 'COLUMN_DEFAULT' => NULL, + 'IS_NULLABLE' => 'NO', + 'DATA_TYPE' => 'int', + 'CHARACTER_MAXIMUM_LENGTH' => NULL, + 'CHARACTER_OCTET_LENGTH' => NULL, + 'NUMERIC_PRECISION' => 10, + 'NUMERIC_SCALE' => 0, + 'DATETIME_PRECISION' => NULL, + 'CHARACTER_SET_NAME' => NULL, + 'COLLATION_NAME' => NULL, + 'COLUMN_TYPE' => 'int(11)', 'COLUMN_KEY' => '', 'EXTRA' => '', 'PRIVILEGES' => 'select,insert,update,references', diff --git a/src/Controller/CLIController.php b/src/Controller/CLIController.php index 6ea7df1..ff4c00b 100644 --- a/src/Controller/CLIController.php +++ b/src/Controller/CLIController.php @@ -66,8 +66,6 @@ class CLIController private bool $quiet ) { - // FIXME needs to be elsewhere $this->runCheckSetup(); - $this->commandGroupContainer = (new CommandGroupContainer()) ->addCommandGroup(commandGroup: (new CommandGroup(name: 'check', description: 'health checks the system can perform')) ->addCommand(command: new Command( @@ -81,7 +79,6 @@ class CLIController callback: function () { $this->checkPanel(); }, - optionalParameters: ['ID', 'fix=xes'], description: 'Validate setting for this panel')) ->addCommand(command: new Command( name: 'panels', @@ -144,7 +141,7 @@ class CLIController $this->panelsUpdate(); }, mandatoryParameters: ['ID'], - optionalParameters: ['name=', 'A=', 'AAAA=', 'apikey=', 'self=<0|1>'])) + optionalParameters: ['name=', 'A=', 'AAAA=', 'apikey=', 'self='])) ->addCommand(command: new Command( name: 'delete', callback: function () { @@ -926,6 +923,7 @@ class CLIController } else { $panel = new Panel(name: $name, id: $id, a: $a, aaaa: $aaaa, self: $self); } + var_dump($panel); if ($this->panelRepository->update(panel: $panel) !== false) { echo 'Panel ' . COLOR_YELLOW . $id . COLOR_DEFAULT . ' has been updated' . PHP_EOL; } else { @@ -2021,8 +2019,8 @@ class CLIController $phinx = new PhinxApplication('Phinx', '0.9.2'); // use DI later when moving to symfony - $input = new \Symfony\Component\Console\Input\ArgvInput(); - $output = new \Symfony\Component\Console\Output\ConsoleOutput(); +// $input = new \Symfony\Component\Console\Input\ArgvInput(); +// $output = new \Symfony\Component\Console\Output\ConsoleOutput(); echo 'show migration status' . PHP_EOL; $command = $phinx->find(name: 'status'); // change 'migrate' to 'status' @@ -2044,6 +2042,7 @@ class CLIController $arguments = [ 'command' => 'generate', + '--overwrite' => true, ]; $output = new ConsoleOutput(); $returnCode = $phinx->run(input: new ArrayInput(parameters: $arguments), output: $output); @@ -2073,10 +2072,10 @@ class CLIController if ($panelCount != 1) { if ($panelCount == 0) { echo 'No panel marked as this server.' . PHP_EOL; - echo 'Use ' . COLOR_YELLOW . 'panels:update self=1 ' . COLOR_DEFAULT . 'to mark this panel.' . PHP_EOL; + echo 'Use ' . COLOR_YELLOW . 'panels:update self=yes ' . COLOR_DEFAULT . 'to mark this panel.' . PHP_EOL; } else { echo 'Only one panel can be marked as self.' . PHP_EOL; - echo 'Use ' . COLOR_YELLOW . 'panels:update self=0 ' . COLOR_DEFAULT . 'to remove the stale panel' . PHP_EOL; + echo 'Use ' . COLOR_YELLOW . 'panels:update self=no ' . COLOR_DEFAULT . 'to remove the stale panel' . PHP_EOL; } } else { if (!$this->quiet) { diff --git a/src/Controller/Commands/CommandGroupContainer.php b/src/Controller/Commands/CommandGroupContainer.php index 919c389..e5d0c1d 100644 --- a/src/Controller/Commands/CommandGroupContainer.php +++ b/src/Controller/Commands/CommandGroupContainer.php @@ -68,7 +68,7 @@ class CommandGroupContainer exit(1); } } else { - echo COLOR_DEFAULT . 'Unknown subcommand ' . COLOR_YELLOW . $subcommand . COLOR_DEFAULT .' for ' . COLOR_YELLOW . $command . COLOR_DEFAULT . '.' . PHP_EOL; + echo COLOR_DEFAULT . 'Unknown command group ' . COLOR_YELLOW . $command . COLOR_DEFAULT . '.' . PHP_EOL; exit(1); } } else { diff --git a/src/Controller/DomainController.php b/src/Controller/DomainController.php index 6a0168f..0d37fba 100644 --- a/src/Controller/DomainController.php +++ b/src/Controller/DomainController.php @@ -72,24 +72,42 @@ class DomainController { $this->logger->debug(message: 'Delete all slave zones'); - $zones = glob(pattern: $this->localZonesDir . '*'); - foreach ($zones as $zone) { - unlink(filename: $zone); - } - + $existingZones = glob(pattern: $this->localZonesDir . '*'); + $domains = $this->domainRepository->findAll(); - $longestEntry = $this->domainRepository->getLongestEntry('name'); + $longestEntry = $this->domainRepository->getLongestEntry(field: 'name'); foreach ($domains as $domain) { + $zoneFile = $this->localZonesDir . $domain->getName(); if (!$this->quiet) { - echo ' ' . COLOR_YELLOW . str_pad($domain->getName(), $longestEntry + 1, " ", STR_PAD_RIGHT) ; + echo ' ' . COLOR_YELLOW . str_pad(string: $domain->getName(), length: $longestEntry + 1, pad_string: " ", pad_type: STR_PAD_RIGHT) ; } - if ($this->createSlaveZoneFile(domain: $domain)) { + + if (!file_exists(filename: $zoneFile)) { if (!$this->quiet) { echo COLOR_GREEN . ' OK' . COLOR_DEFAULT . PHP_EOL; } + $this->createSlaveZoneFile(domain: $domain); + } else { + if (($key = array_search(needle: $zoneFile, haystack: $existingZones)) !== false) { + if (isset($existingZones[$key])) { + unset($existingZones[$key]); + } + } else { + echo 'missing value: ' . $zoneFile; + } + if (!$this->quiet) { + echo COLOR_DEFAULT . 'Zone already exists.' . PHP_EOL; + } } } + // remove stale zones + foreach ($existingZones as $zone) { + if (!$this->quiet) { + echo 'Removing stale zone: ' . COLOR_YELLOW . $zone . COLOR_DEFAULT . PHP_EOL; + } + unlink(filename: $zone); + } $this->createIncludeFile(); } diff --git a/src/Repository/PanelRepository.php b/src/Repository/PanelRepository.php index f608c8e..19e2b16 100644 --- a/src/Repository/PanelRepository.php +++ b/src/Repository/PanelRepository.php @@ -162,6 +162,8 @@ class PanelRepository $apikey = $panel->getApikey(); $apikeyPrefix = $panel->getApikeyPrefix(); $passphrase = $panel->getPassphrase(); + $self = $panel->getSelf(); + echo 'self: ' . $self; $current = $this->findByID(id: $id); @@ -185,7 +187,6 @@ class PanelRepository $self = $current->getSelf(); } - $sql = " UPDATE " . DatabaseConnection::TABLE_PANELS . " SET name = :name,