135 lines
5.3 KiB
PHP
135 lines
5.3 KiB
PHP
<?php
|
|
|
|
namespace App\Network\Drivers\Mikrotik;
|
|
|
|
use App\Network\Clients\RouterOs\RouterOsApiClient;
|
|
use App\Network\Contracts\DeviceDriverInterface;
|
|
use Throwable;
|
|
|
|
class MikrotikDriver implements DeviceDriverInterface
|
|
{
|
|
private const GROUPS = [
|
|
'RADIQ-READ' => 'local,ssh,read,test,winbox,api',
|
|
'RADIQ-WRITE' => 'local,ssh,read,write,test,winbox,password,api',
|
|
'RADIQ-NOC' => 'local,ssh,read,write,test,winbox,password,api',
|
|
];
|
|
|
|
public function __construct(private readonly RouterOsApiClient $client) {}
|
|
|
|
public function testConnection(): array
|
|
{
|
|
$this->client->connect();
|
|
try {
|
|
return $this->client->command(['/system/identity/print', '=.proplist=name'])[0] ?? [];
|
|
} finally {
|
|
$this->client->disconnect();
|
|
}
|
|
}
|
|
|
|
public function getDeviceInfo(): array
|
|
{
|
|
$identity = $this->safeQuery(['/system/identity/print', '=.proplist=name']);
|
|
$routerboard = $this->safeQuery(['/system/routerboard/print', '=.proplist=routerboard,model,serial-number,current-firmware,upgrade-firmware']);
|
|
$resource = $this->safeQuery(['/system/resource/print', '=.proplist=version,board-name,architecture-name,cpu-count,total-memory,free-memory,uptime']);
|
|
$cpu = $this->safeQuery(['/system/resource/print', '=.proplist=cpu']);
|
|
|
|
return ['identity' => $identity['name'] ?? null] + $routerboard + $resource + $cpu;
|
|
}
|
|
|
|
public function provisionBaseAccess(string $username, string $password): array
|
|
{
|
|
$this->client->connect();
|
|
try {
|
|
foreach (self::GROUPS as $name => $policies) {
|
|
$existing = $this->client->command(['/user/group/print', '?name='.$name, '=.proplist=.id']);
|
|
if ($existing === []) {
|
|
$this->client->command(['/user/group/add', '=name='.$name, '=policy='.$policies, '=comment=Managed by RADIQ NDM']);
|
|
} else {
|
|
$this->client->command(['/user/group/set', '=.id='.$existing[0]['.id'], '=policy='.$policies, '=comment=Managed by RADIQ NDM']);
|
|
}
|
|
}
|
|
|
|
$users = $this->client->command(['/user/print', '?name='.$username, '=.proplist=.id']);
|
|
if ($users === []) {
|
|
$this->client->command(['/user/add', '=name='.$username, '=password='.$password, '=group=full', '=disabled=no', '=comment=Managed by RADIQ NDM']);
|
|
} else {
|
|
$this->client->command(['/user/set', '=.id='.$users[0]['.id'], '=password='.$password, '=group=full', '=disabled=no', '=comment=Managed by RADIQ NDM']);
|
|
}
|
|
|
|
return ['groups' => array_keys(self::GROUPS), 'username' => $username];
|
|
} finally {
|
|
$this->client->disconnect();
|
|
}
|
|
}
|
|
|
|
public function syncUser(string $username, string $password, string $group, bool $enabled): array
|
|
{
|
|
$this->client->connect();
|
|
try {
|
|
$users = $this->client->command(['/user/print', '?name='.$username, '=.proplist=.id']);
|
|
if ($users === []) {
|
|
$this->client->command(['/user/add', '=name='.$username, '=password='.$password, '=group='.$group, '=disabled='.($enabled ? 'no' : 'yes'), '=comment=Managed by RADIQ NDM']);
|
|
$users = $this->client->command(['/user/print', '?name='.$username, '=.proplist=.id']);
|
|
} else {
|
|
$this->client->command(['/user/set', '=.id='.$users[0]['.id'], '=password='.$password, '=group='.$group, '=disabled='.($enabled ? 'no' : 'yes'), '=comment=Managed by RADIQ NDM']);
|
|
}
|
|
|
|
return ['remote_id' => $users[0]['.id'] ?? null];
|
|
} finally {
|
|
$this->client->disconnect();
|
|
}
|
|
}
|
|
|
|
public function deleteUser(string $username): void
|
|
{
|
|
$this->client->connect();
|
|
try {
|
|
$users = $this->client->command(['/user/print', '?name='.$username, '=.proplist=.id']);
|
|
if ($users !== []) {
|
|
$this->client->command(['/user/remove', '=.id='.$users[0]['.id']]);
|
|
}
|
|
} finally {
|
|
$this->client->disconnect();
|
|
}
|
|
}
|
|
|
|
public function cleanupLegacyUsers(string $preserveUsername): array
|
|
{
|
|
$this->client->connect();
|
|
try {
|
|
$users = $this->client->command(['/user/print', '=.proplist=.id,name,group']);
|
|
$deleted = [];
|
|
$preserved = [];
|
|
foreach ($users as $user) {
|
|
if (($user['name'] ?? '') === $preserveUsername || strtolower($user['group'] ?? '') === 'full') {
|
|
$preserved[] = $user['name'] ?? '';
|
|
|
|
continue;
|
|
}
|
|
if (isset($user['.id'])) {
|
|
$this->client->command(['/user/remove', '=.id='.$user['.id']]);
|
|
$deleted[] = $user['name'] ?? '';
|
|
}
|
|
}
|
|
|
|
return ['deleted' => $deleted, 'preserved' => $preserved];
|
|
} finally {
|
|
$this->client->disconnect();
|
|
}
|
|
}
|
|
|
|
/** @return array<string, string> */
|
|
private function safeQuery(array $command): array
|
|
{
|
|
try {
|
|
$this->client->connect();
|
|
|
|
return $this->client->command($command)[0] ?? [];
|
|
} catch (Throwable) {
|
|
return [];
|
|
} finally {
|
|
$this->client->disconnect();
|
|
}
|
|
}
|
|
}
|