diff --git a/src/DhcpBundle/Controller/DhcpController.php b/src/DhcpBundle/Controller/DhcpController.php index 9c7d759..efa0ff6 100644 --- a/src/DhcpBundle/Controller/DhcpController.php +++ b/src/DhcpBundle/Controller/DhcpController.php @@ -28,7 +28,6 @@ class DhcpController $this->backup_dir = $params->get('backup_dir'); } - /** * @Route("/ogdhcp/v1/status", name="getDhcpStatus", methods={"GET"}) * @OA\Get( @@ -300,7 +299,8 @@ public function getSubnets(): JsonResponse * @OA\Property(property="mask", type="string", example="255.255.255.0"), * @OA\Property(property="address", type="string", example="192.168.1.0"), * @OA\Property(property="nextServer", type="string", example="192.168.1.1"), - * @OA\Property(property="bootFileName", type="string", example="pxelinux.0") + * @OA\Property(property="bootFileName", type="string", example="pxelinux.0"), + * @OA\Property(property="router", type="string", example="192.168.1.254") * ) * ), * @OA\Response( @@ -357,128 +357,127 @@ public function getSubnets(): JsonResponse * ) * @Route("/ogdhcp/v1/subnets", methods={"POST"}) */ +public function addDhcpSubnet(Request $request): JsonResponse +{ + try { + $input = json_decode($request->getContent()); + $subnetId = (int) htmlspecialchars($input->subnetId); + $mask = htmlspecialchars($input->mask); + $address = htmlspecialchars($input->address); + // Verificar si next-server, boot-file-name y router están presentes + $nextServer = isset($input->nextServer) ? htmlspecialchars($input->nextServer) : null; + $bootFileName = isset($input->bootFileName) ? htmlspecialchars($input->bootFileName) : null; + $router = isset($input->router) ? htmlspecialchars($input->router) : null; + + // Calcular el gatewayIP si no se proporciona el router + $gatewayIP = $router ?: substr($address, 0, strrpos($address, '.')) . '.1'; + } catch (Exception $e) { + $response["message"] = $e->getMessage(); + if (strpos($e->getMessage(), 'Undefined property') !== false) { + preg_match('/Undefined property: stdClass::\$(\w+)/', $e->getMessage(), $matches); + $paramFaltante = $matches[1] ?? 'desconocido'; + return new JsonResponse(['error' => "Falta un parámetro requerido: $paramFaltante"], 400); + } + } + + try { + $response = $this->curlKeaService->executeCurlCommand('config-get'); + $subnetName = $address . '/' . $this->curlKeaService->convertMaskToCIDR($mask); + + // Crear el array newSubnet con los valores obligatorios + $newSubnet = [ + "id" => $subnetId, + "subnet" => $subnetName, + "reservations" => [], + "option-data" => [ + [ + "name" => "routers", + "code" => 3, + "data" => $gatewayIP + ] + ] + ]; + + // Añadir next-server si está presente + if ($nextServer) { + $newSubnet["next-server"] = $nextServer; + } + + // Añadir boot-file-name si está presente + if ($bootFileName) { + $newSubnet["boot-file-name"] = $bootFileName; + } + + if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) { + $response[0]['arguments']['Dhcp4']['subnet4'] = []; + } + + $subnets = $response[0]['arguments']['Dhcp4']['subnet4']; + + // Verificar si el nombre de la subred o el ID ya existe + $subnetNameExists = array_reduce($subnets, function ($exists, $subnetElement) use ($subnetName) { + return $exists || ($subnetElement['subnet'] === $subnetName); + }, false); + + $subnetIdExists = array_reduce($subnets, function ($exists, $subnetElement) use ($subnetId) { + return $exists || ($subnetElement['id'] === $subnetId); + }, false); + + if ($subnetNameExists) { + return new JsonResponse(['error' => "La subred con la ip '$subnetName' ya existe."], 400); + } elseif ($subnetIdExists) { + return new JsonResponse(['error' => "La subred con el ID '$subnetId' ya existe."], 400); + } else { + $response[0]['arguments']['Dhcp4']['subnet4'][] = $newSubnet; + + // Eliminar el campo 'hash' si existe + if (isset($response[0]['arguments']['hash'])) { + unset($response[0]['arguments']['hash']); + } + + $array_encoded = json_encode($response[0]['arguments']); + $configurationParsed = str_replace('\\', '', $array_encoded); + $configuration = json_decode($configurationParsed); + $responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration); + + if ($responseTest[0]["result"] == 0) { + $responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration); + if ($responseSet == false || $responseSet[0]["result"] != 0) { + return new JsonResponse(['error' => "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"]], 400); + } else { + $responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration); + if ($responseWrite == false || $responseWrite[0]["result"] != 0) { + return new JsonResponse(['error' => "Error al guardar la configuración en Kea DHCP: " . $responseWrite[0]["text"]], 400); + } else { + // Realizar una nueva consulta a Kea para obtener la subred recién creada + $configGetResponse = $this->curlKeaService->executeCurlCommand('config-get'); + + // Buscar la subred creada + $createdSubnet = null; + foreach ($configGetResponse[0]['arguments']['Dhcp4']['subnet4'] as $subnet) { + if ($subnet['id'] == $subnetId) { + $createdSubnet = $subnet; + break; + } + } + + if ($createdSubnet === null) { + return new JsonResponse(['error' => "No se pudo encontrar la subred creada"], 400); + } + + return new JsonResponse(['success' => "Subred agregada correctamente", 'message' => $createdSubnet], 200); + } + } + } else { + return new JsonResponse(['error' => "Error en la configuración de Kea: " . $responseTest[0]["text"]], 400); + } + } + } catch (Exception $e) { + return new JsonResponse(['error' => "Error al obtener la configuración de Kea DHCP: " . $e->getMessage()], 500); + } +} - public function addDhcpSubnet(Request $request): JsonResponse - { - try { - $input = json_decode($request->getContent()); - $subnetId = (int) htmlspecialchars($input->subnetId); - $mask = htmlspecialchars($input->mask); - $address = htmlspecialchars($input->address); - - // Verificar si next-server y boot-file-name están presentes - $nextServer = isset($input->nextServer) ? htmlspecialchars($input->nextServer) : null; - $bootFileName = isset($input->bootFileName) ? htmlspecialchars($input->bootFileName) : null; - } catch (Exception $e) { - $response["message"] = $e->getMessage(); - if (strpos($e->getMessage(), 'Undefined property') !== false) { - preg_match('/Undefined property: stdClass::\$(\w+)/', $e->getMessage(), $matches); - $paramFaltante = $matches[1] ?? 'desconocido'; - return new JsonResponse(['error' => "Falta un parámetro requerido: $paramFaltante"], 400); - } - } - - try { - $response = $this->curlKeaService->executeCurlCommand('config-get'); - $subnetName = $address . '/' . $this->curlKeaService->convertMaskToCIDR($mask); - - // Crear el campo option-data para la puerta de enlace (gateway) - $gatewayIP = substr($address, 0, strrpos($address, '.')) . '.1'; - - // Crear el array newSubnet con los valores obligatorios - $newSubnet = [ - "id" => $subnetId, - "subnet" => $subnetName, - "reservations" => [], - "option-data" => [ - [ - "name" => "routers", - "code" => 3, - "data" => $gatewayIP - ] - ] - ]; - - // Añadir next-server si está presente - if ($nextServer) { - $newSubnet["next-server"] = $nextServer; - } - - // Añadir boot-file-name si está presente - if ($bootFileName) { - $newSubnet["boot-file-name"] = $bootFileName; - } - - if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) { - $response[0]['arguments']['Dhcp4']['subnet4'] = []; - } - - $subnets = $response[0]['arguments']['Dhcp4']['subnet4']; - - // Verificar si el nombre de la subred o el ID ya existe - $subnetNameExists = array_reduce($subnets, function ($exists, $subnetElement) use ($subnetName) { - return $exists || ($subnetElement['subnet'] === $subnetName); - }, false); - - $subnetIdExists = array_reduce($subnets, function ($exists, $subnetElement) use ($subnetId) { - return $exists || ($subnetElement['id'] === $subnetId); - }, false); - - if ($subnetNameExists) { - return new JsonResponse(['error' => "La subred con la ip '$subnetName' ya existe."], 400); - } elseif ($subnetIdExists) { - return new JsonResponse(['error' => "La subred con el ID '$subnetId' ya existe."], 400); - } else { - $response[0]['arguments']['Dhcp4']['subnet4'][] = $newSubnet; - - // Eliminar el campo 'hash' si existe - if (isset($response[0]['arguments']['hash'])) { - unset($response[0]['arguments']['hash']); - } - - $array_encoded = json_encode($response[0]['arguments']); - $configurationParsed = str_replace('\\', '', $array_encoded); - $configuration = json_decode($configurationParsed); - $responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration); - - if ($responseTest[0]["result"] == 0) { - $responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration); - if ($responseSet == false || $responseSet[0]["result"] != 0) { - return new JsonResponse(['error' => "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"]], 400); - } else { - $responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration); - if ($responseWrite == false || $responseWrite[0]["result"] != 0) { - return new JsonResponse(['error' => "Error al guardar la configuración en Kea DHCP: " . $responseWrite[0]["text"]], 400); - } else { - // Realizar una nueva consulta a Kea para obtener la subred recién creada - $configGetResponse = $this->curlKeaService->executeCurlCommand('config-get'); - - // Buscar la subred creada - $createdSubnet = null; - foreach ($configGetResponse[0]['arguments']['Dhcp4']['subnet4'] as $subnet) { - if ($subnet['id'] == $subnetId) { - $createdSubnet = $subnet; - break; - } - } - - if ($createdSubnet === null) { - return new JsonResponse(['error' => "No se pudo encontrar la subred creada"], 400); - } - - return new JsonResponse(['success' => "Subred agregada correctamente", 'message' => $createdSubnet], 200); - } - } - } else { - return new JsonResponse(['error' => "Error en la configuración de Kea: " . $responseTest[0]["text"]], 400); - } - } - } catch (Exception $e) { - return new JsonResponse(['error' => "Error al obtener la configuración de Kea DHCP: " . $e->getMessage()], 500); - } - } - /** @@ -617,7 +616,7 @@ public function getSubnets(): JsonResponse } } - /** +/** * @Route("/ogdhcp/v1/subnets/{subnetId}", methods={"PUT"}) * @OA\Put( * path="/ogdhcp/v1/subnets/{subnetId}", @@ -636,6 +635,7 @@ public function getSubnets(): JsonResponse * type="object", * @OA\Property(property="mask", type="string"), * @OA\Property(property="address", type="string"), + * @OA\Property(property="router", type="string", example="192.168.1.254"), * @OA\Property(property="nextServer", type="string"), * @OA\Property(property="bootFileName", type="string") * ) @@ -650,12 +650,12 @@ public function getSubnets(): JsonResponse * ), * @OA\Response( * response=400, - * description="Error occurred while deleting the subnet", + * description="Error occurred while modifying the subnet", * @OA\JsonContent( * oneOf={ * @OA\Schema(@OA\Property(property="error", type="string", example="Falta un parámetro requerido: $paramFaltante")), * @OA\Schema(@OA\Property(property="error", type="string", example="No hay subredes definidas")), - * @OA\Schema(@OA\Property(property="error", type="string", example="Error configuracion de kea invalido")), + * @OA\Schema(@OA\Property(property="error", type="string", example="Error configuración de Kea inválido")), * @OA\Schema(@OA\Property(property="error", type="string", example="Error al guardar la configuración en Kea DHCP")), * @OA\Schema(@OA\Property(property="error", type="string", example="Error al escribir en la configuración en Kea DHCP")) * } @@ -682,9 +682,13 @@ public function modifyDhcpSubnet(Request $request): JsonResponse $mask = htmlspecialchars($input->mask); $address = htmlspecialchars($input->address); - // Verificar si next-server y boot-file-name están presentes + // Verificar si next-server, boot-file-name y router están presentes $nextServer = isset($input->nextServer) ? htmlspecialchars($input->nextServer) : null; $bootFileName = isset($input->bootFileName) ? htmlspecialchars($input->bootFileName) : null; + $router = isset($input->router) ? htmlspecialchars($input->router) : null; + + // Calcular el gateway añadiendo .1 al final de la subred si no se proporciona el router + $gateway = $router ?: preg_replace('/\d+$/', '1', $address); } catch (Exception $e) { if (strpos($e->getMessage(), 'Undefined property') !== false) { preg_match('/Undefined property: stdClass::\$(\w+)/', $e->getMessage(), $matches); @@ -707,9 +711,6 @@ public function modifyDhcpSubnet(Request $request): JsonResponse if ($subnetIndex === false) { return new JsonResponse(['error' => "La subred con el id '$subnetId' no existe"], 400); } else { - // Calcular el gateway añadiendo .1 al final de la subred - $gateway = preg_replace('/\d+$/', '1', $address); - // Obtener la subred actual para mantener las reservas existentes $existingSubnet = $response[0]['arguments']['Dhcp4']['subnet4'][$subnetIndex]; @@ -731,7 +732,6 @@ public function modifyDhcpSubnet(Request $request): JsonResponse if ($nextServer) { $newSubnet["next-server"] = $nextServer; } else { - // Eliminar next-server de las reservas si no está presente foreach ($newSubnet['reservations'] as &$reservation) { unset($reservation['next-server']); } @@ -741,7 +741,6 @@ public function modifyDhcpSubnet(Request $request): JsonResponse if ($bootFileName) { $newSubnet["boot-file-name"] = $bootFileName; } else { - // Eliminar boot-file-name de las reservas si no está presente foreach ($newSubnet['reservations'] as &$reservation) { unset($reservation['boot-file-name']); } @@ -750,10 +749,10 @@ public function modifyDhcpSubnet(Request $request): JsonResponse // Actualizar las reservas con los nuevos valores de next-server y boot-file-name foreach ($newSubnet['reservations'] as &$reservation) { if ($nextServer) { - $reservation['next-server'] = $nextServer; // Actualizar el next-server del host + $reservation['next-server'] = $nextServer; } if ($bootFileName) { - $reservation['boot-file-name'] = $bootFileName; // Actualizar el boot-file-name del host + $reservation['boot-file-name'] = $bootFileName; } } @@ -790,7 +789,7 @@ public function modifyDhcpSubnet(Request $request): JsonResponse } } } else { - return new JsonResponse(['error' => "Error configuracion de kea invalido: " . $responseTest[0]["text"]], 400); + return new JsonResponse(['error' => "Error configuración de Kea inválida: " . $responseTest[0]["text"]], 400); } } } catch (Exception $e) { @@ -799,6 +798,7 @@ public function modifyDhcpSubnet(Request $request): JsonResponse } + /** * @OA\Get(