Merge branch 'IpNetwork/v2' into 'master'
ipnetwork v2 update See merge request fronk/thetool!1672
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property mixed|null $name
|
||||
*/
|
||||
class IpNetwork extends mfBaseModel
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
// IpNetworkController.php
|
||||
|
||||
class IpNetworkController extends mfBaseController {
|
||||
private User $me;
|
||||
|
||||
|
||||
protected function init(): void {
|
||||
$me = new User();
|
||||
$me->loadMe();
|
||||
@@ -16,15 +16,14 @@ class IpNetworkController extends mfBaseController {
|
||||
}
|
||||
|
||||
protected function indexAction(): void {
|
||||
$JSGlobals = ["BASE_URL" => self::getUrl("IpNetwork"),
|
||||
"DASHBOARD_URL" => self::getUrl("Dashboard"),
|
||||
"MFAPPNAME" => MFAPPNAME_SLUG,
|
||||
$JSGlobals = [
|
||||
"BASE_URL" => self::getUrl("IpNetwork"),
|
||||
"API_BASE_URL" => self::getUrl("IpNetwork"),
|
||||
"PAGE_TITLE" => "IPAM",
|
||||
"PATH" => [
|
||||
["text" => MFAPPNAME_SLUG, "href" => self::getUrl("Dashboard")],
|
||||
["text" => "IPAM", "href" => self::getUrl("IpNetwork")]
|
||||
],
|
||||
"IPNETWORK_API_URL" => self::getUrl("IpNetwork/api"),
|
||||
];
|
||||
|
||||
$this->layout()->set("vueViewName", "IpNetwork");
|
||||
@@ -32,187 +31,124 @@ class IpNetworkController extends mfBaseController {
|
||||
$this->layout()->setTemplate("VueViews/Vue");
|
||||
}
|
||||
|
||||
protected function apiAction() {
|
||||
$do = $this->request->do;
|
||||
|
||||
if (!$this->me->isAdmin()) {
|
||||
$this->redirect("dashboard");
|
||||
}
|
||||
|
||||
switch ($do) {
|
||||
case "get":
|
||||
$return = $this->get();
|
||||
break;
|
||||
case "getById":
|
||||
$return = $this->getById();
|
||||
break;
|
||||
case "create":
|
||||
$return = $this->create();
|
||||
break;
|
||||
case "update":
|
||||
$return = $this->update();
|
||||
break;
|
||||
case "delete":
|
||||
$return = $this->delete();
|
||||
break;
|
||||
default:
|
||||
$return = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$return) {
|
||||
$return = [
|
||||
"status" => "error",
|
||||
"message" => "Invalid request."
|
||||
];
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
die(json_encode($return));
|
||||
}
|
||||
|
||||
private function aggregateChildren($network, &$childrenCount) {
|
||||
$children = IpNetworkModel::getChildren($network->id);
|
||||
|
||||
foreach ($children as $child) {
|
||||
$childrenCount++;
|
||||
if ($child->cidr !== 32) {
|
||||
$this->aggregateChildren($child, $childrenCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function get(): array {
|
||||
protected function getAction() {
|
||||
$json = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
$filters = $json['filters'] ?? [];
|
||||
$order = $json['order'] ?? [];
|
||||
$order = $json['order'] ?? ['key' => 'network_address', 'order' => 'asc'];
|
||||
$page = $json['pagination']['page'] ?? 1;
|
||||
$perPage = $json['pagination']['per_page'] ?? 10;
|
||||
$perPage = $json['pagination']['per_page'] ?? 50;
|
||||
$offset = ($page - 1) * $perPage;
|
||||
|
||||
$orderChildren = false;
|
||||
$networks = IpNetworkModel::getIpNetworks($filters, $perPage, $offset, $order);
|
||||
$total_rows = IpNetworkModel::countIpNetworks($filters);
|
||||
|
||||
if ($order['key'] === 'network_address_str') {
|
||||
$order['key'] = 'network_address';
|
||||
} else if ($order['key'] === 'children') {
|
||||
$orderChildren = $order['order'];
|
||||
$order = null;
|
||||
}
|
||||
|
||||
$networks = IpNetworkModel::getIpNetworks($filters, null, $perPage * $page - $perPage, $order);
|
||||
$total_rows = IpNetworkModel::countIpNetworks([
|
||||
"parent_network_id" => $filters['parent_network_id'] ?? ''
|
||||
]);
|
||||
|
||||
$processedNetworks = [];
|
||||
|
||||
foreach ($networks as $network) {
|
||||
$childrenCount = 0;
|
||||
$this->aggregateChildren($network, $childrenCount);
|
||||
|
||||
$from = $filters['children']['from'] ?? null;
|
||||
$to = $filters['children']['to'] ?? null;
|
||||
|
||||
if (($from !== null && $childrenCount < $from) || ($to !== null && $childrenCount > $to)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$network->children = $childrenCount;
|
||||
$processedNetworks[] = $network;
|
||||
}
|
||||
|
||||
if ($orderChildren) {
|
||||
usort($processedNetworks, function ($a, $b) use ($orderChildren) {
|
||||
if ($orderChildren === 'asc') {
|
||||
return $a->children <=> $b->children;
|
||||
} else {
|
||||
return $b->children <=> $a->children;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return [
|
||||
"rows" => array_slice($processedNetworks, $perPage * $page - $perPage, $perPage),
|
||||
self::returnJson([
|
||||
"rows" => $networks,
|
||||
"pagination" => [
|
||||
"page" => $page,
|
||||
"total_pages" => ceil(count($processedNetworks) / $perPage),
|
||||
"filtered_available" => count($processedNetworks),
|
||||
"total_pages" => ceil($total_rows / $perPage),
|
||||
"filtered_available" => intval($total_rows),
|
||||
"per_page" => $perPage,
|
||||
"total_rows" => intval($total_rows)
|
||||
]
|
||||
];
|
||||
|
||||
]);
|
||||
}
|
||||
|
||||
private function getById(): array {
|
||||
$json = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
$network = IpNetworkModel::getById($json['id']);
|
||||
|
||||
if ($network === null) {
|
||||
return [
|
||||
"status" => "error",
|
||||
"message" => "Network not found."
|
||||
];
|
||||
protected function getByIdAction() {
|
||||
$id = $this->request->id;
|
||||
if (!$id) {
|
||||
self::sendError("Network ID is missing.");
|
||||
}
|
||||
|
||||
return [
|
||||
"status" => "success",
|
||||
"network" => $network
|
||||
];
|
||||
$network = IpNetworkModel::getById($id);
|
||||
|
||||
if ($network === null) {
|
||||
self::sendError("Network not found.");
|
||||
}
|
||||
|
||||
self::returnJson(["success" => true, "network" => $network]);
|
||||
}
|
||||
|
||||
protected function globalSearchAction() {
|
||||
$query = $this->request->q ?? '';
|
||||
if (strlen($query) < 2) {
|
||||
self::returnJson([]);
|
||||
return;
|
||||
}
|
||||
$suggestions = IpNetworkModel::findSuggestions($query);
|
||||
self::returnJson($suggestions);
|
||||
}
|
||||
|
||||
private function create(): array {
|
||||
protected function findNetworkByStringAction() {
|
||||
$networkString = $this->request->network_string;
|
||||
if (!$networkString) {
|
||||
self::sendError("Network string is missing.");
|
||||
}
|
||||
|
||||
$network = IpNetworkModel::findByNetworkString($networkString);
|
||||
|
||||
if ($network === null) {
|
||||
self::sendError("Network not found.");
|
||||
}
|
||||
|
||||
$navigateToId = null;
|
||||
if ($network->cidr < 31) {
|
||||
$navigateToId = $network->id;
|
||||
} else {
|
||||
$navigateToId = $network->parent_network_id;
|
||||
}
|
||||
|
||||
self::returnJson(["success" => true, "navigateToId" => $navigateToId]);
|
||||
}
|
||||
|
||||
protected function createAction() {
|
||||
$json = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
try {
|
||||
IpNetworkModel::createIpNetwork($json);
|
||||
return [
|
||||
"status" => "success",
|
||||
"message" => "IP Network created."
|
||||
];
|
||||
self::returnJson([
|
||||
"success" => true,
|
||||
"message" => "IP-Netzwerk wurde erstellt."
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
return [
|
||||
"status" => "error",
|
||||
"message" => $e->getMessage()
|
||||
];
|
||||
self::sendError($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function update(): array {
|
||||
protected function updateAction() {
|
||||
$json = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
if (empty($json['id'])) {
|
||||
self::sendError("Netzwerk-ID fehlt.");
|
||||
}
|
||||
|
||||
try {
|
||||
IpNetworkModel::updateIpNetwork($json);
|
||||
return [
|
||||
"status" => "success",
|
||||
"message" => "IP Network updated."
|
||||
];
|
||||
self::returnJson([
|
||||
"success" => true,
|
||||
"message" => "IP-Netzwerk wurde aktualisiert."
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
return [
|
||||
"status" => "error",
|
||||
"message" => $e->getMessage()
|
||||
];
|
||||
self::sendError($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function delete(): array {
|
||||
protected function deleteAction() {
|
||||
$json = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
if (empty($json['id'])) {
|
||||
self::sendError("Netzwerk-ID fehlt.");
|
||||
}
|
||||
|
||||
try {
|
||||
IpNetworkModel::deleteIpNetwork($json['id']);
|
||||
return [
|
||||
"status" => "success",
|
||||
"message" => "IP Network deleted."
|
||||
];
|
||||
self::returnJson([
|
||||
"success" => true,
|
||||
"message" => "IP-Netzwerk wurde gelöscht."
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
return [
|
||||
"status" => "error",
|
||||
"message" => $e->getMessage()
|
||||
];
|
||||
self::sendError($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
// IpNetworkModel.php
|
||||
|
||||
class IpNetworkModel {
|
||||
|
||||
@@ -7,6 +8,7 @@ class IpNetworkModel {
|
||||
public $cidr;
|
||||
public $parent_network_id;
|
||||
public $status;
|
||||
public $children;
|
||||
public $network_address_str;
|
||||
public $name;
|
||||
public $description;
|
||||
@@ -22,14 +24,52 @@ class IpNetworkModel {
|
||||
}
|
||||
}
|
||||
|
||||
private static function getSqlFilter(array $filters): string {
|
||||
$sqlConditions = [];
|
||||
$db = FronkDB::singleton()->link;
|
||||
|
||||
if (!empty($filters['globalSearch'])) {
|
||||
$searchTerm = $db->real_escape_string($filters['globalSearch']);
|
||||
$sqlConditions[] = " (CONCAT(INET_NTOA(network_address), '/', cidr) LIKE '%{$searchTerm}%' OR `name` LIKE '%{$searchTerm}%' OR `description` LIKE '%{$searchTerm}%') ";
|
||||
}
|
||||
|
||||
if (isset($filters['name'])) $sqlConditions[] = Helper::generateFilterCondition($filters['name'], 'name');
|
||||
if (isset($filters['description'])) $sqlConditions[] = Helper::generateFilterCondition($filters['description'], 'description');
|
||||
if (isset($filters['location'])) $sqlConditions[] = Helper::generateFilterCondition($filters['location'], 'location');
|
||||
if (isset($filters['status'])) $sqlConditions[] = Helper::generateFilterCondition($filters['status'], 'status');
|
||||
|
||||
if (empty($filters['parent_network_id'])) {
|
||||
$sqlConditions[] = " `parent_network_id` IS NULL ";
|
||||
} else {
|
||||
$sqlConditions[] = " `parent_network_id` = " . intval($filters['parent_network_id']) . " ";
|
||||
}
|
||||
|
||||
return empty($sqlConditions) ? "" : " WHERE " . implode(" AND ", $sqlConditions);
|
||||
}
|
||||
|
||||
public static function getIpNetworks($filters, $limit = null, $offset = 0, $order = null): array {
|
||||
$db = FronkDB::singleton();
|
||||
$db = FronkDB::singleton()->link;
|
||||
|
||||
$orderClause = "ORDER BY `network_address` ASC";
|
||||
if ($order && !empty($order['key'])) {
|
||||
$orderKey = $db->real_escape_string($order['key']);
|
||||
$orderDir = (isset($order['order']) && strtolower($order['order']) === 'desc') ? 'DESC' : 'ASC';
|
||||
if ($orderKey === 'network_address_str') $orderKey = 'network_address';
|
||||
$orderClause = "ORDER BY `{$orderKey}` {$orderDir}";
|
||||
}
|
||||
|
||||
$limitClause = is_null($limit) ? "" : " LIMIT " . intval($limit) . " OFFSET " . intval($offset);
|
||||
|
||||
$sql = "
|
||||
SELECT
|
||||
main.*,
|
||||
CONCAT(INET_NTOA(main.network_address), '/', main.cidr) AS network_address_str,
|
||||
(SELECT COUNT(*) FROM `IpNetwork` WHERE `parent_network_id` = main.id) as children
|
||||
FROM `IpNetwork` main
|
||||
" . self::getSqlFilter($filters) . "
|
||||
" . $orderClause . "
|
||||
" . $limitClause;
|
||||
|
||||
$sql = "SELECT *, CONCAT(INET_NTOA(network_address), '/', cidr) AS network_address_str FROM `IpNetwork` WHERE 1 ";
|
||||
$sql .= isset($filters['network_address_str']) ? " AND CONCAT(INET_NTOA(network_address), '/', cidr) LIKE '%" . $filters['network_address_str'] . "%'" : "";
|
||||
$sql .= self::getSqlFilter($filters);
|
||||
$sql .= $order === null || $order['key'] === null ? " ORDER BY `network_address` ASC" : " ORDER BY `" . $order['key'] . "` " . $order['order'];
|
||||
$sql .= $limit === null ? "" : " LIMIT " . $limit . " OFFSET " . $offset;
|
||||
|
||||
$result = $db->query($sql);
|
||||
$rows = [];
|
||||
@@ -40,209 +80,140 @@ class IpNetworkModel {
|
||||
return $rows;
|
||||
}
|
||||
|
||||
public static function getSqlFilter($filters): string {
|
||||
$sql = isset($filters['name']) ? Helper::generateFilterCondition($filters['name'], 'name') : "";
|
||||
$sql .= isset($filters['description']) ? Helper::generateFilterCondition($filters['description'], 'description') : "";
|
||||
$sql .= isset($filters['location']) ? Helper::generateFilterCondition($filters['location'], 'location') : "";
|
||||
$sql .= isset($filters['status']) ? Helper::generateFilterCondition($filters['status'], 'status') : "";
|
||||
$sql .= empty($filters['parent_network_id']) ? " AND `parent_network_id` IS NULL" : " AND `parent_network_id` = " . $filters['parent_network_id'];
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
public static function countIpNetworks($filters) {
|
||||
$db = FronkDB::singleton();
|
||||
$sql = "SELECT COUNT(*) as `total_rows` FROM `IpNetwork` WHERE 1 " . self::getSqlFilter($filters);
|
||||
$result = $db->query($sql);
|
||||
return $result->fetch_assoc()['total_rows'];
|
||||
}
|
||||
|
||||
public static function countChildren($id) {
|
||||
$db = FronkDB::singleton();
|
||||
$sql = "SELECT COUNT(*) as `total_rows` FROM `IpNetwork` WHERE `parent_network_id` = $id";
|
||||
$result = $db->query($sql);
|
||||
return $result->fetch_assoc()['total_rows'];
|
||||
}
|
||||
|
||||
public static function getChildren($id): array {
|
||||
$db = FronkDB::singleton();
|
||||
$sql = "SELECT * FROM `IpNetwork` WHERE `parent_network_id` = $id";
|
||||
$result = $db->query($sql);
|
||||
$rows = [];
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$rows[] = new IpNetworkModel($row);
|
||||
public static function findByNetworkString(string $networkString): ?IpNetworkModel {
|
||||
$db = FronkDB::singleton()->link;
|
||||
if (!str_contains($networkString, '/')) {
|
||||
return null;
|
||||
}
|
||||
// Extract IP and CIDR, allowing for extra text like "(My Network)"
|
||||
preg_match('/^([0-9\.]+)\/(\d+)/', $networkString, $matches);
|
||||
if (count($matches) < 3) {
|
||||
return null;
|
||||
}
|
||||
$ip = $db->real_escape_string($matches[1]);
|
||||
$cidr = (int)$matches[2];
|
||||
|
||||
return $rows;
|
||||
$sql = "SELECT * FROM `IpNetwork` WHERE `network_address` = INET_ATON('$ip') AND `cidr` = $cidr";
|
||||
$result = $db->query($sql);
|
||||
$row = $result->fetch_assoc();
|
||||
return $row ? new IpNetworkModel($row) : null;
|
||||
}
|
||||
|
||||
public static function countIpNetworks($filters): int {
|
||||
$db = FronkDB::singleton()->link;
|
||||
$sql = "SELECT COUNT(*) as `total_rows` FROM `IpNetwork`" . self::getSqlFilter($filters);
|
||||
$result = $db->query($sql);
|
||||
return (int)$result->fetch_assoc()['total_rows'];
|
||||
}
|
||||
|
||||
public static function findSuggestions(string $query, int $limit = 10): array {
|
||||
$db = FronkDB::singleton()->link;
|
||||
$query = $db->real_escape_string($query);
|
||||
$sql = "
|
||||
SELECT
|
||||
CONCAT(INET_NTOA(network_address), '/', cidr) as network_address_str,
|
||||
name
|
||||
FROM `IpNetwork`
|
||||
WHERE
|
||||
CONCAT(INET_NTOA(network_address), '/', cidr) LIKE '%{$query}%' OR
|
||||
`name` LIKE '%{$query}%' OR
|
||||
`description` LIKE '%{$query}%'
|
||||
LIMIT " . $limit;
|
||||
|
||||
$result = $db->query($sql);
|
||||
$suggestions = [];
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$text = $row['network_address_str'];
|
||||
if ($row['name']) {
|
||||
$text .= " ({$row['name']})";
|
||||
}
|
||||
$suggestions[] = [
|
||||
'value' => $row['network_address_str'],
|
||||
'text' => $text
|
||||
];
|
||||
}
|
||||
return $suggestions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function createIpNetwork($data): void {
|
||||
$db = FronkDB::singleton();
|
||||
$db = FronkDB::singleton()->link;
|
||||
|
||||
$network_address = $data['network_address'];
|
||||
$cidr = $data['cidr'];
|
||||
$parent_network_id = $data['parent_network_id'] ?? 'NULL';
|
||||
$status = $data['status'];
|
||||
$name = $data['name'];
|
||||
$description = $data['description'];
|
||||
$location = $data['location'];
|
||||
if (!filter_var($network_address, FILTER_VALIDATE_IP)) {
|
||||
throw new Exception("Ungültige IP-Adresse angegeben.");
|
||||
}
|
||||
|
||||
// Convert network address to integer
|
||||
$network_address_int = ip2long($network_address);
|
||||
|
||||
// Define query to check for overlapping networks
|
||||
$check_sql = "
|
||||
SELECT `id`, `network_address`, `cidr`
|
||||
FROM `IpNetwork`
|
||||
WHERE (
|
||||
(INET_ATON('$network_address') & ~((1 << (32 - `cidr`)) - 1)) = `network_address`
|
||||
OR
|
||||
(`network_address` & ~((1 << (32 - $cidr)) - 1)) = INET_ATON('$network_address')
|
||||
)";
|
||||
|
||||
// die($check_sql);
|
||||
$cidr = (int)$data['cidr'];
|
||||
$parent_network_id = !empty($data['parent_network_id']) ? (int)$data['parent_network_id'] : 'NULL';
|
||||
$status = $db->real_escape_string($data['status']);
|
||||
$name = $db->real_escape_string($data['name']);
|
||||
$description = $db->real_escape_string($data['description']);
|
||||
$location = $db->real_escape_string($data['location']);
|
||||
|
||||
$check_sql = "SELECT id FROM `IpNetwork` WHERE `network_address` = INET_ATON('$network_address') AND `cidr` = $cidr";
|
||||
$result = $db->query($check_sql);
|
||||
|
||||
$parentFound = false;
|
||||
$parentFoundId = null;
|
||||
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$existing_network_address_int = $row['network_address'];
|
||||
$existing_cidr = $row['cidr'];
|
||||
|
||||
// Check if the new network is within an existing network
|
||||
if ($network_address_int >= $existing_network_address_int &&
|
||||
$network_address_int < ($existing_network_address_int + pow(2, (32 - $existing_cidr)))) {
|
||||
|
||||
if ($cidr <= $existing_cidr) {
|
||||
// The new network is larger or equal, which is invalid
|
||||
if ($cidr == 32) {
|
||||
throw new Exception("Address $network_address/32 already exists");
|
||||
} else {
|
||||
throw new Exception("Network $network_address/$cidr conflicts with existing network " . long2ip($existing_network_address_int) . "/$existing_cidr");
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the new network is a correct subnetwork
|
||||
if ($parent_network_id != 'NULL') {
|
||||
$result->data_seek(0);
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
if ($row['id'] == $parent_network_id) {
|
||||
$parentFoundId = $row['id'];
|
||||
$parentFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$parentFound) {
|
||||
throw new Exception("Parent network ID $parent_network_id does not match the actual parent network ID {$row['id']}");
|
||||
}
|
||||
|
||||
// New check for conflicts with child networks
|
||||
$check_child_sql = "
|
||||
SELECT `id`, `network_address`, `cidr`
|
||||
FROM `IpNetwork`
|
||||
WHERE `parent_network_id` = $parent_network_id
|
||||
AND (
|
||||
INET_ATON('$network_address') BETWEEN `network_address`
|
||||
AND (`network_address` + POW(2, (32 - `cidr`)) - 1)
|
||||
OR
|
||||
`network_address` BETWEEN INET_ATON('$network_address')
|
||||
AND (INET_ATON('$network_address') + POW(2, (32 - $cidr)) - 1)
|
||||
)";
|
||||
;
|
||||
|
||||
$child_result = $db->query($check_child_sql);
|
||||
|
||||
while ($child_row = $child_result->fetch_assoc()) {
|
||||
$existing_child_network_address_int = $child_row['network_address'];
|
||||
$existing_child_cidr = $child_row['cidr'];
|
||||
|
||||
// Check if the new network overlaps any existing child networks
|
||||
if ($network_address_int < $existing_child_network_address_int &&
|
||||
($network_address_int + pow(2, (32 - $cidr))) > $existing_child_network_address_int) {
|
||||
throw new Exception("Network $network_address/$cidr conflicts with child network " . long2ip($existing_child_network_address_int) . "/$existing_child_cidr");
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// If no parent ID provided and the new network is within an existing network, throw an error
|
||||
throw new Exception("Network $network_address/$cidr must be a child of " . long2ip($existing_network_address_int) . "/$existing_cidr.");
|
||||
}
|
||||
|
||||
// For CIDR 32, check if it already exists but also check if $parent_network_id is same as $parentFoundId but if $parentFoundId is null, throw an error
|
||||
if ($cidr == 32 && $parent_network_id != 'NULL' && $parent_network_id != $parentFoundId) {
|
||||
throw new Exception("CIDR 32 address $network_address already exists within " . long2ip($existing_network_address_int) . "/$existing_cidr");
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the new network overlaps any existing networks
|
||||
if ($network_address_int < $existing_network_address_int &&
|
||||
($network_address_int + pow(2, (32 - $cidr))) > $existing_network_address_int) {
|
||||
throw new Exception("Network $network_address/$cidr overlaps with existing network " . long2ip($existing_network_address_int) . "/$existing_cidr");
|
||||
}
|
||||
if($result->num_rows > 0) {
|
||||
throw new Exception("Ein identisches Netzwerk existiert bereits.");
|
||||
}
|
||||
|
||||
if (!$parentFound && $parent_network_id === 'NULL' && intval($cidr) >= 32) {
|
||||
throw new Exception("Root Networks cannot be single IPs");
|
||||
if ($parent_network_id === 'NULL' && $cidr >= 32) {
|
||||
throw new Exception("Stamm-Netzwerke können keine einzelnen IPs sein.");
|
||||
}
|
||||
|
||||
// Proceed with insertion if no conflicts are found
|
||||
$sql = "INSERT INTO `IpNetwork` (`network_address`, `cidr`, `parent_network_id`, `status`, `name`, `description`, `location`, `create`, `edit`)
|
||||
VALUES (INET_ATON('$network_address'), $cidr, $parent_network_id, '$status', '$name', '$description', '$location', UNIX_TIMESTAMP(), UNIX_TIMESTAMP())";
|
||||
$result = $db->query($sql);
|
||||
VALUES (INET_ATON('$network_address'), $cidr, $parent_network_id, '$status', '$name', '$description', '$location', UNIX_TIMESTAMP(), UNIX_TIMESTAMP())";
|
||||
|
||||
if (!$result) {
|
||||
throw new Exception("Failed to insert network");
|
||||
if (!$db->query($sql)) {
|
||||
throw new Exception("Fehler beim Einfügen des Netzwerks: " . $db->error);
|
||||
}
|
||||
}
|
||||
|
||||
public static function updateIpNetwork($data): void {
|
||||
$db = FronkDB::singleton();
|
||||
$db = FronkDB::singleton()->link;
|
||||
$id = (int)$data['id'];
|
||||
|
||||
$sqlSetStr = "";
|
||||
$sqlSetStr .= isset($data['status']) ? "`status` = '" . $data['status'] . "', " : "";
|
||||
$sqlSetStr .= isset($data['name']) ? "`name` = '" . $data['name'] . "', " : "";
|
||||
$sqlSetStr .= isset($data['description']) ? "`description` = '" . $data['description'] . "', " : "";
|
||||
$sqlSetStr .= isset($data['location']) ? "`location` = '" . $data['location'] . "', " : "";
|
||||
$sqlSetStr .= "`edit` = UNIX_TIMESTAMP()";
|
||||
$sqlSetStr = [];
|
||||
if (isset($data['status'])) $sqlSetStr[] = "`status` = '" . $db->real_escape_string($data['status']) . "'";
|
||||
if (isset($data['name'])) $sqlSetStr[] = "`name` = '" . $db->real_escape_string($data['name']) . "'";
|
||||
if (isset($data['description'])) $sqlSetStr[] = "`description` = '" . $db->real_escape_string($data['description']) . "'";
|
||||
if (isset($data['location'])) $sqlSetStr[] = "`location` = '" . $db->real_escape_string($data['location']) . "'";
|
||||
|
||||
$sql = "UPDATE `IpNetwork` SET $sqlSetStr WHERE `id` = " . $data['id'];
|
||||
$result = $db->query($sql);
|
||||
if(empty($sqlSetStr)) return;
|
||||
|
||||
if (!$result) {
|
||||
throw new Exception("Failed to update network");
|
||||
$sqlSetStr[] = "`edit` = UNIX_TIMESTAMP()";
|
||||
|
||||
$sql = "UPDATE `IpNetwork` SET " . implode(', ', $sqlSetStr) . " WHERE `id` = $id";
|
||||
|
||||
if (!$db->query($sql)) {
|
||||
throw new Exception("Fehler beim Aktualisieren des Netzwerks: " . $db->error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function getById($id) {
|
||||
$db = FronkDB::singleton();
|
||||
$sql = "SELECT *, INET_NTOA(network_address) as network_address_str FROM `IpNetwork` WHERE `id` = $id";
|
||||
$db = FronkDB::singleton()->link;
|
||||
$id = (int)$id;
|
||||
$sql = "SELECT *, CONCAT(INET_NTOA(network_address), '/', cidr) as network_address_str FROM `IpNetwork` WHERE `id` = $id";
|
||||
$result = $db->query($sql);
|
||||
$row = $result->fetch_assoc();
|
||||
return $row ? new IpNetworkModel($row) : null;
|
||||
}
|
||||
|
||||
public static function deleteIpNetwork($id) {
|
||||
// delete this id and all children and children of children until no more children
|
||||
$db = FronkDB::singleton();
|
||||
$sql = "SELECT `id` FROM `IpNetwork` WHERE `parent_network_id` = $id";
|
||||
$result = $db->query($sql);
|
||||
$db = FronkDB::singleton()->link;
|
||||
$id = (int)$id;
|
||||
|
||||
$child_sql = "SELECT `id` FROM `IpNetwork` WHERE `parent_network_id` = $id";
|
||||
$result = $db->query($child_sql);
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
self::deleteIpNetwork($row['id']);
|
||||
}
|
||||
|
||||
$sql = "DELETE FROM `IpNetwork` WHERE `id` = $id";
|
||||
$result = $db->query($sql);
|
||||
if (!$result) {
|
||||
throw new Exception("Failed to delete network");
|
||||
$delete_sql = "DELETE FROM `IpNetwork` WHERE `id` = $id";
|
||||
if (!$db->query($delete_sql)) {
|
||||
throw new Exception("Fehler beim Löschen des Netzwerks: " . $db->error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user