Compare commits
No commits in common. "main" and "nginx_conf" have entirely different histories.
main
...
nginx_conf
|
|
@ -5,6 +5,7 @@
|
||||||
!app/cache/.gitkeep
|
!app/cache/.gitkeep
|
||||||
!app/logs/.gitkeep
|
!app/logs/.gitkeep
|
||||||
/app/phpunit.xml
|
/app/phpunit.xml
|
||||||
|
/bin/
|
||||||
/build/
|
/build/
|
||||||
/composer.phar
|
/composer.phar
|
||||||
/var/*
|
/var/*
|
||||||
|
|
@ -37,14 +38,3 @@ output.xml
|
||||||
log.html
|
log.html
|
||||||
report.html
|
report.html
|
||||||
__pycache__
|
__pycache__
|
||||||
|
|
||||||
### Debian packaging
|
|
||||||
debian/ogdhcp
|
|
||||||
debian/*.substvars
|
|
||||||
debian/*.log
|
|
||||||
debian/.debhelper/
|
|
||||||
debian/files
|
|
||||||
debian/*.debhelper
|
|
||||||
debian/*.debhelper.log
|
|
||||||
debian/debhelper-build-stamp
|
|
||||||
.vscode/
|
|
||||||
|
|
|
||||||
48
CHANGELOG
48
CHANGELOG
|
|
@ -1,48 +0,0 @@
|
||||||
# CHANGELOG
|
|
||||||
|
|
||||||
# [0.7.1] - 27/05/2025
|
|
||||||
|
|
||||||
### **Cambios principales**
|
|
||||||
1. Añade nuevo parámetro boot-file-name a los endpoints de añadir y actualizar host de una subred.
|
|
||||||
|
|
||||||
# [0.6.3] - 24/03/2025
|
|
||||||
|
|
||||||
### **Cambios principales**
|
|
||||||
1. Mueve directorios de symfony al directorio api
|
|
||||||
|
|
||||||
## [0.6.2] - 03/03/2025
|
|
||||||
|
|
||||||
### **Cambios principales**
|
|
||||||
1. Añade publicacion de paquetes debian a jenkins
|
|
||||||
|
|
||||||
|
|
||||||
## [0.6.1] - 03/03/2025
|
|
||||||
|
|
||||||
### **Cambios principales**
|
|
||||||
1. Añade publicacion de paquetes debian a jenkins
|
|
||||||
|
|
||||||
## [0.6.0] - 03/03/2025
|
|
||||||
|
|
||||||
### **Cambios principales**
|
|
||||||
1. Añade nuevos parametros a la subred: dns y subnetname, añadiendolos a la configuración de kea
|
|
||||||
2. Resuelve error de permisos en el instalador
|
|
||||||
|
|
||||||
### **Cambios principales**
|
|
||||||
1. Arregla bugs en la creacion del home `/opt/opengnsys`del usuario opengnsys
|
|
||||||
|
|
||||||
## [0.5.5] - 06/02/2025
|
|
||||||
|
|
||||||
### **Cambios principales**
|
|
||||||
1. Arregla bugs en la creacion del home `/opt/opengnsys`del usuario opengnsys
|
|
||||||
|
|
||||||
## [0.5.4] - 06/02/2025
|
|
||||||
|
|
||||||
### **Cambios principales**
|
|
||||||
1. Cambia el home del usuario opengnsys como `/opt/opengnsys`
|
|
||||||
|
|
||||||
## [0.5.3] - 13/01/2025
|
|
||||||
|
|
||||||
### **Cambios principales**
|
|
||||||
1. Añade logs para todos los endpoints siguiendo un formato json preestablecido.
|
|
||||||
2. Actualiza monolog.yaml para devolver logs al journal de la maquina.
|
|
||||||
|
|
||||||
49
CHANGELOG.md
49
CHANGELOG.md
|
|
@ -1,49 +0,0 @@
|
||||||
# Changelog
|
|
||||||
|
|
||||||
## [0.7.4] - 2026-07-31
|
|
||||||
### Added
|
|
||||||
- Añadidos endpoints a la API para eliminar concesiones (leases) a nivel de host y de subred.
|
|
||||||
- Añadido el hook de leases a la configuración de Kea.
|
|
||||||
|
|
||||||
## [0.7.3] - 2025-10-20
|
|
||||||
### Fixed
|
|
||||||
- Arregla el código de DNS en el kea cuando se actualiza la información de una subred existente.
|
|
||||||
|
|
||||||
## [0.7.2] - 2025-06-06
|
|
||||||
### Changed
|
|
||||||
- Corrige bug cuando no recibe parámetro boot-file-name.
|
|
||||||
|
|
||||||
## [0.7.1] - 2025-05-27
|
|
||||||
### Changed
|
|
||||||
- Añade nuevo parámetro boot-file-name a los endpoints de añadir y actualizar host de una subred.
|
|
||||||
|
|
||||||
## [0.7.0] - 2025-03-24
|
|
||||||
### Changed
|
|
||||||
- Mueve directorios de symfony al directorio api
|
|
||||||
|
|
||||||
## [0.6.1] - 2025-03-19
|
|
||||||
### Changed
|
|
||||||
- Modified Jenkinsfile to publish packages
|
|
||||||
|
|
||||||
## [0.6.0] - 2025-03-03
|
|
||||||
### Added
|
|
||||||
- Nuevos parámetros a la subred: `dns` y `subnetname`, añadiéndolos a la configuración de Kea.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
- Error de permisos en el instalador.
|
|
||||||
- Bugs en la creación del home `/opt/opengnsys` del usuario `opengnsys`.
|
|
||||||
|
|
||||||
## [0.5.5] - 2025-02-06
|
|
||||||
### Fixed
|
|
||||||
- Bugs en la creación del home `/opt/opengnsys` del usuario `opengnsys`.
|
|
||||||
|
|
||||||
## [0.5.4] - 2025-02-06
|
|
||||||
### Changed
|
|
||||||
- Se cambia el home del usuario `opengnsys` a `/opt/opengnsys`.
|
|
||||||
|
|
||||||
## [0.5.3] - 2025-01-13
|
|
||||||
### Added
|
|
||||||
- Logs para todos los endpoints siguiendo un formato JSON preestablecido.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
- Se actualiza `monolog.yaml` para devolver logs al journal de la máquina.
|
|
||||||
|
|
@ -1,151 +0,0 @@
|
||||||
@Library('jenkins-shared-library') _
|
|
||||||
pipeline {
|
|
||||||
agent {
|
|
||||||
label 'jenkins-slave'
|
|
||||||
}
|
|
||||||
environment {
|
|
||||||
DEBIAN_FRONTEND = 'noninteractive'
|
|
||||||
DEFAULT_DEV_NAME = 'Opengnsys Team'
|
|
||||||
DEFAULT_DEV_EMAIL = 'opengnsys@qindel.com'
|
|
||||||
}
|
|
||||||
options {
|
|
||||||
skipDefaultCheckout()
|
|
||||||
}
|
|
||||||
parameters {
|
|
||||||
string(name: 'DEV_NAME', defaultValue: '', description: 'Nombre del desarrollador')
|
|
||||||
string(name: 'DEV_EMAIL', defaultValue: '', description: 'Email del desarrollador')
|
|
||||||
}
|
|
||||||
stages {
|
|
||||||
stage('Prepare Workspace') {
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
env.BUILD_DIR = "${WORKSPACE}/ogdhcp"
|
|
||||||
sh "mkdir -p ${env.BUILD_DIR}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('Checkout') {
|
|
||||||
steps {
|
|
||||||
dir("${env.BUILD_DIR}") {
|
|
||||||
checkout scm
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('Generate Changelog') {
|
|
||||||
when {
|
|
||||||
expression {
|
|
||||||
return env.TAG_NAME != null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
def devName = params.DEV_NAME ? params.DEV_NAME : env.DEFAULT_DEV_NAME
|
|
||||||
def devEmail = params.DEV_EMAIL ? params.DEV_EMAIL : env.DEFAULT_DEV_EMAIL
|
|
||||||
|
|
||||||
generateDebianChangelog(env.BUILD_DIR, devName, devEmail)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Generate Changelog (Nightly)'){
|
|
||||||
when {
|
|
||||||
branch 'main'
|
|
||||||
}
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
def devName = params.DEV_NAME ? params.DEV_NAME : env.DEFAULT_DEV_NAME
|
|
||||||
def devEmail = params.DEV_EMAIL ? params.DEV_EMAIL : env.DEFAULT_DEV_EMAIL
|
|
||||||
generateDebianChangelog(env.BUILD_DIR, devName, devEmail,"nightly")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('Generate Changelog (Devel)') {
|
|
||||||
when {
|
|
||||||
branch 'devel'
|
|
||||||
}
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
def devName = params.DEV_NAME ? params.DEV_NAME : env.DEFAULT_DEV_NAME
|
|
||||||
def devEmail = params.DEV_EMAIL ? params.DEV_EMAIL : env.DEFAULT_DEV_EMAIL
|
|
||||||
generateDebianChangelog(env.BUILD_DIR, devName, devEmail, "devel")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('Build') {
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
construirPaquete(env.BUILD_DIR, "../artifacts", "172.17.8.68", "/var/tmp/opengnsys/debian-repo/ogdhcp")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage ('Publish to Debian Repository') {
|
|
||||||
when {
|
|
||||||
expression {
|
|
||||||
return env.TAG_NAME != null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
agent { label 'debian-repo' }
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
// Construir el patrón de versión esperado en el nombre del paquete
|
|
||||||
def versionPattern = "${env.TAG_NAME}-${env.BUILD_NUMBER}"
|
|
||||||
publicarEnAptly('/var/tmp/opengnsys/debian-repo/ogdhcp', 'opengnsys-devel', versionPattern)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage ('Publish to Debian Repository (Nightly)') {
|
|
||||||
when {
|
|
||||||
branch 'main'
|
|
||||||
}
|
|
||||||
agent { label 'debian-repo' }
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
// Construir el patrón de versión esperado en el nombre del paquete
|
|
||||||
def versionPattern = "-${env.BUILD_NUMBER}~nightly"
|
|
||||||
publicarEnAptly('/var/tmp/opengnsys/debian-repo/ogdhcp', 'nightly', versionPattern)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage ('Publish to Debian Repository (Devel)') {
|
|
||||||
when {
|
|
||||||
branch 'devel'
|
|
||||||
}
|
|
||||||
agent { label 'debian-repo' }
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
def versionPattern = "-${env.BUILD_NUMBER}~devel"
|
|
||||||
publicarEnAptly('/var/tmp/opengnsys/debian-repo/ogdhcp', 'devel', versionPattern)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
post {
|
|
||||||
success {
|
|
||||||
script {
|
|
||||||
// Solo lanzar cuando el build sea exitoso y en la rama main
|
|
||||||
if (env.BRANCH_NAME == 'main') {
|
|
||||||
build job: 'Aptly publish nightly repository',
|
|
||||||
wait: false,
|
|
||||||
parameters: [
|
|
||||||
string(name: 'TRIGGERED_BY', value: "${env.JOB_NAME}-${env.BUILD_NUMBER}")
|
|
||||||
]
|
|
||||||
}
|
|
||||||
if (env.BRANCH_NAME == 'devel') {
|
|
||||||
build job: 'Aptly publish develop repository',
|
|
||||||
wait: false,
|
|
||||||
parameters: [
|
|
||||||
string(name: 'TRIGGERED_BY', value: "${env.JOB_NAME}-${env.BUILD_NUMBER}")
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
always {
|
|
||||||
notifyBuildStatus('opengnsys@qindel.com')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
#!/usr/bin/env php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
use App\Kernel;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
|
||||||
|
|
||||||
if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {
|
|
||||||
throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".');
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
|
|
||||||
|
|
||||||
return function (array $context) {
|
|
||||||
$kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
|
||||||
|
|
||||||
return new Application($kernel);
|
|
||||||
};
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use App\Kernel;
|
|
||||||
|
|
||||||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
|
|
||||||
|
|
||||||
return function (array $context) {
|
|
||||||
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
|
||||||
};
|
|
||||||
261
api/symfony.lock
261
api/symfony.lock
|
|
@ -1,261 +0,0 @@
|
||||||
{
|
|
||||||
"doctrine/annotations": {
|
|
||||||
"version": "1.14",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "1.0",
|
|
||||||
"ref": "a2759dd6123694c8d901d0ec80006e044c2e6457"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/routes/annotations.yaml"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"doctrine/doctrine-bundle": {
|
|
||||||
"version": "2.11",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "2.4",
|
|
||||||
"ref": "191046a1fdd1a58fcca48d8bf2f58c45a93b1d00"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/doctrine.yaml",
|
|
||||||
"src/Entity/.gitignore",
|
|
||||||
"src/Repository/.gitignore"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"doctrine/doctrine-migrations-bundle": {
|
|
||||||
"version": "3.3",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "3.1",
|
|
||||||
"ref": "1d01ec03c6ecbd67c3375c5478c9a423ae5d6a33"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/doctrine_migrations.yaml",
|
|
||||||
"migrations/.gitignore"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"phpunit/phpunit": {
|
|
||||||
"version": "8.5",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "4.7",
|
|
||||||
"ref": "db276258424d15e572d35a4eb834b8f815662b25"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
".env.test",
|
|
||||||
"phpunit.xml.dist",
|
|
||||||
"tests/bootstrap.php"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/console": {
|
|
||||||
"version": "5.4",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "5.3",
|
|
||||||
"ref": "da0c8be8157600ad34f10ff0c9cc91232522e047"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"bin/console"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/debug-bundle": {
|
|
||||||
"version": "5.4",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "5.3",
|
|
||||||
"ref": "5aa8aa48234c8eb6dbdd7b3cd5d791485d2cec4b"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/debug.yaml"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/flex": {
|
|
||||||
"version": "1.21",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "1.0",
|
|
||||||
"ref": "146251ae39e06a95be0fe3d13c807bcf3938b172"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
".env"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/framework-bundle": {
|
|
||||||
"version": "5.4",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "5.4",
|
|
||||||
"ref": "3cd216a4d007b78d8554d44a5b1c0a446dab24fb"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/cache.yaml",
|
|
||||||
"config/packages/framework.yaml",
|
|
||||||
"config/preload.php",
|
|
||||||
"config/routes/framework.yaml",
|
|
||||||
"config/services.yaml",
|
|
||||||
"public/index.php",
|
|
||||||
"src/Controller/.gitignore",
|
|
||||||
"src/Kernel.php"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/mailer": {
|
|
||||||
"version": "5.4",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "4.3",
|
|
||||||
"ref": "df66ee1f226c46f01e85c29c2f7acce0596ba35a"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/mailer.yaml"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/maker-bundle": {
|
|
||||||
"version": "1.50",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "1.0",
|
|
||||||
"ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"symfony/messenger": {
|
|
||||||
"version": "5.4",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "5.4",
|
|
||||||
"ref": "8bd5f27013fb1d7217191c548e340f0bdb11912c"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/messenger.yaml"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/monolog-bundle": {
|
|
||||||
"version": "3.10",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "3.7",
|
|
||||||
"ref": "aff23899c4440dd995907613c1dd709b6f59503f"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/monolog.yaml"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/notifier": {
|
|
||||||
"version": "5.4",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "5.0",
|
|
||||||
"ref": "178877daf79d2dbd62129dd03612cb1a2cb407cc"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/notifier.yaml"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/phpunit-bridge": {
|
|
||||||
"version": "5.4",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "5.3",
|
|
||||||
"ref": "07ce01a897311647520b43d4ddddad9537b99ba6"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
".env.test",
|
|
||||||
"bin/phpunit",
|
|
||||||
"phpunit.xml.dist",
|
|
||||||
"tests/bootstrap.php"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/routing": {
|
|
||||||
"version": "5.4",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "5.3",
|
|
||||||
"ref": "85de1d8ae45b284c3c84b668171d2615049e698f"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/routing.yaml",
|
|
||||||
"config/routes.yaml"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/security-bundle": {
|
|
||||||
"version": "5.4",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "5.3",
|
|
||||||
"ref": "98f1f2b0d635908c2b40f3675da2d23b1a069d30"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/security.yaml"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/translation": {
|
|
||||||
"version": "5.4",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "5.3",
|
|
||||||
"ref": "e28e27f53663cc34f0be2837aba18e3a1bef8e7b"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/translation.yaml",
|
|
||||||
"translations/.gitignore"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/twig-bundle": {
|
|
||||||
"version": "5.4",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "5.4",
|
|
||||||
"ref": "bb2178c57eee79e6be0b297aa96fc0c0def81387"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/twig.yaml",
|
|
||||||
"templates/base.html.twig"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/validator": {
|
|
||||||
"version": "5.4",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "5.3",
|
|
||||||
"ref": "c32cfd98f714894c4f128bb99aa2530c1227603c"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/validator.yaml"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/web-profiler-bundle": {
|
|
||||||
"version": "5.4",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "5.3",
|
|
||||||
"ref": "24bbc3d84ef2f427f82104f766014e799eefcc3e"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/web_profiler.yaml",
|
|
||||||
"config/routes/web_profiler.yaml"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"twig/extra-bundle": {
|
|
||||||
"version": "v3.8.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -22,11 +22,6 @@ when@dev:
|
||||||
type: console
|
type: console
|
||||||
process_psr_3_messages: false
|
process_psr_3_messages: false
|
||||||
channels: ["!event", "!doctrine", "!console"]
|
channels: ["!event", "!doctrine", "!console"]
|
||||||
syslog:
|
|
||||||
type: syslog
|
|
||||||
ident: "ogdhcp"
|
|
||||||
level: info
|
|
||||||
channels: ["!event"]
|
|
||||||
|
|
||||||
when@test:
|
when@test:
|
||||||
monolog:
|
monolog:
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
# Put parameters here that don't need to change on each machine where the app is deployed
|
# Put parameters here that don't need to change on each machine where the app is deployed
|
||||||
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
|
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
|
||||||
parameters:
|
parameters:
|
||||||
backup_dir: '%kernel.project_dir%/../etc/kea/backup'
|
backup_dir: '%kernel.project_dir%/etc/kea/backup'
|
||||||
services:
|
services:
|
||||||
# default configuration for services in *this* file
|
# default configuration for services in *this* file
|
||||||
_defaults:
|
_defaults:
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
The Debian Package ogdhcp
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
<Comments regarding the Package.>
|
|
||||||
|
|
||||||
-- vagrant <vagrant@build> Wed, 05 Mar 2025 19:49:47 +0000
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
ogdhcp for Debian
|
|
||||||
----------------
|
|
||||||
|
|
||||||
<Possible notes regarding this package - if none, delete this file.>
|
|
||||||
|
|
||||||
-- vagrant <vagrant@build> Wed, 05 Mar 2025 19:49:47 +0000
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
ogdhcp for Debian
|
|
||||||
----------------
|
|
||||||
|
|
||||||
<This file describes information about the source package, see Debian policy
|
|
||||||
manual section 4.14. You WILL either need to modify or delete this file.>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- vagrant <vagrant@build> Wed, 05 Mar 2025 19:49:47 +0000
|
|
||||||
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
ogdhcp (1.0.2+pkg-deb20250310-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* Updates changelog 0.6.0
|
|
||||||
* Merge pull request 'new-parameters-subnet' (#3) from new-parameters-subnet into main
|
|
||||||
* refs #1543 fix swagger annotation
|
|
||||||
* refs #1568 adds new parameters subnetName and dns to kea dhcp
|
|
||||||
* refs #1581 fix backup permissions in installer
|
|
||||||
* refs #1468 update CHANGELOG
|
|
||||||
* refs #1468 fix bug and permissions in opt opengnsys
|
|
||||||
* refs #1468 updates CHANGELOG
|
|
||||||
* refs #1468 changes home of the opengnsys user
|
|
||||||
* Adds changelog
|
|
||||||
|
|
||||||
-- Tu Nombre <tuemail@example.com> Mon, 10 Mar 2025 19:58:42 +0000
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
Source: ogdhcp
|
|
||||||
Section: unknown
|
|
||||||
Priority: optional
|
|
||||||
Maintainer: vagrant <vagrant@build>
|
|
||||||
Rules-Requires-Root: no
|
|
||||||
Build-Depends:
|
|
||||||
debhelper-compat (= 13)
|
|
||||||
Standards-Version: 4.6.2
|
|
||||||
Homepage: <insert the upstream URL, if relevant>
|
|
||||||
#Vcs-Browser: https://salsa.debian.org/debian/ogdhcp
|
|
||||||
#Vcs-Git: https://salsa.debian.org/debian/ogdhcp.git
|
|
||||||
|
|
||||||
Package: ogdhcp
|
|
||||||
Architecture: any
|
|
||||||
Multi-Arch: foreign
|
|
||||||
Recommends: kea-dhcp4-server, kea-common, kea-ctrl-agent
|
|
||||||
Depends: ${shlibs:Depends}, ${misc:Depends}, debconf (>= 1.5.0),
|
|
||||||
php,
|
|
||||||
php-cli,
|
|
||||||
php-fpm,
|
|
||||||
php-json,
|
|
||||||
php-pdo,
|
|
||||||
php-mysql,
|
|
||||||
php-zip,
|
|
||||||
php-gd,
|
|
||||||
php-mbstring,
|
|
||||||
php-curl,
|
|
||||||
php-xml,
|
|
||||||
php-pear,
|
|
||||||
php-bcmath,
|
|
||||||
composer,
|
|
||||||
unzip,
|
|
||||||
jq,
|
|
||||||
net-tools,
|
|
||||||
nginx
|
|
||||||
Conflicts: apache2
|
|
||||||
Description: <insert up to 60 chars description>
|
|
||||||
<Insert long description, indented with spaces.>
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
|
||||||
Source: <url://example.com>
|
|
||||||
Upstream-Name: ogdhcp
|
|
||||||
Upstream-Contact: <preferred name and address to reach the upstream project>
|
|
||||||
|
|
||||||
Files:
|
|
||||||
*
|
|
||||||
Copyright:
|
|
||||||
<years> <put author's name and email here>
|
|
||||||
<years> <likewise for another author>
|
|
||||||
License: GPL-3.0+
|
|
||||||
|
|
||||||
Files:
|
|
||||||
debian/*
|
|
||||||
Copyright:
|
|
||||||
2025 vagrant <vagrant@build>
|
|
||||||
License: GPL-3.0+
|
|
||||||
|
|
||||||
License: GPL-3.0+
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
.
|
|
||||||
This package is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
.
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
Comment:
|
|
||||||
On Debian systems, the complete text of the GNU General
|
|
||||||
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
|
|
||||||
|
|
||||||
# Please also look if there are files or directories which have a
|
|
||||||
# different copyright/license attached and list them here.
|
|
||||||
# Please avoid picking licenses with terms that are more restrictive than the
|
|
||||||
# packaged work, as it may make Debian's contributions unacceptable upstream.
|
|
||||||
#
|
|
||||||
# If you need, there are some extra license texts available in two places:
|
|
||||||
# /usr/share/debhelper/dh_make/licenses/
|
|
||||||
# /usr/share/common-licenses/
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
. /usr/share/debconf/confmodule
|
|
||||||
|
|
||||||
db_input high opengnsys/ogdhcp_interfaces || true
|
|
||||||
db_input high opengnsys/ogdhcp_ip|| true
|
|
||||||
db_input high opengnsys/ogdhcp_ogbootIP || true
|
|
||||||
|
|
||||||
db_go
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
/opt/opengnsys/ogdhcp/api
|
|
||||||
/opt/opengnsys/ogdhcp/api/bin
|
|
||||||
/opt/opengnsys/ogdhcp/api/config
|
|
||||||
/opt/opengnsys/ogdhcp/api/public
|
|
||||||
/opt/opengnsys/ogdhcp/api/src
|
|
||||||
/opt/opengnsys/ogdhcp/api/templates
|
|
||||||
/opt/opengnsys/ogdhcp/api/var/
|
|
||||||
/opt/opengnsys/ogdhcp/api/var/cache
|
|
||||||
/opt/opengnsys/ogdhcp/api/var/log
|
|
||||||
/opt/opengnsys/ogdhcp/api/vendor
|
|
||||||
/opt/opengnsys/ogdhcp/etc
|
|
||||||
/opt/opengnsys/ogdhcp/etc/kea/backup
|
|
||||||
/opt/opengnsys/ogdhcp/docs
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
api /opt/opengnsys/ogdhcp/
|
|
||||||
etc /opt/opengnsys/ogdhcp/
|
|
||||||
docs /opt/opengnsys/ogdhcp/
|
|
||||||
etc/systemd/system/kea-ctrl-agent.service.d/override.conf /etc/systemd/system/kea-ctrl-agent.service.d/
|
|
||||||
|
|
@ -1,206 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
|
|
||||||
. /usr/share/debconf/confmodule
|
|
||||||
|
|
||||||
|
|
||||||
restore_config_if_modified() {
|
|
||||||
local new="$1"
|
|
||||||
local backup="$1.bak.upgrade_package"
|
|
||||||
|
|
||||||
if [ -f "$backup" ]; then
|
|
||||||
if ! cmp -s "$new" "$backup"; then
|
|
||||||
echo ">>> Archivo modificado por el usuario detectado en $new"
|
|
||||||
echo " - Guardando archivo nuevo como ${new}.new"
|
|
||||||
mv -f "$new" "${new}.new"
|
|
||||||
echo " - Restaurando archivo anterior desde backup"
|
|
||||||
mv -f "$backup" "$new"
|
|
||||||
else
|
|
||||||
echo ">>> El archivo $new no ha cambiado desde la última versión, eliminando backup"
|
|
||||||
rm -f "$backup"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Añade el hook lease-cmds a kea-dhcp4.conf solo si no está ya presente
|
|
||||||
ensure_lease_cmds_hook() {
|
|
||||||
local config="$1"
|
|
||||||
local lib="$2"
|
|
||||||
|
|
||||||
[ -f "$config" ] || return 0
|
|
||||||
[ -n "$lib" ] || return 0
|
|
||||||
|
|
||||||
if grep -q "libdhcp_lease_cmds" "$config"; then
|
|
||||||
echo "El hook lease-cmds ya está presente en $config, no se añade de nuevo."
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Añadiendo hook lease-cmds a $config..."
|
|
||||||
local tmp
|
|
||||||
tmp=$(mktemp)
|
|
||||||
jq --arg lib "$lib" \
|
|
||||||
'.Dhcp4["hooks-libraries"] = (.Dhcp4["hooks-libraries"] // []) + [{"library": $lib}]' \
|
|
||||||
"$config" > "$tmp" && mv "$tmp" "$config"
|
|
||||||
chown _kea:_kea "$config"
|
|
||||||
}
|
|
||||||
|
|
||||||
KEA_CTRL_AGENT_CONF="/etc/kea/kea-ctrl-agent.conf"
|
|
||||||
PUBLIC_DIR=/opt/opengnsys/ogdhcp/api/public
|
|
||||||
db_get opengnsys/ogdhcp_interfaces
|
|
||||||
OGDHCP_INTERFACES="$RET"
|
|
||||||
db_get opengnsys/ogdhcp_ip
|
|
||||||
OGDHCP_IP="$RET"
|
|
||||||
db_get opengnsys/ogdhcp_ogbootIP
|
|
||||||
OGBOOT_IP="$RET"
|
|
||||||
|
|
||||||
# Get PHP version
|
|
||||||
PHP_VERSION=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')
|
|
||||||
if [ -z "$PHP_VERSION" ]; then
|
|
||||||
echo "Error: No se pudo determinar la versión de PHP."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
configure)
|
|
||||||
if [ -z "$2" ]; then
|
|
||||||
echo ">>> Configuración de ogdhcp, realizando instalacion nueva"
|
|
||||||
# Configuración de kea-ctrl-agent
|
|
||||||
echo "Eliminando autenticación de kea-ctrl-agent..."
|
|
||||||
if [ -e "$KEA_CTRL_AGENT_CONF" ]; then
|
|
||||||
dpkg-divert --package ogdhcp --divert "$KEA_CTRL_AGENT_CONF.dpkg-dist" --rename "$KEA_CTRL_AGENT_CONF"
|
|
||||||
cp -a "$KEA_CTRL_AGENT_CONF.dpkg-dist" "$KEA_CTRL_AGENT_CONF"
|
|
||||||
if grep -q '^[^#]*"authentication": {' "$KEA_CTRL_AGENT_CONF"; then
|
|
||||||
sed -i '/"authentication": {/,/^[[:space:]]*},/ {
|
|
||||||
s/^\([[:space:]]*\)\([^#]\)/\1#\2/
|
|
||||||
}' "$KEA_CTRL_AGENT_CONF"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
# Configuración de AppArmor
|
|
||||||
APPARMOR_LOCAL_PROFILE="/etc/apparmor.d/local/usr.sbin.kea-dhcp4"
|
|
||||||
echo "Añadiendo permisos personalizados a AppArmor para kea-dhcp4..."
|
|
||||||
mkdir -p "$(dirname "$APPARMOR_LOCAL_PROFILE")"
|
|
||||||
cat > "$APPARMOR_LOCAL_PROFILE" <<EOF
|
|
||||||
/etc/kea/ rw,
|
|
||||||
/etc/kea/** rw,
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "Recargando perfiles de AppArmor..."
|
|
||||||
apparmor_parser -r /etc/apparmor.d/usr.sbin.kea-dhcp4
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
echo "El perfil de AppArmor se recargó correctamente."
|
|
||||||
else
|
|
||||||
echo "Error al recargar el perfil de AppArmor."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Configuración de nginx
|
|
||||||
echo "Configurando nginx..."
|
|
||||||
if [ ! -f /etc/nginx/sites-available/ogdhcp.conf ]; then
|
|
||||||
cp /opt/opengnsys/ogdhcp/etc/nginxServer.conf.tmpl /etc/nginx/sites-available/ogdhcp.conf
|
|
||||||
sed -i "s|__PHPVERSION__|$PHP_VERSION|g" /etc/nginx/sites-available/ogdhcp.conf
|
|
||||||
sed -i "s|__SERVERIP__|$OGDHCP_IP|g" /etc/nginx/sites-available/ogdhcp.conf
|
|
||||||
sed -i "s|__PUBLICDIR__|$PUBLIC_DIR|g" /etc/nginx/sites-available/ogdhcp.conf
|
|
||||||
ln -s /etc/nginx/sites-available/ogdhcp.conf /etc/nginx/sites-enabled/ogdhcp.conf
|
|
||||||
else
|
|
||||||
echo "El archivo /etc/nginx/sites-available/ogdhcp.conf ya existe."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Configuración de php-fpm
|
|
||||||
echo "Configurando php-fpm..."
|
|
||||||
if [ ! -f /etc/php/$PHP_VERSION/fpm/pool.d/ogdhcp.conf ]; then
|
|
||||||
cp /opt/opengnsys/ogdhcp/etc/php/fpm/ogdhcp-fpm.conf /etc/php/$PHP_VERSION/fpm/pool.d/ogdhcp.conf
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Configuración de kea-dhcp4
|
|
||||||
echo "Configurando kea-dhcp4..."
|
|
||||||
IFS=',' read -r -a INTERFACES <<< "$OGDHCP_INTERFACES"
|
|
||||||
KEA_CONFIG="/etc/kea/kea-dhcp4.conf"
|
|
||||||
|
|
||||||
# Detectar la ruta de libdhcp_lease_cmds.so (varía según arquitectura)
|
|
||||||
LEASE_CMDS_LIB=$(find /usr/lib -name "libdhcp_lease_cmds.so" 2>/dev/null | head -1)
|
|
||||||
if [ -z "$LEASE_CMDS_LIB" ]; then
|
|
||||||
echo "Advertencia: no se encontró libdhcp_lease_cmds.so. El hook lease-cmds no estará activo."
|
|
||||||
else
|
|
||||||
echo "Librería lease-cmds encontrada en: $LEASE_CMDS_LIB"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -e "$KEA_CONFIG" ]; then
|
|
||||||
dpkg-divert --package ogdhcp --divert "$KEA_CONFIG.dpkg-dist" --rename "$KEA_CONFIG"
|
|
||||||
# El fichero se genera desde cero, no hay riesgo de duplicación
|
|
||||||
cat > "$KEA_CONFIG" <<EOF
|
|
||||||
{
|
|
||||||
"Dhcp4": {
|
|
||||||
"interfaces-config": {
|
|
||||||
"interfaces": [ $(
|
|
||||||
for interface in "${INTERFACES[@]}"; do
|
|
||||||
echo "\"$interface\""
|
|
||||||
done | paste -sd "," -
|
|
||||||
) ]
|
|
||||||
},
|
|
||||||
"client-classes": [
|
|
||||||
{
|
|
||||||
"name": "UEFI-64",
|
|
||||||
"test": "not substring(option[60].hex,0,20) == 'PXEClient:Arch:00000'",
|
|
||||||
"boot-file-name": "ipxe.efi",
|
|
||||||
"next-server": "$OGBOOT_IP"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Legacy",
|
|
||||||
"test": "substring(option[60].hex,0,20) == 'PXEClient:Arch:00000'",
|
|
||||||
"boot-file-name": "undionly.kpxe",
|
|
||||||
"next-server": "$OGBOOT_IP"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"control-socket": {
|
|
||||||
"socket-name": "/run/kea/kea4-ctrl-socket",
|
|
||||||
"socket-type": "unix"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
# Añadir el hook tras generar el fichero (la función verifica que no esté ya)
|
|
||||||
ensure_lease_cmds_hook "$KEA_CONFIG" "$LEASE_CMDS_LIB"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
|
|
||||||
echo "Actualizando configuración de kea-dhcp4..."
|
|
||||||
restore_config_if_modified "/etc/kea/kea-dhcp4.conf"
|
|
||||||
restore_config_if_modified "/etc/kea/kea-ctrl-agent.conf"
|
|
||||||
restore_config_if_modified "/opt/opengnsys/ogdhcp/api/.env"
|
|
||||||
restore_config_if_modified "/etc/nginx/sites-available/ogdhcp.conf"
|
|
||||||
restore_config_if_modified "/etc/php/$PHP_VERSION/fpm/pool.d/ogdhcp.conf"
|
|
||||||
|
|
||||||
# En upgrade: añadir el hook si se instaló kea-hook-lease-cmds y no estaba configurado
|
|
||||||
LEASE_CMDS_LIB=$(find /usr/lib -name "libdhcp_lease_cmds.so" 2>/dev/null | head -1)
|
|
||||||
ensure_lease_cmds_hook "/etc/kea/kea-dhcp4.conf" "$LEASE_CMDS_LIB"
|
|
||||||
fi
|
|
||||||
echo ">>> Configuración de ogdhcp completada."
|
|
||||||
;;
|
|
||||||
abort-upgrade|abort-remove|abort-deconfigure)
|
|
||||||
echo ">>> Abortando la configuración de ogdhcp"
|
|
||||||
echo "No se realizaron cambios en la configuración."
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
echo "postinst called with unknown argument '$1'" >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
chown opengnsys:www-data /opt/opengnsys/
|
|
||||||
chown -R opengnsys:www-data /opt/opengnsys/ogdhcp
|
|
||||||
chown -R _kea:_kea /etc/kea
|
|
||||||
|
|
||||||
# Reiniciar servicios
|
|
||||||
systemctl daemon-reload
|
|
||||||
systemctl restart nginx || echo "Error al reiniciar nginx"
|
|
||||||
systemctl restart kea-dhcp4-server || echo "Error al reiniciar kea-dhcp4-server"
|
|
||||||
systemctl restart kea-ctrl-agent || echo "Error al reiniciar kea-ctrl-agent"
|
|
||||||
systemctl restart php$PHP_VERSION-fpm || echo "Error al reiniciar php$PHP_VERSION-fpm"
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
backup_file_if_exists() {
|
|
||||||
local original="$1"
|
|
||||||
local backup="$1.bak"
|
|
||||||
|
|
||||||
if [ -e "$original" ]; then
|
|
||||||
echo " - Guardando backup de $original en $backup"
|
|
||||||
cp -a "$original" "$backup"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
USER="opengnsys"
|
|
||||||
HOME_DIR="/opt/opengnsys"
|
|
||||||
|
|
||||||
case $1 in
|
|
||||||
install)
|
|
||||||
if id "$USER" &>/dev/null; then
|
|
||||||
echo "El usuario $USER ya existe."
|
|
||||||
else
|
|
||||||
echo "Creando el usuario $USER con home en $HOME_DIR."
|
|
||||||
useradd -m -d "$HOME_DIR" -s /bin/bash "$USER"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
upgrade)
|
|
||||||
echo ">>> Actualización de ogdhcp" echo ">>> Backup de archivos de configuración reales en /opt/opengnsys"
|
|
||||||
backup_file_if_exists "/etc/kea/kea-dhcp4.conf"
|
|
||||||
backup_file_if_exists "/etc/kea/kea-ctrl-agent.conf"
|
|
||||||
backup_file_if_exists "/opt/opengnsys/ogdhcp/api/.env"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Modo no reconocido: $1"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
KEA_CTRL_AGENT_CONF="/etc/kea/kea-ctrl-agent.conf"
|
|
||||||
KEA_CONFIG="/etc/kea/kea-dhcp4.conf"
|
|
||||||
APPARMOR_LOCAL_PROFILE="/etc/apparmor.d/local/usr.sbin.kea-dhcp4"
|
|
||||||
NGINX_CONF="/etc/nginx/sites-available/ogdhcp.conf"
|
|
||||||
PHP_FPM_CONF="/etc/php/*/fpm/pool.d/ogdhcp.conf"
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
remove)
|
|
||||||
echo "Preparando eliminación de ogdhcp..."
|
|
||||||
|
|
||||||
# Restaurar el archivo kea-ctrl-agent.conf original si se modificó
|
|
||||||
if [ -e "$KEA_CTRL_AGENT_CONF.dpkg-dist" ]; then
|
|
||||||
echo "Restaurando configuración original de kea-ctrl-agent..."
|
|
||||||
mv -f "$KEA_CTRL_AGENT_CONF.dpkg-dist" "$KEA_CTRL_AGENT_CONF"
|
|
||||||
dpkg-divert --package ogdhcp --remove --divert "$KEA_CTRL_AGENT_CONF.dpkg-dist" --rename "$KEA_CTRL_AGENT_CONF"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Restaurar el archivo kea-dhcp4.conf original si se modificó
|
|
||||||
if [ -e "$KEA_CONFIG.dpkg-dist" ]; then
|
|
||||||
echo "Restaurando configuración original de kea-dhcp4..."
|
|
||||||
mv -f "$KEA_CONFIG.dpkg-dist" "$KEA_CONFIG"
|
|
||||||
dpkg-divert --package ogdhcp --remove --divert "$KEA_CONFIG.dpkg-dist" --rename "$KEA_CONFIG"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Eliminar perfil personalizado de AppArmor
|
|
||||||
if [ -f "$APPARMOR_LOCAL_PROFILE" ]; then
|
|
||||||
echo "Eliminando perfil de AppArmor personalizado..."
|
|
||||||
rm -f "$APPARMOR_LOCAL_PROFILE"
|
|
||||||
apparmor_parser -r /etc/apparmor.d/usr.sbin.kea-dhcp4 || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Eliminar configuración de nginx
|
|
||||||
if [ -f "$NGINX_CONF" ]; then
|
|
||||||
echo "Eliminando configuración de nginx..."
|
|
||||||
rm -f "$NGINX_CONF"
|
|
||||||
rm -f "/etc/nginx/sites-enabled/ogdhcp.conf"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Eliminar configuración de php-fpm
|
|
||||||
echo "Eliminando configuración de php-fpm..."
|
|
||||||
rm -f $PHP_FPM_CONF
|
|
||||||
|
|
||||||
# Restaurar permisos de directorios
|
|
||||||
echo "Restaurando permisos en /opt/opengnsys..."
|
|
||||||
chown root:root /opt/opengnsys/
|
|
||||||
chown -R root:root /opt/opengnsys/ogdhcp
|
|
||||||
|
|
||||||
# Detener servicios antes de eliminar el paquete
|
|
||||||
echo "Deteniendo servicios..."
|
|
||||||
systemctl stop nginx || true
|
|
||||||
systemctl stop kea-dhcp4-server || true
|
|
||||||
systemctl stop kea-ctrl-agent || true
|
|
||||||
systemctl stop php*-fpm || true
|
|
||||||
;;
|
|
||||||
|
|
||||||
upgrade|deconfigure)
|
|
||||||
echo "Preparando actualización o desconfiguración de ogdhcp..."
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
echo "prerm llamado con un argumento desconocido '$1'" >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
Template: opengnsys/ogdhcp_interfaces
|
|
||||||
Type: string
|
|
||||||
Default: eth0
|
|
||||||
Description: Interfaces para DHCP
|
|
||||||
|
|
||||||
Template: opengnsys/ogdhcp_ip
|
|
||||||
Type: string
|
|
||||||
Default: 127.0.0.1
|
|
||||||
Description: IP para el servicio de ogdhcp
|
|
||||||
|
|
||||||
Template: opengnsys/ogboot_ogliveUrl
|
|
||||||
Type: string
|
|
||||||
Default: 127.0.0.1
|
|
||||||
Description: URL del OgLive a instalar
|
|
||||||
|
|
||||||
Template: opengnsys/ogdhcp_ogbootIP
|
|
||||||
Type: string
|
|
||||||
Default: 127.0.0.1
|
|
||||||
Description: Ip para el servicio de ogBoot
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
#!/usr/bin/make -f
|
|
||||||
|
|
||||||
# See debhelper(7) (uncomment to enable).
|
|
||||||
# Output every command that modifies files on the build system.
|
|
||||||
#export DH_VERBOSE = 1
|
|
||||||
|
|
||||||
|
|
||||||
# See FEATURE AREAS in dpkg-buildflags(1).
|
|
||||||
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
|
||||||
|
|
||||||
# See ENVIRONMENT in dpkg-buildflags(1).
|
|
||||||
# Package maintainers to append CFLAGS.
|
|
||||||
#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
|
|
||||||
# Package maintainers to append LDFLAGS.
|
|
||||||
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
|
|
||||||
|
|
||||||
|
|
||||||
%:
|
|
||||||
dh $@
|
|
||||||
|
|
||||||
override_dh_auto_build:
|
|
||||||
cd api; \
|
|
||||||
rm -rf var/cache/*; \
|
|
||||||
mkdir -p bin/; \
|
|
||||||
mkdir -p public; \
|
|
||||||
COMPOSER_ALLOW_SUPERUSER=1 APP_ENV=prod composer install --no-interaction --no-progress --optimize-autoloader; \
|
|
||||||
COMPOSER_ALLOW_SUPERUSER=1 APP_ENV=prod composer update doctrine/dbal;
|
|
||||||
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
3.0 (native)
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
[ogdhcp]
|
|
||||||
user = opengnsys
|
|
||||||
group = www-data
|
|
||||||
listen = /var/run/php/php8.3-fpm-ogdhcp.sock
|
|
||||||
listen.owner = opengnsys
|
|
||||||
listen.group = www-data
|
|
||||||
pm = dynamic
|
|
||||||
pm.max_children = 5
|
|
||||||
pm.start_servers = 2
|
|
||||||
pm.min_spare_servers = 1
|
|
||||||
pm.max_spare_servers = 3
|
|
||||||
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
[Unit]
|
|
||||||
# Eliminamos la condición de existencia del archivo de contraseña
|
|
||||||
ConditionFileNotEmpty=
|
|
||||||
|
|
||||||
|
|
@ -34,7 +34,6 @@ function globalSetup() {
|
||||||
# Directorios de instalación y destino de OpenGnsys.
|
# Directorios de instalación y destino de OpenGnsys.
|
||||||
WORKDIR=/tmp/ogdhcp_installer
|
WORKDIR=/tmp/ogdhcp_installer
|
||||||
INSTALL_TARGET=$(jq -r '.ogDhcp_Dir' "$CONFIG_FILE")
|
INSTALL_TARGET=$(jq -r '.ogDhcp_Dir' "$CONFIG_FILE")
|
||||||
SYMFONY_TARGET=$INSTALL_TARGET/api
|
|
||||||
PATH=$PATH:$INSTALL_TARGET/bin
|
PATH=$PATH:$INSTALL_TARGET/bin
|
||||||
|
|
||||||
if command -v service &>/dev/null; then
|
if command -v service &>/dev/null; then
|
||||||
|
|
@ -58,7 +57,7 @@ function globalSetup() {
|
||||||
SOCKET_PATH="/run/php/php__PHPVERSION__-fpm-ogdhcp.sock"
|
SOCKET_PATH="/run/php/php__PHPVERSION__-fpm-ogdhcp.sock"
|
||||||
|
|
||||||
# Registro de incidencias.
|
# Registro de incidencias.
|
||||||
OGLOGFILE="$SYMFONY_TARGET/var/log/${PROGRAMNAME%.sh}.log"
|
OGLOGFILE="$INSTALL_TARGET/var/log/${PROGRAMNAME%.sh}.log"
|
||||||
LOG_FILE="/tmp/$(basename "$OGLOGFILE")"
|
LOG_FILE="/tmp/$(basename "$OGLOGFILE")"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -139,26 +138,37 @@ function createDirs() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local path_opengnsys_base="$1"
|
local path_opengnsys_base="$1"
|
||||||
local symfony_target="$path_opengnsys_base/api"
|
|
||||||
|
|
||||||
# Crear estructura de directorios.
|
# Crear estructura de directorios.
|
||||||
echoAndLog "${FUNCNAME}(): creating directory paths in $path_opengnsys_base"
|
echoAndLog "${FUNCNAME}(): creating directory paths in $path_opengnsys_base"
|
||||||
mkdir -p "$symfony_target"/{bin,config,docs,public,src,templates,var/{cache,log},vendor}
|
mkdir -p "$path_opengnsys_base"/{bin,config,docs,public,src,etc/kea/backup,templates,var/{cache,log},vendor}
|
||||||
mkdir -p "$path_opengnsys_base"/etc/kea/backup
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
errorAndLog "${FUNCNAME}(): error while creating dirs. Do you have write permissions?"
|
errorAndLog "${FUNCNAME}(): error while creating dirs. Do you have write permissions?"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Mover el fichero de registro de instalación al directorio de logs.
|
# Crear usuario ficticio.
|
||||||
echoAndLog "${FUNCNAME}(): moving installation log file"
|
if id -u "$OPENGNSYS_CLIENT_USER" &>/dev/null; then
|
||||||
mv "$LOG_FILE" "$symfony_target/var/log" && LOG_FILE="$OGLOGFILE"
|
echoAndLog "${FUNCNAME}(): user \"$OPENGNSYS_CLIENT_USER\" is already created"
|
||||||
usermod -aG $OPENGNSYS_CLIENT_USER _kea
|
else
|
||||||
|
echoAndLog "${FUNCNAME}(): creating OpenGnsys user"
|
||||||
|
useradd "$OPENGNSYS_CLIENT_USER" 2>/dev/null
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
errorAndLog "${FUNCNAME}(): error creating OpenGnsys user"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Mover el fichero de registro de instalación al directorio de logs.
|
# Mover el fichero de registro de instalación al directorio de logs.
|
||||||
echoAndLog "${FUNCNAME}(): moving installation log file"
|
echoAndLog "${FUNCNAME}(): moving installation log file"
|
||||||
touch "$symfony_target/var/log/dev.log"
|
mv "$LOG_FILE" "$path_opengnsys_base/var/log" && LOG_FILE="$OGLOGFILE"
|
||||||
|
chmod 777 "$LOG_FILE"
|
||||||
|
sudo chmod -R 777 "$path_opengnsys_base/etc"
|
||||||
|
|
||||||
|
# Mover el fichero de registro de instalación al directorio de logs.
|
||||||
|
echoAndLog "${FUNCNAME}(): moving installation log file"
|
||||||
|
touch "$path_opengnsys_base/var/log/dev.log"
|
||||||
|
chmod 777 "$path_opengnsys_base/var/log/dev.log"
|
||||||
|
|
||||||
echoAndLog "${FUNCNAME}(): directory paths created"
|
echoAndLog "${FUNCNAME}(): directory paths created"
|
||||||
return 0
|
return 0
|
||||||
|
|
@ -171,39 +181,16 @@ function createDirs() {
|
||||||
|
|
||||||
function create_ogdhcp_project {
|
function create_ogdhcp_project {
|
||||||
# Crea el usuario ogdhcp si no existe
|
# Crea el usuario ogdhcp si no existe
|
||||||
echo "Creating ogdhcp user..."
|
|
||||||
local path_opengnsys_base="$1"
|
local path_opengnsys_base="$1"
|
||||||
local symfony_target="$path_opengnsys_base/api"
|
if ! id -u opengnsys &>/dev/null; then
|
||||||
echo $symfony_target
|
echoAndLog "${FUNCNAME}(): creating opengnsys user"
|
||||||
# Verificar si el usuario OPENGNSYS_CLIENT_USER existe
|
useradd opengnsys 2>/dev/null
|
||||||
if id -u "$OPENGNSYS_CLIENT_USER" &>/dev/null; then
|
|
||||||
# Salida de getent passwd -> opengnsys:x:1001:1001::/opt/opengnsys:/bin/sh
|
|
||||||
CURRENT_HOME=$(getent passwd "$OPENGNSYS_CLIENT_USER" | cut -d: -f6)
|
|
||||||
echoAndLog "${FUNCNAME[0]}(): user \"$OPENGNSYS_CLIENT_USER\" already exists with home \"$CURRENT_HOME\""
|
|
||||||
|
|
||||||
# Si el home no es correcto, cambiarlo
|
|
||||||
if [ "$CURRENT_HOME" != "/opt/opengnsys" ]; then
|
|
||||||
echoAndLog "${FUNCNAME[0]}(): updating home directory for \"$OPENGNSYS_CLIENT_USER\" to \"/opt/opengnsys\""
|
|
||||||
usermod -d "/opt/opengnsys" -m "$OPENGNSYS_CLIENT_USER"
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
errorAndLog "${FUNCNAME[0]}(): error updating home for \"$OPENGNSYS_CLIENT_USER\""
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Crear usuario si no existe
|
|
||||||
echoAndLog "${FUNCNAME[0]}(): creating OpenGnsys user \"$OPENGNSYS_CLIENT_USER\""
|
|
||||||
useradd --create-home -d "/opt/opengnsys" --shell "/bin/bash" "$OPENGNSYS_CLIENT_USER"
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
errorAndLog "${FUNCNAME[0]}(): error creating user \"$OPENGNSYS_CLIENT_USER\""
|
errorAndLog "${FUNCNAME}(): error creating opengnsys user"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Asegurar que todos los usuarios puedan entrar y leer /opt/opengnsys
|
|
||||||
echoAndLog "${FUNCNAME[0]}(): setting permissions for /opt/opengnsys"
|
|
||||||
# sudo chmod 755 /opt/opengnsys
|
|
||||||
|
|
||||||
# Crea el directorio path_opengnsys_base con el usuario opengnsys
|
# Crea el directorio path_opengnsys_base con el usuario opengnsys
|
||||||
echoAndLog "${FUNCNAME}(): creating directory $path_opengnsys_base with opengnsys user"
|
echoAndLog "${FUNCNAME}(): creating directory $path_opengnsys_base with opengnsys user"
|
||||||
sudo mkdir -p "$path_opengnsys_base"
|
sudo mkdir -p "$path_opengnsys_base"
|
||||||
|
|
@ -223,17 +210,16 @@ function copyServerFiles() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local path_opengnsys_base="$1"
|
local path_opengnsys_base="$1"
|
||||||
local symfony_target="$path_opengnsys_base/api"
|
|
||||||
local etc_target="$path_opengnsys_base/etc"
|
|
||||||
|
|
||||||
# Lista de ficheros y directorios origen y de directorios destino.
|
# Lista de ficheros y directorios origen y de directorios destino.
|
||||||
local SOURCES=(
|
local SOURCES=(
|
||||||
config
|
config
|
||||||
#public
|
#public
|
||||||
src
|
src
|
||||||
|
etc
|
||||||
.env
|
.env
|
||||||
bin
|
|
||||||
composer.json
|
composer.json
|
||||||
|
composer.lock
|
||||||
phpunit.xml.dist
|
phpunit.xml.dist
|
||||||
symfony.lock
|
symfony.lock
|
||||||
)
|
)
|
||||||
|
|
@ -241,9 +227,10 @@ function copyServerFiles() {
|
||||||
config
|
config
|
||||||
#public
|
#public
|
||||||
src
|
src
|
||||||
|
etc
|
||||||
.env
|
.env
|
||||||
bin
|
|
||||||
composer.json
|
composer.json
|
||||||
|
composer.lock
|
||||||
phpunit.xml.dist
|
phpunit.xml.dist
|
||||||
symfony.lock
|
symfony.lock
|
||||||
)
|
)
|
||||||
|
|
@ -256,27 +243,19 @@ function copyServerFiles() {
|
||||||
# Copiar ficheros.
|
# Copiar ficheros.
|
||||||
echoAndLog "${FUNCNAME}(): copying files to server directories"
|
echoAndLog "${FUNCNAME}(): copying files to server directories"
|
||||||
|
|
||||||
pushd "$WORKDIR/ogdhcp/api" || return
|
pushd "$WORKDIR/ogdhcp" || return
|
||||||
local i
|
local i
|
||||||
for (( i = 0; i < ${#SOURCES[@]}; i++ )); do
|
for (( i = 0; i < ${#SOURCES[@]}; i++ )); do
|
||||||
if [ -f "${SOURCES[$i]}" ]; then
|
if [ -f "${SOURCES[$i]}" ]; then
|
||||||
echoAndLog "Copying ${SOURCES[$i]} to $symfony_target/${TARGETS[$i]}"
|
echoAndLog "Copying ${SOURCES[$i]} to $path_opengnsys_base/${TARGETS[$i]}"
|
||||||
cp -a "${SOURCES[$i]}" "$symfony_target/${TARGETS[$i]}"
|
cp -a "${SOURCES[$i]}" "$path_opengnsys_base/${TARGETS[$i]}"
|
||||||
elif [ -d "${SOURCES[$i]}" ]; then
|
elif [ -d "${SOURCES[$i]}" ]; then
|
||||||
echoAndLog "Copying content of ${SOURCES[$i]} to $symfony_target/${TARGETS[$i]}"
|
echoAndLog "Copying content of ${SOURCES[$i]} to $path_opengnsys_base/${TARGETS[$i]}"
|
||||||
cp -a "${SOURCES[$i]}"/* "$symfony_target/${TARGETS[$i]}"
|
cp -a "${SOURCES[$i]}"/* "$path_opengnsys_base/${TARGETS[$i]}"
|
||||||
else
|
else
|
||||||
warningAndLog "Unable to copy ${SOURCES[$i]} to $symfony_target/${TARGETS[$i]}"
|
warningAndLog "Unable to copy ${SOURCES[$i]} to $path_opengnsys_base/${TARGETS[$i]}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
pushd "$WORKDIR/ogdhcp" || return
|
|
||||||
# Copiar el directorio etc
|
|
||||||
echoAndLog "Copying etc directory to $path_opengnsys_base"
|
|
||||||
cp -a etc "$path_opengnsys_base"
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
errorAndLog "Error while copying etc directory to $path_opengnsys_base"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
echoAndLog "Changing user permission"
|
echoAndLog "Changing user permission"
|
||||||
chown -R "$OPENGNSYS_CLIENT_USER:$OPENGNSYS_CLIENT_USER" "$INSTALL_TARGET"
|
chown -R "$OPENGNSYS_CLIENT_USER:$OPENGNSYS_CLIENT_USER" "$INSTALL_TARGET"
|
||||||
|
|
||||||
|
|
@ -287,8 +266,7 @@ function copyServerFiles() {
|
||||||
function runComposer() {
|
function runComposer() {
|
||||||
echoAndLog "Running composer.phar to install dependencies..."
|
echoAndLog "Running composer.phar to install dependencies..."
|
||||||
local path_opengnsys_base="$1"
|
local path_opengnsys_base="$1"
|
||||||
local symfony_target="$path_opengnsys_base/api"
|
pushd $path_opengnsys_base
|
||||||
pushd $symfony_target
|
|
||||||
pwd
|
pwd
|
||||||
# Ejecutar composer.phar
|
# Ejecutar composer.phar
|
||||||
sudo -u "$OPENGNSYS_CLIENT_USER" composer --no-interaction install
|
sudo -u "$OPENGNSYS_CLIENT_USER" composer --no-interaction install
|
||||||
|
|
@ -396,8 +374,7 @@ add_write_permission_apparmor() {
|
||||||
# Función para configurar Nginx
|
# Función para configurar Nginx
|
||||||
setup_nginx() {
|
setup_nginx() {
|
||||||
local path_opengnsys_base="$1"
|
local path_opengnsys_base="$1"
|
||||||
local symfony_target="$path_opengnsys_base/api"
|
local public_dir="$path_opengnsys_base/public"
|
||||||
local public_dir="$symfony_target/public"
|
|
||||||
#ip_address_server=$(get_ip_address "$DEFAULTDEV")
|
#ip_address_server=$(get_ip_address "$DEFAULTDEV")
|
||||||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||||
echo "Error: El archivo de configuración no se encontró."
|
echo "Error: El archivo de configuración no se encontró."
|
||||||
|
|
@ -604,18 +581,6 @@ if [ "$(whoami)" != 'root' ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Verificar si jq está instalado, si no, instalarlo
|
|
||||||
if ! command -v jq &> /dev/null; then
|
|
||||||
echo "jq no está instalado. Instalando jq..."
|
|
||||||
apt-get update -y
|
|
||||||
apt-get install -y jq
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Error al instalar jq. Por favor, instala jq manualmente y vuelve a intentarlo."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "jq instalado correctamente."
|
|
||||||
fi
|
|
||||||
|
|
||||||
globalSetup
|
globalSetup
|
||||||
|
|
||||||
echoAndLog "OpenGnsys installation begins at $(date)"
|
echoAndLog "OpenGnsys installation begins at $(date)"
|
||||||
|
|
@ -625,7 +590,6 @@ pushd $WORKDIR
|
||||||
|
|
||||||
checkDependencies
|
checkDependencies
|
||||||
# Si es necesario, descarga el repositorio de código en directorio temporal
|
# Si es necesario, descarga el repositorio de código en directorio temporal
|
||||||
|
|
||||||
if [ $REMOTE -eq 1 ]; then
|
if [ $REMOTE -eq 1 ]; then
|
||||||
downloadCode $GIT_REPO
|
downloadCode $GIT_REPO
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
|
|
@ -636,7 +600,6 @@ else
|
||||||
ln -fs "$(dirname $PROGRAMDIR)" ogdhcp
|
ln -fs "$(dirname $PROGRAMDIR)" ogdhcp
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
create_ogdhcp_project ${INSTALL_TARGET}
|
create_ogdhcp_project ${INSTALL_TARGET}
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
errorAndLog "Error while creating skeleton directory!"
|
errorAndLog "Error while creating skeleton directory!"
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -61,45 +61,6 @@ class CurlKeaService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function executeLeaseCommand($command, $arguments)
|
|
||||||
{
|
|
||||||
$apiUrl = getenv('DHCP_IP');
|
|
||||||
if (!$apiUrl) {
|
|
||||||
$apiUrl = 'http://localhost:8000/';
|
|
||||||
}
|
|
||||||
|
|
||||||
$requestData = [
|
|
||||||
'command' => $command,
|
|
||||||
'service' => ['dhcp4'],
|
|
||||||
'arguments' => $arguments,
|
|
||||||
];
|
|
||||||
|
|
||||||
$jsonData = json_encode($requestData);
|
|
||||||
try {
|
|
||||||
$ch = curl_init();
|
|
||||||
curl_setopt($ch, CURLOPT_URL, $apiUrl);
|
|
||||||
curl_setopt($ch, CURLOPT_POST, 1);
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', 'Expect:']);
|
|
||||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
|
||||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
||||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
||||||
$output = json_decode($response, true);
|
|
||||||
|
|
||||||
if ($httpCode >= 200 && $httpCode < 300) {
|
|
||||||
return $output;
|
|
||||||
} else {
|
|
||||||
$error = curl_error($ch);
|
|
||||||
throw new Exception($error);
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
throw new Exception($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function convertMaskToCIDR($mask)
|
public function convertMaskToCIDR($mask)
|
||||||
{
|
{
|
||||||
$bits = 0;
|
$bits = 0;
|
||||||
|
|
@ -121,7 +82,7 @@ class CurlKeaService
|
||||||
$config_text = json_encode($get_output[0]['arguments']);
|
$config_text = json_encode($get_output[0]['arguments']);
|
||||||
$configurationParsed = str_replace('\\', '', $config_text);
|
$configurationParsed = str_replace('\\', '', $config_text);
|
||||||
|
|
||||||
$backup_dir = __DIR__ . '/../../../../etc/kea/backup';
|
$backup_dir = __DIR__ . '/../../../etc/kea/backup';
|
||||||
if (!is_dir($backup_dir)) {
|
if (!is_dir($backup_dir)) {
|
||||||
throw new Exception('El directorio de backup no existe');
|
throw new Exception('El directorio de backup no existe');
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,118 @@
|
||||||
|
pipeline {
|
||||||
|
agent {
|
||||||
|
node {
|
||||||
|
label 'jenkins-slave'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
options {
|
||||||
|
// Deshabilita ejecuciones concurrentes
|
||||||
|
disableConcurrentBuilds()
|
||||||
|
}
|
||||||
|
environment {
|
||||||
|
ESXI_PASS = credentials('VI_PASSWORD')
|
||||||
|
QINDEL_PASS = credentials('jenkins-user-slave-password')
|
||||||
|
PATH = "/home/qindel/bin/ovftool:${env.PATH}"
|
||||||
|
}
|
||||||
|
stages {
|
||||||
|
stage('Prepare environment') {
|
||||||
|
steps {
|
||||||
|
dir ('tests/API-dhcp') {
|
||||||
|
echo "Install vagrant plugin"
|
||||||
|
sh '''
|
||||||
|
if ! vagrant plugin list | grep -q vagrant-vmware-esxi; then
|
||||||
|
echo "Vagrant plugin vagrant-vmware-esxi not found. Installing..."
|
||||||
|
vagrant plugin install vagrant-vmware-esxi
|
||||||
|
else
|
||||||
|
echo "Vagrant plugin vagrant-vmware-esxi is already installed."
|
||||||
|
fi
|
||||||
|
'''
|
||||||
|
echo "Deploy API server for DHCP with Vagrant"
|
||||||
|
sh 'vagrant up --provider=vmware_esxi --provision'
|
||||||
|
echo 'Create Python venv to work with robotframework'
|
||||||
|
sh '''
|
||||||
|
python3 -m venv robotframework
|
||||||
|
. robotframework/bin/activate
|
||||||
|
pip install -r requirements.txt
|
||||||
|
'''
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Check Installation') {
|
||||||
|
steps {
|
||||||
|
dir ('tests/API-dhcp') {
|
||||||
|
echo "Get IP of API server for DHCP with Vagrant"
|
||||||
|
sh '''
|
||||||
|
set -e
|
||||||
|
new_ip=$(vagrant ssh -c "hostname -I" | tr -d '\r\n' | sed 's/^[^0-9]*//' | sed 's/[[:space:]]*$//')
|
||||||
|
echo $new_ip > ip.txt
|
||||||
|
echo "$QINDEL_PASS" | sudo -S bash -c "echo '$new_ip api-test' >> /etc/hosts"
|
||||||
|
echo "IP: $new_ip"
|
||||||
|
curl -X 'GET' "http://$new_ip/ogdhcp/v1/subnets" -H 'accept: /'
|
||||||
|
'''
|
||||||
|
script {
|
||||||
|
def new_ip = readFile('ip.txt').trim()
|
||||||
|
env.NEW_IP = new_ip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Run API tests') {
|
||||||
|
steps {
|
||||||
|
dir ('tests/API-dhcp') {
|
||||||
|
|
||||||
|
echo 'Running API tests'
|
||||||
|
|
||||||
|
sh '''
|
||||||
|
. robotframework/bin/activate
|
||||||
|
robot --variable BASE_URL:http://${NEW_IP}/ogdhcp/v1 -d results/ robot/
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
// Aquí incluirías los comandos para ejecutar tus pruebas
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
post {
|
||||||
|
success {
|
||||||
|
// Si el trabajo ha sido exitoso, destruir la máquina de Vagrant
|
||||||
|
echo "El trabajo ha finalizado con éxito. Destruyendo máquina Vagrant..."
|
||||||
|
dir ('tests/API-dhcp') {
|
||||||
|
sh 'vagrant destroy -f'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
always {
|
||||||
|
// Recoger los resultados de los tests
|
||||||
|
dir ('tests/API-dhcp') {
|
||||||
|
robot outputPath: 'results',
|
||||||
|
outputFileName: 'output.xml',
|
||||||
|
logFileName: 'log.html',
|
||||||
|
reportFileName: 'report.html',
|
||||||
|
passThreshold: 100.0,
|
||||||
|
unstableThreshold: 75.0
|
||||||
|
}
|
||||||
|
// Siempre se ejecutará, independientemente del resultado
|
||||||
|
script {
|
||||||
|
// Elimina la entrada del /etc/hosts
|
||||||
|
sh "echo '$QINDEL_PASS' | sudo -S sed -i '/api-test/d' /etc/hosts"
|
||||||
|
def recipientEmail = env.BUILD_USER_EMAIL ?: getCommitterEmail()
|
||||||
|
|
||||||
|
mail to: recipientEmail,
|
||||||
|
subject: "Jenkins Job Completed: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
|
||||||
|
body: """
|
||||||
|
El job '${env.JOB_NAME}' con número de build ${env.BUILD_NUMBER} ha finalizado.
|
||||||
|
|
||||||
|
Estado: ${currentBuild.currentResult}
|
||||||
|
|
||||||
|
Revisa los detalles del build en: ${env.BUILD_URL}
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def getCommitterEmail() {
|
||||||
|
return sh(
|
||||||
|
script: 'git log -1 --pretty=format:"%ae"',
|
||||||
|
returnStdout: true
|
||||||
|
).trim()
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
#
|
||||||
|
# Fully documented Vagrantfile available
|
||||||
|
# in the wiki: https://github.com/josenk/vagrant-vmware-esxi/wiki
|
||||||
|
|
||||||
|
$script = <<SCRIPT
|
||||||
|
SERVER_NAME=localhost
|
||||||
|
echo "Provisioning with shell script..."
|
||||||
|
cd /vagrant/installer
|
||||||
|
chmod +x ogdhcp_installer.sh && ./ogdhcp_installer.sh
|
||||||
|
SCRIPT
|
||||||
|
|
||||||
|
Vagrant.configure('2') do |config|
|
||||||
|
config.vm.box = 'dummy'
|
||||||
|
VM_TEMPLATE = 'template-ubuntu24'
|
||||||
|
# Use rsync and NFS synced folders. (or use the option to disable them)
|
||||||
|
# https://www.vagrantup.com/docs/synced-folders/
|
||||||
|
#config.vm.synced_folder('.', '/vagrant', type: 'rsync')
|
||||||
|
config.vm.synced_folder('../../', '/vagrant', type: 'rsync')
|
||||||
|
|
||||||
|
# Vagrant can configure additional network interfaces using a static IP or
|
||||||
|
# DHCP. Use public_network or private_network to manually set a static IP and
|
||||||
|
# optionally netmask. ESXi doesn't use the concept of public or private
|
||||||
|
# networks so both are valid here. The primary network interface is considered the
|
||||||
|
# "vagrant management" interface and cannot be changed and this plugin
|
||||||
|
# supports 10 NICS, so you can specify 9 entries here!
|
||||||
|
#
|
||||||
|
# https://www.vagrantup.com/docs/networking/public_network.html
|
||||||
|
# https://www.vagrantup.com/docs/networking/private_network.html
|
||||||
|
#
|
||||||
|
# *** Invalid settings could cause 'vagrant up' to fail ***
|
||||||
|
#config.vm.network 'private_network', ip: '192.168.10.170', netmask: '255.255.255.0'
|
||||||
|
#config.vm.network 'private_network', ip: '192.168.11.170'
|
||||||
|
#config.vm.network 'public_network', ip: '192.168.12.170'
|
||||||
|
|
||||||
|
#
|
||||||
|
# Provider (esxi) settings
|
||||||
|
#
|
||||||
|
config.vm.provision 'shell', inline: $script
|
||||||
|
config.vm.provider :vmware_esxi do |esxi|
|
||||||
|
|
||||||
|
# REQUIRED! ESXi hostname/IP
|
||||||
|
esxi.esxi_hostname = 'esxi-jenkins.evlt.uma.es'
|
||||||
|
|
||||||
|
# ESXi username
|
||||||
|
esxi.esxi_username = 'root'
|
||||||
|
|
||||||
|
# IMPORTANT! Set ESXi password.
|
||||||
|
# 1) 'prompt:'
|
||||||
|
# 2) 'file:' or 'file:my_secret_file'
|
||||||
|
# 3) 'env:' or 'env:my_secret_env_var'
|
||||||
|
# 4) 'key:' or key:~/.ssh/some_ssh_private_key'
|
||||||
|
# 5) or esxi.esxi_password = 'my_esxi_password'
|
||||||
|
#
|
||||||
|
esxi.esxi_password = 'env:ESXI_PASS'
|
||||||
|
|
||||||
|
# SSH port.
|
||||||
|
#esxi.esxi_hostport = 22
|
||||||
|
|
||||||
|
# HIGHLY RECOMMENDED! ESXi Virtual Network
|
||||||
|
# You should specify an ESXi Virtual Network! If it's not specified, the
|
||||||
|
# default is to use the first found. You can specify up to 10 virtual
|
||||||
|
# networks using an array format.
|
||||||
|
esxi.esxi_virtual_network = ['vLan_742']
|
||||||
|
|
||||||
|
# OPTIONAL. Specify a Disk Store
|
||||||
|
#esxi.esxi_disk_store = 'DS_001'
|
||||||
|
|
||||||
|
# OPTIONAL. Resource Pool
|
||||||
|
# Vagrant will NOT create a Resource pool it for you.
|
||||||
|
esxi.esxi_resource_pool = '/'
|
||||||
|
|
||||||
|
# Optional. Specify a VM to clone instead of uploading a box.
|
||||||
|
# Vagrant can use any stopped VM as the source 'box'. The VM must be
|
||||||
|
# registered, stopped and must have the vagrant insecure ssh key installed.
|
||||||
|
# If the VM is stored in a resource pool, it must be specified.
|
||||||
|
# See wiki: https://github.com/josenk/vagrant-vmware-esxi/wiki/How-to-clone_from_vm
|
||||||
|
esxi.clone_from_vm = VM_TEMPLATE
|
||||||
|
|
||||||
|
# OPTIONAL. Guest VM name to use.
|
||||||
|
# The Default will be automatically generated.
|
||||||
|
#esxi.guest_name = 'Custom-Guest-VM_Name'
|
||||||
|
|
||||||
|
# OPTIONAL. When automatically naming VMs, use this prefix.
|
||||||
|
#esxi.guest_name_prefix = 'V-'
|
||||||
|
|
||||||
|
# OPTIONAL. Set the guest username login. The default is 'vagrant'.
|
||||||
|
#esxi.guest_username = 'vagrant'
|
||||||
|
|
||||||
|
# OPTIONAL. Memory size override
|
||||||
|
#esxi.guest_memsize = '2048'
|
||||||
|
|
||||||
|
# OPTIONAL. Virtual CPUs override
|
||||||
|
#esxi.guest_numvcpus = '2'
|
||||||
|
|
||||||
|
# OPTIONAL & RISKY. Specify up to 10 MAC addresses
|
||||||
|
# The default is ovftool to automatically generate a MAC address.
|
||||||
|
# You can specify an array of MAC addresses using upper or lower case,
|
||||||
|
# separated by colons ':'.
|
||||||
|
#esxi.guest_mac_address = ['00:50:56:aa:bb:cc', '00:50:56:01:01:01','00:50:56:02:02:02','00:50:56:BE:AF:01' ]
|
||||||
|
|
||||||
|
# OPTIONAL & RISKY. Specify a guest_nic_type
|
||||||
|
# The validated list of guest_nic_types are 'e1000', 'e1000e', 'vmxnet',
|
||||||
|
# 'vmxnet2', 'vmxnet3', 'Vlance', and 'Flexible'.
|
||||||
|
#esxi.guest_nic_type = 'e1000'
|
||||||
|
|
||||||
|
# OPTIONAL. Specify a disk type.
|
||||||
|
# If unspecified, it will be set to 'thin'. Otherwise, you can set to
|
||||||
|
# 'thin', 'thick', or 'eagerzeroedthick'
|
||||||
|
#esxi.guest_disk_type = 'thick'
|
||||||
|
|
||||||
|
# OPTIONAL. Boot disk size.
|
||||||
|
# If unspecified, the boot disk size will be the same as the original
|
||||||
|
# box. You can specify a larger boot disk size in GB. The extra disk space
|
||||||
|
# will NOT automatically be available to your OS. You will need to
|
||||||
|
# create or modify partitions, LVM and/or filesystems.
|
||||||
|
#esxi.guest_boot_disk_size = 50
|
||||||
|
|
||||||
|
# OPTIONAL. Create additional storage for guests.
|
||||||
|
# You can specify an array of up to 13 virtual disk sizes (in GB) that you
|
||||||
|
# would like the provider to create once the guest has been created. You
|
||||||
|
# can optionally specify the size and datastore using a hash.
|
||||||
|
#esxi.guest_storage = [ 10, 20, { size: 30, datastore: 'datastore1' } ]
|
||||||
|
|
||||||
|
# OPTIONAL. specify snapshot options.
|
||||||
|
#esxi.guest_snapshot_includememory = 'true'
|
||||||
|
#esxi.guest_snapshot_quiesced = 'true'
|
||||||
|
|
||||||
|
# RISKY. guest_guestos
|
||||||
|
# https://github.com/josenk/vagrant-vmware-esxi/wiki/VMware-ESXi-6.5-guestOS-types
|
||||||
|
#esxi.guest_guestos = 'centos-64'
|
||||||
|
|
||||||
|
# OPTIONAL. guest_virtualhw_version
|
||||||
|
# ESXi 6.7 supports these versions. 4,7,8,9,10,11,12,13 & 14.
|
||||||
|
#esxi.guest_virtualhw_version = '9'
|
||||||
|
|
||||||
|
# OPTIONAL. Guest Autostart
|
||||||
|
# Guest VM will autostart when esxi host is booted. 'true' or 'false'(default)
|
||||||
|
#esxi.guest_autostart = 'false'
|
||||||
|
|
||||||
|
# RISKY. guest_custom_vmx_settings
|
||||||
|
#esxi.guest_custom_vmx_settings = [['vhv.enable','TRUE'], ['floppy0.present','TRUE']]
|
||||||
|
|
||||||
|
# OPTIONAL. local_lax
|
||||||
|
#esxi.local_lax = 'true'
|
||||||
|
|
||||||
|
# OPTIONAL. Guest IP Caching
|
||||||
|
#esxi.local_use_ip_cache = 'True'
|
||||||
|
|
||||||
|
# DANGEROUS! Allow Overwrite
|
||||||
|
# If unspecified, the default is to produce an error if overwriting
|
||||||
|
# VMs and packages.
|
||||||
|
#esxi.local_allow_overwrite = 'True'
|
||||||
|
|
||||||
|
# Advanced Users.
|
||||||
|
# If set to 'True', all WARNINGS will produce a FAILURE and Vagrant will stop.
|
||||||
|
#esxi.local_failonwarning = 'True'
|
||||||
|
|
||||||
|
# Plugin debug output.
|
||||||
|
# Please send any bug reports with this debug output...
|
||||||
|
#esxi.debug = 'true'
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,374 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
from flask import Flask, jsonify, request
|
||||||
|
import ipaddress
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def convert_to_cidr(address, mask):
|
||||||
|
"""
|
||||||
|
Convert an IP address and subnet mask to CIDR notation.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
address (str): The IP address in dotted decimal format (e.g., '192.168.1.1').
|
||||||
|
mask (str): The subnet mask in dotted decimal format (e.g., '255.255.255.0').
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The CIDR notation of the network (e.g., '192.168.1.1/24').
|
||||||
|
None: If there is an error in conversion, returns None and prints an error message.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If the provided address or mask is invalid.
|
||||||
|
"""
|
||||||
|
# Convertir dirección y máscara a formato CIDR
|
||||||
|
try:
|
||||||
|
# Convertir la máscara de red de formato largo a formato corto
|
||||||
|
# Cada octeto se convierte a su representación binaria y se cuenta el número de bits '1'
|
||||||
|
cidr_mask = ipaddress.IPv4Network(f"0.0.0.0/{mask}").prefixlen
|
||||||
|
red_objeto = f"{address}/{cidr_mask}"
|
||||||
|
return red_objeto
|
||||||
|
except ValueError as e:
|
||||||
|
print(f"Error al convertir a CIDR: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
subnets_collection = [{"id": 1,"subnet": "192.168.1.0/24", "next-server": "192.168.1.1", "boot-file-name": "pxelinux.0", "reservations": [] }]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Endpoint GET /ogdhcp/v1/status
|
||||||
|
"""
|
||||||
|
Endpoint to get the status of the DHCP service.
|
||||||
|
|
||||||
|
This endpoint returns a JSON response with the current status of the DHCP service,
|
||||||
|
including disk usage, subnets configuration, and the status of various services.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response: A JSON response with the following structure:
|
||||||
|
"total": str, # Total disk space
|
||||||
|
"used": str, # Used disk space
|
||||||
|
"available": str, # Available disk space
|
||||||
|
"percentage": str # Percentage of disk space used
|
||||||
|
"id": int, # Subnet ID
|
||||||
|
"subnet": str, # Subnet address
|
||||||
|
"pools": [
|
||||||
|
"pool": str # IP address pool range
|
||||||
|
"reservations": [
|
||||||
|
"ip-address": str, # Reserved IP address
|
||||||
|
"hw-address": str # Hardware address associated with the reservation
|
||||||
|
]
|
||||||
|
...
|
||||||
|
"kea-ctrl-agent": str, # Status of kea-ctrl-agent service
|
||||||
|
"kea-dhcp4": str, # Status of kea-dhcp4 service
|
||||||
|
"nginx": str # Status of nginx service
|
||||||
|
HTTP Status Code:
|
||||||
|
200: If the request was successful.
|
||||||
|
"""
|
||||||
|
@app.route('/ogdhcp/v1/status', methods=['GET'])
|
||||||
|
def get_status():
|
||||||
|
# Simular respuesta de éxito
|
||||||
|
return jsonify({
|
||||||
|
"success": "Mensaje éxito",
|
||||||
|
"message": {
|
||||||
|
"disk_usage": {
|
||||||
|
"total": "20G",
|
||||||
|
"used": "15G",
|
||||||
|
"available": "5G",
|
||||||
|
"percentage": "75%"
|
||||||
|
},
|
||||||
|
"subnets": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"subnet": "192.168.1.0/24",
|
||||||
|
"pools": [{"pool": "192.168.1.10-192.168.1.100"}],
|
||||||
|
"reservations": [{"ip-address": "192.168.1.20", "hw-address": "00:0c:29:6b:5e:71"}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"subnet": "10.0.0.0/24",
|
||||||
|
"pools": [{"pool": "10.0.0.10-10.0.0.100"}],
|
||||||
|
"reservations": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services_status": {
|
||||||
|
"kea-ctrl-agent": "active",
|
||||||
|
"kea-dhcp4": "active",
|
||||||
|
"nginx": "active"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}), 200
|
||||||
|
|
||||||
|
# Endpoint GET /ogdhcp/v1/subnets
|
||||||
|
|
||||||
|
@app.route('/ogdhcp/v1/subnets', methods=['GET'])
|
||||||
|
def get_subnets():
|
||||||
|
# Simular respuesta de éxito
|
||||||
|
return jsonify({
|
||||||
|
"success": "Subredes obtenidas correctamente",
|
||||||
|
"message": subnets_collection
|
||||||
|
}), 200
|
||||||
|
|
||||||
|
# Endpoint POST /ogdhcp/v1/subnets
|
||||||
|
"""
|
||||||
|
Create a new subnet.
|
||||||
|
Endpoint: /ogdhcp/v1/subnets
|
||||||
|
Method: POST
|
||||||
|
Request Body (JSON):
|
||||||
|
{
|
||||||
|
"id": <str>, # Unique identifier for the subnet
|
||||||
|
"address": <str>, # IP address of the subnet
|
||||||
|
"mask": <str>, # Subnet mask
|
||||||
|
"nextServer": <str>, # (Optional) Next server IP address
|
||||||
|
"bootFileName": <str> # (Optional) Boot file name
|
||||||
|
}
|
||||||
|
Responses:
|
||||||
|
200 OK:
|
||||||
|
{
|
||||||
|
"message": <new_subnet>
|
||||||
|
}
|
||||||
|
400 Bad Request:
|
||||||
|
- "Invalid JSON"
|
||||||
|
- "Missing 'id', 'address' or 'mask' key"
|
||||||
|
- {
|
||||||
|
"error": "Error: La subred con el id '<id>' ya existe."
|
||||||
|
}
|
||||||
|
- {
|
||||||
|
"error": "Error: La subred con la dirección '<subnet>' ya existe."
|
||||||
|
}
|
||||||
|
- "Invalid data format"
|
||||||
|
Description:
|
||||||
|
This endpoint allows the creation of a new subnet. It expects a JSON payload with the subnet details.
|
||||||
|
The function checks if the provided JSON is valid and contains the required keys ('id', 'address', 'mask').
|
||||||
|
It also ensures that the subnet ID and subnet address do not already exist in the collection.
|
||||||
|
If the validation passes, the new subnet is added to the collection and a success response is returned.
|
||||||
|
"""
|
||||||
|
@app.route('/ogdhcp/v1/subnets', methods=['POST'])
|
||||||
|
def create_subnet():
|
||||||
|
try:
|
||||||
|
new_subnet = json.loads(request.data)
|
||||||
|
new_subnet["next-server"] = new_subnet.get("nextServer")
|
||||||
|
new_subnet["boot-file-name"] = new_subnet.get("bootFileName")
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
return "Invalid JSON", 400
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if isinstance(new_subnet, dict):
|
||||||
|
if "id" in new_subnet and "address" in new_subnet and "mask" in new_subnet:
|
||||||
|
new_subnet_cidr = convert_to_cidr(new_subnet["address"], new_subnet["mask"])
|
||||||
|
# Comprobar si el id ya existe en la colección
|
||||||
|
for subnet in subnets_collection:
|
||||||
|
if subnet.get("id") == new_subnet["id"]:
|
||||||
|
return jsonify({
|
||||||
|
"error": f"Error: La subred con el id '{new_subnet['id']}' ya existe."
|
||||||
|
}), 400
|
||||||
|
if subnet.get("subnet") == new_subnet_cidr:
|
||||||
|
return jsonify({
|
||||||
|
"error": f"Error: La subred con la dirección '{new_subnet_cidr}' ya existe."
|
||||||
|
}), 400
|
||||||
|
|
||||||
|
# Si el id no existe, continuar con la creación de la subred
|
||||||
|
new_subnet["subnet"] = convert_to_cidr(new_subnet["address"], new_subnet["mask"])
|
||||||
|
subnets_collection.append(new_subnet)
|
||||||
|
return jsonify({
|
||||||
|
"success": "Subred agregada correctamente",
|
||||||
|
"message": new_subnet
|
||||||
|
}), 200
|
||||||
|
|
||||||
|
else:
|
||||||
|
return "Missing 'id', 'address' or 'mask' key", 400
|
||||||
|
else:
|
||||||
|
return "Invalid data format", 400
|
||||||
|
|
||||||
|
|
||||||
|
# Endpoint DELETE /ogdhcp/v1/subnets/<subnetId>
|
||||||
|
"""
|
||||||
|
Deletes a subnet from the subnets_collection based on the provided subnetId.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
subnetId (int): The ID of the subnet to be deleted.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response: A JSON response indicating the success or failure of the deletion.
|
||||||
|
- If the subnet is successfully deleted, returns a JSON response with a success message and HTTP status 200.
|
||||||
|
- If the subnet with the given ID does not exist, returns a JSON response with an error message and HTTP status 404.
|
||||||
|
"""
|
||||||
|
@app.route('/ogdhcp/v1/subnets/<int:subnetId>', methods=['DELETE'])
|
||||||
|
def delete_subnet(subnetId):
|
||||||
|
subnet_to_delete = None
|
||||||
|
for subnet in subnets_collection:
|
||||||
|
if int(subnet["id"]) == subnetId:
|
||||||
|
subnet_to_delete = subnet
|
||||||
|
break
|
||||||
|
if subnet_to_delete:
|
||||||
|
print (f"Subnet Collection {subnets_collection}")
|
||||||
|
print (f"Subnet to delete {subnet_to_delete}")
|
||||||
|
subnets_collection.remove(subnet_to_delete)
|
||||||
|
print (f"Subnet Collection {subnets_collection}")
|
||||||
|
return jsonify({
|
||||||
|
"success": "Subred eliminada correctamente"
|
||||||
|
}), 200
|
||||||
|
else:
|
||||||
|
return jsonify({
|
||||||
|
"error": f"Error: La subred con el id '{subnetId}' no existe"
|
||||||
|
}), 404
|
||||||
|
|
||||||
|
# Endpoint PUT /ogdhcp/v1/subnets/<subnetId>
|
||||||
|
"""
|
||||||
|
Updates a subnet with the given subnetId based on the provided JSON data in the request.
|
||||||
|
Args:
|
||||||
|
subnetId (str): The ID of the subnet to be updated.
|
||||||
|
Returns:
|
||||||
|
Response: A JSON response indicating the success or failure of the update operation.
|
||||||
|
- On success: Returns a JSON response with a success message and the updated subnet data, with a status code of 200.
|
||||||
|
- On failure: Returns a JSON response with an error message and a status code of 400.
|
||||||
|
Raises:
|
||||||
|
json.JSONDecodeError: If the request data is not valid JSON.
|
||||||
|
The function performs the following steps:
|
||||||
|
1. Parses the JSON data from the request.
|
||||||
|
2. Validates the presence of required fields ('address' and 'mask') in the JSON data.
|
||||||
|
3. Converts the 'address' and 'mask' fields to a 'subnet' field in CIDR notation.
|
||||||
|
4. Searches for the subnet with the given subnetId in the subnets_collection.
|
||||||
|
5. Updates the subnet fields ('subnet', 'nextServer', 'bootFileName') if they are present in the JSON data.
|
||||||
|
6. Returns a success response if the subnet is found and updated.
|
||||||
|
7. Returns an error response if the subnet is not found.
|
||||||
|
"""
|
||||||
|
@app.route('/ogdhcp/v1/subnets/<int:subnetId>', methods=['PUT'])
|
||||||
|
def update_subnet(subnetId):
|
||||||
|
|
||||||
|
|
||||||
|
if subnetId == 0:
|
||||||
|
return jsonify({
|
||||||
|
"error": "Error al guardar la configuración en Kea DHCP: Unable to save configuration"
|
||||||
|
}), 400
|
||||||
|
try:
|
||||||
|
modify_data = json.loads(request.data)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
return "Invalid JSON", 400
|
||||||
|
|
||||||
|
print ("Modify data", modify_data)
|
||||||
|
print ("Modify data type", type(modify_data))
|
||||||
|
if modify_data.get("address") != None and modify_data.get("mask") == None:
|
||||||
|
print ("Address", modify_data.get("address"))
|
||||||
|
return jsonify({
|
||||||
|
"error": f"Error: La máscara de red es requerida con el parametro 'address'"
|
||||||
|
}), 400
|
||||||
|
if modify_data.get("mask") != None and modify_data.get("address") == None:
|
||||||
|
return jsonify({
|
||||||
|
"error": f"Error: La dirección de red es requerida con el parametro 'mask'"
|
||||||
|
}), 400
|
||||||
|
|
||||||
|
subnet_to_update = None
|
||||||
|
|
||||||
|
for subnet in subnets_collection:
|
||||||
|
# Casting subnet["id"] to int to avoid type mismatch
|
||||||
|
if str(subnet["id"]) == str(subnetId):
|
||||||
|
# subnet_to_update = subnet
|
||||||
|
if modify_data.get("subnet"):
|
||||||
|
subnet["subnet"] = modify_data["subnet"]
|
||||||
|
|
||||||
|
if modify_data.get("nextServer"):
|
||||||
|
subnet["next-server"] = modify_data["nextServer"]
|
||||||
|
|
||||||
|
if modify_data.get("bootFileName"):
|
||||||
|
subnet["boot-file-name"] = modify_data["bootFileName"]
|
||||||
|
subnet_to_update = subnet
|
||||||
|
break
|
||||||
|
|
||||||
|
if subnet_to_update:
|
||||||
|
# subnet_to_update.update(modify_data)
|
||||||
|
print ("Subnet to update", subnet_to_update)
|
||||||
|
return jsonify({
|
||||||
|
"success": "Subred modificada correctamente",
|
||||||
|
"message": subnet_to_update
|
||||||
|
}), 200
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Si no se encuentra la subred, devolver un error
|
||||||
|
print (f"Subnet Collection {subnets_collection}")
|
||||||
|
response = jsonify({
|
||||||
|
"error": f"Error: La subred con el id '{subnetId}' no existe"
|
||||||
|
})
|
||||||
|
response.status_code = 404
|
||||||
|
response.headers["Content-Type"] = "application/json"
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
# Endpoint GET /ogdhcp/v1/subnets/<subnetId>/hosts
|
||||||
|
@app.route('/ogdhcp/v1/subnets/<int:subnetId>/hosts', methods=['GET'])
|
||||||
|
def get_hosts(subnetId):
|
||||||
|
# Simular respuesta de éxito
|
||||||
|
return jsonify({
|
||||||
|
"success": "Hosts retrieved successfully",
|
||||||
|
"message": [
|
||||||
|
{"ip-address": "192.168.1.10", "hw-address": "00:0c:29:6b:5e:71", "hostname": "host1"},
|
||||||
|
{"ip-address": "192.168.1.20", "hw-address": "00:0c:29:6b:5e:72", "hostname": "host2"}
|
||||||
|
]
|
||||||
|
}), 200
|
||||||
|
|
||||||
|
# Endpoint POST /ogdhcp/v1/subnets/<subnetId>/hosts
|
||||||
|
@app.route('/ogdhcp/v1/subnets/<int:subnetId>/hosts', methods=['POST'])
|
||||||
|
def create_host(subnetId):
|
||||||
|
# Simular respuesta de éxito
|
||||||
|
return jsonify({
|
||||||
|
"success": "Host agregado correctamente",
|
||||||
|
"message": {
|
||||||
|
"id": 1,
|
||||||
|
"subnet": "192.168.1.0/24",
|
||||||
|
"next-server": "192.168.1.1",
|
||||||
|
"boot-file-name": "pxelinux.0",
|
||||||
|
"reservations": [
|
||||||
|
{"hostname": "pc11", "hw-address": "56:6f:c7:4f:00:4f", "ip-address": "172.30.4.11"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}), 200
|
||||||
|
|
||||||
|
# Endpoint DELETE /ogdhcp/v1/subnets/<subnetId>/hosts
|
||||||
|
@app.route('/ogdhcp/v1/subnets/<int:subnetId>/hosts', methods=['DELETE'])
|
||||||
|
def delete_host(subnetId):
|
||||||
|
# Simular respuesta de éxito
|
||||||
|
return jsonify({
|
||||||
|
"success": "Host eliminado correctamente",
|
||||||
|
"message": {
|
||||||
|
"id": 1,
|
||||||
|
"subnet": "192.168.1.0/24",
|
||||||
|
"next-server": "192.168.1.1",
|
||||||
|
"boot-file-name": "pxelinux.0",
|
||||||
|
"reservations": [
|
||||||
|
{"hostname": "host2", "hw-address": "00:0c:29:6b:5e:72", "ip-address": "172.30.4.12"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}), 200
|
||||||
|
|
||||||
|
# Endpoint PUT /ogdhcp/v1/subnets/<subnetId>/hosts
|
||||||
|
@app.route('/ogdhcp/v1/subnets/<int:subnetId>/hosts', methods=['PUT'])
|
||||||
|
def update_host(subnetId):
|
||||||
|
# Simular respuesta de éxito
|
||||||
|
return jsonify({
|
||||||
|
"success": "Host actualizado correctamente",
|
||||||
|
"message": {
|
||||||
|
"id": 1,
|
||||||
|
"subnet": "192.168.1.0/24",
|
||||||
|
"next-server": "192.168.1.1",
|
||||||
|
"boot-file-name": "pxelinux.0",
|
||||||
|
"reservations": [
|
||||||
|
{"hostname": "pc11", "hw-address": "56:6f:c7:4f:01:01", "ip-address": "192.168.1.11"},
|
||||||
|
{"hostname": "host2", "hw-address": "00:0c:29:6b:5e:72", "ip-address": "192.168.1.12"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}), 200
|
||||||
|
|
||||||
|
# Endpoint POST /ogdhcp/v1/backup
|
||||||
|
@app.route('/ogdhcp/v1/backup', methods=['POST'])
|
||||||
|
def backup_config():
|
||||||
|
# Simular respuesta de éxito
|
||||||
|
return jsonify({
|
||||||
|
"success": "Configuración cargada correctamente"
|
||||||
|
}), 200
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(debug=True, port=8006)
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
robotframework
|
||||||
|
robotframework-requests
|
||||||
|
|
@ -0,0 +1,215 @@
|
||||||
|
*** Settings ***
|
||||||
|
Documentation This is a basic skeleton for a Robot Framework test suite.
|
||||||
|
Library Collections
|
||||||
|
Library RequestsLibrary
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** Variables ***
|
||||||
|
${BASE_URL} http://localhost:8006/ogdhcp/v1
|
||||||
|
${headers} Create Dictionary Content-Type application/json
|
||||||
|
${modified_subnet} Create Dictionary mask=255.255.192.0 address=192.168.1.0 nextServer=192.168.1.1 bootFileName=pxelinux.0
|
||||||
|
${wrong_subnet_data_netmask} Create Dictionary mask=333.333.333.333 address=192.168.1.0 nextServer=192.168.1.1 bootFileName=pxelinux.0
|
||||||
|
${wrong_subnet_data_address} Create Dictionary mask=255.255.255.0 address=444.168.1.0 nextServer=192.168.1.1 bootFileName=pxelinux.0
|
||||||
|
${wrong_subnet_data_server} Create Dictionary mask=255.255.255.0 address=192.168.1.0 nextServer=555.168.1.1 bootFileName=pxelinux.0
|
||||||
|
${invalid_net_id} 999
|
||||||
|
${valid_net_id} 2
|
||||||
|
${subnet_error} 0
|
||||||
|
|
||||||
|
*** Test Cases ***
|
||||||
|
Get Status of the DHCP server
|
||||||
|
[Documentation] Get status of the dhcp server and check services status
|
||||||
|
[Tags] status
|
||||||
|
${response}= GET ${BASE_URL}/status
|
||||||
|
Status Should Be 200 ${response}
|
||||||
|
Log ${response.json()}
|
||||||
|
# Convertir la respuesta a JSON usando ${response.json()}
|
||||||
|
${json}= Convert to Dictionary ${response.json()}
|
||||||
|
Dictionary Should Contain Key ${json} success
|
||||||
|
Dictionary Should Contain Key ${json} message
|
||||||
|
Should Contain ${response.json()['message']} disk_usage
|
||||||
|
Should Contain ${response.json()['message']} subnets
|
||||||
|
Should Contain ${response.json()['message']['disk_usage']} total
|
||||||
|
|
||||||
|
|
||||||
|
Get All Subnets
|
||||||
|
[Documentation] Este test verifica que la API retorna las subredes correctamente con el código 200.
|
||||||
|
[Tags] subnets
|
||||||
|
${response}= GET ${BASE_URL}/subnets
|
||||||
|
# Verificar código de estado HTTP
|
||||||
|
Should Be Equal As Numbers ${response.status_code} 200
|
||||||
|
${json}= Convert To Dictionary ${response.json()}
|
||||||
|
# Verificar que la respuesta contiene las claves 'success' y 'message'
|
||||||
|
Dictionary Should Contain Key ${json} success
|
||||||
|
Dictionary Should Contain Key ${json} message
|
||||||
|
# Validar el mensaje de éxito
|
||||||
|
Should Be Equal ${json['success']} Subredes obtenidas correctamente
|
||||||
|
# Verificar que 'message' es una lista
|
||||||
|
# Should Be True ${json['message']} is list
|
||||||
|
# Verificar que cada subred en 'message' tiene los campos esperados
|
||||||
|
FOR ${subred} IN @{json['message']}
|
||||||
|
Dictionary Should Contain Key ${subred} id
|
||||||
|
Dictionary Should Contain Key ${subred} subnet
|
||||||
|
END
|
||||||
|
|
||||||
|
Post a new subnet
|
||||||
|
[Documentation] Post a new subnet
|
||||||
|
[Tags] subnets
|
||||||
|
${new_subnet} Create Dictionary
|
||||||
|
... subnetId=${valid_net_id}
|
||||||
|
... mask=255.255.255.0
|
||||||
|
... address=192.168.2.0
|
||||||
|
... nextServer=192.168.2.1
|
||||||
|
... bootFileName=pxelinux.0
|
||||||
|
${headers}= Create Dictionary Content-Type=application/json
|
||||||
|
${response}= POST ${BASE_URL}/subnets json=${new_subnet} headers=${headers}
|
||||||
|
Status Should Be 200 ${response}
|
||||||
|
${json}= Convert to Dictionary ${response.json()}
|
||||||
|
Dictionary Should Contain Key ${json} success
|
||||||
|
Dictionary Should Contain Key ${json} message
|
||||||
|
Should Contain ${json["success"]} Subred agregada correctamente
|
||||||
|
Should Be Equal As Numbers ${json["message"]["id"]} ${valid_net_id}
|
||||||
|
|
||||||
|
|
||||||
|
Post a new subnet with existing id
|
||||||
|
[Documentation] Post a new subnet with invalid data
|
||||||
|
[Tags] subnets
|
||||||
|
${new_subnet} Create Dictionary
|
||||||
|
... subnetId=2
|
||||||
|
... mask=255.255.255.0
|
||||||
|
... address=192.168.3.0
|
||||||
|
... nextServer=192.168.3.1
|
||||||
|
... bootFileName=pxelinux.0
|
||||||
|
${headers}= Create Dictionary Content-Type=application/json
|
||||||
|
${response}= POST ${BASE_URL}/subnets json=${new_subnet} headers=${headers} expected_status=400
|
||||||
|
Status Should Be 400 ${response}
|
||||||
|
${json}= Convert to Dictionary ${response.json()}
|
||||||
|
Dictionary Should Contain Key ${json} error
|
||||||
|
Should Contain ${response.json()["error"]} La subred con el id '${valid_net_id}' ya existe.
|
||||||
|
|
||||||
|
Post a new subnet with existing address
|
||||||
|
[Documentation] Post a new subnet with invalid data
|
||||||
|
[Tags] subnets
|
||||||
|
${headers}= Create Dictionary Content-Type=application/json
|
||||||
|
${new_subnet_invalid} Create Dictionary
|
||||||
|
... subnetId=3
|
||||||
|
... mask=255.255.255.0
|
||||||
|
... address=192.168.1.0
|
||||||
|
... nextServer=192.168.1.1
|
||||||
|
... bootFileName=pxelinux.0
|
||||||
|
|
||||||
|
${response}= POST ${BASE_URL}/subnets json=${new_subnet_invalid} headers=${headers} expected_status=400
|
||||||
|
Status Should Be 400 ${response}
|
||||||
|
${json}= Convert to Dictionary ${response.json()}
|
||||||
|
Dictionary Should Contain Key ${json} error
|
||||||
|
Should Contain ${response.json()['error']} La subred con la dirección '192.168.1.0/24' ya existe
|
||||||
|
|
||||||
|
|
||||||
|
Modify an existing subnet by id
|
||||||
|
[Documentation] Modify a subnet by id
|
||||||
|
[Tags] subnets
|
||||||
|
${headers}= Create Dictionary Content-Type=application/json
|
||||||
|
${modified_subnet}= Create Dictionary
|
||||||
|
... mask=255.255.192.0
|
||||||
|
... address=192.168.1.0
|
||||||
|
... nextServer=192.168.1.1
|
||||||
|
... bootFileName=pxelinux.0
|
||||||
|
# Modificar la subred con id=2
|
||||||
|
${response}= PUT ${BASE_URL}/subnets/2 json=${modified_subnet} headers=${headers} expected_status=200
|
||||||
|
Status Should Be 200 ${response}
|
||||||
|
${json}= Convert to Dictionary ${response.json()}
|
||||||
|
# Verificar que la respuesta contiene clave 'success'
|
||||||
|
Dictionary Should Contain Key ${json} success
|
||||||
|
|
||||||
|
# Validar el contenido del mensaje de éxito
|
||||||
|
Should Be Equal ${json['success']} Subred modificada correctamente
|
||||||
|
Should Be Equal ${json['message']['id']} 2
|
||||||
|
|
||||||
|
|
||||||
|
Modify a subnet with invalid id
|
||||||
|
[Documentation] Este test verifica que la modificación de una subred falla cuando el ID no existe.
|
||||||
|
[Tags] subnets
|
||||||
|
${headers}= Create Dictionary Content-Type=application/json
|
||||||
|
${modificar_subred}= Create Dictionary mask=255.255.192.0 address=192.168.1.0 nextServer=192.168.1.1 bootFileName=pxelinux.0
|
||||||
|
${response}= PUT ${BASE_URL}/ogdhcp/v1/subnets/${invalid_net_id} json=${modificar_subred} headers=${headers} expected_status=404
|
||||||
|
|
||||||
|
# Verificar código de estado HTTP
|
||||||
|
Should Be Equal As Numbers ${response.status_code} 404
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Modify subnet with error to save configuration
|
||||||
|
[Documentation] Este test verifica que la modificación falla cuando hay un error al guardar la configuración en Kea DHCP.
|
||||||
|
[Tags] subnets
|
||||||
|
${headers}= Create Dictionary Content-Type=application/json
|
||||||
|
${modificar_subred}= Create Dictionary subnet="192.168.1.0" mask="255.255.255.0" nextServer="192.168.1.1" bootFileName="pxelinux.0"
|
||||||
|
${response}= PUT ${BASE_URL}/subnets/${subnet_error} json=${modificar_subred} headers=${headers} expected_status=400
|
||||||
|
|
||||||
|
# Verificar código de estado HTTP
|
||||||
|
Should Be Equal As Numbers ${response.status_code} 400
|
||||||
|
|
||||||
|
${json}= Convert To Dictionary ${response.json()}
|
||||||
|
|
||||||
|
# Verificar que la respuesta contiene el error esperado
|
||||||
|
Should Be Equal ${json['error']} Error al guardar la configuración en Kea DHCP: Unable to save configuration
|
||||||
|
|
||||||
|
Modify subnet with invalid configuration address without netmask
|
||||||
|
[Documentation] Este test verifica que la modificación falla cuando hay un error en la configuración de Kea DHCP.
|
||||||
|
[Tags] subnets
|
||||||
|
${headers}= Create Dictionary Content-Type=application/json
|
||||||
|
${modificar_subred}= Create Dictionary address="192.168.1.0" nextServer="192.168.1.1" bootFileName="pxelinux.0"
|
||||||
|
|
||||||
|
${response}= PUT ${BASE_URL}/subnets/2 json=${modificar_subred} headers=${headers} expected_status=400
|
||||||
|
|
||||||
|
# Verificar código de estado HTTP
|
||||||
|
Should Be Equal As Numbers ${response.status_code} 400
|
||||||
|
|
||||||
|
${json}= Convert To Dictionary ${response.json()}
|
||||||
|
|
||||||
|
# Verificar que la respuesta contiene el error esperado
|
||||||
|
Should Be Equal ${json['error']} Falta un parámetro requerido: mask
|
||||||
|
|
||||||
|
Modify subnet with invalid configuration netmask without address
|
||||||
|
[Documentation] Este test verifica que la modificación falla cuando hay un error en la configuración de Kea DHCP.
|
||||||
|
[Tags] subnets
|
||||||
|
${headers}= Create Dictionary Content-Type=application/json
|
||||||
|
${modificar_subred}= Create Dictionary mask="255.255.255.0" nextServer="192.168.1.1" bootFileName="pxelinux.0"
|
||||||
|
|
||||||
|
${response}= PUT ${BASE_URL}/subnets/2 json=${modificar_subred} headers=${headers} expected_status=400
|
||||||
|
|
||||||
|
# Verificar código de estado HTTP
|
||||||
|
Should Be Equal As Numbers ${response.status_code} 400
|
||||||
|
|
||||||
|
${json}= Convert To Dictionary ${response.json()}
|
||||||
|
|
||||||
|
# Verificar que la respuesta contiene el error esperado
|
||||||
|
Should Be Equal ${json['error']} Falta un parámetro requerido: address
|
||||||
|
|
||||||
|
Delete subnet by id
|
||||||
|
[Documentation] Este test verifica que la subred se elimina correctamente con el código 200.
|
||||||
|
[Tags] subnets
|
||||||
|
${response}= DELETE ${BASE_URL}/subnets/${valid_net_id}
|
||||||
|
# Verificar código de estado HTTP
|
||||||
|
Should Be Equal As Numbers ${response.status_code} 200
|
||||||
|
${json}= Convert To Dictionary ${response.json()}
|
||||||
|
# Verificar que la respuesta contiene la clave 'success'
|
||||||
|
Dictionary Should Contain Key ${json} success
|
||||||
|
# Validar el mensaje de éxito
|
||||||
|
Should Be Equal ${json['success']} Subred eliminada correctamente
|
||||||
|
|
||||||
|
Delete subnet - Error: wrong subnet Id
|
||||||
|
[Documentation] Este test verifica que la eliminación falla si la subred con el ID no existe.
|
||||||
|
[Tags] subnets
|
||||||
|
${response}= DELETE ${BASE_URL}/subnets/${invalid_net_id} expected_status=404
|
||||||
|
# Verificar código de estado HTTP
|
||||||
|
Should Be Equal As Numbers ${response.status_code} 404
|
||||||
|
${json}= Convert To Dictionary ${response.json()}
|
||||||
|
# Verificar que la respuesta contiene la clave 'error'
|
||||||
|
Dictionary Should Contain Key ${json} error
|
||||||
|
# Validar el mensaje de error
|
||||||
|
Should Be Equal ${json['error']} La subred con el id '999' no existe
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue